Bug 1491293 - Do not generate unused code for BinAST parser. r=Yoric
authorTooru Fujisawa <arai_a@mac.com>
Thu, 04 Oct 2018 21:22:42 +0900
changeset 495396 ee9161a4b37ab0d625f3ed25ec9f356d22b63e50
parent 495355 1b1d6fa744e7a7ceaf6e680ca450441a160fc00f
child 495397 638b59fbfb47e37e088c9cf08fd5ba0ae5282660
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric
bugs1491293
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1491293 - Do not generate unused code for BinAST parser. r=Yoric
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource-auto.h
js/src/frontend/binsource/src/main.rs
js/src/frontend/binsource/src/refgraph.rs
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -37,61 +37,16 @@ template<typename Tok, size_t N>
 bool operator==(const typename Tok::Chars& left, const char (&right)[N]) {
     return Tok::equals(left, right);
 }
 
 
 // ----- Sums of interfaces (autogenerated, by lexicographical order)
 // Sums of sums are flattened.
 /*
-ArrowExpression ::= EagerArrowExpressionWithExpression
-    EagerArrowExpressionWithFunctionBody
-    LazyArrowExpressionWithExpression
-    LazyArrowExpressionWithFunctionBody
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseArrowExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumArrowExpression(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumArrowExpression(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::EagerArrowExpressionWithExpression:
-        MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression(start, kind, fields));
-        break;
-      case BinKind::EagerArrowExpressionWithFunctionBody:
-        MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody(start, kind, fields));
-        break;
-      case BinKind::LazyArrowExpressionWithExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression(start, kind, fields));
-        break;
-      case BinKind::LazyArrowExpressionWithFunctionBody:
-        MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("ArrowExpression", kind);
-    }
-    return result;
-}
-
-/*
 AssertedMaybePositionalParameterName ::= AssertedParameterName
     AssertedPositionalParameterName
     AssertedRestParameterName
 */
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseAssertedMaybePositionalParameterName(
         AssertedScopeKind scopeKind,
         MutableHandle<GCVector<JSAtom*>> positionalParams)
@@ -233,53 +188,16 @@ BinASTParser<Tok>::parseSumAssignmentTar
         break;
       default:
         return raiseInvalidKind("AssignmentTargetOrAssignmentTargetWithInitializer", kind);
     }
     return result;
 }
 
 /*
-AssignmentTargetPattern ::= ArrayAssignmentTarget
-    ObjectAssignmentTarget
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseAssignmentTargetPattern()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumAssignmentTargetPattern(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumAssignmentTargetPattern(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::ArrayAssignmentTarget:
-        MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, fields));
-        break;
-      case BinKind::ObjectAssignmentTarget:
-        MOZ_TRY_VAR(result, parseInterfaceObjectAssignmentTarget(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("AssignmentTargetPattern", kind);
-    }
-    return result;
-}
-
-/*
 AssignmentTargetProperty ::= AssignmentTargetPropertyIdentifier
     AssignmentTargetPropertyProperty
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseAssignmentTargetProperty()
 {
     BinKind kind;
     BinFields fields(cx_);
@@ -393,53 +311,16 @@ BinASTParser<Tok>::parseSumBindingOrBind
         break;
       default:
         return raiseInvalidKind("BindingOrBindingWithInitializer", kind);
     }
     return result;
 }
 
 /*
-BindingPattern ::= ArrayBinding
-    ObjectBinding
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseBindingPattern()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumBindingPattern(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumBindingPattern(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::ArrayBinding:
-        MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields));
-        break;
-      case BinKind::ObjectBinding:
-        MOZ_TRY_VAR(result, parseInterfaceObjectBinding(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("BindingPattern", kind);
-    }
-    return result;
-}
-
-/*
 BindingProperty ::= BindingPropertyIdentifier
     BindingPropertyProperty
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseBindingProperty()
 {
     BinKind kind;
     BinFields fields(cx_);
@@ -467,65 +348,16 @@ BinASTParser<Tok>::parseSumBindingProper
         break;
       default:
         return raiseInvalidKind("BindingProperty", kind);
     }
     return result;
 }
 
 /*
-ExportDeclaration ::= Export
-    ExportAllFrom
-    ExportDefault
-    ExportFrom
-    ExportLocals
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExportDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumExportDeclaration(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumExportDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::Export:
-        MOZ_TRY_VAR(result, parseInterfaceExport(start, kind, fields));
-        break;
-      case BinKind::ExportAllFrom:
-        MOZ_TRY_VAR(result, parseInterfaceExportAllFrom(start, kind, fields));
-        break;
-      case BinKind::ExportDefault:
-        MOZ_TRY_VAR(result, parseInterfaceExportDefault(start, kind, fields));
-        break;
-      case BinKind::ExportFrom:
-        MOZ_TRY_VAR(result, parseInterfaceExportFrom(start, kind, fields));
-        break;
-      case BinKind::ExportLocals:
-        MOZ_TRY_VAR(result, parseInterfaceExportLocals(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("ExportDeclaration", kind);
-    }
-    return result;
-}
-
-/*
 Expression ::= ArrayExpression
     AssignmentExpression
     AwaitExpression
     BinaryExpression
     CallExpression
     ClassExpression
     CompoundAssignmentExpression
     ComputedMemberExpression
@@ -1048,53 +880,16 @@ BinASTParser<Tok>::parseSumForInOfBindin
         break;
       default:
         return raiseInvalidKind("ForInOfBindingOrAssignmentTarget", kind);
     }
     return result;
 }
 
 /*
-FunctionDeclaration ::= EagerFunctionDeclaration
-    LazyFunctionDeclaration
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseFunctionDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumFunctionDeclaration(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::EagerFunctionDeclaration:
-        MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields));
-        break;
-      case BinKind::LazyFunctionDeclaration:
-        MOZ_TRY_VAR(result, parseInterfaceLazyFunctionDeclaration(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("FunctionDeclaration", kind);
-    }
-    return result;
-}
-
-/*
 FunctionDeclarationOrClassDeclarationOrExpression ::= ArrayExpression
     AssignmentExpression
     AwaitExpression
     BinaryExpression
     CallExpression
     ClassDeclaration
     ClassExpression
     CompoundAssignmentExpression
@@ -1299,127 +1094,16 @@ BinASTParser<Tok>::parseSumFunctionDecla
         break;
       default:
         return raiseInvalidKind("FunctionDeclarationOrClassDeclarationOrVariableDeclaration", kind);
     }
     return result;
 }
 
 /*
-FunctionExpression ::= EagerFunctionExpression
-    LazyFunctionExpression
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseFunctionExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumFunctionExpression(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::EagerFunctionExpression:
-        MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields));
-        break;
-      case BinKind::LazyFunctionExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("FunctionExpression", kind);
-    }
-    return result;
-}
-
-/*
-Getter ::= EagerGetter
-    LazyGetter
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseGetter()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumGetter(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumGetter(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::EagerGetter:
-        MOZ_TRY_VAR(result, parseInterfaceEagerGetter(start, kind, fields));
-        break;
-      case BinKind::LazyGetter:
-        MOZ_TRY_VAR(result, parseInterfaceLazyGetter(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("Getter", kind);
-    }
-    return result;
-}
-
-/*
-ImportDeclaration ::= Import
-    ImportNamespace
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseImportDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumImportDeclaration(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumImportDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::Import:
-        MOZ_TRY_VAR(result, parseInterfaceImport(start, kind, fields));
-        break;
-      case BinKind::ImportNamespace:
-        MOZ_TRY_VAR(result, parseInterfaceImportNamespace(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("ImportDeclaration", kind);
-    }
-    return result;
-}
-
-/*
 ImportDeclarationOrExportDeclarationOrStatement ::= Block
     BreakStatement
     ClassDeclaration
     ContinueStatement
     DebuggerStatement
     DoWhileStatement
     EagerFunctionDeclaration
     EmptyStatement
@@ -1563,151 +1247,16 @@ BinASTParser<Tok>::parseSumImportDeclara
         break;
       default:
         return raiseInvalidKind("ImportDeclarationOrExportDeclarationOrStatement", kind);
     }
     return result;
 }
 
 /*
-IterationStatement ::= DoWhileStatement
-    ForInStatement
-    ForOfStatement
-    ForStatement
-    WhileStatement
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseIterationStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumIterationStatement(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumIterationStatement(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::DoWhileStatement:
-        MOZ_TRY_VAR(result, parseInterfaceDoWhileStatement(start, kind, fields));
-        break;
-      case BinKind::ForInStatement:
-        MOZ_TRY_VAR(result, parseInterfaceForInStatement(start, kind, fields));
-        break;
-      case BinKind::ForOfStatement:
-        MOZ_TRY_VAR(result, parseInterfaceForOfStatement(start, kind, fields));
-        break;
-      case BinKind::ForStatement:
-        MOZ_TRY_VAR(result, parseInterfaceForStatement(start, kind, fields));
-        break;
-      case BinKind::WhileStatement:
-        MOZ_TRY_VAR(result, parseInterfaceWhileStatement(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("IterationStatement", kind);
-    }
-    return result;
-}
-
-/*
-Literal ::= LiteralBooleanExpression
-    LiteralInfinityExpression
-    LiteralNullExpression
-    LiteralNumericExpression
-    LiteralStringExpression
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteral()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumLiteral(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumLiteral(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::LiteralBooleanExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields));
-        break;
-      case BinKind::LiteralInfinityExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression(start, kind, fields));
-        break;
-      case BinKind::LiteralNullExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression(start, kind, fields));
-        break;
-      case BinKind::LiteralNumericExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression(start, kind, fields));
-        break;
-      case BinKind::LiteralStringExpression:
-        MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("Literal", kind);
-    }
-    return result;
-}
-
-/*
-Method ::= EagerMethod
-    LazyMethod
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseMethod()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumMethod(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumMethod(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::EagerMethod:
-        MOZ_TRY_VAR(result, parseInterfaceEagerMethod(start, kind, fields));
-        break;
-      case BinKind::LazyMethod:
-        MOZ_TRY_VAR(result, parseInterfaceLazyMethod(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("Method", kind);
-    }
-    return result;
-}
-
-/*
 MethodDefinition ::= EagerGetter
     EagerMethod
     EagerSetter
     LazyGetter
     LazyMethod
     LazySetter
 */
 template<typename Tok> JS::Result<ParseNode*>
@@ -1937,53 +1486,16 @@ BinASTParser<Tok>::parseSumPropertyName(
         break;
       default:
         return raiseInvalidKind("PropertyName", kind);
     }
     return result;
 }
 
 /*
-Setter ::= EagerSetter
-    LazySetter
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSetter()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumSetter(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSumSetter(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    ParseNode* result;
-    switch (kind) {
-      case BinKind::EagerSetter:
-        MOZ_TRY_VAR(result, parseInterfaceEagerSetter(start, kind, fields));
-        break;
-      case BinKind::LazySetter:
-        MOZ_TRY_VAR(result, parseInterfaceLazySetter(start, kind, fields));
-        break;
-      default:
-        return raiseInvalidKind("Setter", kind);
-    }
-    return result;
-}
-
-/*
 SimpleAssignmentTarget ::= AssignmentTargetIdentifier
     ComputedMemberAssignmentTarget
     StaticMemberAssignmentTarget
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseSimpleAssignmentTarget()
 {
     BinKind kind;
@@ -2300,66 +1812,16 @@ BinASTParser<Tok>::parseSumStatement(con
         MOZ_TRY_VAR(result, parseInterfaceWithStatement(start, kind, fields));
         break;
       default:
         return raiseInvalidKind("Statement", kind);
     }
     return result;
 }
 
-/*
-VariableDeclarationOrExpression ::= ArrayExpression
-    AssignmentExpression
-    AwaitExpression
-    BinaryExpression
-    CallExpression
-    ClassExpression
-    CompoundAssignmentExpression
-    ComputedMemberExpression
-    ConditionalExpression
-    EagerArrowExpressionWithExpression
-    EagerArrowExpressionWithFunctionBody
-    EagerFunctionExpression
-    IdentifierExpression
-    LazyArrowExpressionWithExpression
-    LazyArrowExpressionWithFunctionBody
-    LazyFunctionExpression
-    LiteralBooleanExpression
-    LiteralInfinityExpression
-    LiteralNullExpression
-    LiteralNumericExpression
-    LiteralRegExpExpression
-    LiteralStringExpression
-    NewExpression
-    NewTargetExpression
-    ObjectExpression
-    StaticMemberExpression
-    TemplateExpression
-    ThisExpression
-    UnaryExpression
-    UpdateExpression
-    VariableDeclaration
-    YieldExpression
-    YieldStarExpression
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseVariableDeclarationOrExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-    const auto start = tokenizer_->offset();
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-
-    BINJS_MOZ_TRY_DECL(result, parseSumVariableDeclarationOrExpression(start, kind, fields));
-
-    MOZ_TRY(guard.done());
-    return result;
-}
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseSumVariableDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     ParseNode* result;
     switch (kind) {
       case BinKind::ArrayExpression:
         MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields));
@@ -2465,131 +1927,28 @@ BinASTParser<Tok>::parseSumVariableDecla
     }
     return result;
 }
 
 
 
 // ----- Interfaces (autogenerated, by lexicographical order)
 // When fields have a non-trivial type, implementation is deanonymized and delegated to another parser.
-
-/*
- interface  : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseNull()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::_Null) {
-        return raiseInvalidKind("_Null", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceNull(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseInterfaceNull(const size_t start, const BinKind kind, const BinFields& fields)
-{
-    return raiseError("FIXME: Not implemented yet (Null)");
-}
-
-
-/*
- interface ArrayAssignmentTarget : Node {
-    FrozenArray<(AssignmentTarget or AssignmentTargetWithInitializer)> elements;
-    AssignmentTarget? rest;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseArrayAssignmentTarget()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ArrayAssignmentTarget) {
-        return raiseInvalidKind("ArrayAssignmentTarget", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceArrayAssignmentTarget(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ArrayAssignmentTarget)");
 }
 
-
-/*
- interface ArrayBinding : Node {
-    FrozenArray<(Binding or BindingWithInitializer)?> elements;
-    Binding? rest;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseArrayBinding()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ArrayBinding) {
-        return raiseInvalidKind("ArrayBinding", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceArrayBinding(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ArrayBinding)");
 }
 
-
-/*
- interface ArrayExpression : Node {
-    FrozenArray<(SpreadElement or Expression)?> elements;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseArrayExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ArrayExpression) {
-        return raiseInvalidKind("ArrayExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceArrayExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ArrayExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Elements };
@@ -2879,44 +2238,16 @@ BinASTParser<Tok>::parseInterfaceAsserte
     ParseContext::Scope* scope;
     DeclarationKind declKind;
     MOZ_TRY(getDeclaredScope(scopeKind, kind_, scope, declKind));
     MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured));
     auto result = Ok();
     return result;
 }
 
-
-/*
- interface AssertedParameterName : Node {
-    IdentifierName name;
-    bool isCaptured;
- }
-*/
-template<typename Tok> JS::Result<Ok>
-BinASTParser<Tok>::parseAssertedParameterName(
-        AssertedScopeKind scopeKind,
-        MutableHandle<GCVector<JSAtom*>> positionalParams)
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssertedParameterName) {
-        return raiseInvalidKind("AssertedParameterName", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedParameterName(start, kind, fields,
-        scopeKind, positionalParams));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseInterfaceAssertedParameterName(const size_t start, const BinKind kind, const BinFields& fields,
         AssertedScopeKind scopeKind,
         MutableHandle<GCVector<JSAtom*>> positionalParams)
 {
     MOZ_ASSERT(kind == BinKind::AssertedParameterName);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
@@ -2992,45 +2323,16 @@ BinASTParser<Tok>::parseInterfaceAsserte
         // In non-strict mode code, direct calls to eval can
         // add variables to the call object.
         parseContext_->functionBox()->setHasExtensibleScope();
     }
     auto result = Ok();
     return result;
 }
 
-
-/*
- interface AssertedPositionalParameterName : Node {
-    unsigned long index;
-    IdentifierName name;
-    bool isCaptured;
- }
-*/
-template<typename Tok> JS::Result<Ok>
-BinASTParser<Tok>::parseAssertedPositionalParameterName(
-        AssertedScopeKind scopeKind,
-        MutableHandle<GCVector<JSAtom*>> positionalParams)
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssertedPositionalParameterName) {
-        return raiseInvalidKind("AssertedPositionalParameterName", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedPositionalParameterName(start, kind, fields,
-        scopeKind, positionalParams));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseInterfaceAssertedPositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
         AssertedScopeKind scopeKind,
         MutableHandle<GCVector<JSAtom*>> positionalParams)
 {
     MOZ_ASSERT(kind == BinKind::AssertedPositionalParameterName);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
@@ -3057,44 +2359,16 @@ BinASTParser<Tok>::parseInterfaceAsserte
     ParseContext::Scope* scope;
     DeclarationKind declKind;
     MOZ_TRY(getBoundScope(scopeKind, scope, declKind));
     MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured));
     auto result = Ok();
     return result;
 }
 
-
-/*
- interface AssertedRestParameterName : Node {
-    IdentifierName name;
-    bool isCaptured;
- }
-*/
-template<typename Tok> JS::Result<Ok>
-BinASTParser<Tok>::parseAssertedRestParameterName(
-        AssertedScopeKind scopeKind,
-        MutableHandle<GCVector<JSAtom*>> positionalParams)
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssertedRestParameterName) {
-        return raiseInvalidKind("AssertedRestParameterName", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedRestParameterName(start, kind, fields,
-        scopeKind, positionalParams));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseInterfaceAssertedRestParameterName(const size_t start, const BinKind kind, const BinFields& fields,
         AssertedScopeKind scopeKind,
         MutableHandle<GCVector<JSAtom*>> positionalParams)
 {
     MOZ_ASSERT(kind == BinKind::AssertedRestParameterName);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
@@ -3218,41 +2492,16 @@ BinASTParser<Tok>::parseInterfaceAsserte
         // In non-strict mode code, direct calls to eval can
         // add variables to the call object.
         parseContext_->functionBox()->setHasExtensibleScope();
     }
     auto result = Ok();
     return result;
 }
 
-
-/*
- interface AssignmentExpression : Node {
-    AssignmentTarget binding;
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseAssignmentExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssignmentExpression) {
-        return raiseInvalidKind("AssignmentExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssignmentExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::AssignmentExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Binding, BinField::Expression };
@@ -3308,165 +2557,40 @@ BinASTParser<Tok>::parseInterfaceAssignm
     if (!IsIdentifier(name)) {
         return raiseError("Invalid identifier");
     }
     BINJS_TRY(usedNames_.noteUse(cx_, name, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
     BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
     return result;
 }
 
-
-/*
- interface AssignmentTargetPropertyIdentifier : Node {
-    AssignmentTargetIdentifier binding;
-    Expression? init;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseAssignmentTargetPropertyIdentifier()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssignmentTargetPropertyIdentifier) {
-        return raiseInvalidKind("AssignmentTargetPropertyIdentifier", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetPropertyIdentifier(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentTargetPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (AssignmentTargetPropertyIdentifier)");
 }
 
-
-/*
- interface AssignmentTargetPropertyProperty : Node {
-    PropertyName name;
-    (AssignmentTarget or AssignmentTargetWithInitializer) binding;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseAssignmentTargetPropertyProperty()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssignmentTargetPropertyProperty) {
-        return raiseInvalidKind("AssignmentTargetPropertyProperty", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetPropertyProperty(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentTargetPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (AssignmentTargetPropertyProperty)");
 }
 
-
-/*
- interface AssignmentTargetWithInitializer : Node {
-    AssignmentTarget binding;
-    Expression init;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseAssignmentTargetWithInitializer()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AssignmentTargetWithInitializer) {
-        return raiseInvalidKind("AssignmentTargetWithInitializer", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetWithInitializer(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (AssignmentTargetWithInitializer)");
 }
 
-
-/*
- interface AwaitExpression : Node {
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseAwaitExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::AwaitExpression) {
-        return raiseInvalidKind("AwaitExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceAwaitExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (AwaitExpression)");
 }
 
-
-/*
- interface BinaryExpression : Node {
-    BinaryOperator operator;
-    Expression left;
-    Expression right;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseBinaryExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::BinaryExpression) {
-        return raiseInvalidKind("BinaryExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceBinaryExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::BinaryExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Operator, BinField::Left, BinField::Right };
@@ -3615,103 +2739,28 @@ BinASTParser<Tok>::parseInterfaceBinding
 
     if (!IsIdentifier(name)) {
         return raiseError("Invalid identifier");
     }
     BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
     return result;
 }
 
-
-/*
- interface BindingPropertyIdentifier : Node {
-    BindingIdentifier binding;
-    Expression? init;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseBindingPropertyIdentifier()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::BindingPropertyIdentifier) {
-        return raiseInvalidKind("BindingPropertyIdentifier", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceBindingPropertyIdentifier(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBindingPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (BindingPropertyIdentifier)");
 }
 
-
-/*
- interface BindingPropertyProperty : Node {
-    PropertyName name;
-    (Binding or BindingWithInitializer) binding;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseBindingPropertyProperty()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::BindingPropertyProperty) {
-        return raiseInvalidKind("BindingPropertyProperty", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceBindingPropertyProperty(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBindingPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (BindingPropertyProperty)");
 }
 
-
-/*
- interface BindingWithInitializer : Node {
-    Binding binding;
-    Expression init;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseBindingWithInitializer()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::BindingWithInitializer) {
-        return raiseInvalidKind("BindingWithInitializer", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceBindingWithInitializer(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (BindingWithInitializer)");
 }
 
 
 /*
@@ -3757,40 +2806,16 @@ BinASTParser<Tok>::parseInterfaceBlock(c
     BINJS_MOZ_TRY_DECL(statements, parseListOfStatement());
 
     MOZ_TRY(checkClosedVars(currentScope));
     BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, parseContext_));
     BINJS_TRY_DECL(result, factory_.newLexicalScope(*bindings, statements));
     return result;
 }
 
-
-/*
- interface BreakStatement : Node {
-    Label? label;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseBreakStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::BreakStatement) {
-        return raiseInvalidKind("BreakStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceBreakStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::BreakStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Label };
@@ -3814,41 +2839,16 @@ BinASTParser<Tok>::parseInterfaceBreakSt
                 return raiseError(kind, "Label not found");
             }
         }
     }
     BINJS_TRY_DECL(result, factory_.newBreakStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface CallExpression : Node {
-    (Expression or Super) callee;
-    Arguments arguments;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseCallExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::CallExpression) {
-        return raiseInvalidKind("CallExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceCallExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::CallExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Callee, BinField::Arguments };
@@ -3938,42 +2938,16 @@ BinASTParser<Tok>::parseInterfaceCatchCl
 
     MOZ_TRY(checkClosedVars(currentScope));
     BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, parseContext_));
     BINJS_TRY_DECL(result, factory_.newLexicalScope(*bindings, body));
     BINJS_TRY(factory_.setupCatchScope(result, binding, body));
     return result;
 }
 
-
-/*
- interface ClassDeclaration : Node {
-    BindingIdentifier name;
-    Expression? super;
-    FrozenArray<ClassElement> elements;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseClassDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ClassDeclaration) {
-        return raiseInvalidKind("ClassDeclaration", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceClassDeclaration(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ClassDeclaration)");
 }
 
 
 /*
@@ -4001,74 +2975,22 @@ BinASTParser<Tok>::parseClassElement()
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceClassElement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ClassElement)");
 }
 
-
-/*
- interface ClassExpression : Node {
-    BindingIdentifier? name;
-    Expression? super;
-    FrozenArray<ClassElement> elements;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseClassExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ClassExpression) {
-        return raiseInvalidKind("ClassExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceClassExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ClassExpression)");
 }
 
-
-/*
- interface CompoundAssignmentExpression : Node {
-    CompoundAssignmentOperator operator;
-    SimpleAssignmentTarget binding;
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseCompoundAssignmentExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::CompoundAssignmentExpression) {
-        return raiseInvalidKind("CompoundAssignmentExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::CompoundAssignmentExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Operator, BinField::Binding, BinField::Expression };
@@ -4119,41 +3041,16 @@ BinASTParser<Tok>::parseInterfaceCompoun
       case CompoundAssignmentOperator::BitAndAssign:
         pnk = ParseNodeKind::BitAndAssign;
         break;
     }
     BINJS_TRY_DECL(result, factory_.newAssignment(pnk, binding, expression));
     return result;
 }
 
-
-/*
- interface ComputedMemberAssignmentTarget : Node {
-    (Expression or Super) object;
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseComputedMemberAssignmentTarget()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ComputedMemberAssignmentTarget) {
-        return raiseInvalidKind("ComputedMemberAssignmentTarget", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceComputedMemberAssignmentTarget(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ComputedMemberAssignmentTarget);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Object, BinField::Expression };
@@ -4163,41 +3060,16 @@ BinASTParser<Tok>::parseInterfaceCompute
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
     BINJS_TRY_DECL(result, factory_.newPropertyByValue(object, expression, tokenizer_->offset()));
     return result;
 }
 
-
-/*
- interface ComputedMemberExpression : Node {
-    (Expression or Super) object;
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseComputedMemberExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ComputedMemberExpression) {
-        return raiseInvalidKind("ComputedMemberExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceComputedMemberExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceComputedMemberExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ComputedMemberExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Object, BinField::Expression };
@@ -4207,72 +3079,22 @@ BinASTParser<Tok>::parseInterfaceCompute
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
     BINJS_TRY_DECL(result, factory_.newPropertyByValue(object, expression, tokenizer_->offset()));
     return result;
 }
 
-
-/*
- interface ComputedPropertyName : Node {
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseComputedPropertyName()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ComputedPropertyName) {
-        return raiseInvalidKind("ComputedPropertyName", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceComputedPropertyName(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceComputedPropertyName(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ComputedPropertyName)");
 }
 
-
-/*
- interface ConditionalExpression : Node {
-    Expression test;
-    Expression consequent;
-    Expression alternate;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseConditionalExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ConditionalExpression) {
-        return raiseInvalidKind("ConditionalExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceConditionalExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceConditionalExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ConditionalExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Test, BinField::Consequent, BinField::Alternate };
@@ -4284,40 +3106,16 @@ BinASTParser<Tok>::parseInterfaceConditi
     BINJS_MOZ_TRY_DECL(consequent, parseExpression());
 
     BINJS_MOZ_TRY_DECL(alternate, parseExpression());
 
     BINJS_TRY_DECL(result, factory_.newConditional(test, consequent, alternate));
     return result;
 }
 
-
-/*
- interface ContinueStatement : Node {
-    Label? label;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseContinueStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ContinueStatement) {
-        return raiseInvalidKind("ContinueStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceContinueStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceContinueStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ContinueStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Label };
@@ -4341,41 +3139,16 @@ BinASTParser<Tok>::parseInterfaceContinu
             }
         }
     }
 
     BINJS_TRY_DECL(result, factory_.newContinueStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface DataProperty : Node {
-    PropertyName name;
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseDataProperty()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::DataProperty) {
-        return raiseInvalidKind("DataProperty", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceDataProperty(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDataProperty(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::DataProperty);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Name, BinField::Expression };
@@ -4389,39 +3162,16 @@ BinASTParser<Tok>::parseInterfaceDataPro
     if (!factory_.isUsableAsObjectPropertyName(name)) {
         return raiseError("DataProperty key kind");
     }
 
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));
     return result;
 }
 
-
-/*
- interface DebuggerStatement : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseDebuggerStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::DebuggerStatement) {
-        return raiseInvalidKind("DebuggerStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceDebuggerStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDebuggerStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (DebuggerStatement)");
 }
 
 
 /*
@@ -4461,41 +3211,16 @@ BinASTParser<Tok>::parseInterfaceDirecti
     RootedAtom rawValue(cx_);
     MOZ_TRY_VAR(rawValue, tokenizer_->readAtom());
 
     TokenPos pos = tokenizer_->pos(start);
     BINJS_TRY_DECL(result, factory_.newStringLiteral(rawValue, pos));
     return result;
 }
 
-
-/*
- interface DoWhileStatement : Node {
-    Expression test;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseDoWhileStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::DoWhileStatement) {
-        return raiseInvalidKind("DoWhileStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceDoWhileStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDoWhileStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::DoWhileStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Test, BinField::Body };
@@ -4506,110 +3231,28 @@ BinASTParser<Tok>::parseInterfaceDoWhile
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
     BINJS_MOZ_TRY_DECL(body, parseStatement());
 
     BINJS_TRY_DECL(result, factory_.newDoWhileStatement(body, test, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface EagerArrowExpressionWithExpression : Node {
-    bool isAsync;
-    unsigned long length;
-    ArrowExpressionContentsWithExpression contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerArrowExpressionWithExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerArrowExpressionWithExpression) {
-        return raiseInvalidKind("EagerArrowExpressionWithExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerArrowExpressionWithExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (EagerArrowExpressionWithExpression)");
 }
 
-
-/*
- interface EagerArrowExpressionWithFunctionBody : Node {
-    bool isAsync;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    ArrowExpressionContentsWithFunctionBody contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerArrowExpressionWithFunctionBody()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerArrowExpressionWithFunctionBody) {
-        return raiseInvalidKind("EagerArrowExpressionWithFunctionBody", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerArrowExpressionWithFunctionBody(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (EagerArrowExpressionWithFunctionBody)");
 }
 
-
-/*
- interface EagerFunctionDeclaration : Node {
-    bool isAsync;
-    bool isGenerator;
-    BindingIdentifier name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    FunctionOrMethodContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerFunctionDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerFunctionDeclaration) {
-        return raiseInvalidKind("EagerFunctionDeclaration", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerFunctionDeclaration);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[6] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::Length, BinField::Directives, BinField::Contents };
@@ -4652,45 +3295,16 @@ BinASTParser<Tok>::parseInterfaceEagerFu
         length, &params, &tmpBody));
     BINJS_MOZ_TRY_DECL(body, appendDirectivesToBody(tmpBody, directives));
     BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, parseContext_));
     BINJS_TRY_VAR(body, factory_.newLexicalScope(*lexicalScopeData, body));
     BINJS_MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox));
     return result;
 }
 
-
-/*
- interface EagerFunctionExpression : Node {
-    bool isAsync;
-    bool isGenerator;
-    BindingIdentifier? name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    FunctionExpressionContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerFunctionExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerFunctionExpression) {
-        return raiseInvalidKind("EagerFunctionExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerFunctionExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerFunctionExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[6] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::Length, BinField::Directives, BinField::Contents };
@@ -4733,42 +3347,16 @@ BinASTParser<Tok>::parseInterfaceEagerFu
         length, &params, &tmpBody));
     BINJS_MOZ_TRY_DECL(body, appendDirectivesToBody(tmpBody, directives));
     BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, parseContext_));
     BINJS_TRY_VAR(body, factory_.newLexicalScope(*lexicalScopeData, body));
     BINJS_MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox));
     return result;
 }
 
-
-/*
- interface EagerGetter : Node {
-    PropertyName name;
-    FrozenArray<Directive> directives;
-    GetterContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerGetter()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerGetter) {
-        return raiseInvalidKind("EagerGetter", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerGetter(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerGetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerGetter);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Name, BinField::Directives, BinField::Contents };
@@ -4808,45 +3396,16 @@ BinASTParser<Tok>::parseInterfaceEagerGe
     MOZ_TRY(parseGetterContents(
         length, &params, &tmpBody));
     BINJS_MOZ_TRY_DECL(body, appendDirectivesToBody(tmpBody, directives));
     BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, accessorType));
     return result;
 }
 
-
-/*
- interface EagerMethod : Node {
-    bool isAsync;
-    bool isGenerator;
-    PropertyName name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    FunctionOrMethodContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerMethod()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerMethod) {
-        return raiseInvalidKind("EagerMethod", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerMethod(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerMethod);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[6] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::Length, BinField::Directives, BinField::Contents };
@@ -4889,43 +3448,16 @@ BinASTParser<Tok>::parseInterfaceEagerMe
     MOZ_TRY(parseFunctionOrMethodContents(
         length, &params, &tmpBody));
     BINJS_MOZ_TRY_DECL(body, appendDirectivesToBody(tmpBody, directives));
     BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, accessorType));
     return result;
 }
 
-
-/*
- interface EagerSetter : Node {
-    PropertyName name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    SetterContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEagerSetter()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EagerSetter) {
-        return raiseInvalidKind("EagerSetter", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEagerSetter(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerSetter);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[4] = { BinField::Name, BinField::Length, BinField::Directives, BinField::Contents };
@@ -4966,165 +3498,45 @@ BinASTParser<Tok>::parseInterfaceEagerSe
     MOZ_TRY(parseSetterContents(
         length, &params, &tmpBody));
     BINJS_MOZ_TRY_DECL(body, appendDirectivesToBody(tmpBody, directives));
     BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, accessorType));
     return result;
 }
 
-
-/*
- interface EmptyStatement : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseEmptyStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::EmptyStatement) {
-        return raiseInvalidKind("EmptyStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceEmptyStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EmptyStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     BINJS_TRY_DECL(result, factory_.newEmptyStatement(tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface Export : Node {
-    (FunctionDeclaration or ClassDeclaration or VariableDeclaration) declaration;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExport()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::Export) {
-        return raiseInvalidKind("Export", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceExport(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExport(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (Export)");
 }
 
-
-/*
- interface ExportAllFrom : Node {
-    string moduleSpecifier;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExportAllFrom()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ExportAllFrom) {
-        return raiseInvalidKind("ExportAllFrom", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceExportAllFrom(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExportAllFrom(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ExportAllFrom)");
 }
 
-
-/*
- interface ExportDefault : Node {
-    (FunctionDeclaration or ClassDeclaration or Expression) body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExportDefault()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ExportDefault) {
-        return raiseInvalidKind("ExportDefault", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceExportDefault(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExportDefault(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ExportDefault)");
 }
 
-
-/*
- interface ExportFrom : Node {
-    FrozenArray<ExportFromSpecifier> namedExports;
-    string moduleSpecifier;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExportFrom()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ExportFrom) {
-        return raiseInvalidKind("ExportFrom", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceExportFrom(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExportFrom(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ExportFrom)");
 }
 
 
 /*
@@ -5183,70 +3595,22 @@ BinASTParser<Tok>::parseExportLocalSpeci
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExportLocalSpecifier(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ExportLocalSpecifier)");
 }
 
-
-/*
- interface ExportLocals : Node {
-    FrozenArray<ExportLocalSpecifier> namedExports;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExportLocals()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ExportLocals) {
-        return raiseInvalidKind("ExportLocals", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceExportLocals(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExportLocals(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ExportLocals)");
 }
 
-
-/*
- interface ExpressionStatement : Node {
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseExpressionStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ExpressionStatement) {
-        return raiseInvalidKind("ExpressionStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceExpressionStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ExpressionStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Expression };
@@ -5254,41 +3618,16 @@ BinASTParser<Tok>::parseInterfaceExpress
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
     BINJS_TRY_DECL(result, factory_.newExprStatement(expression, tokenizer_->offset()));
     return result;
 }
 
-
-/*
- interface ForInOfBinding : Node {
-    VariableDeclarationKind kind;
-    Binding binding;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseForInOfBinding()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ForInOfBinding) {
-        return raiseInvalidKind("ForInOfBinding", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceForInOfBinding(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ForInOfBinding);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Kind, BinField::Binding };
@@ -5307,42 +3646,16 @@ BinASTParser<Tok>::parseInterfaceForInOf
         kind_ == VariableDeclarationKind::Let
             ? ParseNodeKind::Let
             : ParseNodeKind::Var;
     BINJS_TRY_DECL(result, factory_.newDeclarationList(pnk, tokenizer_->pos(start)));
     factory_.addList(result, binding);
     return result;
 }
 
-
-/*
- interface ForInStatement : Node {
-    (ForInOfBinding or AssignmentTarget) left;
-    Expression right;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseForInStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ForInStatement) {
-        return raiseInvalidKind("ForInStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceForInStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ForInStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Left, BinField::Right, BinField::Body };
@@ -5368,75 +3681,22 @@ BinASTParser<Tok>::parseInterfaceForInSt
 
     if (!scope.isEmpty()) {
         BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, parseContext_));
         BINJS_TRY_VAR(result, factory_.newLexicalScope(*bindings, result));
     }
     return result;
 }
 
-
-/*
- interface ForOfStatement : Node {
-    (ForInOfBinding or AssignmentTarget) left;
-    Expression right;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseForOfStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ForOfStatement) {
-        return raiseInvalidKind("ForOfStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceForOfStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForOfStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ForOfStatement)");
 }
 
-
-/*
- interface ForStatement : Node {
-    (VariableDeclaration or Expression)? init;
-    Expression? test;
-    Expression? update;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseForStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ForStatement) {
-        return raiseInvalidKind("ForStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceForStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceForStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ForStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[4] = { BinField::Init, BinField::Test, BinField::Update, BinField::Body };
@@ -5758,42 +4018,16 @@ BinASTParser<Tok>::parseInterfaceIdentif
     if (!IsIdentifier(name)) {
         return raiseError("Invalid identifier");
     }
     BINJS_TRY(usedNames_.noteUse(cx_, name, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
     BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
     return result;
 }
 
-
-/*
- interface IfStatement : Node {
-    Expression test;
-    Statement consequent;
-    Statement? alternate;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseIfStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::IfStatement) {
-        return raiseInvalidKind("IfStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceIfStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::IfStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Test, BinField::Consequent, BinField::Alternate };
@@ -5805,74 +4039,22 @@ BinASTParser<Tok>::parseInterfaceIfState
     BINJS_MOZ_TRY_DECL(consequent, parseStatement());
 
     BINJS_MOZ_TRY_DECL(alternate, parseOptionalStatement());
 
     BINJS_TRY_DECL(result, factory_.newIfStatement(start, test, consequent, alternate));
     return result;
 }
 
-
-/*
- interface Import : Node {
-    string moduleSpecifier;
-    BindingIdentifier? defaultBinding;
-    FrozenArray<ImportSpecifier> namedImports;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseImport()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::Import) {
-        return raiseInvalidKind("Import", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceImport(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceImport(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (Import)");
 }
 
-
-/*
- interface ImportNamespace : Node {
-    string moduleSpecifier;
-    BindingIdentifier? defaultBinding;
-    BindingIdentifier namespaceBinding;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseImportNamespace()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ImportNamespace) {
-        return raiseInvalidKind("ImportNamespace", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceImportNamespace(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceImportNamespace(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ImportNamespace)");
 }
 
 
 /*
@@ -5900,41 +4082,16 @@ BinASTParser<Tok>::parseImportSpecifier(
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceImportSpecifier(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ImportSpecifier)");
 }
 
-
-/*
- interface LabelledStatement : Node {
-    Label label;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLabelledStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LabelledStatement) {
-        return raiseInvalidKind("LabelledStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLabelledStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LabelledStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Label, BinField::Body };
@@ -5948,110 +4105,28 @@ BinASTParser<Tok>::parseInterfaceLabelle
     }
     ParseContext::LabelStatement stmt(parseContext_, label);
     BINJS_MOZ_TRY_DECL(body, parseStatement());
 
     BINJS_TRY_DECL(result, factory_.newLabeledStatement(label->asPropertyName(), body, start));
     return result;
 }
 
-
-/*
- interface LazyArrowExpressionWithExpression : Node {
-    bool isAsync;
-    unsigned long length;
-    ArrowExpressionContentsWithExpression contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazyArrowExpressionWithExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazyArrowExpressionWithExpression) {
-        return raiseInvalidKind("LazyArrowExpressionWithExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazyArrowExpressionWithExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazyArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (LazyArrowExpressionWithExpression)");
 }
 
-
-/*
- interface LazyArrowExpressionWithFunctionBody : Node {
-    bool isAsync;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    ArrowExpressionContentsWithFunctionBody contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazyArrowExpressionWithFunctionBody()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazyArrowExpressionWithFunctionBody) {
-        return raiseInvalidKind("LazyArrowExpressionWithFunctionBody", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazyArrowExpressionWithFunctionBody(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazyArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (LazyArrowExpressionWithFunctionBody)");
 }
 
-
-/*
- interface LazyFunctionDeclaration : Node {
-    bool isAsync;
-    bool isGenerator;
-    BindingIdentifier name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    FunctionOrMethodContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazyFunctionDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazyFunctionDeclaration) {
-        return raiseInvalidKind("LazyFunctionDeclaration", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazyFunctionDeclaration(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazyFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LazyFunctionDeclaration);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::Length, BinField::Directives, BinField::ContentsSkip, BinField::Contents };
@@ -6096,45 +4171,16 @@ BinASTParser<Tok>::parseInterfaceLazyFun
     }
     lazy->setIsBinAST();
     funbox->function()->initLazyScript(lazy);
 
     BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(skipStart, kind, funbox));
     return result;
 }
 
-
-/*
- interface LazyFunctionExpression : Node {
-    bool isAsync;
-    bool isGenerator;
-    BindingIdentifier? name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    FunctionExpressionContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazyFunctionExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazyFunctionExpression) {
-        return raiseInvalidKind("LazyFunctionExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazyFunctionExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazyFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LazyFunctionExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::Length, BinField::Directives, BinField::ContentsSkip, BinField::Contents };
@@ -6179,140 +4225,34 @@ BinASTParser<Tok>::parseInterfaceLazyFun
     }
     lazy->setIsBinAST();
     funbox->function()->initLazyScript(lazy);
 
     BINJS_MOZ_TRY_DECL(result, makeEmptyFunctionNode(skipStart, kind, funbox));
     return result;
 }
 
-
-/*
- interface LazyGetter : Node {
-    PropertyName name;
-    FrozenArray<Directive> directives;
-    GetterContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazyGetter()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazyGetter) {
-        return raiseInvalidKind("LazyGetter", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazyGetter(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazyGetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (LazyGetter)");
 }
 
-
-/*
- interface LazyMethod : Node {
-    bool isAsync;
-    bool isGenerator;
-    PropertyName name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    FunctionOrMethodContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazyMethod()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazyMethod) {
-        return raiseInvalidKind("LazyMethod", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazyMethod(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazyMethod(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (LazyMethod)");
 }
 
-
-/*
- interface LazySetter : Node {
-    PropertyName name;
-    unsigned long length;
-    FrozenArray<Directive> directives;
-    SetterContents contents;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLazySetter()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LazySetter) {
-        return raiseInvalidKind("LazySetter", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLazySetter(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLazySetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (LazySetter)");
 }
 
-
-/*
- interface LiteralBooleanExpression : Node {
-    bool value;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralBooleanExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralBooleanExpression) {
-        return raiseInvalidKind("LiteralBooleanExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralBooleanExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralBooleanExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralBooleanExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Value };
@@ -6320,103 +4260,33 @@ BinASTParser<Tok>::parseInterfaceLiteral
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(value, tokenizer_->readBool());
 
     BINJS_TRY_DECL(result, factory_.newBooleanLiteral(value, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface LiteralInfinityExpression : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralInfinityExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralInfinityExpression) {
-        return raiseInvalidKind("LiteralInfinityExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralInfinityExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralInfinityExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (LiteralInfinityExpression)");
 }
 
-
-/*
- interface LiteralNullExpression : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralNullExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralNullExpression) {
-        return raiseInvalidKind("LiteralNullExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralNullExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralNullExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralNullExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     BINJS_TRY_DECL(result, factory_.newNullLiteral(tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface LiteralNumericExpression : Node {
-    number value;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralNumericExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralNumericExpression) {
-        return raiseInvalidKind("LiteralNumericExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralNumericExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralNumericExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralNumericExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Value };
@@ -6424,40 +4294,16 @@ BinASTParser<Tok>::parseInterfaceLiteral
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(value, tokenizer_->readDouble());
 
     BINJS_TRY_DECL(result, factory_.newNumber(value, DecimalPoint::HasDecimal, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface LiteralPropertyName : Node {
-    string value;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralPropertyName()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralPropertyName) {
-        return raiseInvalidKind("LiteralPropertyName", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralPropertyName(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralPropertyName(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralPropertyName);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Value };
@@ -6472,41 +4318,16 @@ BinASTParser<Tok>::parseInterfaceLiteral
     if (value->isIndex(&index)) {
         BINJS_TRY_VAR(result, factory_.newNumber(index, NoDecimal, TokenPos(start, tokenizer_->offset())));
     } else {
         BINJS_TRY_VAR(result, factory_.newObjectLiteralPropertyName(value, tokenizer_->pos(start)));
     }
     return result;
 }
 
-
-/*
- interface LiteralRegExpExpression : Node {
-    string pattern;
-    string flags;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralRegExpExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralRegExpExpression) {
-        return raiseInvalidKind("LiteralRegExpExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralRegExpExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralRegExpExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralRegExpExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Pattern, BinField::Flags };
@@ -6542,40 +4363,16 @@ BinASTParser<Tok>::parseInterfaceLiteral
         reflags,
         alloc_,
         TenuredObject));
 
     BINJS_TRY_DECL(result, factory_.newRegExp(reobj, tokenizer_->pos(start), *this));
     return result;
 }
 
-
-/*
- interface LiteralStringExpression : Node {
-    string value;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseLiteralStringExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::LiteralStringExpression) {
-        return raiseInvalidKind("LiteralStringExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceLiteralStringExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceLiteralStringExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::LiteralStringExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Value };
@@ -6584,73 +4381,22 @@ BinASTParser<Tok>::parseInterfaceLiteral
 
     RootedAtom value(cx_);
     MOZ_TRY_VAR(value, tokenizer_->readAtom());
 
     BINJS_TRY_DECL(result, factory_.newStringLiteral(value, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface Module : Node {
-    AssertedVarScope scope;
-    FrozenArray<Directive> directives;
-    FrozenArray<(ImportDeclaration or ExportDeclaration or Statement)> items;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseModule()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::Module) {
-        return raiseInvalidKind("Module", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceModule(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceModule(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (Module)");
 }
 
-
-/*
- interface NewExpression : Node {
-    Expression callee;
-    Arguments arguments;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseNewExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::NewExpression) {
-        return raiseInvalidKind("NewExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceNewExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceNewExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::NewExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Callee, BinField::Arguments };
@@ -6660,129 +4406,34 @@ BinASTParser<Tok>::parseInterfaceNewExpr
     BINJS_MOZ_TRY_DECL(callee, parseExpression());
 
     BINJS_MOZ_TRY_DECL(arguments, parseArguments());
 
     BINJS_TRY_DECL(result, factory_.newNewExpression(tokenizer_->pos(start).begin, callee, arguments));
     return result;
 }
 
-
-/*
- interface NewTargetExpression : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseNewTargetExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::NewTargetExpression) {
-        return raiseInvalidKind("NewTargetExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceNewTargetExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceNewTargetExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (NewTargetExpression)");
 }
 
-
-/*
- interface ObjectAssignmentTarget : Node {
-    FrozenArray<AssignmentTargetProperty> properties;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseObjectAssignmentTarget()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ObjectAssignmentTarget) {
-        return raiseInvalidKind("ObjectAssignmentTarget", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceObjectAssignmentTarget(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceObjectAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ObjectAssignmentTarget)");
 }
 
-
-/*
- interface ObjectBinding : Node {
-    FrozenArray<BindingProperty> properties;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseObjectBinding()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ObjectBinding) {
-        return raiseInvalidKind("ObjectBinding", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceObjectBinding(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceObjectBinding(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ObjectBinding)");
 }
 
-
-/*
- interface ObjectExpression : Node {
-    FrozenArray<ObjectProperty> properties;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseObjectExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ObjectExpression) {
-        return raiseInvalidKind("ObjectExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceObjectExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceObjectExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ObjectExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Properties };
@@ -6790,40 +4441,16 @@ BinASTParser<Tok>::parseInterfaceObjectE
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(properties, parseListOfObjectProperty());
 
     auto result = properties;
     return result;
 }
 
-
-/*
- interface ReturnStatement : Node {
-    Expression? expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseReturnStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ReturnStatement) {
-        return raiseInvalidKind("ReturnStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceReturnStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceReturnStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ReturnStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Expression };
@@ -6837,42 +4464,16 @@ BinASTParser<Tok>::parseInterfaceReturnS
     parseContext_->functionBox()->usesReturn = true;
 
     BINJS_MOZ_TRY_DECL(expression, parseOptionalExpression());
 
     BINJS_TRY_DECL(result, factory_.newReturnStatement(expression, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface Script : Node {
-    AssertedScriptGlobalScope scope;
-    FrozenArray<Directive> directives;
-    FrozenArray<Statement> statements;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseScript()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::Script) {
-        return raiseInvalidKind("Script", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceScript(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceScript(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::Script);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Scope, BinField::Directives, BinField::Statements };
@@ -6951,40 +4552,16 @@ BinASTParser<Tok>::parseInterfaceSetterC
     BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
 
     *paramsOut = params;
     *bodyOut = body;
     auto result = Ok();
     return result;
 }
 
-
-/*
- interface ShorthandProperty : Node {
-    IdentifierExpression name;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseShorthandProperty()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ShorthandProperty) {
-        return raiseInvalidKind("ShorthandProperty", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceShorthandProperty(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceShorthandProperty(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ShorthandProperty);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Name };
@@ -6996,71 +4573,22 @@ BinASTParser<Tok>::parseInterfaceShortha
     if (!factory_.isUsableAsObjectPropertyName(name)) {
         BINJS_TRY_VAR(name, factory_.newObjectLiteralPropertyName(name->name(), tokenizer_->pos(start)));
     }
 
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, name, AccessorType::None));
     return result;
 }
 
-
-/*
- interface SpreadElement : Node {
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSpreadElement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::SpreadElement) {
-        return raiseInvalidKind("SpreadElement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceSpreadElement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSpreadElement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (SpreadElement)");
 }
 
-
-/*
- interface StaticMemberAssignmentTarget : Node {
-    (Expression or Super) object;
-    IdentifierName property;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseStaticMemberAssignmentTarget()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::StaticMemberAssignmentTarget) {
-        return raiseInvalidKind("StaticMemberAssignmentTarget", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceStaticMemberAssignmentTarget(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceStaticMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::StaticMemberAssignmentTarget);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Object, BinField::Property };
@@ -7076,41 +4604,16 @@ BinASTParser<Tok>::parseInterfaceStaticM
 
     }
 
     BINJS_TRY_DECL(name, factory_.newPropertyName(property->asPropertyName(), tokenizer_->pos(nameStart)));
     BINJS_TRY_DECL(result, factory_.newPropertyAccess(object, name));
     return result;
 }
 
-
-/*
- interface StaticMemberExpression : Node {
-    (Expression or Super) object;
-    IdentifierName property;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseStaticMemberExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::StaticMemberExpression) {
-        return raiseInvalidKind("StaticMemberExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceStaticMemberExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceStaticMemberExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::StaticMemberExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Object, BinField::Property };
@@ -7126,39 +4629,16 @@ BinASTParser<Tok>::parseInterfaceStaticM
 
     }
 
     BINJS_TRY_DECL(name, factory_.newPropertyName(property->asPropertyName(), tokenizer_->pos(nameStart)));
     BINJS_TRY_DECL(result, factory_.newPropertyAccess(object, name));
     return result;
 }
 
-
-/*
- interface Super : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSuper()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::Super) {
-        return raiseInvalidKind("Super", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceSuper(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSuper(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (Super)");
 }
 
 
 /*
@@ -7240,41 +4720,16 @@ BinASTParser<Tok>::parseInterfaceSwitchD
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(consequent, parseListOfStatement());
 
     BINJS_TRY_DECL(result, factory_.newCaseOrDefault(start, nullptr, consequent));
     return result;
 }
 
-
-/*
- interface SwitchStatement : Node {
-    Expression discriminant;
-    FrozenArray<SwitchCase> cases;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSwitchStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::SwitchStatement) {
-        return raiseInvalidKind("SwitchStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceSwitchStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::SwitchStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Discriminant, BinField::Cases };
@@ -7285,43 +4740,16 @@ BinASTParser<Tok>::parseInterfaceSwitchS
 
     BINJS_MOZ_TRY_DECL(cases, parseListOfSwitchCase());
 
     BINJS_TRY_DECL(scope, factory_.newLexicalScope(nullptr, cases));
     BINJS_TRY_DECL(result, factory_.newSwitchStatement(start, discriminant, scope, false));
     return result;
 }
 
-
-/*
- interface SwitchStatementWithDefault : Node {
-    Expression discriminant;
-    FrozenArray<SwitchCase> preDefaultCases;
-    SwitchDefault defaultCase;
-    FrozenArray<SwitchCase> postDefaultCases;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseSwitchStatementWithDefault()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::SwitchStatementWithDefault) {
-        return raiseInvalidKind("SwitchStatementWithDefault", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceSwitchStatementWithDefault(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::SwitchStatementWithDefault);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[4] = { BinField::Discriminant, BinField::PreDefaultCases, BinField::DefaultCase, BinField::PostDefaultCases };
@@ -7345,100 +4773,28 @@ BinASTParser<Tok>::parseInterfaceSwitchS
         factory_.addList(cases, iter);
         iter = next;
     }
     BINJS_TRY_DECL(scope, factory_.newLexicalScope(nullptr, cases));
     BINJS_TRY_DECL(result, factory_.newSwitchStatement(start, discriminant, scope, true));
     return result;
 }
 
-
-/*
- interface TemplateElement : Node {
-    string rawValue;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseTemplateElement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::TemplateElement) {
-        return raiseInvalidKind("TemplateElement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceTemplateElement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceTemplateElement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (TemplateElement)");
 }
 
-
-/*
- interface TemplateExpression : Node {
-    Expression? tag;
-    FrozenArray<(Expression or TemplateElement)> elements;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseTemplateExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::TemplateExpression) {
-        return raiseInvalidKind("TemplateExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceTemplateExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (TemplateExpression)");
 }
 
-
-/*
- interface ThisExpression : Node {
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseThisExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ThisExpression) {
-        return raiseInvalidKind("ThisExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceThisExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ThisExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     if (parseContext_->isFunctionBox()) {
@@ -7452,40 +4808,16 @@ MOZ_TRY(tokenizer_->checkFields0(kind, f
         BINJS_TRY(usedNames_.noteUse(cx_, dotThis, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
         BINJS_TRY_VAR(thisName, factory_.newName(dotThis, pos, cx_));
     }
 
     BINJS_TRY_DECL(result, factory_.newThisLiteral(pos, thisName));
     return result;
 }
 
-
-/*
- interface ThrowStatement : Node {
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseThrowStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::ThrowStatement) {
-        return raiseInvalidKind("ThrowStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceThrowStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::ThrowStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Expression };
@@ -7493,41 +4825,16 @@ BinASTParser<Tok>::parseInterfaceThrowSt
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
     BINJS_TRY_DECL(result, factory_.newThrowStatement(expression, tokenizer_->pos(start)));
     return result;
 }
 
-
-/*
- interface TryCatchStatement : Node {
-    Block body;
-    CatchClause catchClause;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseTryCatchStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::TryCatchStatement) {
-        return raiseInvalidKind("TryCatchStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceTryCatchStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceTryCatchStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::TryCatchStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Body, BinField::CatchClause };
@@ -7543,42 +4850,16 @@ BinASTParser<Tok>::parseInterfaceTryCatc
     }
 
     BINJS_MOZ_TRY_DECL(catchClause, parseCatchClause());
 
     BINJS_TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, /* finallyBlock = */ nullptr));
     return result;
 }
 
-
-/*
- interface TryFinallyStatement : Node {
-    Block body;
-    CatchClause? catchClause;
-    Block finalizer;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseTryFinallyStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::TryFinallyStatement) {
-        return raiseInvalidKind("TryFinallyStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceTryFinallyStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceTryFinallyStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::TryFinallyStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Body, BinField::CatchClause, BinField::Finalizer };
@@ -7602,41 +4883,16 @@ BinASTParser<Tok>::parseInterfaceTryFina
         MOZ_TRY_VAR(finalizer, parseBlock());
 
     }
 
     BINJS_TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, finalizer));
     return result;
 }
 
-
-/*
- interface UnaryExpression : Node {
-    UnaryOperator operator;
-    Expression operand;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseUnaryExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::UnaryExpression) {
-        return raiseInvalidKind("UnaryExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceUnaryExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceUnaryExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::UnaryExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Operator, BinField::Operand };
@@ -7689,42 +4945,16 @@ BinASTParser<Tok>::parseInterfaceUnaryEx
         }
         break;
       }
     }
     BINJS_TRY_DECL(result, factory_.newUnary(pnk, start, operand));
     return result;
 }
 
-
-/*
- interface UpdateExpression : Node {
-    bool isPrefix;
-    UpdateOperator operator;
-    SimpleAssignmentTarget operand;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseUpdateExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::UpdateExpression) {
-        return raiseInvalidKind("UpdateExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceUpdateExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceUpdateExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::UpdateExpression);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::IsPrefix, BinField::Operator, BinField::Operand };
@@ -7747,41 +4977,16 @@ BinASTParser<Tok>::parseInterfaceUpdateE
         pnk = isPrefix ? ParseNodeKind::PreDecrement
                        : ParseNodeKind::PostDecrement;
         break;
     }
     BINJS_TRY_DECL(result, factory_.newUnary(pnk, start, operand));
     return result;
 }
 
-
-/*
- interface VariableDeclaration : Node {
-    VariableDeclarationKind kind;
-    FrozenArray<VariableDeclarator> declarators;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseVariableDeclaration()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::VariableDeclaration) {
-        return raiseInvalidKind("VariableDeclaration", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceVariableDeclaration(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::VariableDeclaration);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Kind, BinField::Declarators };
@@ -7873,41 +5078,16 @@ BinASTParser<Tok>::parseInterfaceVariabl
         }
 
         MOZ_CRASH("Unimplemented: AssertedScope check for BindingPattern variable declaration");
         BINJS_TRY_VAR(result, factory_.newAssignment(ParseNodeKind::Assign, binding, init));
     }
     return result;
 }
 
-
-/*
- interface WhileStatement : Node {
-    Expression test;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseWhileStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::WhileStatement) {
-        return raiseInvalidKind("WhileStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceWhileStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceWhileStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::WhileStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Test, BinField::Body };
@@ -7918,41 +5098,16 @@ BinASTParser<Tok>::parseInterfaceWhileSt
     BINJS_MOZ_TRY_DECL(test, parseExpression());
 
     BINJS_MOZ_TRY_DECL(body, parseStatement());
 
     BINJS_TRY_DECL(result, factory_.newWhileStatement(start, test, body));
     return result;
 }
 
-
-/*
- interface WithStatement : Node {
-    Expression object;
-    Statement body;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseWithStatement()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::WithStatement) {
-        return raiseInvalidKind("WithStatement", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceWithStatement(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceWithStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::WithStatement);
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Object, BinField::Body };
@@ -7962,70 +5117,22 @@ BinASTParser<Tok>::parseInterfaceWithSta
     BINJS_MOZ_TRY_DECL(object, parseExpression());
 
     BINJS_MOZ_TRY_DECL(body, parseStatement());
 
     BINJS_TRY_DECL(result, factory_.newWithStatement(start, object, body));
     return result;
 }
 
-
-/*
- interface YieldExpression : Node {
-    Expression? expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseYieldExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::YieldExpression) {
-        return raiseInvalidKind("YieldExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceYieldExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceYieldExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (YieldExpression)");
 }
 
-
-/*
- interface YieldStarExpression : Node {
-    Expression expression;
- }
-*/
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseYieldStarExpression()
-{
-    BinKind kind;
-    BinFields fields(cx_);
-    AutoTaggedTuple guard(*tokenizer_);
-
-    MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
-    if (kind != BinKind::YieldStarExpression) {
-        return raiseInvalidKind("YieldStarExpression", kind);
-    }
-    const auto start = tokenizer_->offset();
-    BINJS_MOZ_TRY_DECL(result, parseInterfaceYieldStarExpression(start, kind, fields));
-    MOZ_TRY(guard.done());
-
-    return result;
-}
-
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceYieldStarExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (YieldStarExpression)");
 }
 
 
 
@@ -8714,28 +5821,16 @@ BinASTParser<Tok>::parseOptionalExpressi
         MOZ_TRY_VAR(result, parseSumExpression(start, kind, fields));
     }
     MOZ_TRY(guard.done());
 
     return result;
 }
 
 template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseOptionalIdentifierName()
-{
-    return raiseError("FIXME: Not implemented yet (OptionalIdentifierName)");
-}
-
-template<typename Tok> JS::Result<ParseNode*>
-BinASTParser<Tok>::parseOptionalLabel()
-{
-    return raiseError("FIXME: Not implemented yet (OptionalLabel)");
-}
-
-template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseOptionalSpreadElementOrExpression()
 {
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
 
     MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
     ParseNode* result;
--- a/js/src/frontend/BinSource-auto.h
+++ b/js/src/frontend/BinSource-auto.h
@@ -84,237 +84,112 @@ enum class VariableDeclarationKind {
     Const                     /* "const" */
 };
 
 
 
 // ----- Sums of interfaces (by lexicographical order)
 // Implementations are autogenerated
 // `ParseNode*` may never be nullptr
-JS::Result<ParseNode*> parseArrowExpression();
 JS::Result<Ok> parseAssertedMaybePositionalParameterName(
     AssertedScopeKind scopeKind,
     MutableHandle<GCVector<JSAtom*>> positionalParams);
 JS::Result<ParseNode*> parseAssignmentTarget();
 JS::Result<ParseNode*> parseAssignmentTargetOrAssignmentTargetWithInitializer();
-JS::Result<ParseNode*> parseAssignmentTargetPattern();
 JS::Result<ParseNode*> parseAssignmentTargetProperty();
 JS::Result<ParseNode*> parseBinding();
 JS::Result<ParseNode*> parseBindingOrBindingWithInitializer();
-JS::Result<ParseNode*> parseBindingPattern();
 JS::Result<ParseNode*> parseBindingProperty();
-JS::Result<ParseNode*> parseExportDeclaration();
 JS::Result<ParseNode*> parseExpression();
 JS::Result<ParseNode*> parseExpressionOrSuper();
 JS::Result<ParseNode*> parseExpressionOrTemplateElement();
 JS::Result<ParseNode*> parseForInOfBindingOrAssignmentTarget();
-JS::Result<ParseNode*> parseFunctionDeclaration();
 JS::Result<ParseNode*> parseFunctionDeclarationOrClassDeclarationOrExpression();
 JS::Result<ParseNode*> parseFunctionDeclarationOrClassDeclarationOrVariableDeclaration();
-JS::Result<ParseNode*> parseFunctionExpression();
-JS::Result<ParseNode*> parseGetter();
-JS::Result<ParseNode*> parseImportDeclaration();
 JS::Result<ParseNode*> parseImportDeclarationOrExportDeclarationOrStatement();
-JS::Result<ParseNode*> parseIterationStatement();
-JS::Result<ParseNode*> parseLiteral();
-JS::Result<ParseNode*> parseMethod();
 JS::Result<ParseNode*> parseMethodDefinition();
 JS::Result<ParseNode*> parseObjectProperty();
 JS::Result<ParseNode*> parseParameter();
 JS::Result<ParseNode*> parseProgram();
 JS::Result<ParseNode*> parsePropertyName();
-JS::Result<ParseNode*> parseSetter();
 JS::Result<ParseNode*> parseSimpleAssignmentTarget();
 JS::Result<ParseNode*> parseSpreadElementOrExpression();
 JS::Result<ParseNode*> parseStatement();
-JS::Result<ParseNode*> parseVariableDeclarationOrExpression();
-JS::Result<ParseNode*> parseSumArrowExpression(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<Ok> parseSumAssertedMaybePositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
     AssertedScopeKind scopeKind,
     MutableHandle<GCVector<JSAtom*>> positionalParams);
 JS::Result<ParseNode*> parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumAssignmentTargetOrAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumAssignmentTargetPattern(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumAssignmentTargetProperty(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumBindingOrBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumBindingPattern(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumBindingProperty(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumExportDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumExpressionOrTemplateElement(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumFunctionDeclarationOrClassDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumFunctionDeclarationOrClassDeclarationOrVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumGetter(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumImportDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumImportDeclarationOrExportDeclarationOrStatement(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumIterationStatement(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumLiteral(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumMethod(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumMethodDefinition(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
-JS::Result<ParseNode*> parseSumSetter(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumSimpleAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumSpreadElementOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumStatement(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseSumVariableDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
 
 
 // ----- Interfaces (by lexicographical order)
 // Implementations are autogenerated
 // `ParseNode*` may never be nullptr
-JS::Result<ParseNode*> parseNull();
-JS::Result<ParseNode*> parseArrayAssignmentTarget();
-JS::Result<ParseNode*> parseArrayBinding();
-JS::Result<ParseNode*> parseArrayExpression();
 JS::Result<ParseNode*> parseArrowExpressionContentsWithExpression();
 JS::Result<ParseNode*> parseArrowExpressionContentsWithFunctionBody();
 JS::Result<Ok> parseAssertedBlockScope();
 JS::Result<Ok> parseAssertedBoundName(
     AssertedScopeKind scopeKind);
 JS::Result<Ok> parseAssertedBoundNamesScope();
 JS::Result<Ok> parseAssertedDeclaredName(
     AssertedScopeKind scopeKind);
-JS::Result<Ok> parseAssertedParameterName(
-    AssertedScopeKind scopeKind,
-    MutableHandle<GCVector<JSAtom*>> positionalParams);
 JS::Result<Ok> parseAssertedParameterScope(
     MutableHandle<GCVector<JSAtom*>> positionalParams);
-JS::Result<Ok> parseAssertedPositionalParameterName(
-    AssertedScopeKind scopeKind,
-    MutableHandle<GCVector<JSAtom*>> positionalParams);
-JS::Result<Ok> parseAssertedRestParameterName(
-    AssertedScopeKind scopeKind,
-    MutableHandle<GCVector<JSAtom*>> positionalParams);
 JS::Result<Ok> parseAssertedScriptGlobalScope();
 JS::Result<Ok> parseAssertedVarScope();
-JS::Result<ParseNode*> parseAssignmentExpression();
 JS::Result<ParseNode*> parseAssignmentTargetIdentifier();
-JS::Result<ParseNode*> parseAssignmentTargetPropertyIdentifier();
-JS::Result<ParseNode*> parseAssignmentTargetPropertyProperty();
-JS::Result<ParseNode*> parseAssignmentTargetWithInitializer();
-JS::Result<ParseNode*> parseAwaitExpression();
-JS::Result<ParseNode*> parseBinaryExpression();
 JS::Result<ParseNode*> parseBindingIdentifier();
-JS::Result<ParseNode*> parseBindingPropertyIdentifier();
-JS::Result<ParseNode*> parseBindingPropertyProperty();
-JS::Result<ParseNode*> parseBindingWithInitializer();
 JS::Result<ParseNode*> parseBlock();
-JS::Result<ParseNode*> parseBreakStatement();
-JS::Result<ParseNode*> parseCallExpression();
 JS::Result<LexicalScopeNode*> parseCatchClause();
-JS::Result<ParseNode*> parseClassDeclaration();
 JS::Result<ParseNode*> parseClassElement();
-JS::Result<ParseNode*> parseClassExpression();
-JS::Result<ParseNode*> parseCompoundAssignmentExpression();
-JS::Result<ParseNode*> parseComputedMemberAssignmentTarget();
-JS::Result<ParseNode*> parseComputedMemberExpression();
-JS::Result<ParseNode*> parseComputedPropertyName();
-JS::Result<ParseNode*> parseConditionalExpression();
-JS::Result<ParseNode*> parseContinueStatement();
-JS::Result<ParseNode*> parseDataProperty();
-JS::Result<ParseNode*> parseDebuggerStatement();
 JS::Result<ParseNode*> parseDirective();
-JS::Result<ParseNode*> parseDoWhileStatement();
-JS::Result<ParseNode*> parseEagerArrowExpressionWithExpression();
-JS::Result<ParseNode*> parseEagerArrowExpressionWithFunctionBody();
-JS::Result<ParseNode*> parseEagerFunctionDeclaration();
-JS::Result<ParseNode*> parseEagerFunctionExpression();
-JS::Result<ParseNode*> parseEagerGetter();
-JS::Result<ParseNode*> parseEagerMethod();
-JS::Result<ParseNode*> parseEagerSetter();
-JS::Result<ParseNode*> parseEmptyStatement();
-JS::Result<ParseNode*> parseExport();
-JS::Result<ParseNode*> parseExportAllFrom();
-JS::Result<ParseNode*> parseExportDefault();
-JS::Result<ParseNode*> parseExportFrom();
 JS::Result<ParseNode*> parseExportFromSpecifier();
 JS::Result<ParseNode*> parseExportLocalSpecifier();
-JS::Result<ParseNode*> parseExportLocals();
-JS::Result<ParseNode*> parseExpressionStatement();
-JS::Result<ParseNode*> parseForInOfBinding();
-JS::Result<ParseNode*> parseForInStatement();
-JS::Result<ParseNode*> parseForOfStatement();
-JS::Result<ParseNode*> parseForStatement();
 JS::Result<ListNode*> parseFormalParameters();
 JS::Result<Ok> parseFunctionExpressionContents(
     uint32_t funLength,
     ListNode** paramsOut,
     ListNode** bodyOut);
 JS::Result<Ok> parseFunctionOrMethodContents(
     uint32_t funLength,
     ListNode** paramsOut,
     ListNode** bodyOut);
 JS::Result<Ok> parseGetterContents(
     uint32_t funLength,
     ListNode** paramsOut,
     ListNode** bodyOut);
 JS::Result<ParseNode*> parseIdentifierExpression();
-JS::Result<ParseNode*> parseIfStatement();
-JS::Result<ParseNode*> parseImport();
-JS::Result<ParseNode*> parseImportNamespace();
 JS::Result<ParseNode*> parseImportSpecifier();
-JS::Result<ParseNode*> parseLabelledStatement();
-JS::Result<ParseNode*> parseLazyArrowExpressionWithExpression();
-JS::Result<ParseNode*> parseLazyArrowExpressionWithFunctionBody();
-JS::Result<ParseNode*> parseLazyFunctionDeclaration();
-JS::Result<ParseNode*> parseLazyFunctionExpression();
-JS::Result<ParseNode*> parseLazyGetter();
-JS::Result<ParseNode*> parseLazyMethod();
-JS::Result<ParseNode*> parseLazySetter();
-JS::Result<ParseNode*> parseLiteralBooleanExpression();
-JS::Result<ParseNode*> parseLiteralInfinityExpression();
-JS::Result<ParseNode*> parseLiteralNullExpression();
-JS::Result<ParseNode*> parseLiteralNumericExpression();
-JS::Result<ParseNode*> parseLiteralPropertyName();
-JS::Result<ParseNode*> parseLiteralRegExpExpression();
-JS::Result<ParseNode*> parseLiteralStringExpression();
-JS::Result<ParseNode*> parseModule();
-JS::Result<ParseNode*> parseNewExpression();
-JS::Result<ParseNode*> parseNewTargetExpression();
-JS::Result<ParseNode*> parseObjectAssignmentTarget();
-JS::Result<ParseNode*> parseObjectBinding();
-JS::Result<ParseNode*> parseObjectExpression();
-JS::Result<ParseNode*> parseReturnStatement();
-JS::Result<ParseNode*> parseScript();
 JS::Result<Ok> parseSetterContents(
     uint32_t funLength,
     ListNode** paramsOut,
     ListNode** bodyOut);
-JS::Result<ParseNode*> parseShorthandProperty();
-JS::Result<ParseNode*> parseSpreadElement();
-JS::Result<ParseNode*> parseStaticMemberAssignmentTarget();
-JS::Result<ParseNode*> parseStaticMemberExpression();
-JS::Result<ParseNode*> parseSuper();
 JS::Result<CaseClause*> parseSwitchCase();
 JS::Result<ParseNode*> parseSwitchDefault();
-JS::Result<ParseNode*> parseSwitchStatement();
-JS::Result<ParseNode*> parseSwitchStatementWithDefault();
-JS::Result<ParseNode*> parseTemplateElement();
-JS::Result<ParseNode*> parseTemplateExpression();
-JS::Result<ParseNode*> parseThisExpression();
-JS::Result<ParseNode*> parseThrowStatement();
-JS::Result<ParseNode*> parseTryCatchStatement();
-JS::Result<ParseNode*> parseTryFinallyStatement();
-JS::Result<ParseNode*> parseUnaryExpression();
-JS::Result<ParseNode*> parseUpdateExpression();
-JS::Result<ParseNode*> parseVariableDeclaration();
 JS::Result<ParseNode*> parseVariableDeclarator();
-JS::Result<ParseNode*> parseWhileStatement();
-JS::Result<ParseNode*> parseWithStatement();
-JS::Result<ParseNode*> parseYieldExpression();
-JS::Result<ParseNode*> parseYieldStarExpression();
-JS::Result<ParseNode*> parseInterfaceNull(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseInterfaceArrowExpressionContentsWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<ParseNode*> parseInterfaceArrowExpressionContentsWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<Ok> parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields);
 JS::Result<Ok> parseInterfaceAssertedBoundName(const size_t start, const BinKind kind, const BinFields& fields,
     AssertedScopeKind scopeKind);
@@ -495,14 +370,12 @@ JS::Result<ListNode*> parseListOfVariabl
 // ----- Default values (by lexicographical order)
 // Implementations are autogenerated
 JS::Result<ParseNode*> parseOptionalAssignmentTarget();
 JS::Result<ParseNode*> parseOptionalBinding();
 JS::Result<ParseNode*> parseOptionalBindingIdentifier();
 JS::Result<ParseNode*> parseOptionalBindingOrBindingWithInitializer();
 JS::Result<LexicalScopeNode*> parseOptionalCatchClause();
 JS::Result<ParseNode*> parseOptionalExpression();
-JS::Result<ParseNode*> parseOptionalIdentifierName();
-JS::Result<ParseNode*> parseOptionalLabel();
 JS::Result<ParseNode*> parseOptionalSpreadElementOrExpression();
 JS::Result<ParseNode*> parseOptionalStatement();
 JS::Result<ParseNode*> parseOptionalVariableDeclarationOrExpression();
 
--- a/js/src/frontend/binsource/src/main.rs
+++ b/js/src/frontend/binsource/src/main.rs
@@ -6,16 +6,20 @@ extern crate itertools;
 extern crate webidl;
 extern crate yaml_rust;
 
 use binjs_meta::export::{ ToWebidl, TypeDeanonymizer, TypeName };
 use binjs_meta::import::Importer;
 use binjs_meta::spec::*;
 use binjs_meta::util:: { Reindentable, ToCases, ToStr };
 
+mod refgraph;
+
+use refgraph::{ ReferenceGraph };
+
 use std::collections::{ HashMap, HashSet };
 use std::fs::*;
 use std::io::{ Read, Write };
 use std::path::Path;
 use std::rc::Rc;
 
 use clap::{ App, Arg };
 
@@ -486,24 +490,47 @@ enum MethodCallKind {
     /// Use MOZ_TRY_VAR if the result type is not "Ok",
     /// use MOZ_TRY otherwise.
     Var,
 
     /// Always use MOZ_TRY_VAR regardless of the result type.
     AlwaysVar,
 }
 
+/// Fixed parameter of interface method.
+const INTERFACE_PARAMS: &str =
+    "const size_t start, const BinKind kind, const BinFields& fields";
+
+/// Fixed arguments of interface method.
+const INTERFACE_ARGS: &str =
+    "start, kind, fields";
+
+/// The name of the toplevel interface for the script.
+const TOPLEVEL_INTERFACE: &str =
+    "Program";
+
+/// Get Rc<String> from NodeName.
+///
+/// FIXME: Do not clone the String itself, but just clone the Rc<String> inside
+///        NodeName (Bug NNNNNN).
+fn string_from_nodename(name: &NodeName) -> Rc<String> {
+    Rc::new(name.to_string().clone())
+}
+
 /// The actual exporter.
 struct CPPExporter {
     /// The syntax to export.
     syntax: Spec,
 
     /// Rules, as specified in yaml.
     rules: GlobalRules,
 
+    /// Reference graph of the method call.
+    refgraph: ReferenceGraph,
+
     /// All parsers of lists.
     list_parsers_to_generate: Vec<ListParserData>,
 
     /// All parsers of options.
     option_parsers_to_generate: Vec<OptionParserData>,
 
     /// A mapping from symbol (e.g. `+`, `-`, `instanceof`, ...) to the
     /// name of the symbol as part of `enum class BinVariant`
@@ -574,26 +601,132 @@ impl CPPExporter {
                         .sorted()
                         .into_iter()
                         .format("Or"),
                     symbol = string.to_cpp_enum_case());
                 (string, expanded)
             })
             .collect();
 
+        // This is just a placeholder to instantiate the CPPExporter struct.
+        // The field will be overwritten later in generate_reference_graph.
+        let refgraph = ReferenceGraph::new();
+
         CPPExporter {
             syntax,
             rules,
+            refgraph,
             list_parsers_to_generate,
             option_parsers_to_generate,
             variants_by_symbol,
             enum_types,
         }
     }
 
+    /// Generate a reference graph of methods.
+    fn generate_reference_graph(&mut self) {
+        let mut refgraph = ReferenceGraph::new();
+
+        // FIXME: Reflect `replace` rule in yaml file for each interface to
+        //        the reference (bug NNNNNN).
+
+        // 1. Typesums
+        let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name();
+        for (name, nodes) in sums_of_interfaces {
+            let mut edges: HashSet<Rc<String>> = HashSet::new();
+            edges.insert(Rc::new(format!("Sum{}", name)));
+            refgraph.insert(string_from_nodename(name), edges);
+
+            let mut sum_edges: HashSet<Rc<String>> = HashSet::new();
+            for node in nodes {
+                sum_edges.insert(Rc::new(format!("Interface{}", node.to_string())));
+            }
+            refgraph.insert(Rc::new(format!("Sum{}", name.to_string())), sum_edges);
+        }
+
+        // 2. Single interfaces
+        let interfaces_by_name = self.syntax.interfaces_by_name();
+        for (name, interface) in interfaces_by_name {
+            let mut edges: HashSet<Rc<String>> = HashSet::new();
+            edges.insert(Rc::new(format!("Interface{}", name)));
+            refgraph.insert(string_from_nodename(name), edges);
+
+            let mut interface_edges: HashSet<Rc<String>> = HashSet::new();
+            for field in interface.contents().fields() {
+                match field.type_().get_primitive(&self.syntax) {
+                    Some(IsNullable { is_nullable: _, content: Primitive::Interface(_) })
+                    | None => {
+                        let typename = TypeName::type_(field.type_());
+                        interface_edges.insert(Rc::new(typename.to_string()));
+                    },
+
+                    // Don't have to handle other type of fields (string,
+                    // number, bool, etc).
+                    _ => {}
+                }
+            }
+            refgraph.insert(Rc::new(format!("Interface{}", name)), interface_edges);
+        }
+
+        // 3. String Enums
+        for (kind, _) in self.syntax.string_enums_by_name() {
+            refgraph.insert(string_from_nodename(kind), HashSet::new());
+        }
+
+        // 4. Lists
+        for parser in &self.list_parsers_to_generate {
+            let mut edges: HashSet<Rc<String>> = HashSet::new();
+            edges.insert(string_from_nodename(&parser.elements));
+            refgraph.insert(string_from_nodename(&parser.name), edges);
+        }
+
+        // 5. Optional values
+        for parser in &self.option_parsers_to_generate {
+            let mut edges: HashSet<Rc<String>> = HashSet::new();
+            let named_implementation =
+                if let Some(NamedType::Typedef(ref typedef)) = self.syntax.get_type_by_name(&parser.name) {
+                    assert!(typedef.is_optional());
+                    if let TypeSpec::NamedType(ref named) = *typedef.spec() {
+                        self.syntax.get_type_by_name(named)
+                            .unwrap_or_else(|| panic!("Internal error: Could not find type {}, which should have been generated.", named.to_str()))
+                    } else {
+                        panic!("Internal error: In {}, type {:?} should have been a named type",
+                               parser.name.to_str(),
+                               typedef);
+                    }
+                } else {
+                    panic!("Internal error: In {}, there should be a type with that name",
+                           parser.name.to_str());
+                };
+            match named_implementation {
+                NamedType::Interface(_) => {
+                    edges.insert(Rc::new(format!("Interface{}", parser.elements.to_string())));
+                },
+                NamedType::Typedef(ref type_) => {
+                    match type_.spec() {
+                        &TypeSpec::TypeSum(_) => {
+                            edges.insert(Rc::new(format!("Sum{}", parser.elements.to_string())));
+                        },
+                        _ => {}
+                    }
+                },
+                _ => {}
+            }
+            refgraph.insert(string_from_nodename(&parser.name), edges);
+        }
+
+        self.refgraph = refgraph;
+    }
+
+    /// Trace the reference graph from the node with `name and mark all nodes
+    /// as used. `name` is the name of the method, without leading "parse".
+    fn trace(&mut self, name: Rc<String>) {
+        self.refgraph.trace(name)
+    }
+
 // ----- Generating the header
 
     /// Get the type representing a success for parsing this node.
     fn get_type_ok(&self, name: &NodeName) -> Rc<String> {
         // enum has its own rule.
         if self.enum_types.contains_key(name) {
             return self.enum_types.get(name).unwrap().clone();
         }
@@ -829,27 +962,37 @@ enum class BinVariant {
     fn export_declare_sums_of_interface_methods(&self, buffer: &mut String) {
         let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name()
             .iter()
             .sorted_by(|a, b| a.0.cmp(&b.0));
         buffer.push_str("\n\n// ----- Sums of interfaces (by lexicographical order)\n");
         buffer.push_str("// Implementations are autogenerated\n");
         buffer.push_str("// `ParseNode*` may never be nullptr\n");
         for &(ref name, _) in &sums_of_interfaces {
+            if !self.refgraph.is_used(string_from_nodename(&name)) {
+                continue;
+            }
+
             let rules_for_this_sum = self.rules.get(name);
             let extra_params = rules_for_this_sum.extra_params;
             let rendered = self.get_method_signature(name, "", "",
                                                      &extra_params);
             buffer.push_str(&rendered.reindent("")
                             .newline_if_not_empty());
         }
         for (name, _) in sums_of_interfaces {
+            let prefix = "Sum";
+            if !self.refgraph.is_used(Rc::new(format!("{}{}", prefix, name))) {
+                continue;
+            }
+
             let rules_for_this_sum = self.rules.get(name);
             let extra_params = rules_for_this_sum.extra_params;
-            let rendered = self.get_method_signature(name, "Sum", "const size_t start, const BinKind kind, const BinFields& fields",
+            let rendered = self.get_method_signature(name, prefix,
+                                                     INTERFACE_PARAMS,
                                                      &extra_params);
             buffer.push_str(&rendered.reindent("")
                             .newline_if_not_empty());
         }
     }
 
     fn export_declare_single_interface_methods(&self, buffer: &mut String) {
         buffer.push_str("\n\n// ----- Interfaces (by lexicographical order)\n");
@@ -860,20 +1003,29 @@ enum class BinVariant {
             .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
 
         let mut outer_parsers = Vec::with_capacity(interfaces_by_name.len());
         let mut inner_parsers = Vec::with_capacity(interfaces_by_name.len());
 
         for &(name, _) in &interfaces_by_name {
             let rules_for_this_interface = self.rules.get(name);
             let extra_params = rules_for_this_interface.extra_params;
-            let outer = self.get_method_signature(name, "", "", &extra_params);
-            let inner = self.get_method_signature(name, "Interface", "const size_t start, const BinKind kind, const BinFields& fields",
+
+            if self.refgraph.is_used(string_from_nodename(name)) {
+                let outer = self.get_method_signature(name, "", "", &extra_params);
+                outer_parsers.push(outer.reindent(""));
+            }
+
+            let inner_prefix = "Interface";
+            if !self.refgraph.is_used(Rc::new(format!("{}{}", inner_prefix, name))) {
+                continue;
+            }
+            let inner = self.get_method_signature(name, inner_prefix,
+                                                  INTERFACE_PARAMS,
                                                   &extra_params);
-            outer_parsers.push(outer.reindent(""));
             inner_parsers.push(inner.reindent(""));
         }
 
         for parser in outer_parsers.drain(..) {
             buffer.push_str(&parser);
             buffer.push_str("\n");
         }
 
@@ -885,39 +1037,51 @@ enum class BinVariant {
 
     fn export_declare_string_enums_methods(&self, buffer: &mut String) {
         buffer.push_str("\n\n// ----- String enums (by lexicographical order)\n");
         buffer.push_str("// Implementations are autogenerated\n");
         let string_enums_by_name = self.syntax.string_enums_by_name()
             .iter()
             .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
         for (kind, _) in string_enums_by_name {
+            if !self.refgraph.is_used(string_from_nodename(kind)) {
+                continue;
+            }
+
             let rendered = self.get_method_signature(kind, "", "", &None);
             buffer.push_str(&rendered.reindent(""));
             buffer.push_str("\n");
         }
     }
 
     fn export_declare_list_methods(&self, buffer: &mut String) {
         buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n");
         buffer.push_str("// Implementations are autogenerated\n");
         for parser in &self.list_parsers_to_generate {
+            if !self.refgraph.is_used(string_from_nodename(&parser.name)) {
+                continue;
+            }
+
             let rules_for_this_node = self.rules.get(&parser.name);
             let extra_params = rules_for_this_node.extra_params;
             let rendered = self.get_method_signature(&parser.name, "", "",
                                                      &extra_params);
             buffer.push_str(&rendered.reindent(""));
             buffer.push_str("\n");
         }
     }
 
     fn export_declare_option_methods(&self, buffer: &mut String) {
         buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n");
         buffer.push_str("// Implementations are autogenerated\n");
         for parser in &self.option_parsers_to_generate {
+            if !self.refgraph.is_used(string_from_nodename(&parser.name)) {
+                continue;
+            }
+
             let rules_for_this_node = self.rules.get(&parser.name);
             let extra_params = rules_for_this_node.extra_params;
             let rendered = self.get_method_signature(&parser.name, "", "",
                                                      &extra_params);
             buffer.push_str(&rendered.reindent(""));
             buffer.push_str("\n");
         }
     }
@@ -965,56 +1129,64 @@ impl CPPExporter {
     fn generate_implement_sum(&self, buffer: &mut String, name: &NodeName, nodes: &HashSet<NodeName>) {
         // Generate comments (FIXME: We should use the actual webidl, not the resolved sum)
         let rules_for_this_sum = self.rules.get(name);
         let extra_params = rules_for_this_sum.extra_params;
         let extra_args = rules_for_this_sum.extra_args;
         let nodes = nodes.iter()
             .sorted();
         let kind = name.to_class_cases();
-        let rendered_bnf = format!("/*\n{name} ::= {nodes}\n*/",
-            nodes = nodes.iter()
-                .format("\n    "),
-            name = name.to_str());
 
-        // Generate outer method
-        buffer.push_str(&format!("{bnf}
+        if self.refgraph.is_used(string_from_nodename(name)) {
+            let rendered_bnf = format!("/*\n{name} ::= {nodes}\n*/",
+                nodes = nodes.iter()
+                    .format("\n    "),
+                name = name.to_str());
+
+            // Generate outer method
+            buffer.push_str(&format!("{bnf}
 {first_line}
 {{
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
     const auto start = tokenizer_->offset();
 
     MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
 
 {call}
 
     MOZ_TRY(guard.done());
     return result;
 }}\n",
                 bnf = rendered_bnf,
                 call = self.get_method_call("result", name,
-                                            "Sum", "start, kind, fields",
+                                            "Sum", INTERFACE_ARGS,
                                             &extra_args,
                                             MethodCallKind::AlwaysDecl)
                     .reindent("    "),
                 first_line = self.get_method_definition_start(name, "", "",
                                                               &extra_params)
-        ));
+            ));
+        }
+
+        let inner_prefix = "Sum";
+        if !self.refgraph.is_used(Rc::new(format!("{}{}", inner_prefix, name))) {
+            return;
+        }
 
         // Generate inner method
         let mut buffer_cases = String::new();
         for node in nodes {
             buffer_cases.push_str(&format!("
       case BinKind::{variant_name}:
 {call}
 {arm_after}        break;",
                 call = self.get_method_call("result", node,
-                                            "Interface", "start, kind, fields",
+                                            "Interface", INTERFACE_ARGS,
                                             &extra_args,
                                             MethodCallKind::AlwaysVar)
                     .reindent("        "),
                 variant_name = node.to_cpp_enum_case(),
                 arm_after = rules_for_this_sum.by_sum.get(&node)
                     .cloned()
                     .unwrap_or_default().after_arm.reindent("        ")
                     .newline_if_not_empty()));
@@ -1027,24 +1199,29 @@ impl CPPExporter {
         return raiseInvalidKind(\"{kind}\", kind);
     }}
     return result;
 }}
 
 ",
             kind = kind,
             cases = buffer_cases,
-            first_line = self.get_method_definition_start(name, "Sum", "const size_t start, const BinKind kind, const BinFields& fields",
+            first_line = self.get_method_definition_start(name, inner_prefix,
+                                                          INTERFACE_PARAMS,
                                                           &extra_params),
             type_ok = self.get_type_ok(name)
         ));
     }
 
     /// Generate the implementation of a single list parser
     fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) {
+        if !self.refgraph.is_used(string_from_nodename(&parser.name)) {
+            return;
+        }
+
         let rules_for_this_list = self.rules.get(&parser.name);
         let extra_params = rules_for_this_list.extra_params;
         let extra_args = rules_for_this_list.extra_args;
 
         // Warn if some rules are unused.
         for &(condition, name) in &[
             (rules_for_this_list.build_result.is_some(), "build:"),
             (rules_for_this_list.type_ok.is_some(), "type-ok:"),
@@ -1124,16 +1301,20 @@ impl CPPExporter {
             append = append);
         buffer.push_str(&rendered);
     }
 
     fn generate_implement_option(&self, buffer: &mut String, parser: &OptionParserData) {
         debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}",
             parser.name.to_str(), parser.elements.to_str());
 
+        if !self.refgraph.is_used(string_from_nodename(&parser.name)) {
+            return;
+        }
+
         let rules_for_this_node = self.rules.get(&parser.name);
         let extra_params = rules_for_this_node.extra_params;
         let extra_args = rules_for_this_node.extra_args;
 
         // Warn if some rules are unused.
         for &(condition, name) in &[
             (rules_for_this_node.build_result.is_some(), "build:"),
             (rules_for_this_node.append.is_some(), "append:"),
@@ -1189,17 +1370,17 @@ impl CPPExporter {
 }}
 
 ",
                     first_line = self.get_method_definition_start(&parser.name, "", "",
                                                                   &extra_params),
                     null = self.syntax.get_null_name().to_cpp_enum_case(),
                     call = self.get_method_call("result",
                                                 &parser.elements,
-                                                "Interface", "start, kind, fields",
+                                                "Interface", INTERFACE_ARGS,
                                                 &extra_args,
                                                 MethodCallKind::AlwaysVar)
                         .reindent("        "),
                     before = rules_for_this_node.some_before
                         .map_or_else(|| "".to_string(),
                                      |s| s
                                      .reindent("        ")
                                      .newline_if_not_empty()),
@@ -1238,17 +1419,17 @@ impl CPPExporter {
 
     return result;
 }}
 
 ",
                             first_line = self.get_method_definition_start(&parser.name, "", "",
                                                                           &extra_params),
                             call = self.get_method_call("result", &parser.elements,
-                                                        "Sum", "start, kind, fields",
+                                                        "Sum", INTERFACE_ARGS,
                                                         &extra_args,
                                                         MethodCallKind::AlwaysVar)
                                 .reindent("        "),
                             before = rules_for_this_node.some_before
                                 .map_or_else(|| "".to_string(),
                                              |s| s
                                              .reindent("        ")
                                              .newline_if_not_empty()),
@@ -1312,22 +1493,23 @@ impl CPPExporter {
         for &(condition, rule_name) in &[
             (rules_for_this_interface.append.is_some(), "build:"),
         ] {
             if condition {
                 warn!("In {}, rule `{}` was specified but is ignored.", name, rule_name);
             }
         }
 
-        // Generate comments
-        let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", "    "));
-        buffer.push_str(&comment);
+        if self.refgraph.is_used(string_from_nodename(name)) {
+            // Generate comments
+            let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", "    "));
+            buffer.push_str(&comment);
 
-        // Generate public method
-        buffer.push_str(&format!("{first_line}
+            // Generate public method
+            buffer.push_str(&format!("{first_line}
 {{
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
 
     MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
     if (kind != BinKind::{kind}) {{
         return raiseInvalidKind(\"{kind}\", kind);
@@ -1335,29 +1517,36 @@ impl CPPExporter {
     const auto start = tokenizer_->offset();
 {call}
     MOZ_TRY(guard.done());
 
     return result;
 }}
 
 ",
-            first_line = self.get_method_definition_start(name, "", "",
-                                                          &extra_params),
-            kind = name.to_cpp_enum_case(),
-            call = self.get_method_call("result", name,
-                                        "Interface", "start, kind, fields",
-                                        &extra_args,
-                                        MethodCallKind::AlwaysDecl)
-                .reindent("    ")
-        ));
+                first_line = self.get_method_definition_start(name, "", "",
+                                                              &extra_params),
+                kind = name.to_cpp_enum_case(),
+                call = self.get_method_call("result", name,
+                                            "Interface", INTERFACE_ARGS,
+                                            &extra_args,
+                                            MethodCallKind::AlwaysDecl)
+                    .reindent("    ")
+            ));
+        }
+
+        let inner_prefix = "Interface";
+        if !self.refgraph.is_used(Rc::new(format!("{}{}", inner_prefix, name))) {
+            return;
+        }
 
         // Generate aux method
         let number_of_fields = interface.contents().fields().len();
-        let first_line = self.get_method_definition_start(name, "Interface", "const size_t start, const BinKind kind, const BinFields& fields",
+        let first_line = self.get_method_definition_start(name, inner_prefix,
+                                                          INTERFACE_PARAMS,
                                                           &extra_params);
 
         let fields_type_list = format!("{{ {} }}", interface.contents()
             .fields()
             .iter()
             .map(|field| format!("BinField::{}", field.name().to_cpp_enum_case()))
             .format(", "));
 
@@ -1567,16 +1756,20 @@ impl CPPExporter {
 
         // 3. String Enums
         buffer.push_str("\n\n// ----- String enums (autogenerated, by lexicographical order)\n");
         {
             let string_enums_by_name = self.syntax.string_enums_by_name()
                 .iter()
                 .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
             for (kind, enum_) in string_enums_by_name {
+                if !self.refgraph.is_used(string_from_nodename(kind)) {
+                    continue;
+                }
+
                 let convert = format!("    switch (variant) {{
 {cases}
       default:
         return raiseInvalidVariant(\"{kind}\", variant);
     }}",
                     kind = kind,
                     cases = enum_.strings()
                         .iter()
@@ -1724,17 +1917,20 @@ fn main() {
     file.read_to_string(&mut data)
         .expect("Could not read rules");
 
     let yaml = yaml_rust::YamlLoader::load_from_str(&data)
         .expect("Could not parse rules");
     assert_eq!(yaml.len(), 1);
 
     let global_rules = GlobalRules::new(&new_syntax, &yaml[0]);
-    let exporter = CPPExporter::new(new_syntax, global_rules);
+    let mut exporter = CPPExporter::new(new_syntax, global_rules);
+
+    exporter.generate_reference_graph();
+    exporter.trace(Rc::new(TOPLEVEL_INTERFACE.to_string()));
 
     let get_file_content = |path: &str| {
         if !Path::new(path).is_file() {
             return None;
         }
 
         let mut f = File::open(path)
             .expect("File not found");
new file mode 100644
--- /dev/null
+++ b/js/src/frontend/binsource/src/refgraph.rs
@@ -0,0 +1,90 @@
+use std::cell::RefCell;
+use std::collections::{ HashMap, HashSet };
+use std::rc::Rc;
+
+/// A node in the reference graph
+struct ReferenceGraphNode {
+    /// True if this node is used.
+    used: RefCell<bool>,
+
+    /// The set of method names which node uses.
+    edges: HashSet<Rc<String>>,
+}
+impl ReferenceGraphNode {
+    fn new(edges: HashSet<Rc<String>>) -> Self {
+        ReferenceGraphNode {
+            used: RefCell::new(false),
+            edges,
+        }
+    }
+}
+
+/// A reference graph of the method call.
+///
+/// Each auto-generated method has corresponding node in this reference graph,
+/// and the method definition/declaration are written to the file only if the
+/// method is marked as used.
+///
+/// This is necessary for the following reason:
+///   * we generate parseX and parseInterfaceX for `interface X`
+///   * parseX is not used if `interface X` appears only in sum interface
+pub struct ReferenceGraph {
+    /// The map from the node name to node struct.
+    /// Node name is the method name without leading "parse".
+    refnodes: HashMap<Rc<String>, Rc<ReferenceGraphNode>>,
+}
+impl ReferenceGraph {
+    pub fn new() -> Self {
+        ReferenceGraph {
+            refnodes: HashMap::new()
+        }
+    }
+
+    /// Trace the reference graph from the node with `name and mark all nodes
+    /// as used. `name` is the name of the method, without leading "parse".
+    pub fn trace(&mut self, name: Rc<String>) {
+        // The set of edges to trace in the current iteration.
+        let mut edges: HashSet<Rc<String>> = HashSet::new();
+        edges.insert(name);
+
+        // Iterate over the remaining edges until all edges are traced.
+        loop {
+            // The set of edges to trace in the next iteration.
+            let mut next_edges: HashSet<Rc<String>> = HashSet::new();
+
+            for edge in edges {
+                let refnode = self.refnodes.get(&edge)
+                    .unwrap_or_else(|| panic!("While computing dependencies, node {} doesn't exist", edge));
+                if *refnode.used.borrow() {
+                    continue;
+                }
+
+                refnode.used.replace(true);
+
+                for next_edge in refnode.edges.iter() {
+                    next_edges.insert(next_edge.clone());
+                }
+            }
+
+            if next_edges.len() == 0 {
+                break;
+            }
+
+            edges = next_edges;
+        }
+    }
+
+    /// Return true if the method named `name` (without leading "parse") is
+    /// used.
+    pub fn is_used(&self, name: Rc<String>) -> bool {
+        match self.refnodes.get(&name) {
+            Some(refnode) => *refnode.used.borrow(),
+            None => false
+        }
+    }
+
+    /// Insert a node with `name` to the graph.
+    pub fn insert(&mut self, name: Rc<String>, edges: HashSet<Rc<String>>) {
+        self.refnodes.insert(name, Rc::new(ReferenceGraphNode::new(edges)));
+    }
+}