Bug 1513040 - Rename ParseNodeKinds to end with Stmt or Expr. r=jorendorff
authorAshley Hauck <khyperia@mozilla.com>
Tue, 18 Dec 2018 22:24:56 +0000
changeset 508489 6356c45cfbb73e27ca114e82b769c3634353c9d5
parent 508488 719babda112c5bbedc09749456f0fbf5ea302e08
child 508490 598f93e37949c3daafb09eafc1ba70dd613ae842
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1513040
milestone66.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 1513040 - Rename ParseNodeKinds to end with Stmt or Expr. r=jorendorff Depends on D13991 Differential Revision: https://phabricator.services.mozilla.com/D14321
js/src/builtin/ModuleObject.cpp
js/src/builtin/ReflectParse.cpp
js/src/frontend/BinASTParser.cpp
js/src/frontend/BinASTParser.h
js/src/frontend/BinASTParserPerTokenizer.cpp
js/src/frontend/BinSource.yaml
js/src/frontend/BinToken.h
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/FoldConstants.cpp
js/src/frontend/FullParseHandler.h
js/src/frontend/NameFunctions.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/SyntaxParseHandler.h
js/src/wasm/AsmJS.cpp
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -1244,23 +1244,23 @@ bool ModuleBuilder::initModule() {
                                 starExportEntries);
 
   return true;
 }
 
 bool ModuleBuilder::processImport(frontend::BinaryNode* importNode) {
   using namespace js::frontend;
 
-  MOZ_ASSERT(importNode->isKind(ParseNodeKind::Import));
+  MOZ_ASSERT(importNode->isKind(ParseNodeKind::ImportDecl));
 
   ListNode* specList = &importNode->left()->as<ListNode>();
   MOZ_ASSERT(specList->isKind(ParseNodeKind::ImportSpecList));
 
   NameNode* moduleSpec = &importNode->right()->as<NameNode>();
-  MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::String));
+  MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr));
 
   RootedAtom module(cx_, moduleSpec->atom());
   if (!maybeAppendRequestedModule(module, moduleSpec)) {
     return false;
   }
 
   RootedAtom importName(cx_);
   RootedAtom localName(cx_);
@@ -1295,20 +1295,20 @@ bool ModuleBuilder::appendImportEntryObj
     HandleImportEntryObject importEntry) {
   MOZ_ASSERT(importEntry->localName());
   return importEntries_.put(importEntry->localName(), importEntry);
 }
 
 bool ModuleBuilder::processExport(frontend::ParseNode* exportNode) {
   using namespace js::frontend;
 
-  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::Export) ||
-             exportNode->isKind(ParseNodeKind::ExportDefault));
+  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportStmt) ||
+             exportNode->isKind(ParseNodeKind::ExportDefaultStmt));
 
-  bool isDefault = exportNode->isKind(ParseNodeKind::ExportDefault);
+  bool isDefault = exportNode->isKind(ParseNodeKind::ExportDefaultStmt);
   ParseNode* kid = isDefault ? exportNode->as<BinaryNode>().left()
                              : exportNode->as<UnaryNode>().kid();
 
   if (isDefault && exportNode->as<BinaryNode>().right()) {
     // This is an export default containing an expression.
     HandlePropertyName localName = cx_->names().default_;
     HandlePropertyName exportName = cx_->names().default_;
     return appendExportEntry(exportName, localName);
@@ -1329,52 +1329,52 @@ bool ModuleBuilder::processExport(fronte
         exportName = exportNameNode->atom();
         if (!appendExportEntry(exportName, localName, spec)) {
           return false;
         }
       }
       break;
     }
 
-    case ParseNodeKind::Class: {
+    case ParseNodeKind::ClassDecl: {
       const ClassNode& cls = kid->as<ClassNode>();
       MOZ_ASSERT(cls.names());
       RootedAtom localName(cx_, cls.names()->innerBinding()->atom());
       RootedAtom exportName(
           cx_, isDefault ? cx_->names().default_ : localName.get());
       if (!appendExportEntry(exportName, localName)) {
         return false;
       }
       break;
     }
 
-    case ParseNodeKind::Var:
-    case ParseNodeKind::Const:
-    case ParseNodeKind::Let: {
+    case ParseNodeKind::VarStmt:
+    case ParseNodeKind::ConstDecl:
+    case ParseNodeKind::LetDecl: {
       RootedAtom localName(cx_);
       RootedAtom exportName(cx_);
       for (ParseNode* binding : kid->as<ListNode>().contents()) {
-        if (binding->isKind(ParseNodeKind::Assign)) {
+        if (binding->isKind(ParseNodeKind::AssignExpr)) {
           binding = binding->as<AssignmentNode>().left();
         } else {
           MOZ_ASSERT(binding->isKind(ParseNodeKind::Name));
         }
 
         if (binding->isKind(ParseNodeKind::Name)) {
           localName = binding->as<NameNode>().atom();
           exportName = isDefault ? cx_->names().default_ : localName.get();
           if (!appendExportEntry(exportName, localName)) {
             return false;
           }
-        } else if (binding->isKind(ParseNodeKind::Array)) {
+        } else if (binding->isKind(ParseNodeKind::ArrayExpr)) {
           if (!processExportArrayBinding(&binding->as<ListNode>())) {
             return false;
           }
         } else {
-          MOZ_ASSERT(binding->isKind(ParseNodeKind::Object));
+          MOZ_ASSERT(binding->isKind(ParseNodeKind::ObjectExpr));
           if (!processExportObjectBinding(&binding->as<ListNode>())) {
             return false;
           }
         }
       }
       break;
     }
 
@@ -1401,52 +1401,52 @@ bool ModuleBuilder::processExport(fronte
 bool ModuleBuilder::processExportBinding(frontend::ParseNode* binding) {
   using namespace js::frontend;
 
   if (binding->isKind(ParseNodeKind::Name)) {
     RootedAtom name(cx_, binding->as<NameNode>().atom());
     return appendExportEntry(name, name);
   }
 
-  if (binding->isKind(ParseNodeKind::Array)) {
+  if (binding->isKind(ParseNodeKind::ArrayExpr)) {
     return processExportArrayBinding(&binding->as<ListNode>());
   }
 
-  MOZ_ASSERT(binding->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(binding->isKind(ParseNodeKind::ObjectExpr));
   return processExportObjectBinding(&binding->as<ListNode>());
 }
 
 bool ModuleBuilder::processExportArrayBinding(frontend::ListNode* array) {
   using namespace js::frontend;
 
-  MOZ_ASSERT(array->isKind(ParseNodeKind::Array));
+  MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr));
 
   for (ParseNode* node : array->contents()) {
     if (node->isKind(ParseNodeKind::Elision)) {
       continue;
     }
 
     if (node->isKind(ParseNodeKind::Spread)) {
       node = node->as<UnaryNode>().kid();
-    } else if (node->isKind(ParseNodeKind::Assign)) {
+    } else if (node->isKind(ParseNodeKind::AssignExpr)) {
       node = node->as<AssignmentNode>().left();
     }
 
     if (!processExportBinding(node)) {
       return false;
     }
   }
 
   return true;
 }
 
 bool ModuleBuilder::processExportObjectBinding(frontend::ListNode* obj) {
   using namespace js::frontend;
 
-  MOZ_ASSERT(obj->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr));
 
   for (ParseNode* node : obj->contents()) {
     MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||
                node->isKind(ParseNodeKind::Colon) ||
                node->isKind(ParseNodeKind::Shorthand) ||
                node->isKind(ParseNodeKind::Spread));
 
     ParseNode* target;
@@ -1454,39 +1454,39 @@ bool ModuleBuilder::processExportObjectB
       target = node->as<UnaryNode>().kid();
     } else {
       if (node->isKind(ParseNodeKind::MutateProto)) {
         target = node->as<UnaryNode>().kid();
       } else {
         target = node->as<BinaryNode>().right();
       }
 
-      if (target->isKind(ParseNodeKind::Assign)) {
+      if (target->isKind(ParseNodeKind::AssignExpr)) {
         target = target->as<AssignmentNode>().left();
       }
     }
 
     if (!processExportBinding(target)) {
       return false;
     }
   }
 
   return true;
 }
 
 bool ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode) {
   using namespace js::frontend;
 
-  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportFrom));
+  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportFromStmt));
 
   ListNode* specList = &exportNode->left()->as<ListNode>();
   MOZ_ASSERT(specList->isKind(ParseNodeKind::ExportSpecList));
 
   NameNode* moduleSpec = &exportNode->right()->as<NameNode>();
-  MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::String));
+  MOZ_ASSERT(moduleSpec->isKind(ParseNodeKind::StringExpr));
 
   RootedAtom module(cx_, moduleSpec->atom());
   if (!maybeAppendRequestedModule(module, moduleSpec)) {
     return false;
   }
 
   RootedAtom bindingName(cx_);
   RootedAtom exportName(cx_);
@@ -1497,17 +1497,17 @@ bool ModuleBuilder::processExportFrom(fr
           &spec->as<BinaryNode>().right()->as<NameNode>();
       bindingName = localNameNode->atom();
       exportName = exportNameNode->atom();
       if (!appendExportFromEntry(exportName, module, bindingName,
                                  localNameNode)) {
         return false;
       }
     } else {
-      MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpec));
+      MOZ_ASSERT(spec->isKind(ParseNodeKind::ExportBatchSpecStmt));
       exportName = cx_->names().star;
       if (!appendExportFromEntry(nullptr, module, exportName, spec)) {
         return false;
       }
     }
   }
 
   return true;
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -1704,121 +1704,121 @@ class ASTSerializer {
 
   bool program(ListNode* node, MutableHandleValue dst);
 };
 
 } /* anonymous namespace */
 
 AssignmentOperator ASTSerializer::aop(ParseNodeKind kind) {
   switch (kind) {
-    case ParseNodeKind::Assign:
+    case ParseNodeKind::AssignExpr:
       return AOP_ASSIGN;
-    case ParseNodeKind::AddAssign:
+    case ParseNodeKind::AddAssignExpr:
       return AOP_PLUS;
-    case ParseNodeKind::SubAssign:
+    case ParseNodeKind::SubAssignExpr:
       return AOP_MINUS;
-    case ParseNodeKind::MulAssign:
+    case ParseNodeKind::MulAssignExpr:
       return AOP_STAR;
-    case ParseNodeKind::DivAssign:
+    case ParseNodeKind::DivAssignExpr:
       return AOP_DIV;
-    case ParseNodeKind::ModAssign:
+    case ParseNodeKind::ModAssignExpr:
       return AOP_MOD;
-    case ParseNodeKind::PowAssign:
+    case ParseNodeKind::PowAssignExpr:
       return AOP_POW;
-    case ParseNodeKind::LshAssign:
+    case ParseNodeKind::LshAssignExpr:
       return AOP_LSH;
-    case ParseNodeKind::RshAssign:
+    case ParseNodeKind::RshAssignExpr:
       return AOP_RSH;
-    case ParseNodeKind::UrshAssign:
+    case ParseNodeKind::UrshAssignExpr:
       return AOP_URSH;
-    case ParseNodeKind::BitOrAssign:
+    case ParseNodeKind::BitOrAssignExpr:
       return AOP_BITOR;
-    case ParseNodeKind::BitXorAssign:
+    case ParseNodeKind::BitXorAssignExpr:
       return AOP_BITXOR;
-    case ParseNodeKind::BitAndAssign:
+    case ParseNodeKind::BitAndAssignExpr:
       return AOP_BITAND;
     default:
       return AOP_ERR;
   }
 }
 
 UnaryOperator ASTSerializer::unop(ParseNodeKind kind) {
   if (IsDeleteKind(kind)) {
     return UNOP_DELETE;
   }
 
   if (IsTypeofKind(kind)) {
     return UNOP_TYPEOF;
   }
 
   switch (kind) {
-    case ParseNodeKind::Await:
+    case ParseNodeKind::AwaitExpr:
       return UNOP_AWAIT;
-    case ParseNodeKind::Neg:
+    case ParseNodeKind::NegExpr:
       return UNOP_NEG;
-    case ParseNodeKind::Pos:
+    case ParseNodeKind::PosExpr:
       return UNOP_POS;
-    case ParseNodeKind::Not:
+    case ParseNodeKind::NotExpr:
       return UNOP_NOT;
-    case ParseNodeKind::BitNot:
+    case ParseNodeKind::BitNotExpr:
       return UNOP_BITNOT;
-    case ParseNodeKind::Void:
+    case ParseNodeKind::VoidExpr:
       return UNOP_VOID;
     default:
       return UNOP_ERR;
   }
 }
 
 BinaryOperator ASTSerializer::binop(ParseNodeKind kind) {
   switch (kind) {
-    case ParseNodeKind::Lsh:
+    case ParseNodeKind::LshExpr:
       return BINOP_LSH;
-    case ParseNodeKind::Rsh:
+    case ParseNodeKind::RshExpr:
       return BINOP_RSH;
-    case ParseNodeKind::Ursh:
+    case ParseNodeKind::UrshExpr:
       return BINOP_URSH;
-    case ParseNodeKind::Lt:
+    case ParseNodeKind::LtExpr:
       return BINOP_LT;
-    case ParseNodeKind::Le:
+    case ParseNodeKind::LeExpr:
       return BINOP_LE;
-    case ParseNodeKind::Gt:
+    case ParseNodeKind::GtExpr:
       return BINOP_GT;
-    case ParseNodeKind::Ge:
+    case ParseNodeKind::GeExpr:
       return BINOP_GE;
-    case ParseNodeKind::Eq:
+    case ParseNodeKind::EqExpr:
       return BINOP_EQ;
-    case ParseNodeKind::Ne:
+    case ParseNodeKind::NeExpr:
       return BINOP_NE;
-    case ParseNodeKind::StrictEq:
+    case ParseNodeKind::StrictEqExpr:
       return BINOP_STRICTEQ;
-    case ParseNodeKind::StrictNe:
+    case ParseNodeKind::StrictNeExpr:
       return BINOP_STRICTNE;
-    case ParseNodeKind::Add:
+    case ParseNodeKind::AddExpr:
       return BINOP_ADD;
-    case ParseNodeKind::Sub:
+    case ParseNodeKind::SubExpr:
       return BINOP_SUB;
-    case ParseNodeKind::Star:
+    case ParseNodeKind::MulExpr:
       return BINOP_STAR;
-    case ParseNodeKind::Div:
+    case ParseNodeKind::DivExpr:
       return BINOP_DIV;
-    case ParseNodeKind::Mod:
+    case ParseNodeKind::ModExpr:
       return BINOP_MOD;
-    case ParseNodeKind::Pow:
+    case ParseNodeKind::PowExpr:
       return BINOP_POW;
-    case ParseNodeKind::BitOr:
+    case ParseNodeKind::BitOrExpr:
       return BINOP_BITOR;
-    case ParseNodeKind::BitXor:
+    case ParseNodeKind::BitXorExpr:
       return BINOP_BITXOR;
-    case ParseNodeKind::BitAnd:
+    case ParseNodeKind::BitAndExpr:
       return BINOP_BITAND;
-    case ParseNodeKind::In:
+    case ParseNodeKind::InExpr:
       return BINOP_IN;
-    case ParseNodeKind::InstanceOf:
+    case ParseNodeKind::InstanceOfExpr:
       return BINOP_INSTANCEOF;
-    case ParseNodeKind::Pipeline:
+    case ParseNodeKind::PipelineExpr:
       return BINOP_PIPELINE;
     default:
       return BINOP_ERR;
   }
 }
 
 bool ASTSerializer::statements(ListNode* stmtList, NodeVector& elts) {
   MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList));
@@ -1881,46 +1881,49 @@ bool ASTSerializer::program(ListNode* no
 
 bool ASTSerializer::sourceElement(ParseNode* pn, MutableHandleValue dst) {
   /* SpiderMonkey allows declarations even in pure statement contexts. */
   return statement(pn, dst);
 }
 
 bool ASTSerializer::declaration(ParseNode* pn, MutableHandleValue dst) {
   MOZ_ASSERT(pn->isKind(ParseNodeKind::Function) ||
-             pn->isKind(ParseNodeKind::Var) || pn->isKind(ParseNodeKind::Let) ||
-             pn->isKind(ParseNodeKind::Const));
+             pn->isKind(ParseNodeKind::VarStmt) ||
+             pn->isKind(ParseNodeKind::LetDecl) ||
+             pn->isKind(ParseNodeKind::ConstDecl));
 
   switch (pn->getKind()) {
     case ParseNodeKind::Function:
       return function(&pn->as<CodeNode>(), AST_FUNC_DECL, dst);
 
-    case ParseNodeKind::Var:
+    case ParseNodeKind::VarStmt:
       return variableDeclaration(&pn->as<ListNode>(), false, dst);
 
     default:
-      MOZ_ASSERT(pn->isKind(ParseNodeKind::Let) ||
-                 pn->isKind(ParseNodeKind::Const));
+      MOZ_ASSERT(pn->isKind(ParseNodeKind::LetDecl) ||
+                 pn->isKind(ParseNodeKind::ConstDecl));
       return variableDeclaration(&pn->as<ListNode>(), true, dst);
   }
 }
 
 bool ASTSerializer::variableDeclaration(ListNode* declList, bool lexical,
                                         MutableHandleValue dst) {
-  MOZ_ASSERT_IF(lexical, declList->isKind(ParseNodeKind::Let) ||
-                             declList->isKind(ParseNodeKind::Const));
-  MOZ_ASSERT_IF(!lexical, declList->isKind(ParseNodeKind::Var));
+  MOZ_ASSERT_IF(lexical, declList->isKind(ParseNodeKind::LetDecl) ||
+                             declList->isKind(ParseNodeKind::ConstDecl));
+  MOZ_ASSERT_IF(!lexical, declList->isKind(ParseNodeKind::VarStmt));
 
   VarDeclKind kind = VARDECL_ERR;
   // Treat both the toplevel const binding (secretly var-like) and the lexical
   // const the same way
   if (lexical) {
-    kind = declList->isKind(ParseNodeKind::Let) ? VARDECL_LET : VARDECL_CONST;
+    kind =
+        declList->isKind(ParseNodeKind::LetDecl) ? VARDECL_LET : VARDECL_CONST;
   } else {
-    kind = declList->isKind(ParseNodeKind::Var) ? VARDECL_VAR : VARDECL_CONST;
+    kind =
+        declList->isKind(ParseNodeKind::VarStmt) ? VARDECL_VAR : VARDECL_CONST;
   }
 
   NodeVector dtors(cx);
   if (!dtors.reserve(declList->count())) {
     return false;
   }
   for (ParseNode* decl : declList->contents()) {
     RootedValue child(cx);
@@ -1935,17 +1938,17 @@ bool ASTSerializer::variableDeclaration(
 bool ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst) {
   ParseNode* patternNode;
   ParseNode* initNode;
 
   if (pn->isKind(ParseNodeKind::Name)) {
     patternNode = pn;
     initNode = pn->as<NameNode>().initializer();
     MOZ_ASSERT_IF(initNode, pn->pn_pos.encloses(initNode->pn_pos));
-  } else if (pn->isKind(ParseNodeKind::Assign)) {
+  } else if (pn->isKind(ParseNodeKind::AssignExpr)) {
     AssignmentNode* assignNode = &pn->as<AssignmentNode>();
     patternNode = assignNode->left();
     initNode = assignNode->right();
     MOZ_ASSERT(pn->pn_pos.encloses(patternNode->pn_pos));
     MOZ_ASSERT(pn->pn_pos.encloses(initNode->pn_pos));
   } else {
     /* This happens for a destructuring declarator in a for-in/of loop. */
     patternNode = pn;
@@ -1954,23 +1957,23 @@ bool ASTSerializer::variableDeclarator(P
 
   RootedValue patternVal(cx), init(cx);
   return pattern(patternNode, &patternVal) && optExpression(initNode, &init) &&
          builder.variableDeclarator(patternVal, init, &pn->pn_pos, dst);
 }
 
 bool ASTSerializer::importDeclaration(BinaryNode* importNode,
                                       MutableHandleValue dst) {
-  MOZ_ASSERT(importNode->isKind(ParseNodeKind::Import));
+  MOZ_ASSERT(importNode->isKind(ParseNodeKind::ImportDecl));
 
   ListNode* specList = &importNode->left()->as<ListNode>();
   MOZ_ASSERT(specList->isKind(ParseNodeKind::ImportSpecList));
 
   ParseNode* moduleSpecNode = importNode->right();
-  MOZ_ASSERT(moduleSpecNode->isKind(ParseNodeKind::String));
+  MOZ_ASSERT(moduleSpecNode->isKind(ParseNodeKind::StringExpr));
 
   NodeVector elts(cx);
   if (!elts.reserve(specList->count())) {
     return false;
   }
 
   for (ParseNode* item : specList->contents()) {
     BinaryNode* spec = &item->as<BinaryNode>();
@@ -1997,29 +2000,29 @@ bool ASTSerializer::importSpecifier(Bina
   return identifier(importNameNode, &importName) &&
          identifier(bindingNameNode, &bindingName) &&
          builder.importSpecifier(importName, bindingName, &importSpec->pn_pos,
                                  dst);
 }
 
 bool ASTSerializer::exportDeclaration(ParseNode* exportNode,
                                       MutableHandleValue dst) {
-  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::Export) ||
-             exportNode->isKind(ParseNodeKind::ExportFrom) ||
-             exportNode->isKind(ParseNodeKind::ExportDefault));
-  MOZ_ASSERT_IF(exportNode->isKind(ParseNodeKind::Export),
+  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportStmt) ||
+             exportNode->isKind(ParseNodeKind::ExportFromStmt) ||
+             exportNode->isKind(ParseNodeKind::ExportDefaultStmt));
+  MOZ_ASSERT_IF(exportNode->isKind(ParseNodeKind::ExportStmt),
                 exportNode->is<UnaryNode>());
   MOZ_ASSERT_IF(
-      exportNode->isKind(ParseNodeKind::ExportFrom),
-      exportNode->as<BinaryNode>().right()->isKind(ParseNodeKind::String));
+      exportNode->isKind(ParseNodeKind::ExportFromStmt),
+      exportNode->as<BinaryNode>().right()->isKind(ParseNodeKind::StringExpr));
 
   RootedValue decl(cx, NullValue());
   NodeVector elts(cx);
 
-  ParseNode* kid = exportNode->isKind(ParseNodeKind::Export)
+  ParseNode* kid = exportNode->isKind(ParseNodeKind::ExportStmt)
                        ? exportNode->as<UnaryNode>().kid()
                        : exportNode->as<BinaryNode>().left();
   switch (ParseNodeKind kind = kid->getKind()) {
     case ParseNodeKind::ExportSpecList: {
       ListNode* specList = &kid->as<ListNode>();
       if (!elts.reserve(specList->count())) {
         return false;
       }
@@ -2041,47 +2044,47 @@ bool ASTSerializer::exportDeclaration(Pa
     }
 
     case ParseNodeKind::Function:
       if (!function(&kid->as<CodeNode>(), AST_FUNC_DECL, &decl)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Class:
+    case ParseNodeKind::ClassDecl:
       if (!classDefinition(&kid->as<ClassNode>(), false, &decl)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Var:
-    case ParseNodeKind::Const:
-    case ParseNodeKind::Let:
-      if (!variableDeclaration(&kid->as<ListNode>(), kind != ParseNodeKind::Var,
-                               &decl)) {
+    case ParseNodeKind::VarStmt:
+    case ParseNodeKind::ConstDecl:
+    case ParseNodeKind::LetDecl:
+      if (!variableDeclaration(&kid->as<ListNode>(),
+                               kind != ParseNodeKind::VarStmt, &decl)) {
         return false;
       }
       break;
 
     default:
       if (!expression(kid, &decl)) {
         return false;
       }
       break;
   }
 
   RootedValue moduleSpec(cx, NullValue());
-  if (exportNode->isKind(ParseNodeKind::ExportFrom)) {
+  if (exportNode->isKind(ParseNodeKind::ExportFromStmt)) {
     if (!literal(exportNode->as<BinaryNode>().right(), &moduleSpec)) {
       return false;
     }
   }
 
   RootedValue isDefault(cx, BooleanValue(false));
-  if (exportNode->isKind(ParseNodeKind::ExportDefault)) {
+  if (exportNode->isKind(ParseNodeKind::ExportDefaultStmt)) {
     isDefault.setBoolean(true);
   }
 
   return builder.exportDeclaration(decl, elts, moduleSpec, isDefault,
                                    &exportNode->pn_pos, dst);
 }
 
 bool ASTSerializer::exportSpecifier(BinaryNode* exportSpec,
@@ -2191,19 +2194,19 @@ bool ASTSerializer::tryStatement(TryNode
 }
 
 bool ASTSerializer::forInit(ParseNode* pn, MutableHandleValue dst) {
   if (!pn) {
     dst.setMagic(JS_SERIALIZE_NO_NODE);
     return true;
   }
 
-  bool lexical =
-      pn->isKind(ParseNodeKind::Let) || pn->isKind(ParseNodeKind::Const);
-  return (lexical || pn->isKind(ParseNodeKind::Var))
+  bool lexical = pn->isKind(ParseNodeKind::LetDecl) ||
+                 pn->isKind(ParseNodeKind::ConstDecl);
+  return (lexical || pn->isKind(ParseNodeKind::VarStmt))
              ? variableDeclaration(&pn->as<ListNode>(), lexical, dst)
              : expression(pn, dst);
 }
 
 bool ASTSerializer::forOf(ForNode* loop, ParseNode* iterExpr, HandleValue var,
                           HandleValue stmt, MutableHandleValue dst) {
   RootedValue expr(cx);
 
@@ -2239,51 +2242,51 @@ bool ASTSerializer::classDefinition(Clas
 
 bool ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst) {
   if (!CheckRecursionLimit(cx)) {
     return false;
   }
 
   switch (pn->getKind()) {
     case ParseNodeKind::Function:
-    case ParseNodeKind::Var:
+    case ParseNodeKind::VarStmt:
       return declaration(pn, dst);
 
-    case ParseNodeKind::Let:
-    case ParseNodeKind::Const:
+    case ParseNodeKind::LetDecl:
+    case ParseNodeKind::ConstDecl:
       return declaration(pn, dst);
 
-    case ParseNodeKind::Import:
+    case ParseNodeKind::ImportDecl:
       return importDeclaration(&pn->as<BinaryNode>(), dst);
 
-    case ParseNodeKind::Export:
-    case ParseNodeKind::ExportDefault:
-    case ParseNodeKind::ExportFrom:
+    case ParseNodeKind::ExportStmt:
+    case ParseNodeKind::ExportDefaultStmt:
+    case ParseNodeKind::ExportFromStmt:
       return exportDeclaration(pn, dst);
 
-    case ParseNodeKind::EmptyStatement:
+    case ParseNodeKind::EmptyStmt:
       return builder.emptyStatement(&pn->pn_pos, dst);
 
-    case ParseNodeKind::ExpressionStatement: {
+    case ParseNodeKind::ExpressionStmt: {
       RootedValue expr(cx);
       return expression(pn->as<UnaryNode>().kid(), &expr) &&
              builder.expressionStatement(expr, &pn->pn_pos, dst);
     }
 
     case ParseNodeKind::LexicalScope:
       pn = pn->as<LexicalScopeNode>().scopeBody();
       if (!pn->isKind(ParseNodeKind::StatementList)) {
         return statement(pn, dst);
       }
       MOZ_FALLTHROUGH;
 
     case ParseNodeKind::StatementList:
       return blockStatement(&pn->as<ListNode>(), dst);
 
-    case ParseNodeKind::If: {
+    case ParseNodeKind::IfStmt: {
       TernaryNode* ifNode = &pn->as<TernaryNode>();
 
       ParseNode* testNode = ifNode->kid1();
       MOZ_ASSERT(ifNode->pn_pos.encloses(testNode->pn_pos));
 
       ParseNode* consNode = ifNode->kid2();
       MOZ_ASSERT(ifNode->pn_pos.encloses(consNode->pn_pos));
 
@@ -2292,56 +2295,56 @@ bool ASTSerializer::statement(ParseNode*
 
       RootedValue test(cx), cons(cx), alt(cx);
 
       return expression(testNode, &test) && statement(consNode, &cons) &&
              optStatement(altNode, &alt) &&
              builder.ifStatement(test, cons, alt, &ifNode->pn_pos, dst);
     }
 
-    case ParseNodeKind::Switch:
+    case ParseNodeKind::SwitchStmt:
       return switchStatement(&pn->as<SwitchStatement>(), dst);
 
-    case ParseNodeKind::Try:
+    case ParseNodeKind::TryStmt:
       return tryStatement(&pn->as<TryNode>(), dst);
 
-    case ParseNodeKind::With:
-    case ParseNodeKind::While: {
+    case ParseNodeKind::WithStmt:
+    case ParseNodeKind::WhileStmt: {
       BinaryNode* node = &pn->as<BinaryNode>();
 
       ParseNode* exprNode = node->left();
       MOZ_ASSERT(node->pn_pos.encloses(exprNode->pn_pos));
 
       ParseNode* stmtNode = node->right();
       MOZ_ASSERT(node->pn_pos.encloses(stmtNode->pn_pos));
 
       RootedValue expr(cx), stmt(cx);
 
       return expression(exprNode, &expr) && statement(stmtNode, &stmt) &&
-             (node->isKind(ParseNodeKind::With)
+             (node->isKind(ParseNodeKind::WithStmt)
                   ? builder.withStatement(expr, stmt, &node->pn_pos, dst)
                   : builder.whileStatement(expr, stmt, &node->pn_pos, dst));
     }
 
-    case ParseNodeKind::DoWhile: {
+    case ParseNodeKind::DoWhileStmt: {
       BinaryNode* node = &pn->as<BinaryNode>();
 
       ParseNode* stmtNode = node->left();
       MOZ_ASSERT(node->pn_pos.encloses(stmtNode->pn_pos));
 
       ParseNode* testNode = node->right();
       MOZ_ASSERT(node->pn_pos.encloses(testNode->pn_pos));
 
       RootedValue stmt(cx), test(cx);
 
       return statement(stmtNode, &stmt) && expression(testNode, &test) &&
              builder.doWhileStatement(stmt, test, &node->pn_pos, dst);
     }
 
-    case ParseNodeKind::For: {
+    case ParseNodeKind::ForStmt: {
       ForNode* forNode = &pn->as<ForNode>();
 
       TernaryNode* head = forNode->head();
       MOZ_ASSERT(forNode->pn_pos.encloses(head->pn_pos));
 
       ParseNode* stmtNode = forNode->right();
       MOZ_ASSERT(forNode->pn_pos.encloses(stmtNode->pn_pos));
 
@@ -2363,27 +2366,28 @@ bool ASTSerializer::statement(ParseNode*
           head->isKind(ParseNodeKind::ForOf)) {
         RootedValue var(cx);
         if (initNode->is<LexicalScopeNode>()) {
           LexicalScopeNode* scopeNode = &initNode->as<LexicalScopeNode>();
           if (!variableDeclaration(&scopeNode->scopeBody()->as<ListNode>(),
                                    true, &var)) {
             return false;
           }
-        } else if (!initNode->isKind(ParseNodeKind::Var) &&
-                   !initNode->isKind(ParseNodeKind::Let) &&
-                   !initNode->isKind(ParseNodeKind::Const)) {
+        } else if (!initNode->isKind(ParseNodeKind::VarStmt) &&
+                   !initNode->isKind(ParseNodeKind::LetDecl) &&
+                   !initNode->isKind(ParseNodeKind::ConstDecl)) {
           if (!pattern(initNode, &var)) {
             return false;
           }
         } else {
-          if (!variableDeclaration(&initNode->as<ListNode>(),
-                                   initNode->isKind(ParseNodeKind::Let) ||
-                                       initNode->isKind(ParseNodeKind::Const),
-                                   &var)) {
+          if (!variableDeclaration(
+                  &initNode->as<ListNode>(),
+                  initNode->isKind(ParseNodeKind::LetDecl) ||
+                      initNode->isKind(ParseNodeKind::ConstDecl),
+                  &var)) {
             return false;
           }
         }
         if (head->isKind(ParseNodeKind::ForIn)) {
           return forIn(forNode, updateOrIter, var, stmt, dst);
         }
         return forOf(forNode, updateOrIter, var, stmt, dst);
       }
@@ -2391,65 +2395,65 @@ bool ASTSerializer::statement(ParseNode*
       RootedValue init(cx), test(cx), update(cx);
 
       return forInit(initNode, &init) && optExpression(maybeTest, &test) &&
              optExpression(updateOrIter, &update) &&
              builder.forStatement(init, test, update, stmt, &forNode->pn_pos,
                                   dst);
     }
 
-    case ParseNodeKind::Break:
-    case ParseNodeKind::Continue: {
+    case ParseNodeKind::BreakStmt:
+    case ParseNodeKind::ContinueStmt: {
       LoopControlStatement* node = &pn->as<LoopControlStatement>();
       RootedValue label(cx);
       RootedAtom pnAtom(cx, node->label());
       return optIdentifier(pnAtom, nullptr, &label) &&
-             (node->isKind(ParseNodeKind::Break)
+             (node->isKind(ParseNodeKind::BreakStmt)
                   ? builder.breakStatement(label, &node->pn_pos, dst)
                   : builder.continueStatement(label, &node->pn_pos, dst));
     }
 
-    case ParseNodeKind::Label: {
+    case ParseNodeKind::LabelStmt: {
       LabeledStatement* labelNode = &pn->as<LabeledStatement>();
       ParseNode* stmtNode = labelNode->statement();
       MOZ_ASSERT(labelNode->pn_pos.encloses(stmtNode->pn_pos));
 
       RootedValue label(cx), stmt(cx);
       RootedAtom pnAtom(cx, labelNode->label());
       return identifier(pnAtom, nullptr, &label) &&
              statement(stmtNode, &stmt) &&
              builder.labeledStatement(label, stmt, &labelNode->pn_pos, dst);
     }
 
-    case ParseNodeKind::Throw: {
+    case ParseNodeKind::ThrowStmt: {
       UnaryNode* throwNode = &pn->as<UnaryNode>();
       ParseNode* operand = throwNode->kid();
       MOZ_ASSERT(throwNode->pn_pos.encloses(operand->pn_pos));
 
       RootedValue arg(cx);
 
       return expression(operand, &arg) &&
              builder.throwStatement(arg, &throwNode->pn_pos, dst);
     }
 
-    case ParseNodeKind::Return: {
+    case ParseNodeKind::ReturnStmt: {
       UnaryNode* returnNode = &pn->as<UnaryNode>();
       ParseNode* operand = returnNode->kid();
       MOZ_ASSERT_IF(operand, returnNode->pn_pos.encloses(operand->pn_pos));
 
       RootedValue arg(cx);
 
       return optExpression(operand, &arg) &&
              builder.returnStatement(arg, &returnNode->pn_pos, dst);
     }
 
-    case ParseNodeKind::Debugger:
+    case ParseNodeKind::DebuggerStmt:
       return builder.debuggerStatement(&pn->pn_pos, dst);
 
-    case ParseNodeKind::Class:
+    case ParseNodeKind::ClassDecl:
       return classDefinition(&pn->as<ClassNode>(), false, dst);
 
     case ParseNodeKind::ClassMemberList: {
       ListNode* memberList = &pn->as<ListNode>();
       NodeVector members(cx);
       if (!members.reserve(memberList->count())) {
         return false;
       }
@@ -2505,18 +2509,18 @@ bool ASTSerializer::classMethod(ClassMet
          builder.classMethod(key, val, kind, isStatic, &classMethod->pn_pos,
                              dst);
 }
 
 bool ASTSerializer::leftAssociate(ListNode* node, MutableHandleValue dst) {
   MOZ_ASSERT(!node->empty());
 
   ParseNodeKind kind = node->getKind();
-  bool lor = kind == ParseNodeKind::Or;
-  bool logop = lor || (kind == ParseNodeKind::And);
+  bool lor = kind == ParseNodeKind::OrExpr;
+  bool logop = lor || (kind == ParseNodeKind::AndExpr);
 
   ParseNode* head = node->head();
   RootedValue left(cx);
   if (!expression(head, &left)) {
     return false;
   }
   for (ParseNode* next : node->contentsFrom(head->pn_next)) {
     RootedValue right(cx);
@@ -2596,157 +2600,157 @@ bool ASTSerializer::expression(ParseNode
   switch (pn->getKind()) {
     case ParseNodeKind::Function: {
       CodeNode* funNode = &pn->as<CodeNode>();
       ASTType type = funNode->funbox()->function()->isArrow() ? AST_ARROW_EXPR
                                                               : AST_FUNC_EXPR;
       return function(funNode, type, dst);
     }
 
-    case ParseNodeKind::Comma: {
+    case ParseNodeKind::CommaExpr: {
       NodeVector exprs(cx);
       return expressions(&pn->as<ListNode>(), exprs) &&
              builder.sequenceExpression(exprs, &pn->pn_pos, dst);
     }
 
-    case ParseNodeKind::Conditional: {
+    case ParseNodeKind::ConditionalExpr: {
       ConditionalExpression* condNode = &pn->as<ConditionalExpression>();
       ParseNode* testNode = condNode->kid1();
       ParseNode* consNode = condNode->kid2();
       ParseNode* altNode = condNode->kid3();
       MOZ_ASSERT(condNode->pn_pos.encloses(testNode->pn_pos));
       MOZ_ASSERT(condNode->pn_pos.encloses(consNode->pn_pos));
       MOZ_ASSERT(condNode->pn_pos.encloses(altNode->pn_pos));
 
       RootedValue test(cx), cons(cx), alt(cx);
 
       return expression(testNode, &test) && expression(consNode, &cons) &&
              expression(altNode, &alt) &&
              builder.conditionalExpression(test, cons, alt, &condNode->pn_pos,
                                            dst);
     }
 
-    case ParseNodeKind::Or:
-    case ParseNodeKind::And:
+    case ParseNodeKind::OrExpr:
+    case ParseNodeKind::AndExpr:
       return leftAssociate(&pn->as<ListNode>(), dst);
 
-    case ParseNodeKind::PreIncrement:
-    case ParseNodeKind::PreDecrement: {
+    case ParseNodeKind::PreIncrementExpr:
+    case ParseNodeKind::PreDecrementExpr: {
       UnaryNode* incDec = &pn->as<UnaryNode>();
       ParseNode* operand = incDec->kid();
       MOZ_ASSERT(incDec->pn_pos.encloses(operand->pn_pos));
 
-      bool inc = incDec->isKind(ParseNodeKind::PreIncrement);
+      bool inc = incDec->isKind(ParseNodeKind::PreIncrementExpr);
       RootedValue expr(cx);
       return expression(operand, &expr) &&
              builder.updateExpression(expr, inc, true, &incDec->pn_pos, dst);
     }
 
-    case ParseNodeKind::PostIncrement:
-    case ParseNodeKind::PostDecrement: {
+    case ParseNodeKind::PostIncrementExpr:
+    case ParseNodeKind::PostDecrementExpr: {
       UnaryNode* incDec = &pn->as<UnaryNode>();
       ParseNode* operand = incDec->kid();
       MOZ_ASSERT(incDec->pn_pos.encloses(operand->pn_pos));
 
-      bool inc = incDec->isKind(ParseNodeKind::PostIncrement);
+      bool inc = incDec->isKind(ParseNodeKind::PostIncrementExpr);
       RootedValue expr(cx);
       return expression(operand, &expr) &&
              builder.updateExpression(expr, inc, false, &incDec->pn_pos, dst);
     }
 
-    case ParseNodeKind::Assign:
-    case ParseNodeKind::AddAssign:
-    case ParseNodeKind::SubAssign:
-    case ParseNodeKind::BitOrAssign:
-    case ParseNodeKind::BitXorAssign:
-    case ParseNodeKind::BitAndAssign:
-    case ParseNodeKind::LshAssign:
-    case ParseNodeKind::RshAssign:
-    case ParseNodeKind::UrshAssign:
-    case ParseNodeKind::MulAssign:
-    case ParseNodeKind::DivAssign:
-    case ParseNodeKind::ModAssign:
-    case ParseNodeKind::PowAssign: {
+    case ParseNodeKind::AssignExpr:
+    case ParseNodeKind::AddAssignExpr:
+    case ParseNodeKind::SubAssignExpr:
+    case ParseNodeKind::BitOrAssignExpr:
+    case ParseNodeKind::BitXorAssignExpr:
+    case ParseNodeKind::BitAndAssignExpr:
+    case ParseNodeKind::LshAssignExpr:
+    case ParseNodeKind::RshAssignExpr:
+    case ParseNodeKind::UrshAssignExpr:
+    case ParseNodeKind::MulAssignExpr:
+    case ParseNodeKind::DivAssignExpr:
+    case ParseNodeKind::ModAssignExpr:
+    case ParseNodeKind::PowAssignExpr: {
       AssignmentNode* assignNode = &pn->as<AssignmentNode>();
       ParseNode* lhsNode = assignNode->left();
       ParseNode* rhsNode = assignNode->right();
       MOZ_ASSERT(assignNode->pn_pos.encloses(lhsNode->pn_pos));
       MOZ_ASSERT(assignNode->pn_pos.encloses(rhsNode->pn_pos));
 
       AssignmentOperator op = aop(assignNode->getKind());
       LOCAL_ASSERT(op > AOP_ERR && op < AOP_LIMIT);
 
       RootedValue lhs(cx), rhs(cx);
       return pattern(lhsNode, &lhs) && expression(rhsNode, &rhs) &&
              builder.assignmentExpression(op, lhs, rhs, &assignNode->pn_pos,
                                           dst);
     }
 
-    case ParseNodeKind::Pipeline:
-    case ParseNodeKind::Add:
-    case ParseNodeKind::Sub:
-    case ParseNodeKind::StrictEq:
-    case ParseNodeKind::Eq:
-    case ParseNodeKind::StrictNe:
-    case ParseNodeKind::Ne:
-    case ParseNodeKind::Lt:
-    case ParseNodeKind::Le:
-    case ParseNodeKind::Gt:
-    case ParseNodeKind::Ge:
-    case ParseNodeKind::Lsh:
-    case ParseNodeKind::Rsh:
-    case ParseNodeKind::Ursh:
-    case ParseNodeKind::Star:
-    case ParseNodeKind::Div:
-    case ParseNodeKind::Mod:
-    case ParseNodeKind::BitOr:
-    case ParseNodeKind::BitXor:
-    case ParseNodeKind::BitAnd:
-    case ParseNodeKind::In:
-    case ParseNodeKind::InstanceOf:
+    case ParseNodeKind::PipelineExpr:
+    case ParseNodeKind::AddExpr:
+    case ParseNodeKind::SubExpr:
+    case ParseNodeKind::StrictEqExpr:
+    case ParseNodeKind::EqExpr:
+    case ParseNodeKind::StrictNeExpr:
+    case ParseNodeKind::NeExpr:
+    case ParseNodeKind::LtExpr:
+    case ParseNodeKind::LeExpr:
+    case ParseNodeKind::GtExpr:
+    case ParseNodeKind::GeExpr:
+    case ParseNodeKind::LshExpr:
+    case ParseNodeKind::RshExpr:
+    case ParseNodeKind::UrshExpr:
+    case ParseNodeKind::MulExpr:
+    case ParseNodeKind::DivExpr:
+    case ParseNodeKind::ModExpr:
+    case ParseNodeKind::BitOrExpr:
+    case ParseNodeKind::BitXorExpr:
+    case ParseNodeKind::BitAndExpr:
+    case ParseNodeKind::InExpr:
+    case ParseNodeKind::InstanceOfExpr:
       return leftAssociate(&pn->as<ListNode>(), dst);
 
-    case ParseNodeKind::Pow:
+    case ParseNodeKind::PowExpr:
       return rightAssociate(&pn->as<ListNode>(), dst);
 
-    case ParseNodeKind::DeleteName:
-    case ParseNodeKind::DeleteProp:
-    case ParseNodeKind::DeleteElem:
+    case ParseNodeKind::DeleteNameExpr:
+    case ParseNodeKind::DeletePropExpr:
+    case ParseNodeKind::DeleteElemExpr:
     case ParseNodeKind::DeleteExpr:
-    case ParseNodeKind::TypeOfName:
+    case ParseNodeKind::TypeOfNameExpr:
     case ParseNodeKind::TypeOfExpr:
-    case ParseNodeKind::Void:
-    case ParseNodeKind::Not:
-    case ParseNodeKind::BitNot:
-    case ParseNodeKind::Pos:
-    case ParseNodeKind::Await:
-    case ParseNodeKind::Neg: {
+    case ParseNodeKind::VoidExpr:
+    case ParseNodeKind::NotExpr:
+    case ParseNodeKind::BitNotExpr:
+    case ParseNodeKind::PosExpr:
+    case ParseNodeKind::AwaitExpr:
+    case ParseNodeKind::NegExpr: {
       UnaryNode* unaryNode = &pn->as<UnaryNode>();
       ParseNode* operand = unaryNode->kid();
       MOZ_ASSERT(unaryNode->pn_pos.encloses(operand->pn_pos));
 
       UnaryOperator op = unop(unaryNode->getKind());
       LOCAL_ASSERT(op > UNOP_ERR && op < UNOP_LIMIT);
 
       RootedValue expr(cx);
       return expression(operand, &expr) &&
              builder.unaryExpression(op, expr, &unaryNode->pn_pos, dst);
     }
 
-    case ParseNodeKind::New:
-    case ParseNodeKind::TaggedTemplate:
-    case ParseNodeKind::Call:
-    case ParseNodeKind::SuperCall: {
+    case ParseNodeKind::NewExpr:
+    case ParseNodeKind::TaggedTemplateExpr:
+    case ParseNodeKind::CallExpr:
+    case ParseNodeKind::SuperCallExpr: {
       BinaryNode* node = &pn->as<BinaryNode>();
       ParseNode* calleeNode = node->left();
       ListNode* argsList = &node->right()->as<ListNode>();
       MOZ_ASSERT(node->pn_pos.encloses(calleeNode->pn_pos));
 
       RootedValue callee(cx);
-      if (node->isKind(ParseNodeKind::SuperCall)) {
+      if (node->isKind(ParseNodeKind::SuperCallExpr)) {
         MOZ_ASSERT(calleeNode->isKind(ParseNodeKind::SuperBase));
         if (!builder.super(&calleeNode->pn_pos, &callee)) {
           return false;
         }
       } else {
         if (!expression(calleeNode, &callee)) {
           return false;
         }
@@ -2762,27 +2766,27 @@ bool ASTSerializer::expression(ParseNode
 
         RootedValue arg(cx);
         if (!expression(argNode, &arg)) {
           return false;
         }
         args.infallibleAppend(arg);
       }
 
-      if (node->getKind() == ParseNodeKind::TaggedTemplate) {
+      if (node->getKind() == ParseNodeKind::TaggedTemplateExpr) {
         return builder.taggedTemplate(callee, args, &node->pn_pos, dst);
       }
 
       // SUPERCALL is Call(super, args)
-      return node->isKind(ParseNodeKind::New)
+      return node->isKind(ParseNodeKind::NewExpr)
                  ? builder.newExpression(callee, args, &node->pn_pos, dst)
                  : builder.callExpression(callee, args, &node->pn_pos, dst);
     }
 
-    case ParseNodeKind::Dot: {
+    case ParseNodeKind::DotExpr: {
       PropertyAccess* prop = &pn->as<PropertyAccess>();
       // TODO(khyperia): Implement private field access.
       MOZ_ASSERT(prop->pn_pos.encloses(prop->expression().pn_pos));
 
       RootedValue expr(cx);
       RootedValue propname(cx);
       RootedAtom pnAtom(cx, prop->key().atom());
 
@@ -2796,17 +2800,17 @@ bool ASTSerializer::expression(ParseNode
         }
       }
 
       return identifier(pnAtom, nullptr, &propname) &&
              builder.memberExpression(false, expr, propname, &prop->pn_pos,
                                       dst);
     }
 
-    case ParseNodeKind::Elem: {
+    case ParseNodeKind::ElemExpr: {
       PropertyByValue* elem = &pn->as<PropertyByValue>();
       MOZ_ASSERT(elem->pn_pos.encloses(elem->expression().pn_pos));
       MOZ_ASSERT(elem->pn_pos.encloses(elem->key().pn_pos));
 
       RootedValue expr(cx), key(cx);
 
       if (elem->isSuper()) {
         if (!builder.super(&elem->expression().pn_pos, &expr)) {
@@ -2817,17 +2821,17 @@ bool ASTSerializer::expression(ParseNode
           return false;
         }
       }
 
       return expression(&elem->key(), &key) &&
              builder.memberExpression(true, expr, key, &elem->pn_pos, dst);
     }
 
-    case ParseNodeKind::CallSiteObj: {
+    case ParseNodeKind::CallSiteObjExpr: {
       CallSiteNode* callSiteObj = &pn->as<CallSiteNode>();
       ListNode* rawNodes = callSiteObj->rawNodes();
       NodeVector raw(cx);
       if (!raw.reserve(rawNodes->count())) {
         return false;
       }
       for (ParseNode* item : rawNodes->contents()) {
         NameNode* rawItem = &item->as<NameNode>();
@@ -2843,29 +2847,29 @@ bool ASTSerializer::expression(ParseNode
         return false;
       }
 
       for (ParseNode* cookedItem :
            callSiteObj->contentsFrom(rawNodes->pn_next)) {
         MOZ_ASSERT(callSiteObj->pn_pos.encloses(cookedItem->pn_pos));
 
         RootedValue expr(cx);
-        if (cookedItem->isKind(ParseNodeKind::RawUndefined)) {
+        if (cookedItem->isKind(ParseNodeKind::RawUndefinedExpr)) {
           expr.setUndefined();
         } else {
-          MOZ_ASSERT(cookedItem->isKind(ParseNodeKind::TemplateString));
+          MOZ_ASSERT(cookedItem->isKind(ParseNodeKind::TemplateStringExpr));
           expr.setString(cookedItem->as<NameNode>().atom());
         }
         cooked.infallibleAppend(expr);
       }
 
       return builder.callSiteObj(raw, cooked, &callSiteObj->pn_pos, dst);
     }
 
-    case ParseNodeKind::Array: {
+    case ParseNodeKind::ArrayExpr: {
       ListNode* array = &pn->as<ListNode>();
       NodeVector elts(cx);
       if (!elts.reserve(array->count())) {
         return false;
       }
 
       for (ParseNode* item : array->contents()) {
         MOZ_ASSERT(array->pn_pos.encloses(item->pn_pos));
@@ -2891,17 +2895,17 @@ bool ASTSerializer::expression(ParseNode
     }
 
     case ParseNodeKind::ComputedName: {
       RootedValue name(cx);
       return expression(pn->as<UnaryNode>().kid(), &name) &&
              builder.computedName(name, &pn->pn_pos, dst);
     }
 
-    case ParseNodeKind::Object: {
+    case ParseNodeKind::ObjectExpr: {
       ListNode* obj = &pn->as<ListNode>();
       NodeVector elts(cx);
       if (!elts.reserve(obj->count())) {
         return false;
       }
 
       for (ParseNode* item : obj->contents()) {
         MOZ_ASSERT(obj->pn_pos.encloses(item->pn_pos));
@@ -2914,20 +2918,20 @@ bool ASTSerializer::expression(ParseNode
       }
 
       return builder.objectExpression(elts, &obj->pn_pos, dst);
     }
 
     case ParseNodeKind::Name:
       return identifier(&pn->as<NameNode>(), dst);
 
-    case ParseNodeKind::This:
+    case ParseNodeKind::ThisExpr:
       return builder.thisExpression(&pn->pn_pos, dst);
 
-    case ParseNodeKind::TemplateStringList: {
+    case ParseNodeKind::TemplateStringListExpr: {
       ListNode* list = &pn->as<ListNode>();
       NodeVector elts(cx);
       if (!elts.reserve(list->count())) {
         return false;
       }
 
       for (ParseNode* item : list->contents()) {
         MOZ_ASSERT(list->pn_pos.encloses(item->pn_pos));
@@ -2937,84 +2941,84 @@ bool ASTSerializer::expression(ParseNode
           return false;
         }
         elts.infallibleAppend(expr);
       }
 
       return builder.templateLiteral(elts, &list->pn_pos, dst);
     }
 
-    case ParseNodeKind::TemplateString:
-    case ParseNodeKind::String:
-    case ParseNodeKind::RegExp:
-    case ParseNodeKind::Number:
+    case ParseNodeKind::TemplateStringExpr:
+    case ParseNodeKind::StringExpr:
+    case ParseNodeKind::RegExpExpr:
+    case ParseNodeKind::NumberExpr:
 #ifdef ENABLE_BIGINT
-    case ParseNodeKind::BigInt:
+    case ParseNodeKind::BigIntExpr:
 #endif
-    case ParseNodeKind::True:
-    case ParseNodeKind::False:
-    case ParseNodeKind::Null:
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::TrueExpr:
+    case ParseNodeKind::FalseExpr:
+    case ParseNodeKind::NullExpr:
+    case ParseNodeKind::RawUndefinedExpr:
       return literal(pn, dst);
 
-    case ParseNodeKind::YieldStar: {
+    case ParseNodeKind::YieldStarExpr: {
       UnaryNode* yieldNode = &pn->as<UnaryNode>();
       ParseNode* operand = yieldNode->kid();
       MOZ_ASSERT(yieldNode->pn_pos.encloses(operand->pn_pos));
 
       RootedValue arg(cx);
       return expression(operand, &arg) &&
              builder.yieldExpression(arg, Delegating, &yieldNode->pn_pos, dst);
     }
 
-    case ParseNodeKind::Yield: {
+    case ParseNodeKind::YieldExpr: {
       UnaryNode* yieldNode = &pn->as<UnaryNode>();
       ParseNode* operand = yieldNode->kid();
       MOZ_ASSERT_IF(operand, yieldNode->pn_pos.encloses(operand->pn_pos));
 
       RootedValue arg(cx);
       return optExpression(operand, &arg) &&
              builder.yieldExpression(arg, NotDelegating, &yieldNode->pn_pos,
                                      dst);
     }
 
-    case ParseNodeKind::Class:
+    case ParseNodeKind::ClassDecl:
       return classDefinition(&pn->as<ClassNode>(), true, dst);
 
-    case ParseNodeKind::NewTarget:
-    case ParseNodeKind::ImportMeta: {
+    case ParseNodeKind::NewTargetExpr:
+    case ParseNodeKind::ImportMetaExpr: {
       BinaryNode* node = &pn->as<BinaryNode>();
       ParseNode* firstNode = node->left();
       MOZ_ASSERT(firstNode->isKind(ParseNodeKind::PosHolder));
       MOZ_ASSERT(node->pn_pos.encloses(firstNode->pn_pos));
 
       ParseNode* secondNode = node->right();
       MOZ_ASSERT(secondNode->isKind(ParseNodeKind::PosHolder));
       MOZ_ASSERT(node->pn_pos.encloses(secondNode->pn_pos));
 
       RootedValue firstIdent(cx);
       RootedValue secondIdent(cx);
 
       RootedAtom firstStr(cx);
       RootedAtom secondStr(cx);
 
-      if (node->getKind() == ParseNodeKind::NewTarget) {
+      if (node->getKind() == ParseNodeKind::NewTargetExpr) {
         firstStr = cx->names().new_;
         secondStr = cx->names().target;
       } else {
         firstStr = cx->names().import;
         secondStr = cx->names().meta;
       }
 
       return identifier(firstStr, &firstNode->pn_pos, &firstIdent) &&
              identifier(secondStr, &secondNode->pn_pos, &secondIdent) &&
              builder.metaProperty(firstIdent, secondIdent, &node->pn_pos, dst);
     }
 
-    case ParseNodeKind::CallImport: {
+    case ParseNodeKind::CallImportExpr: {
       BinaryNode* node = &pn->as<BinaryNode>();
       ParseNode* identNode = node->left();
       MOZ_ASSERT(identNode->isKind(ParseNodeKind::PosHolder));
       MOZ_ASSERT(identNode->pn_pos.encloses(identNode->pn_pos));
 
       ParseNode* argNode = node->right();
       MOZ_ASSERT(node->pn_pos.encloses(argNode->pn_pos));
 
@@ -3043,18 +3047,18 @@ bool ASTSerializer::expression(ParseNode
 bool ASTSerializer::propertyName(ParseNode* key, MutableHandleValue dst) {
   if (key->isKind(ParseNodeKind::ComputedName)) {
     return expression(key, dst);
   }
   if (key->isKind(ParseNodeKind::ObjectPropertyName)) {
     return identifier(&key->as<NameNode>(), dst);
   }
 
-  LOCAL_ASSERT(key->isKind(ParseNodeKind::String) ||
-               key->isKind(ParseNodeKind::Number));
+  LOCAL_ASSERT(key->isKind(ParseNodeKind::StringExpr) ||
+               key->isKind(ParseNodeKind::NumberExpr));
 
   return literal(key, dst);
 }
 
 bool ASTSerializer::property(ParseNode* pn, MutableHandleValue dst) {
   if (pn->isKind(ParseNodeKind::MutateProto)) {
     RootedValue val(cx);
     return expression(pn->as<UnaryNode>().kid(), &val) &&
@@ -3094,72 +3098,72 @@ bool ASTSerializer::property(ParseNode* 
   return propertyName(keyNode, &key) && expression(valNode, &val) &&
          builder.propertyInitializer(key, val, kind, isShorthand, isMethod,
                                      &node->pn_pos, dst);
 }
 
 bool ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst) {
   RootedValue val(cx);
   switch (pn->getKind()) {
-    case ParseNodeKind::TemplateString:
-    case ParseNodeKind::String:
+    case ParseNodeKind::TemplateStringExpr:
+    case ParseNodeKind::StringExpr:
       val.setString(pn->as<NameNode>().atom());
       break;
 
-    case ParseNodeKind::RegExp: {
+    case ParseNodeKind::RegExpExpr: {
       RootedObject re1(cx, pn->as<RegExpLiteral>().objbox()->object());
       LOCAL_ASSERT(re1 && re1->is<RegExpObject>());
 
       RootedObject re2(cx, CloneRegExpObject(cx, re1.as<RegExpObject>()));
       if (!re2) {
         return false;
       }
 
       val.setObject(*re2);
       break;
     }
 
-    case ParseNodeKind::Number:
+    case ParseNodeKind::NumberExpr:
       val.setNumber(pn->as<NumericLiteral>().value());
       break;
 
 #ifdef ENABLE_BIGINT
     case ParseNodeKind::BigInt: {
       BigInt* x = pn->as<BigIntLiteral>().box()->value();
       cx->check(x);
       val.setBigInt(x);
       break;
     }
 #endif
 
-    case ParseNodeKind::Null:
+    case ParseNodeKind::NullExpr:
       val.setNull();
       break;
 
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::RawUndefinedExpr:
       val.setUndefined();
       break;
 
-    case ParseNodeKind::True:
+    case ParseNodeKind::TrueExpr:
       val.setBoolean(true);
       break;
 
-    case ParseNodeKind::False:
+    case ParseNodeKind::FalseExpr:
       val.setBoolean(false);
       break;
 
     default:
       LOCAL_NOT_REACHED("unexpected literal type");
   }
 
   return builder.literal(val, &pn->pn_pos, dst);
 }
 
 bool ASTSerializer::arrayPattern(ListNode* array, MutableHandleValue dst) {
-  MOZ_ASSERT(array->isKind(ParseNodeKind::Array));
+  MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr));
 
   NodeVector elts(cx);
   if (!elts.reserve(array->count())) {
     return false;
   }
 
   for (ParseNode* item : array->contents()) {
     if (item->isKind(ParseNodeKind::Elision)) {
@@ -3181,17 +3185,17 @@ bool ASTSerializer::arrayPattern(ListNod
       elts.infallibleAppend(patt);
     }
   }
 
   return builder.arrayPattern(elts, &array->pn_pos, dst);
 }
 
 bool ASTSerializer::objectPattern(ListNode* obj, MutableHandleValue dst) {
-  MOZ_ASSERT(obj->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr));
 
   NodeVector elts(cx);
   if (!elts.reserve(obj->count())) {
     return false;
   }
 
   for (ParseNode* propdef : obj->contents()) {
     if (propdef->isKind(ParseNodeKind::Spread)) {
@@ -3239,20 +3243,20 @@ bool ASTSerializer::objectPattern(ListNo
 }
 
 bool ASTSerializer::pattern(ParseNode* pn, MutableHandleValue dst) {
   if (!CheckRecursionLimit(cx)) {
     return false;
   }
 
   switch (pn->getKind()) {
-    case ParseNodeKind::Object:
+    case ParseNodeKind::ObjectExpr:
       return objectPattern(&pn->as<ListNode>(), dst);
 
-    case ParseNodeKind::Array:
+    case ParseNodeKind::ArrayExpr:
       return arrayPattern(&pn->as<ListNode>(), dst);
 
     default:
       return expression(pn, dst);
   }
 }
 
 bool ASTSerializer::identifier(HandleAtom atom, TokenPos* pos,
@@ -3318,33 +3322,34 @@ bool ASTSerializer::functionArgsAndBody(
   }
 
   if (bodyNode->is<LexicalScopeNode>()) {
     bodyNode = bodyNode->as<LexicalScopeNode>().scopeBody();
   }
 
   /* Serialize the arguments and body. */
   switch (bodyNode->getKind()) {
-    case ParseNodeKind::Return: /* expression closure, no destructured args */
+    case ParseNodeKind::ReturnStmt: /* expression closure, no destructured args
+                                     */
       return functionArgs(pn, argsList, args, defaults, rest) &&
              expression(bodyNode->as<UnaryNode>().kid(), body);
 
     case ParseNodeKind::StatementList: /* statement closure */
     {
       ParseNode* firstNode = bodyNode->as<ListNode>().head();
 
       // Skip over initial yield in generator.
       if (firstNode && firstNode->isKind(ParseNodeKind::InitialYield)) {
         firstNode = firstNode->pn_next;
       }
 
       // Async arrow with expression body is converted into STATEMENTLIST
       // to insert initial yield.
       if (isAsync && isExpression) {
-        MOZ_ASSERT(firstNode->getKind() == ParseNodeKind::Return);
+        MOZ_ASSERT(firstNode->getKind() == ParseNodeKind::ReturnStmt);
         return functionArgs(pn, argsList, args, defaults, rest) &&
                expression(firstNode->as<UnaryNode>().kid(), body);
       }
 
       return functionArgs(pn, argsList, args, defaults, rest) &&
              functionBody(firstNode, &bodyNode->pn_pos, body);
     }
 
@@ -3364,31 +3369,32 @@ bool ASTSerializer::functionArgs(ParseNo
   bool defaultsNull = true;
   MOZ_ASSERT(defaults.empty(),
              "must be initially empty for it to be proper to clear this "
              "when there are no defaults");
 
   for (ParseNode* arg : argsList->contentsTo(argsList->last())) {
     ParseNode* pat;
     ParseNode* defNode;
-    if (arg->isKind(ParseNodeKind::Name) || arg->isKind(ParseNodeKind::Array) ||
-        arg->isKind(ParseNodeKind::Object)) {
+    if (arg->isKind(ParseNodeKind::Name) ||
+        arg->isKind(ParseNodeKind::ArrayExpr) ||
+        arg->isKind(ParseNodeKind::ObjectExpr)) {
       pat = arg;
       defNode = nullptr;
     } else {
-      MOZ_ASSERT(arg->isKind(ParseNodeKind::Assign));
+      MOZ_ASSERT(arg->isKind(ParseNodeKind::AssignExpr));
       AssignmentNode* assignNode = &arg->as<AssignmentNode>();
       pat = assignNode->left();
       defNode = assignNode->right();
     }
 
     // Process the name or pattern.
     MOZ_ASSERT(pat->isKind(ParseNodeKind::Name) ||
-               pat->isKind(ParseNodeKind::Array) ||
-               pat->isKind(ParseNodeKind::Object));
+               pat->isKind(ParseNodeKind::ArrayExpr) ||
+               pat->isKind(ParseNodeKind::ObjectExpr));
     if (!pattern(pat, &node)) {
       return false;
     }
     if (rest.isUndefined() && arg->pn_next == argsList->last()) {
       rest.setObject(node.toObject());
     } else {
       if (!args.append(node)) {
         return false;
--- a/js/src/frontend/BinASTParser.cpp
+++ b/js/src/frontend/BinASTParser.cpp
@@ -1,12 +1,12 @@
 // This file was autogenerated by binjs_generate_spidermonkey,
 // please DO NOT EDIT BY HAND.
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: set ts=8 sts=2 et sw=2 tw=80:
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // To generate this file, see the documentation in
 // js/src/frontend/binsource/README.md.
 
 #include "frontend/BinASTParser.h"
@@ -1759,18 +1759,18 @@ JS::Result<ParseNode*> BinASTParser<Tok>
   const BinField expected_fields[2] = {BinField::Binding, BinField::Expression};
   MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif  // defined(DEBUG)
 
   BINJS_MOZ_TRY_DECL(binding, parseAssignmentTarget());
 
   BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
-  BINJS_TRY_DECL(result, factory_.newAssignment(ParseNodeKind::Assign, binding,
-                                                expression));
+  BINJS_TRY_DECL(result, factory_.newAssignment(ParseNodeKind::AssignExpr,
+                                                binding, expression));
   return result;
 }
 
 template <typename Tok>
 JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceAssignmentTargetIdentifier(
     const size_t start, const BinKind kind, const BinFields& fields) {
   MOZ_ASSERT(kind == BinKind::AssignmentTargetIdentifier);
@@ -1817,96 +1817,96 @@ JS::Result<ParseNode*> BinASTParser<Tok>
 
   BINJS_MOZ_TRY_DECL(left, parseExpression());
 
   BINJS_MOZ_TRY_DECL(right, parseExpression());
 
   ParseNodeKind pnk;
   switch (operator_) {
     case BinaryOperator::Comma:
-      pnk = ParseNodeKind::Comma;
+      pnk = ParseNodeKind::CommaExpr;
       break;
     case BinaryOperator::LogicalOr:
-      pnk = ParseNodeKind::Or;
+      pnk = ParseNodeKind::OrExpr;
       break;
     case BinaryOperator::LogicalAnd:
-      pnk = ParseNodeKind::And;
+      pnk = ParseNodeKind::AndExpr;
       break;
     case BinaryOperator::BitOr:
-      pnk = ParseNodeKind::BitOr;
+      pnk = ParseNodeKind::BitOrExpr;
       break;
     case BinaryOperator::BitXor:
-      pnk = ParseNodeKind::BitXor;
+      pnk = ParseNodeKind::BitXorExpr;
       break;
     case BinaryOperator::BitAnd:
-      pnk = ParseNodeKind::BitAnd;
+      pnk = ParseNodeKind::BitAndExpr;
       break;
     case BinaryOperator::Eq:
-      pnk = ParseNodeKind::Eq;
+      pnk = ParseNodeKind::EqExpr;
       break;
     case BinaryOperator::Neq:
-      pnk = ParseNodeKind::Ne;
+      pnk = ParseNodeKind::NeExpr;
       break;
     case BinaryOperator::StrictEq:
-      pnk = ParseNodeKind::StrictEq;
+      pnk = ParseNodeKind::StrictEqExpr;
       break;
     case BinaryOperator::StrictNeq:
-      pnk = ParseNodeKind::StrictNe;
+      pnk = ParseNodeKind::StrictNeExpr;
       break;
     case BinaryOperator::LessThan:
-      pnk = ParseNodeKind::Lt;
+      pnk = ParseNodeKind::LtExpr;
       break;
     case BinaryOperator::LeqThan:
-      pnk = ParseNodeKind::Le;
+      pnk = ParseNodeKind::LeExpr;
       break;
     case BinaryOperator::GreaterThan:
-      pnk = ParseNodeKind::Gt;
+      pnk = ParseNodeKind::GtExpr;
       break;
     case BinaryOperator::GeqThan:
-      pnk = ParseNodeKind::Ge;
+      pnk = ParseNodeKind::GeExpr;
       break;
     case BinaryOperator::In:
-      pnk = ParseNodeKind::In;
+      pnk = ParseNodeKind::InExpr;
       break;
     case BinaryOperator::Instanceof:
-      pnk = ParseNodeKind::InstanceOf;
+      pnk = ParseNodeKind::InstanceOfExpr;
       break;
     case BinaryOperator::Lsh:
-      pnk = ParseNodeKind::Lsh;
+      pnk = ParseNodeKind::LshExpr;
       break;
     case BinaryOperator::Rsh:
-      pnk = ParseNodeKind::Rsh;
+      pnk = ParseNodeKind::RshExpr;
       break;
     case BinaryOperator::Ursh:
-      pnk = ParseNodeKind::Ursh;
+      pnk = ParseNodeKind::UrshExpr;
       break;
     case BinaryOperator::Plus:
-      pnk = ParseNodeKind::Add;
+      pnk = ParseNodeKind::AddExpr;
       break;
     case BinaryOperator::Minus:
-      pnk = ParseNodeKind::Sub;
+      pnk = ParseNodeKind::SubExpr;
       break;
     case BinaryOperator::Mul:
-      pnk = ParseNodeKind::Star;
+      pnk = ParseNodeKind::MulExpr;
       break;
     case BinaryOperator::Div:
-      pnk = ParseNodeKind::Div;
+      pnk = ParseNodeKind::DivExpr;
       break;
     case BinaryOperator::Mod:
-      pnk = ParseNodeKind::Mod;
+      pnk = ParseNodeKind::ModExpr;
       break;
     case BinaryOperator::Pow:
-      pnk = ParseNodeKind::Pow;
+      pnk = ParseNodeKind::PowExpr;
       break;
   }
 
   ParseNode* result;
   if (left->isKind(pnk) &&
-      pnk !=
-          ParseNodeKind::Pow /* ParseNodeKind::Pow is not left-associative */) {
+      pnk != ParseNodeKind::
+                 PowExpr /* ParseNodeKind::PowExpr is not left-associative */) {
     // Regroup left-associative operations into lists.
     left->template as<ListNode>().appendWithoutOrderAssumption(right);
     result = left;
   } else {
     BINJS_TRY_DECL(list, factory_.newList(pnk, tokenizer_->pos(start)));
 
     list->appendWithoutOrderAssumption(left);
     list->appendWithoutOrderAssumption(right);
@@ -2183,50 +2183,50 @@ BinASTParser<Tok>::parseInterfaceCompoun
 
   BINJS_MOZ_TRY_DECL(binding, parseSimpleAssignmentTarget());
 
   BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
   ParseNodeKind pnk;
   switch (operator_) {
     case CompoundAssignmentOperator::PlusAssign:
-      pnk = ParseNodeKind::AddAssign;
+      pnk = ParseNodeKind::AddAssignExpr;
       break;
     case CompoundAssignmentOperator::MinusAssign:
-      pnk = ParseNodeKind::SubAssign;
+      pnk = ParseNodeKind::SubAssignExpr;
       break;
     case CompoundAssignmentOperator::MulAssign:
-      pnk = ParseNodeKind::MulAssign;
+      pnk = ParseNodeKind::MulAssignExpr;
       break;
     case CompoundAssignmentOperator::DivAssign:
-      pnk = ParseNodeKind::DivAssign;
+      pnk = ParseNodeKind::DivAssignExpr;
       break;
     case CompoundAssignmentOperator::ModAssign:
-      pnk = ParseNodeKind::ModAssign;
+      pnk = ParseNodeKind::ModAssignExpr;
       break;
     case CompoundAssignmentOperator::PowAssign:
-      pnk = ParseNodeKind::PowAssign;
+      pnk = ParseNodeKind::PowAssignExpr;
       break;
     case CompoundAssignmentOperator::LshAssign:
-      pnk = ParseNodeKind::LshAssign;
+      pnk = ParseNodeKind::LshAssignExpr;
       break;
     case CompoundAssignmentOperator::RshAssign:
-      pnk = ParseNodeKind::RshAssign;
+      pnk = ParseNodeKind::RshAssignExpr;
       break;
     case CompoundAssignmentOperator::UrshAssign:
-      pnk = ParseNodeKind::UrshAssign;
+      pnk = ParseNodeKind::UrshAssignExpr;
       break;
     case CompoundAssignmentOperator::BitOrAssign:
-      pnk = ParseNodeKind::BitOrAssign;
+      pnk = ParseNodeKind::BitOrAssignExpr;
       break;
     case CompoundAssignmentOperator::BitXorAssign:
-      pnk = ParseNodeKind::BitXorAssign;
+      pnk = ParseNodeKind::BitXorAssignExpr;
       break;
     case CompoundAssignmentOperator::BitAndAssign:
-      pnk = ParseNodeKind::BitAndAssign;
+      pnk = ParseNodeKind::BitAndAssignExpr;
       break;
   }
   BINJS_TRY_DECL(result, factory_.newAssignment(pnk, binding, expression));
   return result;
 }
 
 template <typename Tok>
 JS::Result<ParseNode*>
@@ -2801,17 +2801,17 @@ JS::Result<ParseNode*> BinASTParser<Tok>
 
   // Restored by `kindGuard`.
   variableDeclarationKind_ = kind_;
   MOZ_TRY(
       checkBinding(binding->template as<NameNode>().atom()->asPropertyName()));
   ParseNodeKind pnk;
   switch (kind_) {
     case VariableDeclarationKind::Var:
-      pnk = ParseNodeKind::Var;
+      pnk = ParseNodeKind::VarStmt;
       break;
     case VariableDeclarationKind::Let:
       return raiseError("Let is not supported in this preview release");
     case VariableDeclarationKind::Const:
       return raiseError("Const is not supported in this preview release");
   }
   BINJS_TRY_DECL(result,
                  factory_.newDeclarationList(pnk, tokenizer_->pos(start)));
@@ -4087,49 +4087,49 @@ JS::Result<ParseNode*> BinASTParser<Tok>
 
   BINJS_MOZ_TRY_DECL(operator_, parseUnaryOperator());
 
   BINJS_MOZ_TRY_DECL(operand, parseExpression());
 
   ParseNodeKind pnk;
   switch (operator_) {
     case UnaryOperator::Minus:
-      pnk = ParseNodeKind::Neg;
+      pnk = ParseNodeKind::NegExpr;
       break;
     case UnaryOperator::Plus:
-      pnk = ParseNodeKind::Pos;
+      pnk = ParseNodeKind::PosExpr;
       break;
     case UnaryOperator::Not:
-      pnk = ParseNodeKind::Not;
+      pnk = ParseNodeKind::NotExpr;
       break;
     case UnaryOperator::BitNot:
-      pnk = ParseNodeKind::BitNot;
+      pnk = ParseNodeKind::BitNotExpr;
       break;
     case UnaryOperator::Typeof: {
       if (operand->isKind(ParseNodeKind::Name)) {
-        pnk = ParseNodeKind::TypeOfName;
+        pnk = ParseNodeKind::TypeOfNameExpr;
       } else {
         pnk = ParseNodeKind::TypeOfExpr;
       }
       break;
     }
     case UnaryOperator::Void:
-      pnk = ParseNodeKind::Void;
+      pnk = ParseNodeKind::VoidExpr;
       break;
     case UnaryOperator::Delete: {
       switch (operand->getKind()) {
         case ParseNodeKind::Name:
           operand->setOp(JSOP_DELNAME);
-          pnk = ParseNodeKind::DeleteName;
+          pnk = ParseNodeKind::DeleteNameExpr;
           break;
-        case ParseNodeKind::Dot:
-          pnk = ParseNodeKind::DeleteProp;
+        case ParseNodeKind::DotExpr:
+          pnk = ParseNodeKind::DeletePropExpr;
           break;
-        case ParseNodeKind::Elem:
-          pnk = ParseNodeKind::DeleteElem;
+        case ParseNodeKind::ElemExpr:
+          pnk = ParseNodeKind::DeleteElemExpr;
           break;
         default:
           pnk = ParseNodeKind::DeleteExpr;
       }
       break;
     }
   }
   BINJS_TRY_DECL(result, factory_.newUnary(pnk, start, operand));
@@ -4152,22 +4152,22 @@ JS::Result<ParseNode*> BinASTParser<Tok>
 
   BINJS_MOZ_TRY_DECL(operator_, parseUpdateOperator());
 
   BINJS_MOZ_TRY_DECL(operand, parseSimpleAssignmentTarget());
 
   ParseNodeKind pnk;
   switch (operator_) {
     case UpdateOperator::Incr:
-      pnk =
-          isPrefix ? ParseNodeKind::PreIncrement : ParseNodeKind::PostIncrement;
+      pnk = isPrefix ? ParseNodeKind::PreIncrementExpr
+                     : ParseNodeKind::PostIncrementExpr;
       break;
     case UpdateOperator::Decr:
-      pnk =
-          isPrefix ? ParseNodeKind::PreDecrement : ParseNodeKind::PostDecrement;
+      pnk = isPrefix ? ParseNodeKind::PreDecrementExpr
+                     : ParseNodeKind::PostDecrementExpr;
       break;
   }
   BINJS_TRY_DECL(result, factory_.newUnary(pnk, start, operand));
   return result;
 }
 
 template <typename Tok>
 JS::Result<ParseNode*> BinASTParser<Tok>::parseInterfaceVariableDeclaration(
@@ -4189,17 +4189,17 @@ JS::Result<ParseNode*> BinASTParser<Tok>
   // By specification, the list may not be empty.
   if (declarators->empty()) {
     return raiseEmpty("VariableDeclaration");
   }
 
   ParseNodeKind pnk;
   switch (kind_) {
     case VariableDeclarationKind::Var:
-      pnk = ParseNodeKind::Var;
+      pnk = ParseNodeKind::VarStmt;
       break;
     case VariableDeclarationKind::Let:
       return raiseError("Let is not supported in this preview release");
     case VariableDeclarationKind::Const:
       return raiseError("Const is not supported in this preview release");
   }
   declarators->setKind(pnk);
   auto result = declarators;
@@ -4260,18 +4260,18 @@ JS::Result<ParseNode*> BinASTParser<Tok>
       // Here, `init` is required.
       return raiseMissingField("VariableDeclarator (with non-trivial pattern)",
                                BinField::Init);
     }
 
     MOZ_CRASH(
         "Unimplemented: AssertedScope check for BindingPattern variable "
         "declaration");
-    BINJS_TRY_VAR(result,
-                  factory_.newAssignment(ParseNodeKind::Assign, binding, init));
+    BINJS_TRY_VAR(result, factory_.newAssignment(ParseNodeKind::AssignExpr,
+                                                 binding, init));
   }
   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);
@@ -4802,19 +4802,19 @@ JS::Result<ListNode*> BinASTParser<Tok>:
 
 template <typename Tok>
 JS::Result<ListNode*> BinASTParser<Tok>::parseListOfVariableDeclarator() {
   uint32_t length;
   AutoList guard(*tokenizer_);
 
   const auto start = tokenizer_->offset();
   MOZ_TRY(tokenizer_->enterList(length, guard));
-  BINJS_TRY_DECL(
-      result, factory_.newDeclarationList(ParseNodeKind::Const /*Placeholder*/,
-                                          tokenizer_->pos(start)));
+  BINJS_TRY_DECL(result, factory_.newDeclarationList(
+                             ParseNodeKind::ConstDecl /*Placeholder*/,
+                             tokenizer_->pos(start)));
 
   for (uint32_t i = 0; i < length; ++i) {
     BINJS_MOZ_TRY_DECL(item, parseVariableDeclarator());
     result->appendWithoutOrderAssumption(item);
   }
 
   MOZ_TRY(guard.done());
   return result;
--- a/js/src/frontend/BinASTParser.h
+++ b/js/src/frontend/BinASTParser.h
@@ -1,12 +1,12 @@
 // This file was autogenerated by binjs_generate_spidermonkey,
 // please DO NOT EDIT BY HAND.
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: set ts=8 sts=2 et sw=2 tw=80:
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // To generate this file, see the documentation in
 // js/src/frontend/binsource/README.md.
 
 #ifndef frontend_BinASTParser_h
--- a/js/src/frontend/BinASTParserPerTokenizer.cpp
+++ b/js/src/frontend/BinASTParserPerTokenizer.cpp
@@ -507,17 +507,17 @@ JS::Result<Ok> BinASTParserPerTokenizer<
 
   // Steps 1-3.
   // PositionalParameterNames (3.1.9 CheckAssertedScope step 5.d) and
   // CreatePositionalParameterIndices (3.1.5 CheckPositionalParameterIndices
   // step 1) are done implicitly.
   uint32_t i = 0;
   const bool hasRest = parseContext_->functionBox()->hasRest();
   for (ParseNode* param : params->contents()) {
-    if (param->isKind(ParseNodeKind::Assign)) {
+    if (param->isKind(ParseNodeKind::AssignExpr)) {
       param = param->as<AssignmentNode>().left();
     }
 
     // At this point, function body is not part of params list.
     const bool isRest = hasRest && !param->pn_next;
     if (isRest) {
       // Rest parameter
 
@@ -557,18 +557,18 @@ JS::Result<Ok> BinASTParserPerTokenizer<
             "AssertedParameterScope.paramNames and actual parameter");
       }
 
       // Step 2.a.i.1.
       // Implicitly done.
     } else {
       // Destructuring parameter.
 
-      MOZ_ASSERT(param->isKind(ParseNodeKind::Object) ||
-                 param->isKind(ParseNodeKind::Array));
+      MOZ_ASSERT(param->isKind(ParseNodeKind::ObjectExpr) ||
+                 param->isKind(ParseNodeKind::ArrayExpr));
 
       // Step 3.
       if (i >= positionalParams.get().length()) {
         continue;
       }
 
       if (positionalParams.get()[i]) {
         return raiseError(
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -342,17 +342,17 @@ hpp:
 
             } // namespace frontend
             } // namespace js
 
             #endif // frontend_BinToken_h
 
 Arguments:
     init:
-        BINJS_TRY_DECL(result, factory_.newList(ParseNodeKind::Arguments, tokenizer_->pos(start)));
+        BINJS_TRY_DECL(result, factory_.newList(ParseNodeKind::ArgumentsExpr, tokenizer_->pos(start)));
     append:
         factory_.addList(/* list = */ result, /* kid = */ item);
 
 ArrayExpression:
     build: |
         if (elements->empty()) {
             elements->setHasNonConstInitializer();
         }
@@ -477,17 +477,17 @@ AssertedScriptGlobalScope:
 
 AssertedVarScope:
     inherits: AssertedBlockScope
     init: |
         const auto scopeKind = AssertedScopeKind::Var;
 
 AssignmentExpression:
     build: |
-        BINJS_TRY_DECL(result, factory_.newAssignment(ParseNodeKind::Assign, binding, expression));
+        BINJS_TRY_DECL(result, factory_.newAssignment(ParseNodeKind::AssignExpr, binding, expression));
 
 AssignmentTargetIdentifier:
     build: |
         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_));
@@ -499,95 +499,95 @@ BindingIdentifier:
         }
         BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
 
 BinaryExpression:
     build: |
         ParseNodeKind pnk;
         switch (operator_) {
           case BinaryOperator::Comma:
-            pnk = ParseNodeKind::Comma;
+            pnk = ParseNodeKind::CommaExpr;
             break;
           case BinaryOperator::LogicalOr:
-            pnk = ParseNodeKind::Or;
+            pnk = ParseNodeKind::OrExpr;
             break;
           case BinaryOperator::LogicalAnd:
-            pnk = ParseNodeKind::And;
+            pnk = ParseNodeKind::AndExpr;
             break;
           case BinaryOperator::BitOr:
-            pnk = ParseNodeKind::BitOr;
+            pnk = ParseNodeKind::BitOrExpr;
             break;
           case BinaryOperator::BitXor:
-            pnk = ParseNodeKind::BitXor;
+            pnk = ParseNodeKind::BitXorExpr;
             break;
           case BinaryOperator::BitAnd:
-            pnk = ParseNodeKind::BitAnd;
+            pnk = ParseNodeKind::BitAndExpr;
             break;
           case BinaryOperator::Eq:
-            pnk = ParseNodeKind::Eq;
+            pnk = ParseNodeKind::EqExpr;
             break;
           case BinaryOperator::Neq:
-            pnk = ParseNodeKind::Ne;
+            pnk = ParseNodeKind::NeExpr;
             break;
           case BinaryOperator::StrictEq:
-            pnk = ParseNodeKind::StrictEq;
+            pnk = ParseNodeKind::StrictEqExpr;
             break;
           case BinaryOperator::StrictNeq:
-            pnk = ParseNodeKind::StrictNe;
+            pnk = ParseNodeKind::StrictNeExpr;
             break;
           case BinaryOperator::LessThan:
-            pnk = ParseNodeKind::Lt;
+            pnk = ParseNodeKind::LtExpr;
             break;
           case BinaryOperator::LeqThan:
-            pnk = ParseNodeKind::Le;
+            pnk = ParseNodeKind::LeExpr;
             break;
           case BinaryOperator::GreaterThan:
-            pnk = ParseNodeKind::Gt;
+            pnk = ParseNodeKind::GtExpr;
             break;
           case BinaryOperator::GeqThan:
-            pnk = ParseNodeKind::Ge;
+            pnk = ParseNodeKind::GeExpr;
             break;
           case BinaryOperator::In:
-            pnk = ParseNodeKind::In;
+            pnk = ParseNodeKind::InExpr;
             break;
           case BinaryOperator::Instanceof:
-            pnk = ParseNodeKind::InstanceOf;
+            pnk = ParseNodeKind::InstanceOfExpr;
             break;
           case BinaryOperator::Lsh:
-            pnk = ParseNodeKind::Lsh;
+            pnk = ParseNodeKind::LshExpr;
             break;
           case BinaryOperator::Rsh:
-            pnk = ParseNodeKind::Rsh;
+            pnk = ParseNodeKind::RshExpr;
             break;
           case BinaryOperator::Ursh:
-            pnk = ParseNodeKind::Ursh;
+            pnk = ParseNodeKind::UrshExpr;
             break;
           case BinaryOperator::Plus:
-            pnk = ParseNodeKind::Add;
+            pnk = ParseNodeKind::AddExpr;
             break;
           case BinaryOperator::Minus:
-            pnk = ParseNodeKind::Sub;
+            pnk = ParseNodeKind::SubExpr;
             break;
           case BinaryOperator::Mul:
-            pnk = ParseNodeKind::Star;
+            pnk = ParseNodeKind::MulExpr;
             break;
           case BinaryOperator::Div:
-            pnk = ParseNodeKind::Div;
+            pnk = ParseNodeKind::DivExpr;
             break;
           case BinaryOperator::Mod:
-            pnk = ParseNodeKind::Mod;
+            pnk = ParseNodeKind::ModExpr;
             break;
           case BinaryOperator::Pow:
-            pnk = ParseNodeKind::Pow;
+            pnk = ParseNodeKind::PowExpr;
             break;
         }
 
         ParseNode* result;
         if (left->isKind(pnk) &&
-            pnk != ParseNodeKind::Pow /* ParseNodeKind::Pow is not left-associative */)
+            pnk != ParseNodeKind::PowExpr /* ParseNodeKind::PowExpr is not left-associative */)
         {
             // Regroup left-associative operations into lists.
             left->template as<ListNode>().appendWithoutOrderAssumption(right);
             result = left;
         } else {
             BINJS_TRY_DECL(list, factory_.newList(pnk, tokenizer_->pos(start)));
 
             list->appendWithoutOrderAssumption(left);
@@ -678,50 +678,50 @@ CatchClause:
         BINJS_TRY_DECL(result, factory_.newLexicalScope(*bindings, body));
         BINJS_TRY(factory_.setupCatchScope(result, binding, body));
 
 CompoundAssignmentExpression:
     build: |
         ParseNodeKind pnk;
         switch (operator_){
           case CompoundAssignmentOperator::PlusAssign:
-            pnk = ParseNodeKind::AddAssign;
+            pnk = ParseNodeKind::AddAssignExpr;
             break;
           case CompoundAssignmentOperator::MinusAssign:
-            pnk = ParseNodeKind::SubAssign;
+            pnk = ParseNodeKind::SubAssignExpr;
             break;
           case CompoundAssignmentOperator::MulAssign:
-            pnk = ParseNodeKind::MulAssign;
+            pnk = ParseNodeKind::MulAssignExpr;
             break;
           case CompoundAssignmentOperator::DivAssign:
-            pnk = ParseNodeKind::DivAssign;
+            pnk = ParseNodeKind::DivAssignExpr;
             break;
           case CompoundAssignmentOperator::ModAssign:
-            pnk = ParseNodeKind::ModAssign;
+            pnk = ParseNodeKind::ModAssignExpr;
             break;
           case CompoundAssignmentOperator::PowAssign:
-            pnk = ParseNodeKind::PowAssign;
+            pnk = ParseNodeKind::PowAssignExpr;
             break;
           case CompoundAssignmentOperator::LshAssign:
-            pnk = ParseNodeKind::LshAssign;
+            pnk = ParseNodeKind::LshAssignExpr;
             break;
           case CompoundAssignmentOperator::RshAssign:
-            pnk = ParseNodeKind::RshAssign;
+            pnk = ParseNodeKind::RshAssignExpr;
             break;
           case CompoundAssignmentOperator::UrshAssign:
-            pnk = ParseNodeKind::UrshAssign;
+            pnk = ParseNodeKind::UrshAssignExpr;
             break;
           case CompoundAssignmentOperator::BitOrAssign:
-            pnk = ParseNodeKind::BitOrAssign;
+            pnk = ParseNodeKind::BitOrAssignExpr;
             break;
           case CompoundAssignmentOperator::BitXorAssign:
-            pnk = ParseNodeKind::BitXorAssign;
+            pnk = ParseNodeKind::BitXorAssignExpr;
             break;
           case CompoundAssignmentOperator::BitAndAssign:
-            pnk = ParseNodeKind::BitAndAssign;
+            pnk = ParseNodeKind::BitAndAssignExpr;
             break;
         }
         BINJS_TRY_DECL(result, factory_.newAssignment(pnk, binding, expression));
 
 ComputedMemberAssignmentTarget:
     build: |
         BINJS_TRY_DECL(result, factory_.newPropertyByValue(object, expression, tokenizer_->offset()));
 
@@ -763,17 +763,17 @@ ContinueStatement:
 DataProperty:
     build: |
         if (!factory_.isUsableAsObjectPropertyName(name)) {
             return raiseError("DataProperty key kind");
         }
 
         ParseNode* result;
         if (name->template is<NameNode>() && name->template as<NameNode>().atom() == cx_->names().proto) {
-            BINJS_TRY_VAR(result, factory_.newUnary(ParseNodeKind::MutateProto, start, expression));
+            BINJS_TRY_VAR(result, factory_.newUnary(ParseNodeKind::MutateProtoExpr, start, expression));
         } else {
             BINJS_TRY_VAR(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));
         }
 
 Directive:
     build: |
         TokenPos pos = tokenizer_->pos(start);
         BINJS_TRY_DECL(result, factory_.newStringLiteral(rawValue, pos));
@@ -982,17 +982,17 @@ ForInOfBinding:
         AutoVariableDeclarationKind kindGuard(this);
     build: |
         // Restored by `kindGuard`.
         variableDeclarationKind_ = kind_;
         MOZ_TRY(checkBinding(binding->template as<NameNode>().atom()->asPropertyName()));
         ParseNodeKind pnk;
         switch (kind_) {
           case VariableDeclarationKind::Var:
-            pnk = ParseNodeKind::Var;
+            pnk = ParseNodeKind::VarStmt;
             break;
           case VariableDeclarationKind::Let:
             return raiseError("Let is not supported in this preview release");
           case VariableDeclarationKind::Const:
             return raiseError("Const is not supported in this preview release");
         }
         BINJS_TRY_DECL(result, factory_.newDeclarationList(pnk, tokenizer_->pos(start)));
         factory_.addList(result, binding);
@@ -1167,17 +1167,17 @@ ListOfSwitchCase:
         BINJS_TRY_DECL(result, factory_.newStatementList(tokenizer_->pos(start)));
     append:
         factory_.addCaseStatementToList(result, item);
 
 ListOfVariableDeclarator:
     type-ok:
         ListNode*
     init: |
-        BINJS_TRY_DECL(result, factory_.newDeclarationList(ParseNodeKind::Const /*Placeholder*/,
+        BINJS_TRY_DECL(result, factory_.newDeclarationList(ParseNodeKind::ConstStmt /*Placeholder*/,
             tokenizer_->pos(start)));
 
 LiteralBooleanExpression:
     build:
         BINJS_TRY_DECL(result, factory_.newBooleanLiteral(value, tokenizer_->pos(start)));
 
 LiteralNumericExpression:
     build:
@@ -1281,17 +1281,17 @@ Script:
 
 ShorthandProperty:
     build: |
         MOZ_ASSERT(name->isKind(ParseNodeKind::Name));
         MOZ_ASSERT(!factory_.isUsableAsObjectPropertyName(name));
         BINJS_TRY_DECL(propName, factory_.newObjectLiteralPropertyName(name->template as<NameNode>().name(), tokenizer_->pos(start)));
 
         BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(propName, name, AccessorType::None));
-        result->setKind(ParseNodeKind::Shorthand);
+        result->setKind(ParseNodeKind::ShorthandExpr);
 
 SwitchCase:
     type-ok:
         CaseClause*
     build: |
         BINJS_TRY_DECL(result, factory_.newCaseOrDefault(start, test, consequent));
 
 SwitchDefault:
@@ -1395,69 +1395,69 @@ TryFinallyStatement:
     build:
         BINJS_TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, finalizer));
 
 UnaryExpression:
     build: |
         ParseNodeKind pnk;
         switch (operator_) {
           case UnaryOperator::Minus:
-            pnk = ParseNodeKind::Neg;
+            pnk = ParseNodeKind::NegExpr;
             break;
           case UnaryOperator::Plus:
-            pnk = ParseNodeKind::Pos;
+            pnk = ParseNodeKind::PosExpr;
             break;
           case UnaryOperator::Not:
-            pnk = ParseNodeKind::Not;
+            pnk = ParseNodeKind::NotExpr;
             break;
           case UnaryOperator::BitNot:
-            pnk = ParseNodeKind::BitNot;
+            pnk = ParseNodeKind::BitNotExpr;
             break;
           case UnaryOperator::Typeof: {
             if (operand->isKind(ParseNodeKind::Name)) {
-                pnk = ParseNodeKind::TypeOfName;
+                pnk = ParseNodeKind::TypeOfNameExpr;
             } else {
                 pnk = ParseNodeKind::TypeOfExpr;
             }
             break;
           }
           case UnaryOperator::Void:
-            pnk = ParseNodeKind::Void;
+            pnk = ParseNodeKind::VoidExpr;
             break;
           case UnaryOperator::Delete: {
             switch (operand->getKind()) {
               case ParseNodeKind::Name:
                 operand->setOp(JSOP_DELNAME);
-                pnk = ParseNodeKind::DeleteName;
+                pnk = ParseNodeKind::DeleteNameExpr;
                 break;
-              case ParseNodeKind::Dot:
-                pnk = ParseNodeKind::DeleteProp;
+              case ParseNodeKind::DotExpr:
+                pnk = ParseNodeKind::DeletePropExpr;
                 break;
-              case ParseNodeKind::Elem:
-                pnk = ParseNodeKind::DeleteElem;
+              case ParseNodeKind::ElemExpr:
+                pnk = ParseNodeKind::DeleteElemExpr;
                 break;
               default:
                 pnk = ParseNodeKind::DeleteExpr;
             }
             break;
           }
         }
         BINJS_TRY_DECL(result, factory_.newUnary(pnk, start, operand));
 
 UpdateExpression:
     build: |
         ParseNodeKind pnk;
         switch (operator_) {
           case UpdateOperator::Incr:
-            pnk = isPrefix ? ParseNodeKind::PreIncrement
-                           : ParseNodeKind::PostIncrement;
+            pnk = isPrefix ? ParseNodeKind::PreIncrementExpr
+                           : ParseNodeKind::PostIncrementExpr;
             break;
           case UpdateOperator::Decr:
-            pnk = isPrefix ? ParseNodeKind::PreDecrement
-                           : ParseNodeKind::PostDecrement;
+            pnk = isPrefix ? ParseNodeKind::PreDecrementExpr
+                           : ParseNodeKind::PostDecrementExpr;
             break;
         }
         BINJS_TRY_DECL(result, factory_.newUnary(pnk, start, operand));
 
 VariableDeclaration:
     init:
         AutoVariableDeclarationKind kindGuard(this);
 
@@ -1471,17 +1471,17 @@ VariableDeclaration:
         // By specification, the list may not be empty.
         if (declarators->empty()) {
             return raiseEmpty("VariableDeclaration");
         }
 
         ParseNodeKind pnk;
         switch (kind_) {
           case VariableDeclarationKind::Var:
-            pnk = ParseNodeKind::Var;
+            pnk = ParseNodeKind::VarStmt;
             break;
           case VariableDeclarationKind::Let:
             return raiseError("Let is not supported in this preview release");
           case VariableDeclarationKind::Const:
             return raiseError("Const is not supported in this preview release");
         }
         declarators->setKind(pnk);
         auto result = declarators;
@@ -1500,17 +1500,17 @@ VariableDeclarator:
         } else {
             // `var pattern = bar`
             if (!init) {
                 // Here, `init` is required.
                 return raiseMissingField("VariableDeclarator (with non-trivial pattern)", BinField::Init);
             }
 
             MOZ_CRASH("Unimplemented: AssertedScope check for BindingPattern variable declaration");
-            BINJS_TRY_VAR(result, factory_.newAssignment(ParseNodeKind::Assign, binding, init));
+            BINJS_TRY_VAR(result, factory_.newAssignment(ParseNodeKind::AssignExpr, binding, init));
         }
 
 WhileStatement:
     init:
         ParseContext::Statement stmt(parseContext_, StatementKind::WhileLoop);
     build:
         BINJS_TRY_DECL(result, factory_.newWhileStatement(start, test, body));
 
--- a/js/src/frontend/BinToken.h
+++ b/js/src/frontend/BinToken.h
@@ -1,12 +1,12 @@
 // This file was autogenerated by binjs_generate_spidermonkey,
 // please DO NOT EDIT BY HAND.
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: set ts=8 sts=2 et sw=2 tw=80:
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // To generate this file, see the documentation in
 // js/src/frontend/binsource/README.md.
 
 #ifndef frontend_BinToken_h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -74,17 +74,17 @@ using mozilla::Unused;
 static bool ParseNodeRequiresSpecialLineNumberNotes(ParseNode* pn) {
   // The few node types listed below are exceptions to the usual
   // location-source-note-emitting code in BytecodeEmitter::emitTree().
   // Single-line `while` loops and C-style `for` loops require careful
   // handling to avoid strange stepping behavior.
   // Functions usually shouldn't have location information (bug 1431202).
 
   ParseNodeKind kind = pn->getKind();
-  return kind == ParseNodeKind::While || kind == ParseNodeKind::For ||
+  return kind == ParseNodeKind::WhileStmt || kind == ParseNodeKind::ForStmt ||
          kind == ParseNodeKind::Function;
 }
 
 BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, SharedContext* sc,
                                  HandleScript script,
                                  Handle<LazyScript*> lazyScript,
                                  uint32_t lineNum, EmitterMode emitterMode)
     : sc(sc),
@@ -929,95 +929,95 @@ bool BytecodeEmitter::checkSideEffects(P
   if (!CheckRecursionLimit(cx)) {
     return false;
   }
 
 restart:
 
   switch (pn->getKind()) {
     // Trivial cases with no side effects.
-    case ParseNodeKind::EmptyStatement:
-    case ParseNodeKind::True:
-    case ParseNodeKind::False:
-    case ParseNodeKind::Null:
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::EmptyStmt:
+    case ParseNodeKind::TrueExpr:
+    case ParseNodeKind::FalseExpr:
+    case ParseNodeKind::NullExpr:
+    case ParseNodeKind::RawUndefinedExpr:
     case ParseNodeKind::Elision:
     case ParseNodeKind::Generator:
       MOZ_ASSERT(pn->is<NullaryNode>());
       *answer = false;
       return true;
 
     case ParseNodeKind::ObjectPropertyName:
     case ParseNodeKind::PrivateName:  // no side effects, unlike
                                       // ParseNodeKind::Name
-    case ParseNodeKind::String:
-    case ParseNodeKind::TemplateString:
+    case ParseNodeKind::StringExpr:
+    case ParseNodeKind::TemplateStringExpr:
       MOZ_ASSERT(pn->is<NameNode>());
       *answer = false;
       return true;
 
-    case ParseNodeKind::RegExp:
+    case ParseNodeKind::RegExpExpr:
       MOZ_ASSERT(pn->is<RegExpLiteral>());
       *answer = false;
       return true;
 
-    case ParseNodeKind::Number:
+    case ParseNodeKind::NumberExpr:
       MOZ_ASSERT(pn->is<NumericLiteral>());
       *answer = false;
       return true;
 
 #ifdef ENABLE_BIGINT
     case ParseNodeKind::BigInt:
       MOZ_ASSERT(pn->is<BigIntLiteral>());
       *answer = false;
       return true;
 #endif
 
     // |this| can throw in derived class constructors, including nested arrow
     // functions or eval.
-    case ParseNodeKind::This:
+    case ParseNodeKind::ThisExpr:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = sc->needsThisTDZChecks();
       return true;
 
     // Trivial binary nodes with more token pos holders.
-    case ParseNodeKind::NewTarget:
-    case ParseNodeKind::ImportMeta: {
+    case ParseNodeKind::NewTargetExpr:
+    case ParseNodeKind::ImportMetaExpr: {
       MOZ_ASSERT(pn->as<BinaryNode>().left()->isKind(ParseNodeKind::PosHolder));
       MOZ_ASSERT(
           pn->as<BinaryNode>().right()->isKind(ParseNodeKind::PosHolder));
       *answer = false;
       return true;
     }
 
-    case ParseNodeKind::Break:
+    case ParseNodeKind::BreakStmt:
       MOZ_ASSERT(pn->is<BreakStatement>());
       *answer = true;
       return true;
 
-    case ParseNodeKind::Continue:
+    case ParseNodeKind::ContinueStmt:
       MOZ_ASSERT(pn->is<ContinueStatement>());
       *answer = true;
       return true;
 
-    case ParseNodeKind::Debugger:
+    case ParseNodeKind::DebuggerStmt:
       MOZ_ASSERT(pn->is<DebuggerStatement>());
       *answer = true;
       return true;
 
     // Watch out for getters!
-    case ParseNodeKind::Dot:
+    case ParseNodeKind::DotExpr:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     // Unary cases with side effects only if the child has them.
     case ParseNodeKind::TypeOfExpr:
-    case ParseNodeKind::Void:
-    case ParseNodeKind::Not:
+    case ParseNodeKind::VoidExpr:
+    case ParseNodeKind::NotExpr:
       return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
 
     // Even if the name expression is effect-free, performing ToPropertyKey on
     // it might not be effect-free:
     //
     //   RegExp.prototype.toString = () => { throw 42; };
     //   ({ [/regex/]: 0 }); // ToPropertyKey(/regex/) throws 42
     //
@@ -1027,154 +1027,154 @@ restart:
     //   Q.toString = () => { throw 17; };
     //   new Q; // new.target will be Q, ToPropertyKey(Q) throws 17
     case ParseNodeKind::ComputedName:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     // Looking up or evaluating the associated name could throw.
-    case ParseNodeKind::TypeOfName:
+    case ParseNodeKind::TypeOfNameExpr:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     // This unary case has side effects on the enclosing object, sure.  But
     // that's not the question this function answers: it's whether the
     // operation may have a side effect on something *other* than the result
     // of the overall operation in which it's embedded.  The answer to that
     // is no, because an object literal having a mutated prototype only
     // produces a value, without affecting anything else.
     case ParseNodeKind::MutateProto:
       return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
 
     // Unary cases with obvious side effects.
-    case ParseNodeKind::PreIncrement:
-    case ParseNodeKind::PostIncrement:
-    case ParseNodeKind::PreDecrement:
-    case ParseNodeKind::PostDecrement:
-    case ParseNodeKind::Throw:
+    case ParseNodeKind::PreIncrementExpr:
+    case ParseNodeKind::PostIncrementExpr:
+    case ParseNodeKind::PreDecrementExpr:
+    case ParseNodeKind::PostDecrementExpr:
+    case ParseNodeKind::ThrowStmt:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     // These might invoke valueOf/toString, even with a subexpression without
     // side effects!  Consider |+{ valueOf: null, toString: null }|.
-    case ParseNodeKind::BitNot:
-    case ParseNodeKind::Pos:
-    case ParseNodeKind::Neg:
+    case ParseNodeKind::BitNotExpr:
+    case ParseNodeKind::PosExpr:
+    case ParseNodeKind::NegExpr:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     // This invokes the (user-controllable) iterator protocol.
     case ParseNodeKind::Spread:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     case ParseNodeKind::InitialYield:
-    case ParseNodeKind::YieldStar:
-    case ParseNodeKind::Yield:
-    case ParseNodeKind::Await:
+    case ParseNodeKind::YieldStarExpr:
+    case ParseNodeKind::YieldExpr:
+    case ParseNodeKind::AwaitExpr:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     // Deletion generally has side effects, even if isolated cases have none.
-    case ParseNodeKind::DeleteName:
-    case ParseNodeKind::DeleteProp:
-    case ParseNodeKind::DeleteElem:
+    case ParseNodeKind::DeleteNameExpr:
+    case ParseNodeKind::DeletePropExpr:
+    case ParseNodeKind::DeleteElemExpr:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
     // Deletion of a non-Reference expression has side effects only through
     // evaluating the expression.
     case ParseNodeKind::DeleteExpr: {
       ParseNode* expr = pn->as<UnaryNode>().kid();
       return checkSideEffects(expr, answer);
     }
 
-    case ParseNodeKind::ExpressionStatement:
+    case ParseNodeKind::ExpressionStmt:
       return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
 
     // Binary cases with obvious side effects.
-    case ParseNodeKind::Assign:
-    case ParseNodeKind::AddAssign:
-    case ParseNodeKind::SubAssign:
-    case ParseNodeKind::BitOrAssign:
-    case ParseNodeKind::BitXorAssign:
-    case ParseNodeKind::BitAndAssign:
-    case ParseNodeKind::LshAssign:
-    case ParseNodeKind::RshAssign:
-    case ParseNodeKind::UrshAssign:
-    case ParseNodeKind::MulAssign:
-    case ParseNodeKind::DivAssign:
-    case ParseNodeKind::ModAssign:
-    case ParseNodeKind::PowAssign:
+    case ParseNodeKind::AssignExpr:
+    case ParseNodeKind::AddAssignExpr:
+    case ParseNodeKind::SubAssignExpr:
+    case ParseNodeKind::BitOrAssignExpr:
+    case ParseNodeKind::BitXorAssignExpr:
+    case ParseNodeKind::BitAndAssignExpr:
+    case ParseNodeKind::LshAssignExpr:
+    case ParseNodeKind::RshAssignExpr:
+    case ParseNodeKind::UrshAssignExpr:
+    case ParseNodeKind::MulAssignExpr:
+    case ParseNodeKind::DivAssignExpr:
+    case ParseNodeKind::ModAssignExpr:
+    case ParseNodeKind::PowAssignExpr:
       MOZ_ASSERT(pn->is<AssignmentNode>());
       *answer = true;
       return true;
 
     case ParseNodeKind::SetThis:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     case ParseNodeKind::StatementList:
     // Strict equality operations and logical operators are well-behaved and
     // perform no conversions.
-    case ParseNodeKind::Or:
-    case ParseNodeKind::And:
-    case ParseNodeKind::StrictEq:
-    case ParseNodeKind::StrictNe:
+    case ParseNodeKind::OrExpr:
+    case ParseNodeKind::AndExpr:
+    case ParseNodeKind::StrictEqExpr:
+    case ParseNodeKind::StrictNeExpr:
     // Any subexpression of a comma expression could be effectful.
-    case ParseNodeKind::Comma:
+    case ParseNodeKind::CommaExpr:
       MOZ_ASSERT(!pn->as<ListNode>().empty());
       MOZ_FALLTHROUGH;
     // Subcomponents of a literal may be effectful.
-    case ParseNodeKind::Array:
-    case ParseNodeKind::Object:
+    case ParseNodeKind::ArrayExpr:
+    case ParseNodeKind::ObjectExpr:
       for (ParseNode* item : pn->as<ListNode>().contents()) {
         if (!checkSideEffects(item, answer)) {
           return false;
         }
         if (*answer) {
           return true;
         }
       }
       return true;
 
     // Most other binary operations (parsed as lists in SpiderMonkey) may
     // perform conversions triggering side effects.  Math operations perform
     // ToNumber and may fail invoking invalid user-defined toString/valueOf:
     // |5 < { toString: null }|.  |instanceof| throws if provided a
     // non-object constructor: |null instanceof null|.  |in| throws if given
     // a non-object RHS: |5 in null|.
-    case ParseNodeKind::BitOr:
-    case ParseNodeKind::BitXor:
-    case ParseNodeKind::BitAnd:
-    case ParseNodeKind::Eq:
-    case ParseNodeKind::Ne:
-    case ParseNodeKind::Lt:
-    case ParseNodeKind::Le:
-    case ParseNodeKind::Gt:
-    case ParseNodeKind::Ge:
-    case ParseNodeKind::InstanceOf:
-    case ParseNodeKind::In:
-    case ParseNodeKind::Lsh:
-    case ParseNodeKind::Rsh:
-    case ParseNodeKind::Ursh:
-    case ParseNodeKind::Add:
-    case ParseNodeKind::Sub:
-    case ParseNodeKind::Star:
-    case ParseNodeKind::Div:
-    case ParseNodeKind::Mod:
-    case ParseNodeKind::Pow:
+    case ParseNodeKind::BitOrExpr:
+    case ParseNodeKind::BitXorExpr:
+    case ParseNodeKind::BitAndExpr:
+    case ParseNodeKind::EqExpr:
+    case ParseNodeKind::NeExpr:
+    case ParseNodeKind::LtExpr:
+    case ParseNodeKind::LeExpr:
+    case ParseNodeKind::GtExpr:
+    case ParseNodeKind::GeExpr:
+    case ParseNodeKind::InstanceOfExpr:
+    case ParseNodeKind::InExpr:
+    case ParseNodeKind::LshExpr:
+    case ParseNodeKind::RshExpr:
+    case ParseNodeKind::UrshExpr:
+    case ParseNodeKind::AddExpr:
+    case ParseNodeKind::SubExpr:
+    case ParseNodeKind::MulExpr:
+    case ParseNodeKind::DivExpr:
+    case ParseNodeKind::ModExpr:
+    case ParseNodeKind::PowExpr:
       MOZ_ASSERT(pn->as<ListNode>().count() >= 2);
       *answer = true;
       return true;
 
     case ParseNodeKind::Colon:
     case ParseNodeKind::Case: {
       BinaryNode* node = &pn->as<BinaryNode>();
       if (!checkSideEffects(node->left(), answer)) {
@@ -1182,62 +1182,62 @@ restart:
       }
       if (*answer) {
         return true;
       }
       return checkSideEffects(node->right(), answer);
     }
 
     // More getters.
-    case ParseNodeKind::Elem:
+    case ParseNodeKind::ElemExpr:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     // These affect visible names in this code, or in other code.
-    case ParseNodeKind::Import:
-    case ParseNodeKind::ExportFrom:
-    case ParseNodeKind::ExportDefault:
+    case ParseNodeKind::ImportDecl:
+    case ParseNodeKind::ExportFromStmt:
+    case ParseNodeKind::ExportDefaultStmt:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     // Likewise.
-    case ParseNodeKind::Export:
+    case ParseNodeKind::ExportStmt:
       MOZ_ASSERT(pn->is<UnaryNode>());
       *answer = true;
       return true;
 
-    case ParseNodeKind::CallImport:
+    case ParseNodeKind::CallImportExpr:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     // Every part of a loop might be effect-free, but looping infinitely *is*
     // an effect.  (Language lawyer trivia: C++ says threads can be assumed
     // to exit or have side effects, C++14 [intro.multithread]p27, so a C++
     // implementation's equivalent of the below could set |*answer = false;|
     // if all loop sub-nodes set |*answer = false|!)
-    case ParseNodeKind::DoWhile:
-    case ParseNodeKind::While:
-    case ParseNodeKind::For:
+    case ParseNodeKind::DoWhileStmt:
+    case ParseNodeKind::WhileStmt:
+    case ParseNodeKind::ForStmt:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     // Declarations affect the name set of the relevant scope.
-    case ParseNodeKind::Var:
-    case ParseNodeKind::Const:
-    case ParseNodeKind::Let:
+    case ParseNodeKind::VarStmt:
+    case ParseNodeKind::ConstDecl:
+    case ParseNodeKind::LetDecl:
       MOZ_ASSERT(pn->is<ListNode>());
       *answer = true;
       return true;
 
-    case ParseNodeKind::If:
-    case ParseNodeKind::Conditional: {
+    case ParseNodeKind::IfStmt:
+    case ParseNodeKind::ConditionalExpr: {
       TernaryNode* node = &pn->as<TernaryNode>();
       if (!checkSideEffects(node->kid1(), answer)) {
         return false;
       }
       if (*answer) {
         return true;
       }
       if (!checkSideEffects(node->kid2(), answer)) {
@@ -1248,53 +1248,53 @@ restart:
       }
       if ((pn = node->kid3())) {
         goto restart;
       }
       return true;
     }
 
     // Function calls can invoke non-local code.
-    case ParseNodeKind::New:
-    case ParseNodeKind::Call:
-    case ParseNodeKind::TaggedTemplate:
-    case ParseNodeKind::SuperCall:
+    case ParseNodeKind::NewExpr:
+    case ParseNodeKind::CallExpr:
+    case ParseNodeKind::TaggedTemplateExpr:
+    case ParseNodeKind::SuperCallExpr:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     // Function arg lists can contain arbitrary expressions. Technically
     // this only causes side-effects if one of the arguments does, but since
     // the call being made will always trigger side-effects, it isn't needed.
     case ParseNodeKind::Arguments:
       MOZ_ASSERT(pn->is<ListNode>());
       *answer = true;
       return true;
 
-    case ParseNodeKind::Pipeline:
+    case ParseNodeKind::PipelineExpr:
       MOZ_ASSERT(pn->as<ListNode>().count() >= 2);
       *answer = true;
       return true;
 
     // Classes typically introduce names.  Even if no name is introduced,
     // the heritage and/or class body (through computed property names)
     // usually have effects.
-    case ParseNodeKind::Class:
+    case ParseNodeKind::ClassDecl:
       MOZ_ASSERT(pn->is<ClassNode>());
       *answer = true;
       return true;
 
     // |with| calls |ToObject| on its expression and so throws if that value
     // is null/undefined.
-    case ParseNodeKind::With:
+    case ParseNodeKind::WithStmt:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
-    case ParseNodeKind::Return:
+    case ParseNodeKind::ReturnStmt:
       MOZ_ASSERT(pn->is<BinaryNode>());
       *answer = true;
       return true;
 
     case ParseNodeKind::Name:
       MOZ_ASSERT(pn->is<NameNode>());
       *answer = true;
       return true;
@@ -1319,17 +1319,17 @@ restart:
        */
       *answer = false;
       return true;
 
     case ParseNodeKind::Module:
       *answer = false;
       return true;
 
-    case ParseNodeKind::Try: {
+    case ParseNodeKind::TryStmt: {
       TryNode* tryNode = &pn->as<TryNode>();
       if (!checkSideEffects(tryNode->body(), answer)) {
         return false;
       }
       if (*answer) {
         return true;
       }
       if (LexicalScopeNode* catchScope = tryNode->catchScope()) {
@@ -1356,65 +1356,65 @@ restart:
         }
         if (*answer) {
           return true;
         }
       }
       return checkSideEffects(catchClause->right(), answer);
     }
 
-    case ParseNodeKind::Switch: {
+    case ParseNodeKind::SwitchStmt: {
       SwitchStatement* switchStmt = &pn->as<SwitchStatement>();
       if (!checkSideEffects(&switchStmt->discriminant(), answer)) {
         return false;
       }
       return *answer ||
              checkSideEffects(&switchStmt->lexicalForCaseList(), answer);
     }
 
-    case ParseNodeKind::Label:
+    case ParseNodeKind::LabelStmt:
       return checkSideEffects(pn->as<LabeledStatement>().statement(), answer);
 
     case ParseNodeKind::LexicalScope:
       return checkSideEffects(pn->as<LexicalScopeNode>().scopeBody(), answer);
 
     // We could methodically check every interpolated expression, but it's
     // probably not worth the trouble.  Treat template strings as effect-free
     // only if they don't contain any substitutions.
-    case ParseNodeKind::TemplateStringList: {
+    case ParseNodeKind::TemplateStringListExpr: {
       ListNode* list = &pn->as<ListNode>();
       MOZ_ASSERT(!list->empty());
       MOZ_ASSERT((list->count() % 2) == 1,
                  "template strings must alternate template and substitution "
                  "parts");
       *answer = list->count() > 1;
       return true;
     }
 
     // This should be unreachable but is left as-is for now.
     case ParseNodeKind::ParamsBody:
       *answer = true;
       return true;
 
-    case ParseNodeKind::ForIn:            // by ParseNodeKind::For
-    case ParseNodeKind::ForOf:            // by ParseNodeKind::For
-    case ParseNodeKind::ForHead:          // by ParseNodeKind::For
-    case ParseNodeKind::ClassMethod:      // by ParseNodeKind::Class
-    case ParseNodeKind::ClassField:       // by ParseNodeKind::Class
-    case ParseNodeKind::ClassNames:       // by ParseNodeKind::Class
-    case ParseNodeKind::ClassMemberList:  // by ParseNodeKind::Class
-    case ParseNodeKind::ImportSpecList:   // by ParseNodeKind::Import
-    case ParseNodeKind::ImportSpec:       // by ParseNodeKind::Import
-    case ParseNodeKind::ExportBatchSpec:  // by ParseNodeKind::Export
-    case ParseNodeKind::ExportSpecList:   // by ParseNodeKind::Export
-    case ParseNodeKind::ExportSpec:       // by ParseNodeKind::Export
-    case ParseNodeKind::CallSiteObj:      // by ParseNodeKind::TaggedTemplate
-    case ParseNodeKind::PosHolder:        // by ParseNodeKind::NewTarget
-    case ParseNodeKind::SuperBase:        // by ParseNodeKind::Elem and others
-    case ParseNodeKind::PropertyName:     // by ParseNodeKind::Dot
+    case ParseNodeKind::ForIn:                // by ParseNodeKind::For
+    case ParseNodeKind::ForOf:                // by ParseNodeKind::For
+    case ParseNodeKind::ForHead:              // by ParseNodeKind::For
+    case ParseNodeKind::ClassMethod:          // by ParseNodeKind::ClassDecl
+    case ParseNodeKind::ClassField:           // by ParseNodeKind::ClassDecl
+    case ParseNodeKind::ClassNames:           // by ParseNodeKind::ClassDecl
+    case ParseNodeKind::ClassMemberList:      // by ParseNodeKind::ClassDecl
+    case ParseNodeKind::ImportSpecList:       // by ParseNodeKind::Import
+    case ParseNodeKind::ImportSpec:           // by ParseNodeKind::Import
+    case ParseNodeKind::ExportBatchSpecStmt:  // by ParseNodeKind::Export
+    case ParseNodeKind::ExportSpecList:       // by ParseNodeKind::Export
+    case ParseNodeKind::ExportSpec:           // by ParseNodeKind::Export
+    case ParseNodeKind::CallSiteObjExpr:   // by ParseNodeKind::TaggedTemplate
+    case ParseNodeKind::PosHolder:         // by ParseNodeKind::NewTarget
+    case ParseNodeKind::SuperBase:         // by ParseNodeKind::Elem and others
+    case ParseNodeKind::PropertyNameExpr:  // by ParseNodeKind::Dot
       MOZ_CRASH("handled by parent nodes");
 
     case ParseNodeKind::Limit:  // invalid sentinel value
       MOZ_CRASH("invalid node kind");
   }
 
   MOZ_CRASH(
       "invalid, unenumerated ParseNodeKind value encountered in "
@@ -1757,21 +1757,21 @@ bool BytecodeEmitter::emitPropLHS(Proper
 
 bool BytecodeEmitter::emitPropIncDec(UnaryNode* incDec) {
   PropertyAccess* prop = &incDec->kid()->as<PropertyAccess>();
   // TODO(khyperia): Implement private field access.
   bool isSuper = prop->isSuper();
   ParseNodeKind kind = incDec->getKind();
   PropOpEmitter poe(
       this,
-      kind == ParseNodeKind::PostIncrement
+      kind == ParseNodeKind::PostIncrementExpr
           ? PropOpEmitter::Kind::PostIncrement
-          : kind == ParseNodeKind::PreIncrement
+          : kind == ParseNodeKind::PreIncrementExpr
                 ? PropOpEmitter::Kind::PreIncrement
-                : kind == ParseNodeKind::PostDecrement
+                : kind == ParseNodeKind::PostDecrementExpr
                       ? PropOpEmitter::Kind::PostDecrement
                       : PropOpEmitter::Kind::PreDecrement,
       isSuper ? PropOpEmitter::ObjKind::Super : PropOpEmitter::ObjKind::Other);
   if (!poe.prepareForObj()) {
     return false;
   }
   if (isSuper) {
     UnaryNode* base = &prop->expression().as<UnaryNode>();
@@ -1794,21 +1794,21 @@ bool BytecodeEmitter::emitPropIncDec(Una
 }
 
 bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec) {
   MOZ_ASSERT(incDec->kid()->isKind(ParseNodeKind::Name));
 
   ParseNodeKind kind = incDec->getKind();
   NameNode* name = &incDec->kid()->as<NameNode>();
   NameOpEmitter noe(this, name->atom(),
-                    kind == ParseNodeKind::PostIncrement
+                    kind == ParseNodeKind::PostIncrementExpr
                         ? NameOpEmitter::Kind::PostIncrement
-                        : kind == ParseNodeKind::PreIncrement
+                        : kind == ParseNodeKind::PreIncrementExpr
                               ? NameOpEmitter::Kind::PreIncrement
-                              : kind == ParseNodeKind::PostDecrement
+                              : kind == ParseNodeKind::PostDecrementExpr
                                     ? NameOpEmitter::Kind::PostDecrement
                                     : NameOpEmitter::Kind::PreDecrement);
   if (!noe.emitIncDec()) {
     return false;
   }
 
   return true;
 }
@@ -1867,21 +1867,21 @@ bool BytecodeEmitter::emitElemObjAndKey(
 }
 
 bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec) {
   PropertyByValue* elemExpr = &incDec->kid()->as<PropertyByValue>();
   bool isSuper = elemExpr->isSuper();
   ParseNodeKind kind = incDec->getKind();
   ElemOpEmitter eoe(
       this,
-      kind == ParseNodeKind::PostIncrement
+      kind == ParseNodeKind::PostIncrementExpr
           ? ElemOpEmitter::Kind::PostIncrement
-          : kind == ParseNodeKind::PreIncrement
+          : kind == ParseNodeKind::PreIncrementExpr
                 ? ElemOpEmitter::Kind::PreIncrement
-                : kind == ParseNodeKind::PostDecrement
+                : kind == ParseNodeKind::PostDecrementExpr
                       ? ElemOpEmitter::Kind::PostDecrement
                       : ElemOpEmitter::Kind::PreDecrement,
       isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
   if (!emitElemObjAndKey(elemExpr, isSuper, eoe)) {
     //              [stack] # if Super
     //              [stack] THIS KEY
     //              [stack] # otherwise
     //              [stack] OBJ KEY
@@ -1891,23 +1891,23 @@ bool BytecodeEmitter::emitElemIncDec(Una
     //              [stack] RESULT
     return false;
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitCallIncDec(UnaryNode* incDec) {
-  MOZ_ASSERT(incDec->isKind(ParseNodeKind::PreIncrement) ||
-             incDec->isKind(ParseNodeKind::PostIncrement) ||
-             incDec->isKind(ParseNodeKind::PreDecrement) ||
-             incDec->isKind(ParseNodeKind::PostDecrement));
+  MOZ_ASSERT(incDec->isKind(ParseNodeKind::PreIncrementExpr) ||
+             incDec->isKind(ParseNodeKind::PostIncrementExpr) ||
+             incDec->isKind(ParseNodeKind::PreDecrementExpr) ||
+             incDec->isKind(ParseNodeKind::PostDecrementExpr));
 
   ParseNode* call = incDec->kid();
-  MOZ_ASSERT(call->isKind(ParseNodeKind::Call));
+  MOZ_ASSERT(call->isKind(ParseNodeKind::CallExpr));
   if (!emitTree(call)) {
     //              [stack] CALLRESULT
     return false;
   }
   if (!emit1(JSOP_POS)) {
     //              [stack] N
     return false;
   }
@@ -2011,17 +2011,17 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::e
     for (ParseNode* item : cases->contents()) {
       CaseClause* caseClause = &item->as<CaseClause>();
       if (caseClause->isDefault()) {
         continue;
       }
 
       ParseNode* caseValue = caseClause->caseExpression();
 
-      if (caseValue->getKind() != ParseNodeKind::Number) {
+      if (caseValue->getKind() != ParseNodeKind::NumberExpr) {
         tableGen.setInvalid();
         break;
       }
 
       int32_t i;
       if (!NumberEqualsInt32(caseValue->as<NumericLiteral>().value(), &i)) {
         tableGen.setInvalid();
         break;
@@ -2080,17 +2080,17 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::e
     CaseClause* caseClause = &item->as<CaseClause>();
     if (caseClause->isDefault()) {
       if (!se.emitDefaultBody()) {
         return false;
       }
     } else {
       if (isTableSwitch) {
         ParseNode* caseValue = caseClause->caseExpression();
-        MOZ_ASSERT(caseValue->isKind(ParseNodeKind::Number));
+        MOZ_ASSERT(caseValue->isKind(ParseNodeKind::NumberExpr));
 
         NumericLiteral* literal = &caseValue->as<NumericLiteral>();
 #ifdef DEBUG
         // Use NumberEqualsInt32 here because switches compare using
         // strict equality, which will equate -0 and +0.  In contrast
         // NumberIsInt32 would return false for -0.
         int32_t v;
         MOZ_ASSERT(mozilla::NumberEqualsInt32(literal->value(), &v));
@@ -2423,36 +2423,36 @@ bool BytecodeEmitter::emitFunctionScript
 }
 
 bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
                                               size_t* emitted) {
   *emitted = 0;
 
   if (target->isKind(ParseNodeKind::Spread)) {
     target = target->as<UnaryNode>().kid();
-  } else if (target->isKind(ParseNodeKind::Assign)) {
+  } else if (target->isKind(ParseNodeKind::AssignExpr)) {
     target = target->as<AssignmentNode>().left();
   }
 
   // No need to recur into ParseNodeKind::Array and
   // ParseNodeKind::Object subpatterns here, since
   // emitSetOrInitializeDestructuring does the recursion when
   // setting or initializing value.  Getting reference doesn't recur.
   if (target->isKind(ParseNodeKind::Name) ||
-      target->isKind(ParseNodeKind::Array) ||
-      target->isKind(ParseNodeKind::Object)) {
+      target->isKind(ParseNodeKind::ArrayExpr) ||
+      target->isKind(ParseNodeKind::ObjectExpr)) {
     return true;
   }
 
 #ifdef DEBUG
   int depth = stackDepth;
 #endif
 
   switch (target->getKind()) {
-    case ParseNodeKind::Dot: {
+    case ParseNodeKind::DotExpr: {
       PropertyAccess* prop = &target->as<PropertyAccess>();
       bool isSuper = prop->isSuper();
       PropOpEmitter poe(this, PropOpEmitter::Kind::SimpleAssignment,
                         isSuper ? PropOpEmitter::ObjKind::Super
                                 : PropOpEmitter::ObjKind::Other);
       if (!poe.prepareForObj()) {
         return false;
       }
@@ -2476,17 +2476,17 @@ bool BytecodeEmitter::emitDestructuringL
         //          [stack] THIS SUPERBASE
         //          [stack] # otherwise
         //          [stack] OBJ
         return false;
       }
       break;
     }
 
-    case ParseNodeKind::Elem: {
+    case ParseNodeKind::ElemExpr: {
       PropertyByValue* elem = &target->as<PropertyByValue>();
       bool isSuper = elem->isSuper();
       ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
                         isSuper ? ElemOpEmitter::ObjKind::Super
                                 : ElemOpEmitter::ObjKind::Other);
       if (!emitElemObjAndKey(elem, isSuper, eoe)) {
         //          [stack] # if Super
         //          [stack] THIS KEY
@@ -2505,17 +2505,17 @@ bool BytecodeEmitter::emitDestructuringL
         //          [stack] THIS KEY SUPERBASE
         //          [stack] # otherwise
         //          [stack] OBJ KEY
         return false;
       }
       break;
     }
 
-    case ParseNodeKind::Call:
+    case ParseNodeKind::CallExpr:
       MOZ_ASSERT_UNREACHABLE(
           "Parser::reportIfNotValidSimpleAssignmentTarget "
           "rejects function calls as assignment "
           "targets in destructuring assignments");
       break;
 
     default:
       MOZ_CRASH("emitDestructuringLHSRef: bad lhs kind");
@@ -2529,21 +2529,21 @@ bool BytecodeEmitter::emitDestructuringL
 bool BytecodeEmitter::emitSetOrInitializeDestructuring(
     ParseNode* target, DestructuringFlavor flav) {
   // Now emit the lvalue opcode sequence. If the lvalue is a nested
   // destructuring initialiser-form, call ourselves to handle it, then pop
   // the matched value. Otherwise emit an lvalue bytecode sequence followed
   // by an assignment op.
   if (target->isKind(ParseNodeKind::Spread)) {
     target = target->as<UnaryNode>().kid();
-  } else if (target->isKind(ParseNodeKind::Assign)) {
+  } else if (target->isKind(ParseNodeKind::AssignExpr)) {
     target = target->as<AssignmentNode>().left();
   }
-  if (target->isKind(ParseNodeKind::Array) ||
-      target->isKind(ParseNodeKind::Object)) {
+  if (target->isKind(ParseNodeKind::ArrayExpr) ||
+      target->isKind(ParseNodeKind::ObjectExpr)) {
     if (!emitDestructuringOps(&target->as<ListNode>(), flav)) {
       return false;
     }
     // Per its post-condition, emitDestructuringOps has left the
     // to-be-destructured value on top of the stack.
     if (!emit1(JSOP_POP)) {
       return false;
     }
@@ -2606,17 +2606,17 @@ bool BytecodeEmitter::emitSetOrInitializ
         if (!noe.emitAssignment()) {
           //        [stack] V
           return false;
         }
 
         break;
       }
 
-      case ParseNodeKind::Dot: {
+      case ParseNodeKind::DotExpr: {
         // The reference is already pushed by emitDestructuringLHSRef.
         //          [stack] # if Super
         //          [stack] THIS SUPERBASE VAL
         //          [stack] # otherwise
         //          [stack] OBJ VAL
         PropertyAccess* prop = &target->as<PropertyAccess>();
         // TODO(khyperia): Implement private field access.
         bool isSuper = prop->isSuper();
@@ -2628,17 +2628,17 @@ bool BytecodeEmitter::emitSetOrInitializ
         }
         //          [stack] # VAL
         if (!poe.emitAssignment(prop->key().atom())) {
           return false;
         }
         break;
       }
 
-      case ParseNodeKind::Elem: {
+      case ParseNodeKind::ElemExpr: {
         // The reference is already pushed by emitDestructuringLHSRef.
         //          [stack] # if Super
         //          [stack] THIS KEY SUPERBASE VAL
         //          [stack] # otherwise
         //          [stack] OBJ KEY VAL
         PropertyByValue* elem = &target->as<PropertyByValue>();
         bool isSuper = elem->isSuper();
         ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
@@ -2649,17 +2649,17 @@ bool BytecodeEmitter::emitSetOrInitializ
         }
         if (!eoe.emitAssignment()) {
           //        [stack] VAL
           return false;
         }
         break;
       }
 
-      case ParseNodeKind::Call:
+      case ParseNodeKind::CallExpr:
         MOZ_ASSERT_UNREACHABLE(
             "Parser::reportIfNotValidSimpleAssignmentTarget "
             "rejects function calls as assignment "
             "targets in destructuring assignments");
         break;
 
       default:
         MOZ_CRASH("emitSetOrInitializeDestructuring: bad lhs kind");
@@ -3037,17 +3037,17 @@ bool BytecodeEmitter::setOrEmitSetFunNam
 
       return true;
     }
 
     fun->setInferredName(name);
     return true;
   }
 
-  MOZ_ASSERT(maybeFun->isKind(ParseNodeKind::Class));
+  MOZ_ASSERT(maybeFun->isKind(ParseNodeKind::ClassDecl));
 
   uint32_t nameIndex;
   if (!makeAtomIndex(name, &nameIndex)) {
     return false;
   }
   if (!emitIndexOp(JSOP_STRING, nameIndex)) {
     //              [stack] FUN NAME
     return false;
@@ -3074,17 +3074,17 @@ bool BytecodeEmitter::emitInitializer(Pa
     }
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
                                                 DestructuringFlavor flav) {
-  MOZ_ASSERT(pattern->isKind(ParseNodeKind::Array));
+  MOZ_ASSERT(pattern->isKind(ParseNodeKind::ArrayExpr));
   MOZ_ASSERT(this->stackDepth != 0);
 
   // Here's pseudo code for |let [a, b, , c=y, ...d] = x;|
   //
   // Lines that are annotated "covered by trynote" mean that upon throwing
   // an exception, IteratorClose is called on iter only if done is false.
   //
   //   let x, y;
@@ -3209,17 +3209,17 @@ bool BytecodeEmitter::emitDestructuringO
   for (ParseNode* member : pattern->contents()) {
     bool isFirst = member == pattern->head();
     DebugOnly<bool> hasNext = !!member->pn_next;
 
     size_t emitted = 0;
 
     // Spec requires LHS reference to be evaluated first.
     ParseNode* lhsPattern = member;
-    if (lhsPattern->isKind(ParseNodeKind::Assign)) {
+    if (lhsPattern->isKind(ParseNodeKind::AssignExpr)) {
       lhsPattern = lhsPattern->as<AssignmentNode>().left();
     }
 
     bool isElision = lhsPattern->isKind(ParseNodeKind::Elision);
     if (!isElision) {
       auto emitLHSRef = [lhsPattern, &emitted](BytecodeEmitter* bce) {
         return bce->emitDestructuringLHSRef(lhsPattern, &emitted);
         //          [stack] ... OBJ NEXT ITER DONE LREF*
@@ -3325,17 +3325,17 @@ bool BytecodeEmitter::emitDestructuringO
         return false;
       }
 
       MOZ_ASSERT(!hasNext);
       break;
     }
 
     ParseNode* pndefault = nullptr;
-    if (member->isKind(ParseNodeKind::Assign)) {
+    if (member->isKind(ParseNodeKind::AssignExpr)) {
       pndefault = member->as<AssignmentNode>().right();
     }
 
     MOZ_ASSERT(!member->isKind(ParseNodeKind::Spread));
 
     InternalIfEmitter ifAlreadyDone(this);
     if (!isFirst) {
       //            [stack] ... OBJ NEXT ITER LREF* DONE
@@ -3509,17 +3509,17 @@ bool BytecodeEmitter::emitDestructuringO
 
 bool BytecodeEmitter::emitComputedPropertyName(UnaryNode* computedPropName) {
   MOZ_ASSERT(computedPropName->isKind(ParseNodeKind::ComputedName));
   return emitTree(computedPropName->kid()) && emit1(JSOP_TOID);
 }
 
 bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
                                                  DestructuringFlavor flav) {
-  MOZ_ASSERT(pattern->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(pattern->isKind(ParseNodeKind::ObjectExpr));
 
   //                [stack] ... RHS
   MOZ_ASSERT(this->stackDepth > 0);
 
   if (!emit1(JSOP_CHECKOBJCOERCIBLE)) {
     //              [stack] ... RHS
     return false;
   }
@@ -3546,18 +3546,18 @@ bool BytecodeEmitter::emitDestructuringO
     } else {
       MOZ_ASSERT(member->isKind(ParseNodeKind::Colon) ||
                  member->isKind(ParseNodeKind::Shorthand));
       subpattern = member->as<BinaryNode>().right();
     }
 
     ParseNode* lhs = subpattern;
     MOZ_ASSERT_IF(member->isKind(ParseNodeKind::Spread),
-                  !lhs->isKind(ParseNodeKind::Assign));
-    if (lhs->isKind(ParseNodeKind::Assign)) {
+                  !lhs->isKind(ParseNodeKind::AssignExpr));
+    if (lhs->isKind(ParseNodeKind::AssignExpr)) {
       lhs = lhs->as<AssignmentNode>().left();
     }
 
     size_t emitted;
     if (!emitDestructuringLHSRef(lhs, &emitted)) {
       //            [stack] ... SET? RHS LREF*
       return false;
     }
@@ -3621,23 +3621,23 @@ bool BytecodeEmitter::emitDestructuringO
         return false;
       }
       needsGetElem = false;
     } else {
       MOZ_ASSERT(member->isKind(ParseNodeKind::Colon) ||
                  member->isKind(ParseNodeKind::Shorthand));
 
       ParseNode* key = member->as<BinaryNode>().left();
-      if (key->isKind(ParseNodeKind::Number)) {
+      if (key->isKind(ParseNodeKind::NumberExpr)) {
         if (!emitNumberOp(key->as<NumericLiteral>().value())) {
           //        [stack]... SET? RHS LREF* RHS KEY
           return false;
         }
       } else if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
-                 key->isKind(ParseNodeKind::String)) {
+                 key->isKind(ParseNodeKind::StringExpr)) {
         if (!emitAtomOp(key->as<NameNode>().atom(), JSOP_GETPROP)) {
           //        [stack] ... SET? RHS LREF* PROP
           return false;
         }
         needsGetElem = false;
       } else {
         if (!emitComputedPropertyName(&key->as<UnaryNode>())) {
           //        [stack] ... SET? RHS LREF* RHS KEY
@@ -3671,17 +3671,17 @@ bool BytecodeEmitter::emitDestructuringO
     }
 
     // Get the property value if not done already.
     if (needsGetElem && !emitElemOpBase(JSOP_GETELEM)) {
       //            [stack] ... SET? RHS LREF* PROP
       return false;
     }
 
-    if (subpattern->isKind(ParseNodeKind::Assign)) {
+    if (subpattern->isKind(ParseNodeKind::AssignExpr)) {
       if (!emitDefault(subpattern->as<AssignmentNode>().right(), lhs)) {
         //          [stack] ... SET? RHS LREF* VALUE
         return false;
       }
     }
 
     // Destructure PROP per this member's lhs.
     if (!emitSetOrInitializeDestructuring(subpattern, flav)) {
@@ -3689,17 +3689,17 @@ bool BytecodeEmitter::emitDestructuringO
       return false;
     }
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) {
-  MOZ_ASSERT(pattern->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(pattern->isKind(ParseNodeKind::ObjectExpr));
   MOZ_ASSERT(pattern->last()->isKind(ParseNodeKind::Spread));
 
   ptrdiff_t offset = this->offset();
   if (!emitNewInit()) {
     return false;
   }
 
   // Try to construct the shape of the object as we go, so we can emit a
@@ -3723,23 +3723,23 @@ bool BytecodeEmitter::emitDestructuringO
       break;
     }
 
     bool isIndex = false;
     if (member->isKind(ParseNodeKind::MutateProto)) {
       pnatom.set(cx->names().proto);
     } else {
       ParseNode* key = member->as<BinaryNode>().left();
-      if (key->isKind(ParseNodeKind::Number)) {
+      if (key->isKind(ParseNodeKind::NumberExpr)) {
         if (!emitNumberOp(key->as<NumericLiteral>().value())) {
           return false;
         }
         isIndex = true;
       } else if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
-                 key->isKind(ParseNodeKind::String)) {
+                 key->isKind(ParseNodeKind::StringExpr)) {
         pnatom.set(key->as<NameNode>().atom());
       } else {
         // Otherwise this is a computed property name which needs to
         // be added dynamically.
         obj.set(nullptr);
         continue;
       }
     }
@@ -3786,28 +3786,28 @@ bool BytecodeEmitter::emitDestructuringO
     }
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDestructuringOps(ListNode* pattern,
                                            DestructuringFlavor flav) {
-  if (pattern->isKind(ParseNodeKind::Array)) {
+  if (pattern->isKind(ParseNodeKind::ArrayExpr)) {
     return emitDestructuringOpsArray(pattern, flav);
   }
   return emitDestructuringOpsObject(pattern, flav);
 }
 
 bool BytecodeEmitter::emitTemplateString(ListNode* templateString) {
   bool pushedString = false;
 
   for (ParseNode* item : templateString->contents()) {
-    bool isString = (item->getKind() == ParseNodeKind::String ||
-                     item->getKind() == ParseNodeKind::TemplateString);
+    bool isString = (item->getKind() == ParseNodeKind::StringExpr ||
+                     item->getKind() == ParseNodeKind::TemplateStringExpr);
 
     // Skip empty strings. These are very common: a template string like
     // `${a}${b}` has three empty strings and without this optimization
     // we'd emit four JSOP_ADD operations instead of just one.
     if (isString && item->as<NameNode>().atom()->empty()) {
       continue;
     }
 
@@ -3854,23 +3854,23 @@ bool BytecodeEmitter::emitTemplateString
 bool BytecodeEmitter::emitDeclarationList(ListNode* declList) {
   MOZ_ASSERT(declList->isOp(JSOP_NOP));
 
   for (ParseNode* decl : declList->contents()) {
     if (!updateSourceCoordNotes(decl->pn_pos.begin)) {
       return false;
     }
 
-    if (decl->isKind(ParseNodeKind::Assign)) {
+    if (decl->isKind(ParseNodeKind::AssignExpr)) {
       MOZ_ASSERT(decl->isOp(JSOP_NOP));
 
       AssignmentNode* assignNode = &decl->as<AssignmentNode>();
       ListNode* pattern = &assignNode->left()->as<ListNode>();
-      MOZ_ASSERT(pattern->isKind(ParseNodeKind::Array) ||
-                 pattern->isKind(ParseNodeKind::Object));
+      MOZ_ASSERT(pattern->isKind(ParseNodeKind::ArrayExpr) ||
+                 pattern->isKind(ParseNodeKind::ObjectExpr));
 
       if (!emitTree(assignNode->right())) {
         return false;
       }
 
       if (!emitDestructuringOps(pattern, DestructuringDeclaration)) {
         return false;
       }
@@ -3888,29 +3888,29 @@ bool BytecodeEmitter::emitDeclarationLis
   return true;
 }
 
 bool BytecodeEmitter::emitSingleDeclaration(ListNode* declList, NameNode* decl,
                                             ParseNode* initializer) {
   MOZ_ASSERT(decl->isKind(ParseNodeKind::Name));
 
   // Nothing to do for initializer-less 'var' declarations, as there's no TDZ.
-  if (!initializer && declList->isKind(ParseNodeKind::Var)) {
+  if (!initializer && declList->isKind(ParseNodeKind::VarStmt)) {
     return true;
   }
 
   NameOpEmitter noe(this, decl->name(), NameOpEmitter::Kind::Initialize);
   if (!noe.prepareForRhs()) {
     //              [stack] ENV?
     return false;
   }
   if (!initializer) {
     // Lexical declarations are initialized to undefined without an
     // initializer.
-    MOZ_ASSERT(declList->isKind(ParseNodeKind::Let),
+    MOZ_ASSERT(declList->isKind(ParseNodeKind::LetDecl),
                "var declarations without initializers handled above, "
                "and const declarations must have initializers");
     if (!emit1(JSOP_UNDEFINED)) {
       //            [stack] ENV? UNDEF
       return false;
     }
   } else {
     MOZ_ASSERT(initializer);
@@ -3946,41 +3946,41 @@ static bool EmitAssignmentRhs(BytecodeEm
     return false;
   }
 
   return true;
 }
 
 static inline JSOp CompoundAssignmentParseNodeKindToJSOp(ParseNodeKind pnk) {
   switch (pnk) {
-    case ParseNodeKind::Assign:
+    case ParseNodeKind::AssignExpr:
       return JSOP_NOP;
-    case ParseNodeKind::AddAssign:
+    case ParseNodeKind::AddAssignExpr:
       return JSOP_ADD;
-    case ParseNodeKind::SubAssign:
+    case ParseNodeKind::SubAssignExpr:
       return JSOP_SUB;
-    case ParseNodeKind::BitOrAssign:
+    case ParseNodeKind::BitOrAssignExpr:
       return JSOP_BITOR;
-    case ParseNodeKind::BitXorAssign:
+    case ParseNodeKind::BitXorAssignExpr:
       return JSOP_BITXOR;
-    case ParseNodeKind::BitAndAssign:
+    case ParseNodeKind::BitAndAssignExpr:
       return JSOP_BITAND;
-    case ParseNodeKind::LshAssign:
+    case ParseNodeKind::LshAssignExpr:
       return JSOP_LSH;
-    case ParseNodeKind::RshAssign:
+    case ParseNodeKind::RshAssignExpr:
       return JSOP_RSH;
-    case ParseNodeKind::UrshAssign:
+    case ParseNodeKind::UrshAssignExpr:
       return JSOP_URSH;
-    case ParseNodeKind::MulAssign:
+    case ParseNodeKind::MulAssignExpr:
       return JSOP_MUL;
-    case ParseNodeKind::DivAssign:
+    case ParseNodeKind::DivAssignExpr:
       return JSOP_DIV;
-    case ParseNodeKind::ModAssign:
+    case ParseNodeKind::ModAssignExpr:
       return JSOP_MOD;
-    case ParseNodeKind::PowAssign:
+    case ParseNodeKind::PowAssignExpr:
       return JSOP_POW;
     default:
       MOZ_CRASH("unexpected compound assignment op");
   }
 }
 
 bool BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp compoundOp,
                                      ParseNode* rhs) {
@@ -4032,17 +4032,17 @@ bool BytecodeEmitter::emitAssignment(Par
 
   Maybe<PropOpEmitter> poe;
   Maybe<ElemOpEmitter> eoe;
 
   // Deal with non-name assignments.
   uint8_t offset = 1;
 
   switch (lhs->getKind()) {
-    case ParseNodeKind::Dot: {
+    case ParseNodeKind::DotExpr: {
       PropertyAccess* prop = &lhs->as<PropertyAccess>();
       bool isSuper = prop->isSuper();
       poe.emplace(this,
                   isCompound ? PropOpEmitter::Kind::CompoundAssignment
                              : PropOpEmitter::Kind::SimpleAssignment,
                   isSuper ? PropOpEmitter::ObjKind::Super
                           : PropOpEmitter::ObjKind::Other);
       if (!poe->prepareForObj()) {
@@ -4060,17 +4060,17 @@ bool BytecodeEmitter::emitAssignment(Par
         if (!emitTree(&prop->expression())) {
           //        [stack] OBJ
           return false;
         }
         offset += 1;
       }
       break;
     }
-    case ParseNodeKind::Elem: {
+    case ParseNodeKind::ElemExpr: {
       PropertyByValue* elem = &lhs->as<PropertyByValue>();
       bool isSuper = elem->isSuper();
       eoe.emplace(this,
                   isCompound ? ElemOpEmitter::Kind::CompoundAssignment
                              : ElemOpEmitter::Kind::SimpleAssignment,
                   isSuper ? ElemOpEmitter::ObjKind::Super
                           : ElemOpEmitter::ObjKind::Other);
       if (!emitElemObjAndKey(elem, isSuper, *eoe)) {
@@ -4083,20 +4083,20 @@ bool BytecodeEmitter::emitAssignment(Par
       if (isSuper) {
         // SUPERBASE is pushed onto KEY in eoe->emitGet below.
         offset += 3;
       } else {
         offset += 2;
       }
       break;
     }
-    case ParseNodeKind::Array:
-    case ParseNodeKind::Object:
+    case ParseNodeKind::ArrayExpr:
+    case ParseNodeKind::ObjectExpr:
       break;
-    case ParseNodeKind::Call:
+    case ParseNodeKind::CallExpr:
       if (!emitTree(lhs)) {
         return false;
       }
 
       // Assignment to function calls is forbidden, but we have to make the
       // call first.  Now we can throw.
       if (!emitUint16Operand(JSOP_THROWMSG, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
         return false;
@@ -4109,63 +4109,63 @@ bool BytecodeEmitter::emitAssignment(Par
       break;
     default:
       MOZ_ASSERT(0);
   }
 
   if (isCompound) {
     MOZ_ASSERT(rhs);
     switch (lhs->getKind()) {
-      case ParseNodeKind::Dot: {
+      case ParseNodeKind::DotExpr: {
         PropertyAccess* prop = &lhs->as<PropertyAccess>();
         // TODO(khyperia): Implement private field access.
         if (!poe->emitGet(prop->key().atom())) {
           //        [stack] # if Super
           //        [stack] THIS SUPERBASE PROP
           //        [stack] # otherwise
           //        [stack] OBJ PROP
           return false;
         }
         break;
       }
-      case ParseNodeKind::Elem: {
+      case ParseNodeKind::ElemExpr: {
         if (!eoe->emitGet()) {
           //        [stack] KEY THIS OBJ ELEM
           return false;
         }
         break;
       }
-      case ParseNodeKind::Call:
+      case ParseNodeKind::CallExpr:
         // We just emitted a JSOP_THROWMSG and popped the call's return
         // value.  Push a random value to make sure the stack depth is
         // correct.
         if (!emit1(JSOP_NULL)) {
           //        [stack] NULL
           return false;
         }
         break;
       default:;
     }
   }
 
   switch (lhs->getKind()) {
-    case ParseNodeKind::Dot:
+    case ParseNodeKind::DotExpr:
       if (!poe->prepareForRhs()) {
         //          [stack] # if Simple Assignment with Super
         //          [stack] THIS SUPERBASE
         //          [stack] # if Simple Assignment with other
         //          [stack] OBJ
         //          [stack] # if Compound Assignment with Super
         //          [stack] THIS SUPERBASE PROP
         //          [stack] # if Compound Assignment with other
         //          [stack] OBJ PROP
         return false;
       }
       break;
-    case ParseNodeKind::Elem:
+    case ParseNodeKind::ElemExpr:
       if (!eoe->prepareForRhs()) {
         //          [stack] # if Simple Assignment with Super
         //          [stack] THIS KEY SUPERBASE
         //          [stack] # if Simple Assignment with other
         //          [stack] OBJ KEY
         //          [stack] # if Compound Assignment with Super
         //          [stack] THIS KEY SUPERBASE ELEM
         //          [stack] # if Compound Assignment with other
@@ -4190,41 +4190,41 @@ bool BytecodeEmitter::emitAssignment(Par
     if (!emit1(compoundOp)) {
       //            [stack] ... VAL
       return false;
     }
   }
 
   /* Finally, emit the specialized assignment bytecode. */
   switch (lhs->getKind()) {
-    case ParseNodeKind::Dot: {
+    case ParseNodeKind::DotExpr: {
       PropertyAccess* prop = &lhs->as<PropertyAccess>();
       // TODO(khyperia): Implement private field access.
       if (!poe->emitAssignment(prop->key().atom())) {
         //          [stack] VAL
         return false;
       }
 
       poe.reset();
       break;
     }
-    case ParseNodeKind::Call:
+    case ParseNodeKind::CallExpr:
       // We threw above, so nothing to do here.
       break;
-    case ParseNodeKind::Elem: {
+    case ParseNodeKind::ElemExpr: {
       if (!eoe->emitAssignment()) {
         //          [stack] VAL
         return false;
       }
 
       eoe.reset();
       break;
     }
-    case ParseNodeKind::Array:
-    case ParseNodeKind::Object:
+    case ParseNodeKind::ArrayExpr:
+    case ParseNodeKind::ObjectExpr:
       if (!emitDestructuringOps(&lhs->as<ListNode>(),
                                 DestructuringAssignment)) {
         return false;
       }
       break;
     default:
       MOZ_ASSERT(0);
   }
@@ -4233,57 +4233,57 @@ bool BytecodeEmitter::emitAssignment(Par
 
 bool ParseNode::getConstantValue(JSContext* cx,
                                  AllowConstantObjects allowObjects,
                                  MutableHandleValue vp, Value* compare,
                                  size_t ncompare, NewObjectKind newKind) {
   MOZ_ASSERT(newKind == TenuredObject || newKind == SingletonObject);
 
   switch (getKind()) {
-    case ParseNodeKind::Number:
+    case ParseNodeKind::NumberExpr:
       vp.setNumber(as<NumericLiteral>().value());
       return true;
 #ifdef ENABLE_BIGINT
     case ParseNodeKind::BigInt:
       vp.setBigInt(as<BigIntLiteral>().box()->value());
       return true;
 #endif
-    case ParseNodeKind::TemplateString:
-    case ParseNodeKind::String:
+    case ParseNodeKind::TemplateStringExpr:
+    case ParseNodeKind::StringExpr:
       vp.setString(as<NameNode>().atom());
       return true;
-    case ParseNodeKind::True:
+    case ParseNodeKind::TrueExpr:
       vp.setBoolean(true);
       return true;
-    case ParseNodeKind::False:
+    case ParseNodeKind::FalseExpr:
       vp.setBoolean(false);
       return true;
-    case ParseNodeKind::Null:
+    case ParseNodeKind::NullExpr:
       vp.setNull();
       return true;
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::RawUndefinedExpr:
       vp.setUndefined();
       return true;
-    case ParseNodeKind::CallSiteObj:
-    case ParseNodeKind::Array: {
+    case ParseNodeKind::CallSiteObjExpr:
+    case ParseNodeKind::ArrayExpr: {
       unsigned count;
       ParseNode* pn;
 
       if (allowObjects == DontAllowObjects) {
         vp.setMagic(JS_GENERIC_MAGIC);
         return true;
       }
 
       ObjectGroup::NewArrayKind arrayKind = ObjectGroup::NewArrayKind::Normal;
       if (allowObjects == ForCopyOnWriteArray) {
         arrayKind = ObjectGroup::NewArrayKind::CopyOnWrite;
         allowObjects = DontAllowObjects;
       }
 
-      if (getKind() == ParseNodeKind::CallSiteObj) {
+      if (getKind() == ParseNodeKind::CallSiteObjExpr) {
         count = as<CallSiteNode>().count() - 1;
         pn = as<CallSiteNode>().head()->pn_next;
       } else {
         MOZ_ASSERT(!as<ListNode>().hasNonConstInitializer());
         count = as<ListNode>().count();
         pn = as<ListNode>().head();
       }
 
@@ -4312,17 +4312,17 @@ bool ParseNode::getConstantValue(JSConte
 
       if (!CombineArrayElementTypes(cx, obj, compare, ncompare)) {
         return false;
       }
 
       vp.setObject(*obj);
       return true;
     }
-    case ParseNodeKind::Object: {
+    case ParseNodeKind::ObjectExpr: {
       MOZ_ASSERT(!as<ListNode>().hasNonConstInitializer());
 
       if (allowObjects == DontAllowObjects) {
         vp.setMagic(JS_GENERIC_MAGIC);
         return true;
       }
       MOZ_ASSERT(allowObjects == AllowObjects);
 
@@ -4336,21 +4336,21 @@ bool ParseNode::getConstantValue(JSConte
           return false;
         }
         if (value.isMagic(JS_GENERIC_MAGIC)) {
           vp.setMagic(JS_GENERIC_MAGIC);
           return true;
         }
 
         ParseNode* key = prop->left();
-        if (key->isKind(ParseNodeKind::Number)) {
+        if (key->isKind(ParseNodeKind::NumberExpr)) {
           idvalue = NumberValue(key->as<NumericLiteral>().value());
         } else {
           MOZ_ASSERT(key->isKind(ParseNodeKind::ObjectPropertyName) ||
-                     key->isKind(ParseNodeKind::String));
+                     key->isKind(ParseNodeKind::StringExpr));
           MOZ_ASSERT(key->as<NameNode>().atom() != cx->names().proto);
           idvalue = StringValue(key->as<NameNode>().atom());
         }
 
         RootedId id(cx);
         if (!ValueToId<CanGC>(cx, idvalue, &id)) {
           return false;
         }
@@ -4375,17 +4375,17 @@ bool ParseNode::getConstantValue(JSConte
     }
     default:
       MOZ_CRASH("Unexpected node");
   }
   return false;
 }
 
 bool BytecodeEmitter::emitSingletonInitialiser(ListNode* objOrArray) {
-  NewObjectKind newKind = (objOrArray->getKind() == ParseNodeKind::Object)
+  NewObjectKind newKind = (objOrArray->getKind() == ParseNodeKind::ObjectExpr)
                               ? SingletonObject
                               : TenuredObject;
 
   RootedValue value(cx);
   if (!objOrArray->getConstantValue(cx, ParseNode::AllowObjects, &value,
                                     nullptr, 0, newKind)) {
     return false;
   }
@@ -4453,18 +4453,18 @@ bool BytecodeEmitter::emitCatch(BinaryNo
   ParseNode* param = catchClause->left();
   if (!param) {
     // Catch parameter was omitted; just discard the exception.
     if (!emit1(JSOP_POP)) {
       return false;
     }
   } else {
     switch (param->getKind()) {
-      case ParseNodeKind::Array:
-      case ParseNodeKind::Object:
+      case ParseNodeKind::ArrayExpr:
+      case ParseNodeKind::ObjectExpr:
         if (!emitDestructuringOps(&param->as<ListNode>(),
                                   DestructuringDeclaration)) {
           return false;
         }
         if (!emit1(JSOP_POP)) {
           return false;
         }
         break;
@@ -4603,17 +4603,17 @@ if_again:
   }
 
   /* Emit code for the then part. */
   if (!emitTree(ifNode->kid2())) {
     return false;
   }
 
   if (elseNode) {
-    if (elseNode->isKind(ParseNodeKind::If)) {
+    if (elseNode->isKind(ParseNodeKind::IfStmt)) {
       ifNode = &elseNode->as<TernaryNode>();
 
       if (!ifThenElse.emitElseIf(Some(ifNode->pn_pos.begin))) {
         return false;
       }
 
       goto if_again;
     }
@@ -4637,17 +4637,17 @@ if_again:
 
 bool BytecodeEmitter::emitHoistedFunctionsInList(ListNode* stmtList) {
   MOZ_ASSERT(stmtList->hasTopLevelFunctionDeclarations());
 
   for (ParseNode* stmt : stmtList->contents()) {
     ParseNode* maybeFun = stmt;
 
     if (!sc->strict()) {
-      while (maybeFun->isKind(ParseNodeKind::Label)) {
+      while (maybeFun->isKind(ParseNodeKind::LabelStmt)) {
         maybeFun = maybeFun->as<LabeledStatement>().statement();
       }
     }
 
     if (maybeFun->isKind(ParseNodeKind::Function) &&
         maybeFun->as<CodeNode>().functionIsHoisted()) {
       if (!emitTree(maybeFun)) {
         return false;
@@ -4706,17 +4706,17 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::e
   } else {
     kind = ScopeKind::Lexical;
   }
 
   if (!emitterScope.enterLexical(this, kind, lexicalScope->scopeBindings())) {
     return false;
   }
 
-  if (body->isKind(ParseNodeKind::For)) {
+  if (body->isKind(ParseNodeKind::ForStmt)) {
     // for loops need to emit {FRESHEN,RECREATE}LEXICALENV if there are
     // lexical declarations in the head. Signal this by passing a
     // non-nullptr lexical scope.
     if (!emitFor(&body->as<ForNode>(), &emitterScope)) {
       return false;
     }
   } else {
     if (!emitLexicalScopeBody(body, SUPPRESS_LINENOTE)) {
@@ -5143,28 +5143,28 @@ bool BytecodeEmitter::emitInitializeForI
       return false;
     }
 
     // The caller handles removing the iteration value from the stack.
     return true;
   }
 
   MOZ_ASSERT(
-      !target->isKind(ParseNodeKind::Assign),
+      !target->isKind(ParseNodeKind::AssignExpr),
       "for-in/of loop destructuring declarations can't have initializers");
 
-  MOZ_ASSERT(target->isKind(ParseNodeKind::Array) ||
-             target->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(target->isKind(ParseNodeKind::ArrayExpr) ||
+             target->isKind(ParseNodeKind::ObjectExpr));
   return emitDestructuringOps(&target->as<ListNode>(),
                               DestructuringDeclaration);
 }
 
 bool BytecodeEmitter::emitForOf(ForNode* forOfLoop,
                                 const EmitterScope* headLexicalEmitterScope) {
-  MOZ_ASSERT(forOfLoop->isKind(ParseNodeKind::For));
+  MOZ_ASSERT(forOfLoop->isKind(ParseNodeKind::ForStmt));
 
   TernaryNode* forOfHead = forOfLoop->head();
   MOZ_ASSERT(forOfHead->isKind(ParseNodeKind::ForOf));
 
   unsigned iflags = forOfLoop->iflags();
   IteratorKind iterKind =
       (iflags & JSITER_FORAWAITOF) ? IteratorKind::Async : IteratorKind::Sync;
   MOZ_ASSERT_IF(iterKind == IteratorKind::Async, sc->asFunctionBox());
@@ -5172,17 +5172,17 @@ bool BytecodeEmitter::emitForOf(ForNode*
                 sc->asFunctionBox()->isAsync());
 
   ParseNode* forHeadExpr = forOfHead->kid3();
 
   // Certain builtins (e.g. Array.from) are implemented in self-hosting
   // as for-of loops.
   bool allowSelfHostedIter = false;
   if (emitterMode == BytecodeEmitter::SelfHosting &&
-      forHeadExpr->isKind(ParseNodeKind::Call) &&
+      forHeadExpr->isKind(ParseNodeKind::CallExpr) &&
       forHeadExpr->as<BinaryNode>().left()->isName(
           cx->names().allowContentIter)) {
     allowSelfHostedIter = true;
   }
 
   ForOfEmitter forOf(this, headLexicalEmitterScope, allowSelfHostedIter,
                      iterKind);
 
@@ -5193,18 +5193,18 @@ bool BytecodeEmitter::emitForOf(ForNode*
 
   if (!emitTree(forHeadExpr)) {
     //              [stack] ITERABLE
     return false;
   }
 
   if (headLexicalEmitterScope) {
     DebugOnly<ParseNode*> forOfTarget = forOfHead->kid1();
-    MOZ_ASSERT(forOfTarget->isKind(ParseNodeKind::Let) ||
-               forOfTarget->isKind(ParseNodeKind::Const));
+    MOZ_ASSERT(forOfTarget->isKind(ParseNodeKind::LetDecl) ||
+               forOfTarget->isKind(ParseNodeKind::ConstDecl));
   }
 
   if (!forOf.emitInitialize(Some(forOfHead->pn_pos.begin))) {
     //              [stack] NEXT ITER VALUE
     return false;
   }
 
   if (!emitInitializeForInOrOfTarget(forOfHead)) {
@@ -5245,17 +5245,17 @@ bool BytecodeEmitter::emitForIn(ForNode*
   // |for (var i = initializer in expr) { ... }|
   ParseNode* forInTarget = forInHead->kid1();
   if (parser->astGenerator().isDeclarationList(forInTarget)) {
     ParseNode* decl = parser->astGenerator().singleBindingFromDeclaration(
         &forInTarget->as<ListNode>());
     if (decl->isKind(ParseNodeKind::Name)) {
       if (ParseNode* initializer = decl->as<NameNode>().initializer()) {
         MOZ_ASSERT(
-            forInTarget->isKind(ParseNodeKind::Var),
+            forInTarget->isKind(ParseNodeKind::VarStmt),
             "for-in initializers are only permitted for |var| declarations");
 
         if (!updateSourceCoordNotes(decl->pn_pos.begin)) {
           return false;
         }
 
         NameNode* nameNode = &decl->as<NameNode>();
         NameOpEmitter noe(this, nameNode->name(),
@@ -5288,18 +5288,18 @@ bool BytecodeEmitter::emitForIn(ForNode*
   if (!emitTree(expr)) {
     //              [stack] EXPR
     return false;
   }
 
   MOZ_ASSERT(forInLoop->iflags() == 0);
 
   MOZ_ASSERT_IF(headLexicalEmitterScope,
-                forInTarget->isKind(ParseNodeKind::Let) ||
-                    forInTarget->isKind(ParseNodeKind::Const));
+                forInTarget->isKind(ParseNodeKind::LetDecl) ||
+                    forInTarget->isKind(ParseNodeKind::ConstDecl));
 
   if (!forIn.emitInitialize()) {
     //              [stack] ITER ITERVAL
     return false;
   }
 
   if (!emitInitializeForInOrOfTarget(forInHead)) {
     //              [stack] ITER ITERVAL
@@ -5329,17 +5329,17 @@ bool BytecodeEmitter::emitForIn(ForNode*
 /* C-style `for (init; cond; update) ...` loop. */
 bool BytecodeEmitter::emitCStyleFor(
     ForNode* forNode, const EmitterScope* headLexicalEmitterScope) {
   TernaryNode* forHead = forNode->head();
   ParseNode* forBody = forNode->body();
   ParseNode* init = forHead->kid1();
   ParseNode* cond = forHead->kid2();
   ParseNode* update = forHead->kid3();
-  bool isLet = init && init->isKind(ParseNodeKind::Let);
+  bool isLet = init && init->isKind(ParseNodeKind::LetDecl);
 
   CForEmitter cfor(this, isLet ? headLexicalEmitterScope : nullptr);
 
   if (!cfor.emitInit(init ? Some(init->pn_pos.begin) : Nothing())) {
     //              [stack]
     return false;
   }
 
@@ -6043,17 +6043,17 @@ bool BytecodeEmitter::emitInitialYield(U
     return false;
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitYield(UnaryNode* yieldNode) {
   MOZ_ASSERT(sc->isFunctionBox());
-  MOZ_ASSERT(yieldNode->isKind(ParseNodeKind::Yield));
+  MOZ_ASSERT(yieldNode->isKind(ParseNodeKind::YieldExpr));
 
   bool needsIteratorResult = sc->asFunctionBox()->needsIteratorResult();
   if (needsIteratorResult) {
     if (!emitPrepareIteratorResult()) {
       //            [stack] ITEROBJ
       return false;
     }
   }
@@ -6095,17 +6095,17 @@ bool BytecodeEmitter::emitYield(UnaryNod
     return false;
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitAwaitInInnermostScope(UnaryNode* awaitNode) {
   MOZ_ASSERT(sc->isFunctionBox());
-  MOZ_ASSERT(awaitNode->isKind(ParseNodeKind::Await));
+  MOZ_ASSERT(awaitNode->isKind(ParseNodeKind::AwaitExpr));
 
   if (!emitTree(awaitNode->kid())) {
     return false;
   }
   return emitAwaitInInnermostScope();
 }
 
 bool BytecodeEmitter::emitAwaitInScope(EmitterScope& currentScope) {
@@ -6583,17 +6583,17 @@ bool BytecodeEmitter::emitStatementList(
     if (!emitTree(stmt)) {
       return false;
     }
   }
   return true;
 }
 
 bool BytecodeEmitter::emitExpressionStatement(UnaryNode* exprStmt) {
-  MOZ_ASSERT(exprStmt->isKind(ParseNodeKind::ExpressionStatement));
+  MOZ_ASSERT(exprStmt->isKind(ParseNodeKind::ExpressionStmt));
 
   /*
    * Top-level or called-from-a-native JS_Execute/EvaluateScript,
    * debugger, and eval frames may need the value of the ultimate
    * expression statement as the script's result, despite the fact
    * that it appears useless to the compiler.
    *
    * API users may also set the JSOPTION_NO_SCRIPT_RVAL option when
@@ -6623,17 +6623,18 @@ bool BytecodeEmitter::emitExpressionStat
         innermostNestableControl->is<LabelControl>() &&
         innermostNestableControl->as<LabelControl>().startOffset() >=
             offset()) {
       useful = true;
     }
   }
 
   if (useful) {
-    MOZ_ASSERT_IF(expr->isKind(ParseNodeKind::Assign), expr->isOp(JSOP_NOP));
+    MOZ_ASSERT_IF(expr->isKind(ParseNodeKind::AssignExpr),
+                  expr->isOp(JSOP_NOP));
     ValueUsage valueUsage =
         wantval ? ValueUsage::WantValue : ValueUsage::IgnoreValue;
     ExpressionStatementEmitter ese(this, valueUsage);
     if (!ese.prepareForExpr(Some(exprStmt->pn_pos.begin))) {
       return false;
     }
     if (!emitTree(expr, valueUsage)) {
       return false;
@@ -6675,26 +6676,26 @@ bool BytecodeEmitter::emitExpressionStat
       }
     }
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDeleteName(UnaryNode* deleteNode) {
-  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteName));
+  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteNameExpr));
 
   NameNode* nameExpr = &deleteNode->kid()->as<NameNode>();
   MOZ_ASSERT(nameExpr->isKind(ParseNodeKind::Name));
 
   return emitAtomOp(nameExpr->atom(), JSOP_DELNAME);
 }
 
 bool BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) {
-  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteProp));
+  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeletePropExpr));
 
   PropertyAccess* propExpr = &deleteNode->kid()->as<PropertyAccess>();
   // TODO(khyperia): Implement private field access.
   PropOpEmitter poe(this, PropOpEmitter::Kind::Delete,
                     propExpr->as<PropertyAccess>().isSuper()
                         ? PropOpEmitter::ObjKind::Super
                         : PropOpEmitter::ObjKind::Other);
   if (propExpr->isSuper()) {
@@ -6724,17 +6725,17 @@ bool BytecodeEmitter::emitDeleteProperty
     //              [stack] SUCCEEDED
     return false;
   }
 
   return true;
 }
 
 bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) {
-  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteElem));
+  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteElemExpr));
 
   PropertyByValue* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
   bool isSuper = elemExpr->isSuper();
   ElemOpEmitter eoe(
       this, ElemOpEmitter::Kind::Delete,
       isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
   if (isSuper) {
     // The expression |delete super[foo];| has to evaluate |super[foo]|,
@@ -6914,17 +6915,17 @@ bool BytecodeEmitter::emitSelfHostedResu
   }
 
   ParseNode* valNode = genNode->pn_next;
   if (!emitTree(valNode)) {
     return false;
   }
 
   ParseNode* kindNode = valNode->pn_next;
-  MOZ_ASSERT(kindNode->isKind(ParseNodeKind::String));
+  MOZ_ASSERT(kindNode->isKind(ParseNodeKind::StringExpr));
   uint16_t operand =
       GeneratorObject::getResumeKind(cx, kindNode->as<NameNode>().atom());
   MOZ_ASSERT(!kindNode->pn_next);
 
   if (!emitCall(JSOP_RESUME, operand)) {
     return false;
   }
 
@@ -7036,17 +7037,17 @@ bool BytecodeEmitter::isRestParameter(Pa
   FunctionBox* funbox = sc->asFunctionBox();
   RootedFunction fun(cx, funbox->function());
   if (!funbox->hasRest()) {
     return false;
   }
 
   if (!expr->isKind(ParseNodeKind::Name)) {
     if (emitterMode == BytecodeEmitter::SelfHosting &&
-        expr->isKind(ParseNodeKind::Call)) {
+        expr->isKind(ParseNodeKind::CallExpr)) {
       BinaryNode* callNode = &expr->as<BinaryNode>();
       ParseNode* calleeNode = callNode->left();
       if (calleeNode->isName(cx->names().allowContentIter)) {
         return isRestParameter(callNode->right()->as<ListNode>().head());
       }
     }
     return false;
   }
@@ -7072,17 +7073,17 @@ bool BytecodeEmitter::emitCalleeAndThis(
                                         CallOrNewEmitter& cone) {
   switch (callee->getKind()) {
     case ParseNodeKind::Name:
       if (!cone.emitNameCallee(callee->as<NameNode>().name())) {
         //          [stack] CALLEE THIS
         return false;
       }
       break;
-    case ParseNodeKind::Dot: {
+    case ParseNodeKind::DotExpr: {
       MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
       PropertyAccess* prop = &callee->as<PropertyAccess>();
       // TODO(khyperia): Implement private field access.
       bool isSuper = prop->isSuper();
 
       PropOpEmitter& poe = cone.prepareForPropCallee(isSuper);
       if (!poe.prepareForObj()) {
         return false;
@@ -7101,17 +7102,17 @@ bool BytecodeEmitter::emitCalleeAndThis(
       }
       if (!poe.emitGet(prop->key().atom())) {
         //          [stack] CALLEE THIS?
         return false;
       }
 
       break;
     }
-    case ParseNodeKind::Elem: {
+    case ParseNodeKind::ElemExpr: {
       MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
       PropertyByValue* elem = &callee->as<PropertyByValue>();
       bool isSuper = elem->isSuper();
 
       ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
       if (!emitElemObjAndKey(elem, isSuper, eoe)) {
         //          [stack] # if Super
         //          [stack] THIS? THIS KEY
@@ -7131,17 +7132,17 @@ bool BytecodeEmitter::emitCalleeAndThis(
         return false;
       }
       if (!emitTree(callee)) {
         //          [stack] CALLEE
         return false;
       }
       break;
     case ParseNodeKind::SuperBase:
-      MOZ_ASSERT(call->isKind(ParseNodeKind::SuperCall));
+      MOZ_ASSERT(call->isKind(ParseNodeKind::SuperCallExpr));
       MOZ_ASSERT(parser->astGenerator().isSuperBase(callee));
       if (!cone.emitSuperCallee()) {
         //          [stack] CALLEE THIS
         return false;
       }
       break;
     default:
       if (!cone.prepareForOtherCallee()) {
@@ -7246,18 +7247,18 @@ bool BytecodeEmitter::emitCallOrNew(
    * barrier -- see the code in jsinterp.cpp for JSOP_LAMBDA followed by
    * JSOP_{SET,INIT}PROP.
    *
    * Then (or in a call case that has no explicit reference-base
    * object) we emit JSOP_UNDEFINED to produce the undefined |this|
    * value required for calls (which non-strict mode functions
    * will box into the global object).
    */
-  bool isCall = callNode->isKind(ParseNodeKind::Call) ||
-                callNode->isKind(ParseNodeKind::TaggedTemplate);
+  bool isCall = callNode->isKind(ParseNodeKind::CallExpr) ||
+                callNode->isKind(ParseNodeKind::TaggedTemplateExpr);
   ParseNode* calleeNode = callNode->left();
   ListNode* argsList = &callNode->right()->as<ListNode>();
   bool isSpread = JOF_OPTYPE(callNode->getOp()) == JOF_BYTE;
   if (calleeNode->isKind(ParseNodeKind::Name) &&
       emitterMode == BytecodeEmitter::SelfHosting && !isSpread) {
     // Calls to "forceInterpreter", "callFunction",
     // "callContentFunction", or "resumeGenerator" in self-hosted
     // code generate inline bytecode.
@@ -7305,27 +7306,27 @@ bool BytecodeEmitter::emitCallOrNew(
   if (!emitArguments(argsList, isCall, isSpread, cone)) {
     //              [stack] CALLEE THIS ARGS...
     return false;
   }
 
   ParseNode* coordNode = callNode;
   if (op == JSOP_CALL || op == JSOP_SPREADCALL) {
     switch (calleeNode->getKind()) {
-      case ParseNodeKind::Dot: {
+      case ParseNodeKind::DotExpr: {
         // Check if this member is a simple chain of simple chain of
         // property accesses, e.g. x.y.z, this.x.y, super.x.y
         bool simpleDotChain = false;
-        for (ParseNode* cur = calleeNode; cur->isKind(ParseNodeKind::Dot);
+        for (ParseNode* cur = calleeNode; cur->isKind(ParseNodeKind::DotExpr);
              cur = &cur->as<PropertyAccess>().expression()) {
           PropertyAccess* prop = &cur->as<PropertyAccess>();
           ParseNode* left = &prop->expression();
           // TODO(khyperia): Implement private field access.
           if (left->isKind(ParseNodeKind::Name) ||
-              left->isKind(ParseNodeKind::This) ||
+              left->isKind(ParseNodeKind::ThisExpr) ||
               left->isKind(ParseNodeKind::SuperBase)) {
             simpleDotChain = true;
           }
         }
 
         if (!simpleDotChain) {
           // obj().aprop() // expression
           //       ^       // column coord
@@ -7334,17 +7335,17 @@ bool BytecodeEmitter::emitCallOrNew(
           // this case also applies for constant string properties.
           //
           // obj()['aprop']() // expression
           //       ^          // column coord
           coordNode = &calleeNode->as<PropertyAccess>().key();
         }
         break;
       }
-      case ParseNodeKind::Elem:
+      case ParseNodeKind::ElemExpr:
         // obj[expr]() // expression
         //          ^  // column coord
         coordNode = argsList;
         break;
       default:
         break;
     }
   }
@@ -7368,17 +7369,17 @@ static const JSOp ParseNodeKindToJSOp[] 
 static inline JSOp BinaryOpParseNodeKindToJSOp(ParseNodeKind pnk) {
   MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst);
   MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast);
   return ParseNodeKindToJSOp[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
 }
 
 bool BytecodeEmitter::emitRightAssociative(ListNode* node) {
   // ** is the only right-associative operator.
-  MOZ_ASSERT(node->isKind(ParseNodeKind::Pow));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::PowExpr));
 
   // Right-associative operator chain.
   for (ParseNode* subexpr : node->contents()) {
     if (!emitTree(subexpr)) {
       return false;
     }
   }
   for (uint32_t i = 0; i < node->count() - 1; i++) {
@@ -7403,18 +7404,18 @@ bool BytecodeEmitter::emitLeftAssociativ
     if (!emit1(op)) {
       return false;
     }
   } while ((nextExpr = nextExpr->pn_next));
   return true;
 }
 
 bool BytecodeEmitter::emitLogical(ListNode* node) {
-  MOZ_ASSERT(node->isKind(ParseNodeKind::Or) ||
-             node->isKind(ParseNodeKind::And));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::OrExpr) ||
+             node->isKind(ParseNodeKind::AndExpr));
 
   /*
    * JSOP_OR converts the operand on the stack to boolean, leaves the original
    * value on the stack and jumps if true; otherwise it falls into the next
    * bytecode, which pops the left operand and then evaluates the right operand.
    * The jump goes around the right operand evaluation.
    *
    * JSOP_AND converts the operand on the stack to boolean and jumps if false;
@@ -7423,17 +7424,17 @@ bool BytecodeEmitter::emitLogical(ListNo
 
   TDZCheckCache tdzCache(this);
 
   /* Left-associative operator chain: avoid too much recursion. */
   ParseNode* expr = node->head();
   if (!emitTree(expr)) {
     return false;
   }
-  JSOp op = node->isKind(ParseNodeKind::Or) ? JSOP_OR : JSOP_AND;
+  JSOp op = node->isKind(ParseNodeKind::OrExpr) ? JSOP_OR : JSOP_AND;
   JumpList jump;
   if (!emitJump(op, &jump)) {
     return false;
   }
   if (!emit1(JSOP_POP)) {
     return false;
   }
 
@@ -7478,21 +7479,21 @@ bool BytecodeEmitter::emitSequenceExpr(
   }
   return true;
 }
 
 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
 // the comment on emitSwitch.
 MOZ_NEVER_INLINE bool BytecodeEmitter::emitIncOrDec(UnaryNode* incDec) {
   switch (incDec->kid()->getKind()) {
-    case ParseNodeKind::Dot:
+    case ParseNodeKind::DotExpr:
       return emitPropIncDec(incDec);
-    case ParseNodeKind::Elem:
+    case ParseNodeKind::ElemExpr:
       return emitElemIncDec(incDec);
-    case ParseNodeKind::Call:
+    case ParseNodeKind::CallExpr:
       return emitCallIncDec(incDec);
     default:
       return emitNameIncDec(incDec);
   }
 }
 
 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
 // the comment on emitSwitch.
@@ -7620,23 +7621,23 @@ bool BytecodeEmitter::emitPropertyList(L
       if (!emit1(JSOP_POP)) {
         return false;
       }
     }
 
     /* Emit an index for t[2] for later consumption by JSOP_INITELEM. */
     ParseNode* key = propdef->as<BinaryNode>().left();
     bool isIndex = false;
-    if (key->isKind(ParseNodeKind::Number)) {
+    if (key->isKind(ParseNodeKind::NumberExpr)) {
       if (!emitNumberOp(key->as<NumericLiteral>().value())) {
         return false;
       }
       isIndex = true;
     } else if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
-               key->isKind(ParseNodeKind::String)) {
+               key->isKind(ParseNodeKind::StringExpr)) {
       // EmitClass took care of constructor already.
       if (type == ClassBody &&
           key->as<NameNode>().atom() == cx->names().constructor &&
           !propdef->as<ClassMethod>().isStatic()) {
         continue;
       }
     } else {
       MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName));
@@ -7738,17 +7739,17 @@ bool BytecodeEmitter::emitPropertyList(L
           return false;
         }
       }
       if (!emit1(op)) {
         return false;
       }
     } else {
       MOZ_ASSERT(key->isKind(ParseNodeKind::ObjectPropertyName) ||
-                 key->isKind(ParseNodeKind::String));
+                 key->isKind(ParseNodeKind::StringExpr));
 
       uint32_t index;
       if (!makeAtomIndex(key->as<NameNode>().atom(), &index)) {
         return false;
       }
 
       if (objp) {
         MOZ_ASSERT(type == ObjectLiteral);
@@ -7955,17 +7956,17 @@ bool BytecodeEmitter::emitArray(ParseNod
         return false;
       }
     } else {
       ParseNode* expr;
       if (elem->isKind(ParseNodeKind::Spread)) {
         expr = elem->as<UnaryNode>().kid();
 
         if (emitterMode == BytecodeEmitter::SelfHosting &&
-            expr->isKind(ParseNodeKind::Call) &&
+            expr->isKind(ParseNodeKind::CallExpr) &&
             expr->as<BinaryNode>().left()->isName(
                 cx->names().allowContentIter)) {
           allowSelfHostedIter = true;
         }
       } else {
         expr = elem;
       }
       if (!emitTree(expr)) {
@@ -8007,27 +8008,27 @@ bool BytecodeEmitter::emitArray(ParseNod
       return false;
     }
   }
   return true;
 }
 
 static inline JSOp UnaryOpParseNodeKindToJSOp(ParseNodeKind pnk) {
   switch (pnk) {
-    case ParseNodeKind::Throw:
+    case ParseNodeKind::ThrowStmt:
       return JSOP_THROW;
-    case ParseNodeKind::Void:
+    case ParseNodeKind::VoidExpr:
       return JSOP_VOID;
-    case ParseNodeKind::Not:
+    case ParseNodeKind::NotExpr:
       return JSOP_NOT;
-    case ParseNodeKind::BitNot:
+    case ParseNodeKind::BitNotExpr:
       return JSOP_BITNOT;
-    case ParseNodeKind::Pos:
+    case ParseNodeKind::PosExpr:
       return JSOP_POS;
-    case ParseNodeKind::Neg:
+    case ParseNodeKind::NegExpr:
       return JSOP_NEG;
     default:
       MOZ_CRASH("unexpected unary op");
   }
 }
 
 bool BytecodeEmitter::emitUnary(UnaryNode* unaryNode) {
   if (!updateSourceCoordNotes(unaryNode->pn_pos.begin)) {
@@ -8180,25 +8181,25 @@ bool BytecodeEmitter::emitFunctionFormal
   bool hasParameterExprs = funbox->hasParameterExprs;
   bool hasRest = funbox->hasRest();
 
   uint16_t argSlot = 0;
   for (ParseNode* arg = paramsBody->head(); arg != funBody;
        arg = arg->pn_next, argSlot++) {
     ParseNode* bindingElement = arg;
     ParseNode* initializer = nullptr;
-    if (arg->isKind(ParseNodeKind::Assign)) {
+    if (arg->isKind(ParseNodeKind::AssignExpr)) {
       bindingElement = arg->as<AssignmentNode>().left();
       initializer = arg->as<AssignmentNode>().right();
     }
 
     // Left-hand sides are either simple names or destructuring patterns.
     MOZ_ASSERT(bindingElement->isKind(ParseNodeKind::Name) ||
-               bindingElement->isKind(ParseNodeKind::Array) ||
-               bindingElement->isKind(ParseNodeKind::Object));
+               bindingElement->isKind(ParseNodeKind::ArrayExpr) ||
+               bindingElement->isKind(ParseNodeKind::ObjectExpr));
 
     // The rest parameter doesn't have an initializer.
     bool isRest = hasRest && arg->pn_next == funBody;
     MOZ_ASSERT_IF(isRest, !initializer);
 
     bool isDestructuring = !bindingElement->isKind(ParseNodeKind::Name);
 
     // ES 14.1.19 says if BindingElement contains an expression in the
@@ -8434,17 +8435,17 @@ bool BytecodeEmitter::emitClass(ClassNod
     if (mn->is<ClassField>()) {
       // TODO(khyperia): Implement private field access.
       return false;
     }
     ClassMethod& method = mn->as<ClassMethod>();
     ParseNode& methodName = method.name();
     if (!method.isStatic() &&
         (methodName.isKind(ParseNodeKind::ObjectPropertyName) ||
-         methodName.isKind(ParseNodeKind::String)) &&
+         methodName.isKind(ParseNodeKind::StringExpr)) &&
         methodName.as<NameNode>().atom() == cx->names().constructor) {
       constructor = &method.method();
       break;
     }
   }
 
   bool savedStrictness = sc->setLocalStrictMode(true);
 
@@ -8689,17 +8690,17 @@ bool BytecodeEmitter::emitClass(ClassNod
   // The CONSTRUCTOR is left on stack if this is an expression.
 
   MOZ_ALWAYS_TRUE(sc->setLocalStrictMode(savedStrictness));
 
   return true;
 }
 
 bool BytecodeEmitter::emitExportDefault(BinaryNode* exportNode) {
-  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportDefault));
+  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportDefaultStmt));
 
   ParseNode* nameNode = exportNode->left();
   if (!emitTree(nameNode)) {
     return false;
   }
 
   if (ParseNode* binding = exportNode->right()) {
     if (!emitLexicalInitialization(&binding->as<NameNode>())) {
@@ -8748,99 +8749,99 @@ bool BytecodeEmitter::emitTree(
       break;
 
     case ParseNodeKind::ParamsBody:
       if (!emitFunctionFormalParametersAndBody(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::If:
+    case ParseNodeKind::IfStmt:
       if (!emitIf(&pn->as<TernaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Switch:
+    case ParseNodeKind::SwitchStmt:
       if (!emitSwitch(&pn->as<SwitchStatement>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::While:
+    case ParseNodeKind::WhileStmt:
       if (!emitWhile(&pn->as<BinaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::DoWhile:
+    case ParseNodeKind::DoWhileStmt:
       if (!emitDo(&pn->as<BinaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::For:
+    case ParseNodeKind::ForStmt:
       if (!emitFor(&pn->as<ForNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Break:
+    case ParseNodeKind::BreakStmt:
       // Ensure that the column of the 'break' is set properly.
       if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
         return false;
       }
 
       if (!emitBreak(pn->as<BreakStatement>().label())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Continue:
+    case ParseNodeKind::ContinueStmt:
       // Ensure that the column of the 'continue' is set properly.
       if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
         return false;
       }
 
       if (!emitContinue(pn->as<ContinueStatement>().label())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::With:
+    case ParseNodeKind::WithStmt:
       if (!emitWith(&pn->as<BinaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Try:
+    case ParseNodeKind::TryStmt:
       if (!emitTry(&pn->as<TryNode>())) {
         return false;
       }
       break;
 
     case ParseNodeKind::Catch:
       if (!emitCatch(&pn->as<BinaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Var:
+    case ParseNodeKind::VarStmt:
       if (!emitDeclarationList(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Return:
+    case ParseNodeKind::ReturnStmt:
       if (!emitReturn(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::YieldStar:
+    case ParseNodeKind::YieldStarExpr:
       if (!emitYieldStar(pn->as<UnaryNode>().kid())) {
         return false;
       }
       break;
 
     case ParseNodeKind::Generator:
       if (!emit1(JSOP_GENERATOR)) {
         return false;
@@ -8848,187 +8849,187 @@ bool BytecodeEmitter::emitTree(
       break;
 
     case ParseNodeKind::InitialYield:
       if (!emitInitialYield(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Yield:
+    case ParseNodeKind::YieldExpr:
       if (!emitYield(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Await:
+    case ParseNodeKind::AwaitExpr:
       if (!emitAwaitInInnermostScope(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
     case ParseNodeKind::StatementList:
       if (!emitStatementList(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::EmptyStatement:
+    case ParseNodeKind::EmptyStmt:
       break;
 
-    case ParseNodeKind::ExpressionStatement:
+    case ParseNodeKind::ExpressionStmt:
       if (!emitExpressionStatement(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Label:
+    case ParseNodeKind::LabelStmt:
       if (!emitLabeledStatement(&pn->as<LabeledStatement>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Comma:
+    case ParseNodeKind::CommaExpr:
       if (!emitSequenceExpr(&pn->as<ListNode>(), valueUsage)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Assign:
-    case ParseNodeKind::AddAssign:
-    case ParseNodeKind::SubAssign:
-    case ParseNodeKind::BitOrAssign:
-    case ParseNodeKind::BitXorAssign:
-    case ParseNodeKind::BitAndAssign:
-    case ParseNodeKind::LshAssign:
-    case ParseNodeKind::RshAssign:
-    case ParseNodeKind::UrshAssign:
-    case ParseNodeKind::MulAssign:
-    case ParseNodeKind::DivAssign:
-    case ParseNodeKind::ModAssign:
-    case ParseNodeKind::PowAssign: {
+    case ParseNodeKind::AssignExpr:
+    case ParseNodeKind::AddAssignExpr:
+    case ParseNodeKind::SubAssignExpr:
+    case ParseNodeKind::BitOrAssignExpr:
+    case ParseNodeKind::BitXorAssignExpr:
+    case ParseNodeKind::BitAndAssignExpr:
+    case ParseNodeKind::LshAssignExpr:
+    case ParseNodeKind::RshAssignExpr:
+    case ParseNodeKind::UrshAssignExpr:
+    case ParseNodeKind::MulAssignExpr:
+    case ParseNodeKind::DivAssignExpr:
+    case ParseNodeKind::ModAssignExpr:
+    case ParseNodeKind::PowAssignExpr: {
       AssignmentNode* assignNode = &pn->as<AssignmentNode>();
       if (!emitAssignment(
               assignNode->left(),
               CompoundAssignmentParseNodeKindToJSOp(assignNode->getKind()),
               assignNode->right())) {
         return false;
       }
       break;
     }
 
-    case ParseNodeKind::Conditional:
+    case ParseNodeKind::ConditionalExpr:
       if (!emitConditionalExpression(pn->as<ConditionalExpression>(),
                                      valueUsage)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Or:
-    case ParseNodeKind::And:
+    case ParseNodeKind::OrExpr:
+    case ParseNodeKind::AndExpr:
       if (!emitLogical(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Add:
-    case ParseNodeKind::Sub:
-    case ParseNodeKind::BitOr:
-    case ParseNodeKind::BitXor:
-    case ParseNodeKind::BitAnd:
-    case ParseNodeKind::StrictEq:
-    case ParseNodeKind::Eq:
-    case ParseNodeKind::StrictNe:
-    case ParseNodeKind::Ne:
-    case ParseNodeKind::Lt:
-    case ParseNodeKind::Le:
-    case ParseNodeKind::Gt:
-    case ParseNodeKind::Ge:
-    case ParseNodeKind::In:
-    case ParseNodeKind::InstanceOf:
-    case ParseNodeKind::Lsh:
-    case ParseNodeKind::Rsh:
-    case ParseNodeKind::Ursh:
-    case ParseNodeKind::Star:
-    case ParseNodeKind::Div:
-    case ParseNodeKind::Mod:
+    case ParseNodeKind::AddExpr:
+    case ParseNodeKind::SubExpr:
+    case ParseNodeKind::BitOrExpr:
+    case ParseNodeKind::BitXorExpr:
+    case ParseNodeKind::BitAndExpr:
+    case ParseNodeKind::StrictEqExpr:
+    case ParseNodeKind::EqExpr:
+    case ParseNodeKind::StrictNeExpr:
+    case ParseNodeKind::NeExpr:
+    case ParseNodeKind::LtExpr:
+    case ParseNodeKind::LeExpr:
+    case ParseNodeKind::GtExpr:
+    case ParseNodeKind::GeExpr:
+    case ParseNodeKind::InExpr:
+    case ParseNodeKind::InstanceOfExpr:
+    case ParseNodeKind::LshExpr:
+    case ParseNodeKind::RshExpr:
+    case ParseNodeKind::UrshExpr:
+    case ParseNodeKind::MulExpr:
+    case ParseNodeKind::DivExpr:
+    case ParseNodeKind::ModExpr:
       if (!emitLeftAssociative(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Pow:
+    case ParseNodeKind::PowExpr:
       if (!emitRightAssociative(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Pipeline:
+    case ParseNodeKind::PipelineExpr:
       if (!emitPipeline(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::TypeOfName:
+    case ParseNodeKind::TypeOfNameExpr:
       if (!emitTypeof(&pn->as<UnaryNode>(), JSOP_TYPEOF)) {
         return false;
       }
       break;
 
     case ParseNodeKind::TypeOfExpr:
       if (!emitTypeof(&pn->as<UnaryNode>(), JSOP_TYPEOFEXPR)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Throw:
-    case ParseNodeKind::Void:
-    case ParseNodeKind::Not:
-    case ParseNodeKind::BitNot:
-    case ParseNodeKind::Pos:
-    case ParseNodeKind::Neg:
+    case ParseNodeKind::ThrowStmt:
+    case ParseNodeKind::VoidExpr:
+    case ParseNodeKind::NotExpr:
+    case ParseNodeKind::BitNotExpr:
+    case ParseNodeKind::PosExpr:
+    case ParseNodeKind::NegExpr:
       if (!emitUnary(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::PreIncrement:
-    case ParseNodeKind::PreDecrement:
-    case ParseNodeKind::PostIncrement:
-    case ParseNodeKind::PostDecrement:
+    case ParseNodeKind::PreIncrementExpr:
+    case ParseNodeKind::PreDecrementExpr:
+    case ParseNodeKind::PostIncrementExpr:
+    case ParseNodeKind::PostDecrementExpr:
       if (!emitIncOrDec(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::DeleteName:
+    case ParseNodeKind::DeleteNameExpr:
       if (!emitDeleteName(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::DeleteProp:
+    case ParseNodeKind::DeletePropExpr:
       if (!emitDeleteProperty(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::DeleteElem:
+    case ParseNodeKind::DeleteElemExpr:
       if (!emitDeleteElement(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
     case ParseNodeKind::DeleteExpr:
       if (!emitDeleteExpression(&pn->as<UnaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Dot: {
+    case ParseNodeKind::DotExpr: {
       PropertyAccess* prop = &pn->as<PropertyAccess>();
       // TODO(khyperia): Implement private field access.
       bool isSuper = prop->isSuper();
       PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
                         isSuper ? PropOpEmitter::ObjKind::Super
                                 : PropOpEmitter::ObjKind::Other);
       if (!poe.prepareForObj()) {
         return false;
@@ -9047,17 +9048,17 @@ bool BytecodeEmitter::emitTree(
       }
       if (!poe.emitGet(prop->key().atom())) {
         //          [stack] PROP
         return false;
       }
       break;
     }
 
-    case ParseNodeKind::Elem: {
+    case ParseNodeKind::ElemExpr: {
       PropertyByValue* elem = &pn->as<PropertyByValue>();
       bool isSuper = elem->isSuper();
       ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
                         isSuper ? ElemOpEmitter::ObjKind::Super
                                 : ElemOpEmitter::ObjKind::Other);
       if (!emitElemObjAndKey(elem, isSuper, eoe)) {
         //          [stack] # if Super
         //          [stack] THIS KEY
@@ -9068,178 +9069,178 @@ bool BytecodeEmitter::emitTree(
       if (!eoe.emitGet()) {
         //          [stack] ELEM
         return false;
       }
 
       break;
     }
 
-    case ParseNodeKind::New:
-    case ParseNodeKind::TaggedTemplate:
-    case ParseNodeKind::Call:
-    case ParseNodeKind::SuperCall:
+    case ParseNodeKind::NewExpr:
+    case ParseNodeKind::TaggedTemplateExpr:
+    case ParseNodeKind::CallExpr:
+    case ParseNodeKind::SuperCallExpr:
       if (!emitCallOrNew(&pn->as<BinaryNode>(), valueUsage)) {
         return false;
       }
       break;
 
     case ParseNodeKind::LexicalScope:
       if (!emitLexicalScope(&pn->as<LexicalScopeNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Const:
-    case ParseNodeKind::Let:
+    case ParseNodeKind::ConstDecl:
+    case ParseNodeKind::LetDecl:
       if (!emitDeclarationList(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Import:
+    case ParseNodeKind::ImportDecl:
       MOZ_ASSERT(sc->isModuleContext());
       break;
 
-    case ParseNodeKind::Export: {
+    case ParseNodeKind::ExportStmt: {
       MOZ_ASSERT(sc->isModuleContext());
       UnaryNode* node = &pn->as<UnaryNode>();
       ParseNode* decl = node->kid();
       if (decl->getKind() != ParseNodeKind::ExportSpecList) {
         if (!emitTree(decl)) {
           return false;
         }
       }
       break;
     }
 
-    case ParseNodeKind::ExportDefault:
+    case ParseNodeKind::ExportDefaultStmt:
       MOZ_ASSERT(sc->isModuleContext());
       if (!emitExportDefault(&pn->as<BinaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::ExportFrom:
+    case ParseNodeKind::ExportFromStmt:
       MOZ_ASSERT(sc->isModuleContext());
       break;
 
-    case ParseNodeKind::CallSiteObj:
+    case ParseNodeKind::CallSiteObjExpr:
       if (!emitCallSiteObject(&pn->as<CallSiteNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Array:
+    case ParseNodeKind::ArrayExpr:
       if (!emitArrayLiteral(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Object:
+    case ParseNodeKind::ObjectExpr:
       if (!emitObject(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
     case ParseNodeKind::Name:
       if (!emitGetName(&pn->as<NameNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::TemplateStringList:
+    case ParseNodeKind::TemplateStringListExpr:
       if (!emitTemplateString(&pn->as<ListNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::TemplateString:
-    case ParseNodeKind::String:
+    case ParseNodeKind::TemplateStringExpr:
+    case ParseNodeKind::StringExpr:
       if (!emitAtomOp(pn->as<NameNode>().atom(), JSOP_STRING)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Number:
+    case ParseNodeKind::NumberExpr:
       if (!emitNumberOp(pn->as<NumericLiteral>().value())) {
         return false;
       }
       break;
 
 #ifdef ENABLE_BIGINT
     case ParseNodeKind::BigInt:
       if (!emitBigIntOp(pn->as<BigIntLiteral>().box()->value())) {
         return false;
       }
       break;
 #endif
 
-    case ParseNodeKind::RegExp:
+    case ParseNodeKind::RegExpExpr:
       if (!emitRegExp(objectList.add(pn->as<RegExpLiteral>().objbox()))) {
         return false;
       }
       break;
 
-    case ParseNodeKind::True:
-    case ParseNodeKind::False:
-    case ParseNodeKind::Null:
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::TrueExpr:
+    case ParseNodeKind::FalseExpr:
+    case ParseNodeKind::NullExpr:
+    case ParseNodeKind::RawUndefinedExpr:
       if (!emit1(pn->getOp())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::This:
+    case ParseNodeKind::ThisExpr:
       if (!emitThisLiteral(&pn->as<ThisLiteral>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Debugger:
+    case ParseNodeKind::DebuggerStmt:
       if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
         return false;
       }
       if (!emit1(JSOP_DEBUGGER)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::Class:
+    case ParseNodeKind::ClassDecl:
       if (!emitClass(&pn->as<ClassNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::NewTarget:
+    case ParseNodeKind::NewTargetExpr:
       if (!emit1(JSOP_NEWTARGET)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::ImportMeta:
+    case ParseNodeKind::ImportMetaExpr:
       if (!emit1(JSOP_IMPORTMETA)) {
         return false;
       }
       break;
 
-    case ParseNodeKind::CallImport:
+    case ParseNodeKind::CallImportExpr:
       if (!emitTree(pn->as<BinaryNode>().right()) ||
           !emit1(JSOP_DYNAMIC_IMPORT)) {
         return false;
       }
       break;
 
     case ParseNodeKind::SetThis:
       if (!emitSetThis(&pn->as<BinaryNode>())) {
         return false;
       }
       break;
 
-    case ParseNodeKind::PropertyName:
+    case ParseNodeKind::PropertyNameExpr:
     case ParseNodeKind::PosHolder:
       MOZ_FALLTHROUGH_ASSERT(
           "Should never try to emit ParseNodeKind::PosHolder or ::Property");
 
     default:
       MOZ_ASSERT(0);
   }
 
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -65,30 +65,30 @@ restart:
   // With a better-typed AST, we would have distinct parse node classes for
   // expressions and for statements and would characterize expressions with
   // ExpressionKind and statements with StatementKind.  Perhaps someday.  In
   // the meantime we must characterize every ParseNodeKind, even the
   // expression/sub-expression ones that, if we handle all statement kinds
   // correctly, we'll never see.
   switch (node->getKind()) {
     // Base case.
-    case ParseNodeKind::Var:
+    case ParseNodeKind::VarStmt:
       *result = true;
       return true;
 
     // Non-global lexical declarations are block-scoped (ergo not hoistable).
-    case ParseNodeKind::Let:
-    case ParseNodeKind::Const:
+    case ParseNodeKind::LetDecl:
+    case ParseNodeKind::ConstDecl:
       MOZ_ASSERT(node->is<ListNode>());
       *result = false;
       return true;
 
     // Similarly to the lexical declarations above, classes cannot add hoisted
     // declarations
-    case ParseNodeKind::Class:
+    case ParseNodeKind::ClassDecl:
       MOZ_ASSERT(node->is<ClassNode>());
       *result = false;
       return true;
 
     // Function declarations *can* be hoisted declarations.  But in the
     // magical world of the rewritten frontend, the declaration necessitated
     // by a nested function statement, not at body level, doesn't require
     // that we preserve an unreachable function declaration node against
@@ -98,82 +98,82 @@ restart:
       *result = false;
       return true;
 
     case ParseNodeKind::Module:
       *result = false;
       return true;
 
     // Statements with no sub-components at all.
-    case ParseNodeKind::EmptyStatement:
+    case ParseNodeKind::EmptyStmt:
       MOZ_ASSERT(node->is<NullaryNode>());
       *result = false;
       return true;
 
-    case ParseNodeKind::Debugger:
+    case ParseNodeKind::DebuggerStmt:
       MOZ_ASSERT(node->is<DebuggerStatement>());
       *result = false;
       return true;
 
     // Statements containing only an expression have no declarations.
-    case ParseNodeKind::ExpressionStatement:
-    case ParseNodeKind::Throw:
-    case ParseNodeKind::Return:
+    case ParseNodeKind::ExpressionStmt:
+    case ParseNodeKind::ThrowStmt:
+    case ParseNodeKind::ReturnStmt:
       MOZ_ASSERT(node->is<UnaryNode>());
       *result = false;
       return true;
 
     // These two aren't statements in the spec, but we sometimes insert them
     // in statement lists anyway.
     case ParseNodeKind::InitialYield:
-    case ParseNodeKind::YieldStar:
-    case ParseNodeKind::Yield:
+    case ParseNodeKind::YieldStarExpr:
+    case ParseNodeKind::YieldExpr:
       MOZ_ASSERT(node->is<UnaryNode>());
       *result = false;
       return true;
 
     // Other statements with no sub-statement components.
-    case ParseNodeKind::Break:
-    case ParseNodeKind::Continue:
-    case ParseNodeKind::Import:
+    case ParseNodeKind::BreakStmt:
+    case ParseNodeKind::ContinueStmt:
+    case ParseNodeKind::ImportDecl:
     case ParseNodeKind::ImportSpecList:
     case ParseNodeKind::ImportSpec:
-    case ParseNodeKind::ExportFrom:
-    case ParseNodeKind::ExportDefault:
+    case ParseNodeKind::ExportFromStmt:
+    case ParseNodeKind::ExportDefaultStmt:
     case ParseNodeKind::ExportSpecList:
     case ParseNodeKind::ExportSpec:
-    case ParseNodeKind::Export:
-    case ParseNodeKind::ExportBatchSpec:
-    case ParseNodeKind::CallImport:
+    case ParseNodeKind::ExportStmt:
+    case ParseNodeKind::ExportBatchSpecStmt:
+    case ParseNodeKind::CallImportExpr:
       *result = false;
       return true;
 
     // Statements possibly containing hoistable declarations only in the left
     // half, in ParseNode terms -- the loop body in AST terms.
-    case ParseNodeKind::DoWhile:
+    case ParseNodeKind::DoWhileStmt:
       return ContainsHoistedDeclaration(cx, node->as<BinaryNode>().left(),
                                         result);
 
     // Statements possibly containing hoistable declarations only in the
     // right half, in ParseNode terms -- the loop body or nested statement
     // (usually a block statement), in AST terms.
-    case ParseNodeKind::While:
-    case ParseNodeKind::With:
+    case ParseNodeKind::WhileStmt:
+    case ParseNodeKind::WithStmt:
       return ContainsHoistedDeclaration(cx, node->as<BinaryNode>().right(),
                                         result);
 
-    case ParseNodeKind::Label:
+    case ParseNodeKind::LabelStmt:
       return ContainsHoistedDeclaration(
           cx, node->as<LabeledStatement>().statement(), result);
 
     // Statements with more complicated structures.
 
     // if-statement nodes may have hoisted declarations in their consequent
     // and alternative components.
-    case ParseNodeKind::If: {
+    case ParseNodeKind::IfStmt: {
       TernaryNode* ifNode = &node->as<TernaryNode>();
       ParseNode* consequent = ifNode->kid2();
       if (!ContainsHoistedDeclaration(cx, consequent, result)) {
         return false;
       }
       if (*result) {
         return true;
       }
@@ -183,17 +183,17 @@ restart:
       }
 
       *result = false;
       return true;
     }
 
     // try-statements have statements to execute, and one or both of a
     // catch-list and a finally-block.
-    case ParseNodeKind::Try: {
+    case ParseNodeKind::TryStmt: {
       TernaryNode* tryNode = &node->as<TernaryNode>();
 
       MOZ_ASSERT(tryNode->kid2() || tryNode->kid3(),
                  "must have either catch or finally");
 
       ParseNode* tryBlock = tryNode->kid1();
       if (!ContainsHoistedDeclaration(cx, tryBlock, result)) {
         return false;
@@ -222,43 +222,43 @@ restart:
 
       *result = false;
       return true;
     }
 
     // A switch node's left half is an expression; only its right half (a
     // list of cases/defaults, or a block node) could contain hoisted
     // declarations.
-    case ParseNodeKind::Switch: {
+    case ParseNodeKind::SwitchStmt: {
       SwitchStatement* switchNode = &node->as<SwitchStatement>();
       return ContainsHoistedDeclaration(cx, &switchNode->lexicalForCaseList(),
                                         result);
     }
 
     case ParseNodeKind::Case: {
       CaseClause* caseClause = &node->as<CaseClause>();
       return ContainsHoistedDeclaration(cx, caseClause->statementList(),
                                         result);
     }
 
-    case ParseNodeKind::For: {
+    case ParseNodeKind::ForStmt: {
       ForNode* forNode = &node->as<ForNode>();
       TernaryNode* loopHead = forNode->head();
       MOZ_ASSERT(loopHead->isKind(ParseNodeKind::ForHead) ||
                  loopHead->isKind(ParseNodeKind::ForIn) ||
                  loopHead->isKind(ParseNodeKind::ForOf));
 
       if (loopHead->isKind(ParseNodeKind::ForHead)) {
         // for (init?; cond?; update?), with only init possibly containing
         // a hoisted declaration.  (Note: a lexical-declaration |init| is
         // (at present) hoisted in SpiderMonkey parlance -- but such
         // hoisting doesn't extend outside of this statement, so it is not
         // hoisting in the sense meant by ContainsHoistedDeclaration.)
         ParseNode* init = loopHead->kid1();
-        if (init && init->isKind(ParseNodeKind::Var)) {
+        if (init && init->isKind(ParseNodeKind::VarStmt)) {
           *result = true;
           return true;
         }
       } else {
         MOZ_ASSERT(loopHead->isKind(ParseNodeKind::ForIn) ||
                    loopHead->isKind(ParseNodeKind::ForOf));
 
         // for each? (target in ...), where only target may introduce
@@ -267,31 +267,31 @@ restart:
         //   -- or --
         //
         // for (target of ...), where only target may introduce hoisted
         // declarations.
         //
         // Either way, if |target| contains a declaration, it's |loopHead|'s
         // first kid.
         ParseNode* decl = loopHead->kid1();
-        if (decl && decl->isKind(ParseNodeKind::Var)) {
+        if (decl && decl->isKind(ParseNodeKind::VarStmt)) {
           *result = true;
           return true;
         }
       }
 
       ParseNode* loopBody = forNode->body();
       return ContainsHoistedDeclaration(cx, loopBody, result);
     }
 
     case ParseNodeKind::LexicalScope: {
       LexicalScopeNode* scope = &node->as<LexicalScopeNode>();
       ParseNode* expr = scope->scopeBody();
 
-      if (expr->isKind(ParseNodeKind::For) ||
+      if (expr->isKind(ParseNodeKind::ForStmt) ||
           expr->isKind(ParseNodeKind::Function)) {
         return ContainsHoistedDeclaration(cx, expr, result);
       }
 
       MOZ_ASSERT(expr->isKind(ParseNodeKind::StatementList));
       return ListContainsHoistedDeclaration(
           cx, &scope->scopeBody()->as<ListNode>(), result);
     }
@@ -303,118 +303,118 @@ restart:
     // Grammar sub-components that should never be reached directly by this
     // method, because some parent component should have asserted itself.
     case ParseNodeKind::ObjectPropertyName:
     case ParseNodeKind::ComputedName:
     case ParseNodeKind::Spread:
     case ParseNodeKind::MutateProto:
     case ParseNodeKind::Colon:
     case ParseNodeKind::Shorthand:
-    case ParseNodeKind::Conditional:
-    case ParseNodeKind::TypeOfName:
+    case ParseNodeKind::ConditionalExpr:
+    case ParseNodeKind::TypeOfNameExpr:
     case ParseNodeKind::TypeOfExpr:
-    case ParseNodeKind::Await:
-    case ParseNodeKind::Void:
-    case ParseNodeKind::Not:
-    case ParseNodeKind::BitNot:
-    case ParseNodeKind::DeleteName:
-    case ParseNodeKind::DeleteProp:
-    case ParseNodeKind::DeleteElem:
+    case ParseNodeKind::AwaitExpr:
+    case ParseNodeKind::VoidExpr:
+    case ParseNodeKind::NotExpr:
+    case ParseNodeKind::BitNotExpr:
+    case ParseNodeKind::DeleteNameExpr:
+    case ParseNodeKind::DeletePropExpr:
+    case ParseNodeKind::DeleteElemExpr:
     case ParseNodeKind::DeleteExpr:
-    case ParseNodeKind::Pos:
-    case ParseNodeKind::Neg:
-    case ParseNodeKind::PreIncrement:
-    case ParseNodeKind::PostIncrement:
-    case ParseNodeKind::PreDecrement:
-    case ParseNodeKind::PostDecrement:
-    case ParseNodeKind::Or:
-    case ParseNodeKind::And:
-    case ParseNodeKind::BitOr:
-    case ParseNodeKind::BitXor:
-    case ParseNodeKind::BitAnd:
-    case ParseNodeKind::StrictEq:
-    case ParseNodeKind::Eq:
-    case ParseNodeKind::StrictNe:
-    case ParseNodeKind::Ne:
-    case ParseNodeKind::Lt:
-    case ParseNodeKind::Le:
-    case ParseNodeKind::Gt:
-    case ParseNodeKind::Ge:
-    case ParseNodeKind::InstanceOf:
-    case ParseNodeKind::In:
-    case ParseNodeKind::Lsh:
-    case ParseNodeKind::Rsh:
-    case ParseNodeKind::Ursh:
-    case ParseNodeKind::Add:
-    case ParseNodeKind::Sub:
-    case ParseNodeKind::Star:
-    case ParseNodeKind::Div:
-    case ParseNodeKind::Mod:
-    case ParseNodeKind::Pow:
-    case ParseNodeKind::Assign:
-    case ParseNodeKind::AddAssign:
-    case ParseNodeKind::SubAssign:
-    case ParseNodeKind::BitOrAssign:
-    case ParseNodeKind::BitXorAssign:
-    case ParseNodeKind::BitAndAssign:
-    case ParseNodeKind::LshAssign:
-    case ParseNodeKind::RshAssign:
-    case ParseNodeKind::UrshAssign:
-    case ParseNodeKind::MulAssign:
-    case ParseNodeKind::DivAssign:
-    case ParseNodeKind::ModAssign:
-    case ParseNodeKind::PowAssign:
-    case ParseNodeKind::Comma:
-    case ParseNodeKind::Array:
-    case ParseNodeKind::Object:
-    case ParseNodeKind::PropertyName:
-    case ParseNodeKind::Dot:
-    case ParseNodeKind::Elem:
+    case ParseNodeKind::PosExpr:
+    case ParseNodeKind::NegExpr:
+    case ParseNodeKind::PreIncrementExpr:
+    case ParseNodeKind::PostIncrementExpr:
+    case ParseNodeKind::PreDecrementExpr:
+    case ParseNodeKind::PostDecrementExpr:
+    case ParseNodeKind::OrExpr:
+    case ParseNodeKind::AndExpr:
+    case ParseNodeKind::BitOrExpr:
+    case ParseNodeKind::BitXorExpr:
+    case ParseNodeKind::BitAndExpr:
+    case ParseNodeKind::StrictEqExpr:
+    case ParseNodeKind::EqExpr:
+    case ParseNodeKind::StrictNeExpr:
+    case ParseNodeKind::NeExpr:
+    case ParseNodeKind::LtExpr:
+    case ParseNodeKind::LeExpr:
+    case ParseNodeKind::GtExpr:
+    case ParseNodeKind::GeExpr:
+    case ParseNodeKind::InstanceOfExpr:
+    case ParseNodeKind::InExpr:
+    case ParseNodeKind::LshExpr:
+    case ParseNodeKind::RshExpr:
+    case ParseNodeKind::UrshExpr:
+    case ParseNodeKind::AddExpr:
+    case ParseNodeKind::SubExpr:
+    case ParseNodeKind::MulExpr:
+    case ParseNodeKind::DivExpr:
+    case ParseNodeKind::ModExpr:
+    case ParseNodeKind::PowExpr:
+    case ParseNodeKind::AssignExpr:
+    case ParseNodeKind::AddAssignExpr:
+    case ParseNodeKind::SubAssignExpr:
+    case ParseNodeKind::BitOrAssignExpr:
+    case ParseNodeKind::BitXorAssignExpr:
+    case ParseNodeKind::BitAndAssignExpr:
+    case ParseNodeKind::LshAssignExpr:
+    case ParseNodeKind::RshAssignExpr:
+    case ParseNodeKind::UrshAssignExpr:
+    case ParseNodeKind::MulAssignExpr:
+    case ParseNodeKind::DivAssignExpr:
+    case ParseNodeKind::ModAssignExpr:
+    case ParseNodeKind::PowAssignExpr:
+    case ParseNodeKind::CommaExpr:
+    case ParseNodeKind::ArrayExpr:
+    case ParseNodeKind::ObjectExpr:
+    case ParseNodeKind::PropertyNameExpr:
+    case ParseNodeKind::DotExpr:
+    case ParseNodeKind::ElemExpr:
     case ParseNodeKind::Arguments:
-    case ParseNodeKind::Call:
+    case ParseNodeKind::CallExpr:
     case ParseNodeKind::Name:
     case ParseNodeKind::PrivateName:
-    case ParseNodeKind::TemplateString:
-    case ParseNodeKind::TemplateStringList:
-    case ParseNodeKind::TaggedTemplate:
-    case ParseNodeKind::CallSiteObj:
-    case ParseNodeKind::String:
-    case ParseNodeKind::RegExp:
-    case ParseNodeKind::True:
-    case ParseNodeKind::False:
-    case ParseNodeKind::Null:
-    case ParseNodeKind::RawUndefined:
-    case ParseNodeKind::This:
+    case ParseNodeKind::TemplateStringExpr:
+    case ParseNodeKind::TemplateStringListExpr:
+    case ParseNodeKind::TaggedTemplateExpr:
+    case ParseNodeKind::CallSiteObjExpr:
+    case ParseNodeKind::StringExpr:
+    case ParseNodeKind::RegExpExpr:
+    case ParseNodeKind::TrueExpr:
+    case ParseNodeKind::FalseExpr:
+    case ParseNodeKind::NullExpr:
+    case ParseNodeKind::RawUndefinedExpr:
+    case ParseNodeKind::ThisExpr:
     case ParseNodeKind::Elision:
-    case ParseNodeKind::Number:
+    case ParseNodeKind::NumberExpr:
 #ifdef ENABLE_BIGINT
     case ParseNodeKind::BigInt:
 #endif
-    case ParseNodeKind::New:
+    case ParseNodeKind::NewExpr:
     case ParseNodeKind::Generator:
     case ParseNodeKind::ParamsBody:
     case ParseNodeKind::Catch:
     case ParseNodeKind::ForIn:
     case ParseNodeKind::ForOf:
     case ParseNodeKind::ForHead:
     case ParseNodeKind::ClassMethod:
     case ParseNodeKind::ClassField:
     case ParseNodeKind::ClassMemberList:
     case ParseNodeKind::ClassNames:
-    case ParseNodeKind::NewTarget:
-    case ParseNodeKind::ImportMeta:
+    case ParseNodeKind::NewTargetExpr:
+    case ParseNodeKind::ImportMetaExpr:
     case ParseNodeKind::PosHolder:
-    case ParseNodeKind::SuperCall:
+    case ParseNodeKind::SuperCallExpr:
     case ParseNodeKind::SuperBase:
     case ParseNodeKind::SetThis:
       MOZ_CRASH(
           "ContainsHoistedDeclaration should have indicated false on "
           "some parent node without recurring to test this node");
 
-    case ParseNodeKind::Pipeline:
+    case ParseNodeKind::PipelineExpr:
       MOZ_ASSERT(node->is<ListNode>());
       *result = false;
       return true;
 
     case ParseNodeKind::Limit:  // invalid sentinel value
       MOZ_CRASH("unexpected ParseNodeKind::Limit in node");
   }
 
@@ -423,102 +423,102 @@ restart:
 
 /*
  * Fold from one constant type to another.
  * XXX handles only strings and numbers for now
  */
 static bool FoldType(JSContext* cx, ParseNode* pn, ParseNodeKind kind) {
   if (!pn->isKind(kind)) {
     switch (kind) {
-      case ParseNodeKind::Number:
-        if (pn->isKind(ParseNodeKind::String)) {
+      case ParseNodeKind::NumberExpr:
+        if (pn->isKind(ParseNodeKind::StringExpr)) {
           double d;
           if (!StringToNumber(cx, pn->as<NameNode>().atom(), &d)) {
             return false;
           }
-          pn->setKind(ParseNodeKind::Number);
+          pn->setKind(ParseNodeKind::NumberExpr);
           pn->setOp(JSOP_DOUBLE);
           pn->as<NumericLiteral>().setValue(d);
           pn->as<NumericLiteral>().setDecimalPoint(NoDecimal);
         }
         break;
 
-      case ParseNodeKind::String:
-        if (pn->isKind(ParseNodeKind::Number)) {
+      case ParseNodeKind::StringExpr:
+        if (pn->isKind(ParseNodeKind::NumberExpr)) {
           JSAtom* atom = NumberToAtom(cx, pn->as<NumericLiteral>().value());
           if (!atom) {
             return false;
           }
-          pn->setKind(ParseNodeKind::String);
+          pn->setKind(ParseNodeKind::StringExpr);
           pn->setOp(JSOP_STRING);
           pn->as<NameNode>().setAtom(atom);
           pn->as<NameNode>().setInitializer(nullptr);
         }
         break;
 
       default:
         MOZ_CRASH("Invalid type in constant folding FoldType");
     }
   }
   return true;
 }
 
 static bool IsEffectless(ParseNode* node) {
-  return node->isKind(ParseNodeKind::True) ||
-         node->isKind(ParseNodeKind::False) ||
-         node->isKind(ParseNodeKind::String) ||
-         node->isKind(ParseNodeKind::TemplateString) ||
-         node->isKind(ParseNodeKind::Number) ||
+  return node->isKind(ParseNodeKind::TrueExpr) ||
+         node->isKind(ParseNodeKind::FalseExpr) ||
+         node->isKind(ParseNodeKind::StringExpr) ||
+         node->isKind(ParseNodeKind::TemplateStringExpr) ||
+         node->isKind(ParseNodeKind::NumberExpr) ||
 #ifdef ENABLE_BIGINT
          node->isKind(ParseNodeKind::BigInt) ||
 #endif
-         node->isKind(ParseNodeKind::Null) ||
-         node->isKind(ParseNodeKind::RawUndefined) ||
+         node->isKind(ParseNodeKind::NullExpr) ||
+         node->isKind(ParseNodeKind::RawUndefinedExpr) ||
          node->isKind(ParseNodeKind::Function);
 }
 
 enum Truthiness { Truthy, Falsy, Unknown };
 
 static Truthiness Boolish(ParseNode* pn) {
   switch (pn->getKind()) {
-    case ParseNodeKind::Number:
+    case ParseNodeKind::NumberExpr:
       return (pn->as<NumericLiteral>().value() != 0 &&
               !IsNaN(pn->as<NumericLiteral>().value()))
                  ? Truthy
                  : Falsy;
 
 #ifdef ENABLE_BIGINT
     case ParseNodeKind::BigInt:
       return (pn->as<BigIntLiteral>().box()->value()->toBoolean()) ? Truthy
                                                                    : Falsy;
 #endif
 
-    case ParseNodeKind::String:
-    case ParseNodeKind::TemplateString:
+    case ParseNodeKind::StringExpr:
+    case ParseNodeKind::TemplateStringExpr:
       return (pn->as<NameNode>().atom()->length() > 0) ? Truthy : Falsy;
 
-    case ParseNodeKind::True:
+    case ParseNodeKind::TrueExpr:
     case ParseNodeKind::Function:
       return Truthy;
 
-    case ParseNodeKind::False:
-    case ParseNodeKind::Null:
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::FalseExpr:
+    case ParseNodeKind::NullExpr:
+    case ParseNodeKind::RawUndefinedExpr:
       return Falsy;
 
-    case ParseNodeKind::Void: {
+    case ParseNodeKind::VoidExpr: {
       // |void <foo>| evaluates to |undefined| which isn't truthy.  But the
       // sense of this method requires that the expression be literally
       // replaceable with true/false: not the case if the nested expression
       // is effectful, might throw, &c.  Walk past the |void| (and nested
       // |void| expressions, for good measure) and check that the nested
       // expression doesn't break this requirement before indicating falsity.
       do {
         pn = pn->as<UnaryNode>().kid();
-      } while (pn->isKind(ParseNodeKind::Void));
+      } while (pn->isKind(ParseNodeKind::VoidExpr));
 
       return IsEffectless(pn) ? Falsy : Unknown;
     }
 
     default:
       return Unknown;
   }
 }
@@ -532,154 +532,156 @@ static bool SimplifyCondition(JSContext*
   Truthiness t = Boolish(node);
   if (t != Unknown) {
     // We can turn function nodes into constant nodes here, but mutating
     // function nodes is tricky --- in particular, mutating a function node
     // that appears on a method list corrupts the method list. However,
     // methods are M's in statements of the form 'this.foo = M;', which we
     // never fold, so we're okay.
     if (t == Truthy) {
-      node->setKind(ParseNodeKind::True);
+      node->setKind(ParseNodeKind::TrueExpr);
       node->setOp(JSOP_TRUE);
     } else {
-      node->setKind(ParseNodeKind::False);
+      node->setKind(ParseNodeKind::FalseExpr);
       node->setOp(JSOP_FALSE);
     }
   }
 
   return true;
 }
 
 static bool FoldTypeOfExpr(JSContext* cx, UnaryNode* node) {
   MOZ_ASSERT(node->isKind(ParseNodeKind::TypeOfExpr));
 
   ParseNode* expr = node->kid();
 
   // Constant-fold the entire |typeof| if given a constant with known type.
   RootedPropertyName result(cx);
-  if (expr->isKind(ParseNodeKind::String) ||
-      expr->isKind(ParseNodeKind::TemplateString)) {
+  if (expr->isKind(ParseNodeKind::StringExpr) ||
+      expr->isKind(ParseNodeKind::TemplateStringExpr)) {
     result = cx->names().string;
-  } else if (expr->isKind(ParseNodeKind::Number)) {
+  } else if (expr->isKind(ParseNodeKind::NumberExpr)) {
     result = cx->names().number;
   }
 #ifdef ENABLE_BIGINT
   else if (expr->isKind(ParseNodeKind::BigInt)) {
     result = cx->names().bigint;
   }
 #endif
-  else if (expr->isKind(ParseNodeKind::Null)) {
+  else if (expr->isKind(ParseNodeKind::NullExpr)) {
     result = cx->names().object;
-  } else if (expr->isKind(ParseNodeKind::True) ||
-             expr->isKind(ParseNodeKind::False)) {
+  } else if (expr->isKind(ParseNodeKind::TrueExpr) ||
+             expr->isKind(ParseNodeKind::FalseExpr)) {
     result = cx->names().boolean;
   } else if (expr->isKind(ParseNodeKind::Function)) {
     result = cx->names().function;
   }
 
   if (result) {
-    node->setKind(ParseNodeKind::String);
+    node->setKind(ParseNodeKind::StringExpr);
     node->setOp(JSOP_NOP);
     node->as<NameNode>().setAtom(result);
     node->as<NameNode>().setInitializer(nullptr);
   }
 
   return true;
 }
 
 static bool FoldDeleteExpr(JSContext* cx, UnaryNode* node) {
   MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteExpr));
   ParseNode* expr = node->kid();
 
   // Expression deletion evaluates the expression, then evaluates to true.
   // For effectless expressions, eliminate the expression evaluation.
   if (IsEffectless(expr)) {
-    node->setKind(ParseNodeKind::True);
+    node->setKind(ParseNodeKind::TrueExpr);
     node->setOp(JSOP_TRUE);
   }
 
   return true;
 }
 
 static bool FoldDeleteElement(JSContext* cx, UnaryNode* node) {
-  MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteElem));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteElemExpr));
   ParseNode* expr = node->kid();
 
   // If we're deleting an element, but constant-folding converted our
   // element reference into a dotted property access, we must *also*
   // morph the node's kind.
   //
   // In principle this also applies to |super["foo"] -> super.foo|,
   // but we don't constant-fold |super["foo"]| yet.
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::Elem) ||
-             expr->isKind(ParseNodeKind::Dot));
-  if (expr->isKind(ParseNodeKind::Dot)) {
-    node->setKind(ParseNodeKind::DeleteProp);
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::ElemExpr) ||
+             expr->isKind(ParseNodeKind::DotExpr));
+  if (expr->isKind(ParseNodeKind::DotExpr)) {
+    node->setKind(ParseNodeKind::DeletePropExpr);
   }
 
   return true;
 }
 
 static bool FoldNot(JSContext* cx, UnaryNode* node) {
-  MOZ_ASSERT(node->isKind(ParseNodeKind::Not));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::NotExpr));
 
   if (!SimplifyCondition(cx, node->unsafeKidReference())) {
     return false;
   }
 
   ParseNode* expr = node->kid();
 
-  if (expr->isKind(ParseNodeKind::True) || expr->isKind(ParseNodeKind::False)) {
-    bool newval = !expr->isKind(ParseNodeKind::True);
+  if (expr->isKind(ParseNodeKind::TrueExpr) ||
+      expr->isKind(ParseNodeKind::FalseExpr)) {
+    bool newval = !expr->isKind(ParseNodeKind::TrueExpr);
 
-    node->setKind(newval ? ParseNodeKind::True : ParseNodeKind::False);
+    node->setKind(newval ? ParseNodeKind::TrueExpr : ParseNodeKind::FalseExpr);
     node->setOp(newval ? JSOP_TRUE : JSOP_FALSE);
   }
 
   return true;
 }
 
 static bool FoldUnaryArithmetic(JSContext* cx, UnaryNode* node) {
-  MOZ_ASSERT(node->isKind(ParseNodeKind::BitNot) ||
-                 node->isKind(ParseNodeKind::Pos) ||
-                 node->isKind(ParseNodeKind::Neg),
+  MOZ_ASSERT(node->isKind(ParseNodeKind::BitNotExpr) ||
+                 node->isKind(ParseNodeKind::PosExpr) ||
+                 node->isKind(ParseNodeKind::NegExpr),
              "need a different method for this node kind");
 
   ParseNode* expr = node->kid();
 
-  if (expr->isKind(ParseNodeKind::Number) ||
-      expr->isKind(ParseNodeKind::True) || expr->isKind(ParseNodeKind::False)) {
-    double d = expr->isKind(ParseNodeKind::Number)
+  if (expr->isKind(ParseNodeKind::NumberExpr) ||
+      expr->isKind(ParseNodeKind::TrueExpr) ||
+      expr->isKind(ParseNodeKind::FalseExpr)) {
+    double d = expr->isKind(ParseNodeKind::NumberExpr)
                    ? expr->as<NumericLiteral>().value()
-                   : double(expr->isKind(ParseNodeKind::True));
+                   : double(expr->isKind(ParseNodeKind::TrueExpr));
 
-    if (node->isKind(ParseNodeKind::BitNot)) {
+    if (node->isKind(ParseNodeKind::BitNotExpr)) {
       d = ~ToInt32(d);
-    } else if (node->isKind(ParseNodeKind::Neg)) {
+    } else if (node->isKind(ParseNodeKind::NegExpr)) {
       d = -d;
     } else {
-      MOZ_ASSERT(node->isKind(ParseNodeKind::Pos));  // nothing to do
+      MOZ_ASSERT(node->isKind(ParseNodeKind::PosExpr));  // nothing to do
     }
 
-    node->setKind(ParseNodeKind::Number);
+    node->setKind(ParseNodeKind::NumberExpr);
     node->setOp(JSOP_DOUBLE);
     node->as<NumericLiteral>().setValue(d);
     node->as<NumericLiteral>().setDecimalPoint(NoDecimal);
   }
 
   return true;
 }
 
 static bool FoldAndOr(JSContext* cx, ParseNode** nodePtr) {
   ListNode* node = &(*nodePtr)->as<ListNode>();
 
-  MOZ_ASSERT(node->isKind(ParseNodeKind::And) ||
-             node->isKind(ParseNodeKind::Or));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::AndExpr) ||
+             node->isKind(ParseNodeKind::OrExpr));
 
-  bool isOrNode = node->isKind(ParseNodeKind::Or);
+  bool isOrNode = node->isKind(ParseNodeKind::OrExpr);
   ParseNode** elem = node->unsafeHeadReference();
   do {
     Truthiness t = Boolish(*elem);
 
     // If we don't know the constant-folded node's truthiness, we can't
     // reduce this node with its surroundings.  Continue folding any
     // remaining nodes.
     if (t == Unknown) {
@@ -741,17 +743,17 @@ static bool FoldConditional(JSContext* c
   do {
     // |nextNode| on entry points to the C?T:F expression to be folded.
     // Reset it to exit the loop in the common case where F isn't another
     // ?: expression.
     nodePtr = nextNode;
     nextNode = nullptr;
 
     TernaryNode* node = &(*nodePtr)->as<TernaryNode>();
-    MOZ_ASSERT(node->isKind(ParseNodeKind::Conditional));
+    MOZ_ASSERT(node->isKind(ParseNodeKind::ConditionalExpr));
 
     ParseNode** expr = node->unsafeKid1Reference();
     if (!Fold(cx, expr)) {
       return false;
     }
     if (!SimplifyCondition(cx, expr)) {
       return false;
     }
@@ -765,17 +767,17 @@ static bool FoldConditional(JSContext* c
 
     // If our C?T:F node has F as another ?: node, *iteratively* constant-
     // fold F *after* folding C and T (and possibly eliminating C and one
     // of T/F entirely); otherwise fold F normally.  Making |nextNode| non-
     // null causes this loop to run again to fold F.
     //
     // Conceivably we could instead/also iteratively constant-fold T, if T
     // were more complex than F.  Such an optimization is unimplemented.
-    if ((*ifFalsy)->isKind(ParseNodeKind::Conditional)) {
+    if ((*ifFalsy)->isKind(ParseNodeKind::ConditionalExpr)) {
       MOZ_ASSERT((*ifFalsy)->is<TernaryNode>());
       nextNode = ifFalsy;
     } else {
       if (!Fold(cx, ifFalsy)) {
         return false;
       }
     }
 
@@ -805,17 +807,17 @@ static bool FoldIf(JSContext* cx, ParseN
 
   do {
     // |nextNode| on entry points to the initial |if| to be folded.  Reset
     // it to exit the loop when the |else| arm isn't another |if|.
     nodePtr = nextNode;
     nextNode = nullptr;
 
     TernaryNode* node = &(*nodePtr)->as<TernaryNode>();
-    MOZ_ASSERT(node->isKind(ParseNodeKind::If));
+    MOZ_ASSERT(node->isKind(ParseNodeKind::IfStmt));
 
     ParseNode** expr = node->unsafeKid1Reference();
     if (!Fold(cx, expr)) {
       return false;
     }
     if (!SimplifyCondition(cx, expr)) {
       return false;
     }
@@ -827,17 +829,17 @@ static bool FoldIf(JSContext* cx, ParseN
 
     ParseNode** alternative = node->unsafeKid3Reference();
     if (*alternative) {
       // If in |if (C) T; else F;| we have |F| as another |if|,
       // *iteratively* constant-fold |F| *after* folding |C| and |T| (and
       // possibly completely replacing the whole thing with |T| or |F|);
       // otherwise fold F normally.  Making |nextNode| non-null causes
       // this loop to run again to fold F.
-      if ((*alternative)->isKind(ParseNodeKind::If)) {
+      if ((*alternative)->isKind(ParseNodeKind::IfStmt)) {
         MOZ_ASSERT((*alternative)->is<TernaryNode>());
         nextNode = alternative;
       } else {
         if (!Fold(cx, alternative)) {
           return false;
         }
       }
     }
@@ -893,115 +895,117 @@ static bool FoldIf(JSContext* cx, ParseN
       ReplaceNode(nodePtr, replacement);
     }
   } while (nextNode);
 
   return true;
 }
 
 static double ComputeBinary(ParseNodeKind kind, double left, double right) {
-  if (kind == ParseNodeKind::Add) {
+  if (kind == ParseNodeKind::AddExpr) {
     return left + right;
   }
 
-  if (kind == ParseNodeKind::Sub) {
+  if (kind == ParseNodeKind::SubExpr) {
     return left - right;
   }
 
-  if (kind == ParseNodeKind::Star) {
+  if (kind == ParseNodeKind::MulExpr) {
     return left * right;
   }
 
-  if (kind == ParseNodeKind::Mod) {
+  if (kind == ParseNodeKind::ModExpr) {
     return NumberMod(left, right);
   }
 
-  if (kind == ParseNodeKind::Ursh) {
+  if (kind == ParseNodeKind::UrshExpr) {
     return ToUint32(left) >> (ToUint32(right) & 31);
   }
 
-  if (kind == ParseNodeKind::Div) {
+  if (kind == ParseNodeKind::DivExpr) {
     return NumberDiv(left, right);
   }
 
-  MOZ_ASSERT(kind == ParseNodeKind::Lsh || kind == ParseNodeKind::Rsh);
+  MOZ_ASSERT(kind == ParseNodeKind::LshExpr || kind == ParseNodeKind::RshExpr);
 
   int32_t i = ToInt32(left);
   uint32_t j = ToUint32(right) & 31;
-  return int32_t((kind == ParseNodeKind::Lsh) ? uint32_t(i) << j : i >> j);
+  return int32_t((kind == ParseNodeKind::LshExpr) ? uint32_t(i) << j : i >> j);
 }
 
 static bool FoldBinaryArithmetic(JSContext* cx, ListNode* node) {
-  MOZ_ASSERT(
-      node->isKind(ParseNodeKind::Sub) || node->isKind(ParseNodeKind::Star) ||
-      node->isKind(ParseNodeKind::Lsh) || node->isKind(ParseNodeKind::Rsh) ||
-      node->isKind(ParseNodeKind::Ursh) || node->isKind(ParseNodeKind::Div) ||
-      node->isKind(ParseNodeKind::Mod));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::SubExpr) ||
+             node->isKind(ParseNodeKind::MulExpr) ||
+             node->isKind(ParseNodeKind::LshExpr) ||
+             node->isKind(ParseNodeKind::RshExpr) ||
+             node->isKind(ParseNodeKind::UrshExpr) ||
+             node->isKind(ParseNodeKind::DivExpr) ||
+             node->isKind(ParseNodeKind::ModExpr));
   MOZ_ASSERT(node->count() >= 2);
 
   // Fold each operand to a number if possible.
   ParseNode** listp = node->unsafeHeadReference();
   for (; *listp; listp = &(*listp)->pn_next) {
-    if (!FoldType(cx, *listp, ParseNodeKind::Number)) {
+    if (!FoldType(cx, *listp, ParseNodeKind::NumberExpr)) {
       return false;
     }
   }
   node->unsafeReplaceTail(listp);
 
   // Now fold all leading numeric terms together into a single number.
   // (Trailing terms for the non-shift operations can't be folded together
   // due to floating point imprecision.  For example, if |x === -2**53|,
   // |x - 1 - 1 === -2**53| but |x - 2 === -2**53 - 2|.  Shifts could be
   // folded, but it doesn't seem worth the effort.)
   ParseNode* elem = node->head();
   ParseNode* next = elem->pn_next;
-  if (elem->isKind(ParseNodeKind::Number)) {
+  if (elem->isKind(ParseNodeKind::NumberExpr)) {
     ParseNodeKind kind = node->getKind();
     while (true) {
-      if (!next || !next->isKind(ParseNodeKind::Number)) {
+      if (!next || !next->isKind(ParseNodeKind::NumberExpr)) {
         break;
       }
 
       double d = ComputeBinary(kind, elem->as<NumericLiteral>().value(),
                                next->as<NumericLiteral>().value());
 
       next = next->pn_next;
       elem->pn_next = next;
 
-      elem->setKind(ParseNodeKind::Number);
+      elem->setKind(ParseNodeKind::NumberExpr);
       elem->setOp(JSOP_DOUBLE);
       elem->as<NumericLiteral>().setValue(d);
       elem->as<NumericLiteral>().setDecimalPoint(NoDecimal);
 
       node->unsafeDecrementCount();
     }
 
     if (node->count() == 1) {
       MOZ_ASSERT(node->head() == elem);
-      MOZ_ASSERT(elem->isKind(ParseNodeKind::Number));
+      MOZ_ASSERT(elem->isKind(ParseNodeKind::NumberExpr));
 
       double d = elem->as<NumericLiteral>().value();
-      node->setKind(ParseNodeKind::Number);
+      node->setKind(ParseNodeKind::NumberExpr);
       node->setOp(JSOP_DOUBLE);
       node->as<NumericLiteral>().setValue(d);
       node->as<NumericLiteral>().setDecimalPoint(NoDecimal);
     }
   }
 
   return true;
 }
 
 static bool FoldExponentiation(JSContext* cx, ListNode* node) {
-  MOZ_ASSERT(node->isKind(ParseNodeKind::Pow));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::PowExpr));
   MOZ_ASSERT(node->count() >= 2);
 
   // Fold each operand, ideally into a number.
   ParseNode** listp = node->unsafeHeadReference();
   for (; *listp; listp = &(*listp)->pn_next) {
-    if (!FoldType(cx, *listp, ParseNodeKind::Number)) {
+    if (!FoldType(cx, *listp, ParseNodeKind::NumberExpr)) {
       return false;
     }
   }
 
   node->unsafeReplaceTail(listp);
 
   // Unlike all other binary arithmetic operators, ** is right-associative:
   // 2**3**5 is 2**(3**5), not (2**3)**5.  As list nodes singly-link their
@@ -1009,52 +1013,52 @@ static bool FoldExponentiation(JSContext
   // in-place linked list reversal.  So we only fold one exponentiation: it's
   // easy and addresses common cases like |2**32|.
   if (node->count() > 2) {
     return true;
   }
 
   ParseNode* base = node->head();
   ParseNode* exponent = base->pn_next;
-  if (!base->isKind(ParseNodeKind::Number) ||
-      !exponent->isKind(ParseNodeKind::Number)) {
+  if (!base->isKind(ParseNodeKind::NumberExpr) ||
+      !exponent->isKind(ParseNodeKind::NumberExpr)) {
     return true;
   }
 
   double d1 = base->as<NumericLiteral>().value();
   double d2 = exponent->as<NumericLiteral>().value();
 
-  node->setKind(ParseNodeKind::Number);
+  node->setKind(ParseNodeKind::NumberExpr);
   node->setOp(JSOP_DOUBLE);
   node->as<NumericLiteral>().setValue(ecmaPow(d1, d2));
   node->as<NumericLiteral>().setDecimalPoint(NoDecimal);
   return true;
 }
 
 static bool FoldElement(JSContext* cx, ParseNode** nodePtr) {
   PropertyByValue* elem = &(*nodePtr)->as<PropertyByValue>();
 
   ParseNode* expr = &elem->expression();
   ParseNode* key = &elem->key();
   PropertyName* name = nullptr;
-  if (key->isKind(ParseNodeKind::String)) {
+  if (key->isKind(ParseNodeKind::StringExpr)) {
     JSAtom* atom = key->as<NameNode>().atom();
     uint32_t index;
 
     if (atom->isIndex(&index)) {
       // Optimization 1: We have something like expr["100"]. This is
       // equivalent to expr[100] which is faster.
-      key->setKind(ParseNodeKind::Number);
+      key->setKind(ParseNodeKind::NumberExpr);
       key->setOp(JSOP_DOUBLE);
       key->as<NumericLiteral>().setValue(index);
       key->as<NumericLiteral>().setDecimalPoint(NoDecimal);
     } else {
       name = atom->asPropertyName();
     }
-  } else if (key->isKind(ParseNodeKind::Number)) {
+  } else if (key->isKind(ParseNodeKind::NumberExpr)) {
     double number = key->as<NumericLiteral>().value();
     if (number != ToUint32(number)) {
       // Optimization 2: We have something like expr[3.14]. The number
       // isn't an array index, so it converts to a string ("3.14"),
       // enabling optimization 3 below.
       JSAtom* atom = NumberToAtom(cx, number);
       if (!atom) {
         return false;
@@ -1065,47 +1069,47 @@ static bool FoldElement(JSContext* cx, P
 
   // If we don't have a name, we can't optimize to getprop.
   if (!name) {
     return true;
   }
 
   // Optimization 3: We have expr["foo"] where foo is not an index.  Convert
   // to a property access (like expr.foo) that optimizes better downstream.
-  key->setKind(ParseNodeKind::PropertyName);
+  key->setKind(ParseNodeKind::PropertyNameExpr);
   key->setOp(JSOP_NOP);
   key->as<NameNode>().setAtom(name);
   key->as<NameNode>().setInitializer(nullptr);
 
-  (*nodePtr)->setKind(ParseNodeKind::Dot);
+  (*nodePtr)->setKind(ParseNodeKind::DotExpr);
   (*nodePtr)->setOp(JSOP_NOP);
   *(*nodePtr)->as<PropertyAccess>().unsafeLeftReference() = expr;
   *(*nodePtr)->as<PropertyAccess>().unsafeRightReference() = key;
   (*nodePtr)->as<PropertyAccess>().setInParens(elem->isInParens());
 
   return true;
 }
 
 static bool FoldAdd(JSContext* cx, ParseNode** nodePtr) {
   ListNode* node = &(*nodePtr)->as<ListNode>();
 
-  MOZ_ASSERT(node->isKind(ParseNodeKind::Add));
+  MOZ_ASSERT(node->isKind(ParseNodeKind::AddExpr));
   MOZ_ASSERT(node->count() >= 2);
 
   // Fold leading numeric operands together:
   //
   //   (1 + 2 + x)  becomes  (3 + x)
   //
   // Don't go past the leading operands: additions after a string are
   // string concatenations, not additions: ("1" + 2 + 3 === "123").
   ParseNode* current = node->head();
   ParseNode* next = current->pn_next;
-  if (current->isKind(ParseNodeKind::Number)) {
+  if (current->isKind(ParseNodeKind::NumberExpr)) {
     do {
-      if (!next->isKind(ParseNodeKind::Number)) {
+      if (!next->isKind(ParseNodeKind::NumberExpr)) {
         break;
       }
 
       NumericLiteral* num = &current->as<NumericLiteral>();
 
       num->setValue(num->value() + next->as<NumericLiteral>().value());
       current->pn_next = next->pn_next;
       next = current->pn_next;
@@ -1118,28 +1122,28 @@ static bool FoldAdd(JSContext* cx, Parse
   do {
     // If no operands remain, we're done.
     if (!next) {
       break;
     }
 
     // (number + string) is string concatenation *only* at the start of
     // the list: (x + 1 + "2" !== x + "12") when x is a number.
-    if (current->isKind(ParseNodeKind::Number) &&
-        next->isKind(ParseNodeKind::String)) {
-      if (!FoldType(cx, current, ParseNodeKind::String)) {
+    if (current->isKind(ParseNodeKind::NumberExpr) &&
+        next->isKind(ParseNodeKind::StringExpr)) {
+      if (!FoldType(cx, current, ParseNodeKind::StringExpr)) {
         return false;
       }
       next = current->pn_next;
     }
 
     // The first string forces all subsequent additions to be
     // string concatenations.
     do {
-      if (current->isKind(ParseNodeKind::String)) {
+      if (current->isKind(ParseNodeKind::StringExpr)) {
         break;
       }
 
       current = next;
       next = next->pn_next;
     } while (next);
 
     // If there's nothing left to fold, we're done.
@@ -1148,28 +1152,28 @@ static bool FoldAdd(JSContext* cx, Parse
     }
 
     RootedString combination(cx);
     RootedString tmp(cx);
     do {
       // Create a rope of the current string and all succeeding
       // constants that we can convert to strings, then atomize it
       // and replace them all with that fresh string.
-      MOZ_ASSERT(current->isKind(ParseNodeKind::String));
+      MOZ_ASSERT(current->isKind(ParseNodeKind::StringExpr));
 
       combination = current->as<NameNode>().atom();
 
       do {
         // Try folding the next operand to a string.
-        if (!FoldType(cx, next, ParseNodeKind::String)) {
+        if (!FoldType(cx, next, ParseNodeKind::StringExpr)) {
           return false;
         }
 
         // Stop glomming once folding doesn't produce a string.
-        if (!next->isKind(ParseNodeKind::String)) {
+        if (!next->isKind(ParseNodeKind::StringExpr)) {
           break;
         }
 
         // Add this string to the combination and remove the node.
         tmp = next->as<NameNode>().atom();
         combination = ConcatStrings<CanGC>(cx, combination, tmp);
         if (!combination) {
           return false;
@@ -1177,17 +1181,17 @@ static bool FoldAdd(JSContext* cx, Parse
 
         next = next->pn_next;
         current->pn_next = next;
 
         node->unsafeDecrementCount();
       } while (next);
 
       // Replace |current|'s string with the entire combination.
-      MOZ_ASSERT(current->isKind(ParseNodeKind::String));
+      MOZ_ASSERT(current->isKind(ParseNodeKind::StringExpr));
       combination = AtomizeString(cx, combination);
       if (!combination) {
         return false;
       }
       current->as<NameNode>().setAtom(&combination->asAtom());
 
       // If we're out of nodes, we're done.
       if (!next) {
@@ -1203,21 +1207,21 @@ static bool FoldAdd(JSContext* cx, Parse
         break;
       }
 
       // Otherwise find the next node foldable to a string, and loop.
       do {
         current = next;
         next = current->pn_next;
 
-        if (!FoldType(cx, current, ParseNodeKind::String)) {
+        if (!FoldType(cx, current, ParseNodeKind::StringExpr)) {
           return false;
         }
         next = current->pn_next;
-      } while (!current->isKind(ParseNodeKind::String) && next);
+      } while (!current->isKind(ParseNodeKind::StringExpr) && next);
     } while (next);
   } while (false);
 
   MOZ_ASSERT(!next, "must have considered all nodes here");
   MOZ_ASSERT(!current->pn_next, "current node must be the last node");
 
   node->unsafeReplaceTail(&current->pn_next);
 
@@ -1231,110 +1235,120 @@ static bool FoldAdd(JSContext* cx, Parse
 }
 
 class FoldVisitor : public ParseNodeVisitor<FoldVisitor> {
   using Base = ParseNodeVisitor;
 
  public:
   explicit FoldVisitor(JSContext* cx) : ParseNodeVisitor(cx) {}
 
-  bool visitElem(ParseNode*& pn) {
-    return Base::visitElem(pn) && FoldElement(cx, &pn);
+  bool visitElemExpr(ParseNode*& pn) {
+    return Base::visitElemExpr(pn) && FoldElement(cx, &pn);
   }
 
   bool visitTypeOfExpr(ParseNode*& pn) {
     return Base::visitTypeOfExpr(pn) &&
            FoldTypeOfExpr(cx, &pn->as<UnaryNode>());
   }
 
   bool visitDeleteExpr(ParseNode*& pn) {
     return Base::visitDeleteExpr(pn) &&
            FoldDeleteExpr(cx, &pn->as<UnaryNode>());
   }
 
-  bool visitDeleteElem(ParseNode*& pn) {
-    return Base::visitDeleteElem(pn) &&
+  bool visitDeleteElemExpr(ParseNode*& pn) {
+    return Base::visitDeleteElemExpr(pn) &&
            FoldDeleteElement(cx, &pn->as<UnaryNode>());
   }
 
-  bool visitNot(ParseNode*& pn) {
-    return Base::visitNot(pn) && FoldNot(cx, &pn->as<UnaryNode>());
+  bool visitNotExpr(ParseNode*& pn) {
+    return Base::visitNotExpr(pn) && FoldNot(cx, &pn->as<UnaryNode>());
   }
 
-  bool visitBitNot(ParseNode*& pn) {
-    return Base::visitBitNot(pn) &&
+  bool visitBitNotExpr(ParseNode*& pn) {
+    return Base::visitBitNotExpr(pn) &&
+           FoldUnaryArithmetic(cx, &pn->as<UnaryNode>());
+  }
+
+  bool visitPosExpr(ParseNode*& pn) {
+    return Base::visitPosExpr(pn) &&
+           FoldUnaryArithmetic(cx, &pn->as<UnaryNode>());
+  }
+
+  bool visitNegExpr(ParseNode*& pn) {
+    return Base::visitNegExpr(pn) &&
            FoldUnaryArithmetic(cx, &pn->as<UnaryNode>());
   }
 
-  bool visitPos(ParseNode*& pn) {
-    return Base::visitPos(pn) && FoldUnaryArithmetic(cx, &pn->as<UnaryNode>());
+  bool visitPowExpr(ParseNode*& pn) {
+    return Base::visitPowExpr(pn) &&
+           FoldExponentiation(cx, &pn->as<ListNode>());
   }
 
-  bool visitNeg(ParseNode*& pn) {
-    return Base::visitNeg(pn) && FoldUnaryArithmetic(cx, &pn->as<UnaryNode>());
-  }
-
-  bool visitPow(ParseNode*& pn) {
-    return Base::visitPow(pn) && FoldExponentiation(cx, &pn->as<ListNode>());
+  bool visitMulExpr(ParseNode*& pn) {
+    return Base::visitMulExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitStar(ParseNode*& pn) {
-    return Base::visitStar(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
+  bool visitDivExpr(ParseNode*& pn) {
+    return Base::visitDivExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitDiv(ParseNode*& pn) {
-    return Base::visitDiv(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
+  bool visitModExpr(ParseNode*& pn) {
+    return Base::visitModExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitMod(ParseNode*& pn) {
-    return Base::visitMod(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
-  }
-
-  bool visitAdd(ParseNode*& pn) {
-    return Base::visitAdd(pn) && FoldAdd(cx, &pn);
+  bool visitAddExpr(ParseNode*& pn) {
+    return Base::visitAddExpr(pn) && FoldAdd(cx, &pn);
   }
 
-  bool visitSub(ParseNode*& pn) {
-    return Base::visitSub(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
+  bool visitSubExpr(ParseNode*& pn) {
+    return Base::visitSubExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitLsh(ParseNode*& pn) {
-    return Base::visitLsh(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
+  bool visitLshExpr(ParseNode*& pn) {
+    return Base::visitLshExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitRsh(ParseNode*& pn) {
-    return Base::visitRsh(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
+  bool visitRshExpr(ParseNode*& pn) {
+    return Base::visitRshExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitUrsh(ParseNode*& pn) {
-    return Base::visitUrsh(pn) && FoldBinaryArithmetic(cx, &pn->as<ListNode>());
+  bool visitUrshExpr(ParseNode*& pn) {
+    return Base::visitUrshExpr(pn) &&
+           FoldBinaryArithmetic(cx, &pn->as<ListNode>());
   }
 
-  bool visitAnd(ParseNode*& pn) {
+  bool visitAndExpr(ParseNode*& pn) {
     // Note that this does result in the unfortunate fact that dead arms of this
     // node get constant folded. The same goes for visitOr.
-    return Base::visitAnd(pn) && FoldAndOr(cx, &pn);
+    return Base::visitAndExpr(pn) && FoldAndOr(cx, &pn);
   }
 
-  bool visitOr(ParseNode*& pn) {
-    return Base::visitOr(pn) && FoldAndOr(cx, &pn);
+  bool visitOrExpr(ParseNode*& pn) {
+    return Base::visitOrExpr(pn) && FoldAndOr(cx, &pn);
   }
 
-  bool visitConditional(ParseNode*& pn) {
+  bool visitConditionalExpr(ParseNode*& pn) {
     // Don't call base-class visitConditional because FoldConditional processes
     // pn's child nodes specially to save stack space.
     return FoldConditional(cx, &pn);
   }
 
  private:
   bool internalVisitCall(BinaryNode* node) {
-    MOZ_ASSERT(node->isKind(ParseNodeKind::Call) ||
-               node->isKind(ParseNodeKind::SuperCall) ||
-               node->isKind(ParseNodeKind::New) ||
-               node->isKind(ParseNodeKind::TaggedTemplate));
+    MOZ_ASSERT(node->isKind(ParseNodeKind::CallExpr) ||
+               node->isKind(ParseNodeKind::SuperCallExpr) ||
+               node->isKind(ParseNodeKind::NewExpr) ||
+               node->isKind(ParseNodeKind::TaggedTemplateExpr));
 
     // Don't fold a parenthesized callable component in an invocation, as this
     // might cause a different |this| value to be used, changing semantics:
     //
     //   var prop = "global";
     //   var obj = { prop: "obj", f: function() { return this.prop; } };
     //   assertEq((true ? obj.f : null)(), "global");
     //   assertEq(obj.f(), "obj");
@@ -1342,84 +1356,84 @@ class FoldVisitor : public ParseNodeVisi
     //   assertEq(obj.f``, "obj");
     //
     // As an exception to this, we do allow folding the function in
     // `(function() { ... })()` (the module pattern), because that lets us
     // constant fold code inside that function.
     //
     // See bug 537673 and bug 1182373.
     ParseNode* callee = node->left();
-    if (node->isKind(ParseNodeKind::New) || !callee->isInParens() ||
+    if (node->isKind(ParseNodeKind::NewExpr) || !callee->isInParens() ||
         callee->isKind(ParseNodeKind::Function)) {
       if (!visit(*node->unsafeLeftReference())) {
         return false;
       }
     }
 
     if (!visit(*node->unsafeRightReference())) {
       return false;
     }
 
     return true;
   }
 
  public:
-  bool visitCall(ParseNode*& pn) {
+  bool visitCallExpr(ParseNode*& pn) {
     return internalVisitCall(&pn->as<BinaryNode>());
   }
 
-  bool visitNew(ParseNode*& pn) {
+  bool visitNewExpr(ParseNode*& pn) {
     return internalVisitCall(&pn->as<BinaryNode>());
   }
 
-  bool visitSuperCall(ParseNode*& pn) {
+  bool visitSuperCallExpr(ParseNode*& pn) {
     return internalVisitCall(&pn->as<BinaryNode>());
   }
 
-  bool visitTaggedTemplate(ParseNode*& pn) {
+  bool visitTaggedTemplateExpr(ParseNode*& pn) {
     return internalVisitCall(&pn->as<BinaryNode>());
   }
 
-  bool visitIf(ParseNode*& pn) {
+  bool visitIfStmt(ParseNode*& pn) {
     // Don't call base-class visitIf because FoldIf processes pn's child nodes
     // specially to save stack space.
     return FoldIf(cx, &pn);
   }
 
-  bool visitFor(ParseNode*& pn) {
-    if (!Base::visitFor(pn)) {
+  bool visitForStmt(ParseNode*& pn) {
+    if (!Base::visitForStmt(pn)) {
       return false;
     }
 
     ForNode& stmt = pn->as<ForNode>();
     if (stmt.left()->isKind(ParseNodeKind::ForHead)) {
       TernaryNode& head = stmt.left()->as<TernaryNode>();
       ParseNode** test = head.unsafeKid2Reference();
       if (*test) {
         if (!SimplifyCondition(cx, test)) {
           return false;
         }
-        if ((*test)->isKind(ParseNodeKind::True)) {
+        if ((*test)->isKind(ParseNodeKind::TrueExpr)) {
           *test = nullptr;
         }
       }
     }
 
     return true;
   }
 
-  bool visitWhile(ParseNode*& pn) {
+  bool visitWhileStmt(ParseNode*& pn) {
     BinaryNode& node = pn->as<BinaryNode>();
-    return Base::visitWhile(pn) &&
+    return Base::visitWhileStmt(pn) &&
            SimplifyCondition(cx, node.unsafeLeftReference());
   }
 
-  bool visitDoWhile(ParseNode*& pn) {
+  bool visitDoWhileStmt(ParseNode*& pn) {
     BinaryNode& node = pn->as<BinaryNode>();
-    return Base::visitDoWhile(pn) &&
+    return Base::visitDoWhileStmt(pn) &&
            SimplifyCondition(cx, node.unsafeRightReference());
   }
 
   bool visitFunction(ParseNode*& pn) {
     CodeNode& node = pn->as<CodeNode>();
 
     // Don't constant-fold inside "use asm" code, as this could create a parse
     // tree that doesn't type-check as asm.js.
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -61,37 +61,37 @@ class FullParseHandler {
 #define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
   using longTypeName = typeName*;
   FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
 #undef DECLARE_TYPE
 
   using NullNode = std::nullptr_t;
 
   bool isPropertyAccess(Node node) {
-    return node->isKind(ParseNodeKind::Dot) ||
-           node->isKind(ParseNodeKind::Elem);
+    return node->isKind(ParseNodeKind::DotExpr) ||
+           node->isKind(ParseNodeKind::ElemExpr);
   }
 
   bool isFunctionCall(Node node) {
     // Note: super() is a special form, *not* a function call.
-    return node->isKind(ParseNodeKind::Call);
+    return node->isKind(ParseNodeKind::CallExpr);
   }
 
   static bool isUnparenthesizedDestructuringPattern(Node node) {
-    return !node->isInParens() && (node->isKind(ParseNodeKind::Object) ||
-                                   node->isKind(ParseNodeKind::Array));
+    return !node->isInParens() && (node->isKind(ParseNodeKind::ObjectExpr) ||
+                                   node->isKind(ParseNodeKind::ArrayExpr));
   }
 
   static bool isParenthesizedDestructuringPattern(Node node) {
     // Technically this isn't a destructuring pattern at all -- the grammar
     // doesn't treat it as such.  But we need to know when this happens to
     // consider it a SyntaxError rather than an invalid-left-hand-side
     // ReferenceError.
-    return node->isInParens() && (node->isKind(ParseNodeKind::Object) ||
-                                  node->isKind(ParseNodeKind::Array));
+    return node->isInParens() && (node->isKind(ParseNodeKind::ObjectExpr) ||
+                                  node->isKind(ParseNodeKind::ArrayExpr));
   }
 
   FullParseHandler(JSContext* cx, LifoAlloc& alloc,
                    LazyScript* lazyOuterFunction,
                    SourceKind kind = SourceKind::Text)
       : allocator(cx, alloc),
         lazyOuterFunction_(cx, lazyOuterFunction),
         lazyInnerFunctionIndex(0),
@@ -145,21 +145,22 @@ class FullParseHandler {
   }
 #endif
 
   BooleanLiteralType newBooleanLiteral(bool cond, const TokenPos& pos) {
     return new_<BooleanLiteral>(cond, pos);
   }
 
   NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) {
-    return new_<NameNode>(ParseNodeKind::String, JSOP_NOP, atom, pos);
+    return new_<NameNode>(ParseNodeKind::StringExpr, JSOP_NOP, atom, pos);
   }
 
   NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
-    return new_<NameNode>(ParseNodeKind::TemplateString, JSOP_NOP, atom, pos);
+    return new_<NameNode>(ParseNodeKind::TemplateStringExpr, JSOP_NOP, atom,
+                          pos);
   }
 
   CallSiteNodeType newCallSiteObject(uint32_t begin) {
     CallSiteNode* callSiteObj = new_<CallSiteNode>(begin);
     if (!callSiteObj) {
       return null();
     }
 
@@ -170,17 +171,17 @@ class FullParseHandler {
 
     addArrayElement(callSiteObj, rawNodes);
 
     return callSiteObj;
   }
 
   void addToCallSiteObject(CallSiteNodeType callSiteObj, Node rawNode,
                            Node cookedNode) {
-    MOZ_ASSERT(callSiteObj->isKind(ParseNodeKind::CallSiteObj));
+    MOZ_ASSERT(callSiteObj->isKind(ParseNodeKind::CallSiteObjExpr));
 
     addArrayElement(callSiteObj, cookedNode);
     addArrayElement(callSiteObj->rawNodes(), rawNode);
 
     /*
      * We don't know when the last noSubstTemplate will come in, and we
      * don't want to deal with this outside this method
      */
@@ -215,33 +216,33 @@ class FullParseHandler {
   ConditionalExpressionType newConditional(Node cond, Node thenExpr,
                                            Node elseExpr) {
     return new_<ConditionalExpression>(cond, thenExpr, elseExpr);
   }
 
   UnaryNodeType newDelete(uint32_t begin, Node expr) {
     if (expr->isKind(ParseNodeKind::Name)) {
       expr->setOp(JSOP_DELNAME);
-      return newUnary(ParseNodeKind::DeleteName, begin, expr);
+      return newUnary(ParseNodeKind::DeleteNameExpr, begin, expr);
     }
 
-    if (expr->isKind(ParseNodeKind::Dot)) {
-      return newUnary(ParseNodeKind::DeleteProp, begin, expr);
+    if (expr->isKind(ParseNodeKind::DotExpr)) {
+      return newUnary(ParseNodeKind::DeletePropExpr, begin, expr);
     }
 
-    if (expr->isKind(ParseNodeKind::Elem)) {
-      return newUnary(ParseNodeKind::DeleteElem, begin, expr);
+    if (expr->isKind(ParseNodeKind::ElemExpr)) {
+      return newUnary(ParseNodeKind::DeleteElemExpr, begin, expr);
     }
 
     return newUnary(ParseNodeKind::DeleteExpr, begin, expr);
   }
 
   UnaryNodeType newTypeof(uint32_t begin, Node kid) {
     ParseNodeKind pnk = kid->isKind(ParseNodeKind::Name)
-                            ? ParseNodeKind::TypeOfName
+                            ? ParseNodeKind::TypeOfNameExpr
                             : ParseNodeKind::TypeOfExpr;
     return newUnary(pnk, begin, kid);
   }
 
   UnaryNodeType newUnary(ParseNodeKind kind, uint32_t begin, Node kid) {
     TokenPos pos(begin, kid->pn_pos.end);
     return new_<UnaryNode>(kind, pos, kid);
   }
@@ -267,35 +268,35 @@ class FullParseHandler {
   Node appendOrCreateList(ParseNodeKind kind, Node left, Node right,
                           ParseContext* pc) {
     return ParseNode::appendOrCreateList(kind, left, right, this, pc);
   }
 
   // Expressions
 
   ListNodeType newArrayLiteral(uint32_t begin) {
-    return new_<ListNode>(ParseNodeKind::Array, TokenPos(begin, begin + 1));
+    return new_<ListNode>(ParseNodeKind::ArrayExpr, TokenPos(begin, begin + 1));
   }
 
   MOZ_MUST_USE bool addElision(ListNodeType literal, const TokenPos& pos) {
-    MOZ_ASSERT(literal->isKind(ParseNodeKind::Array));
+    MOZ_ASSERT(literal->isKind(ParseNodeKind::ArrayExpr));
 
     NullaryNode* elision = new_<NullaryNode>(ParseNodeKind::Elision, pos);
     if (!elision) {
       return false;
     }
     addList(/* list = */ literal, /* kid = */ elision);
     literal->setHasArrayHoleOrSpread();
     literal->setHasNonConstInitializer();
     return true;
   }
 
   MOZ_MUST_USE bool addSpreadElement(ListNodeType literal, uint32_t begin,
                                      Node inner) {
-    MOZ_ASSERT(literal->isKind(ParseNodeKind::Array));
+    MOZ_ASSERT(literal->isKind(ParseNodeKind::ArrayExpr));
 
     ParseNode* spread = newSpread(begin, inner);
     if (!spread) {
       return false;
     }
     addList(/* list = */ literal, /* kid = */ spread);
     literal->setHasArrayHoleOrSpread();
     literal->setHasNonConstInitializer();
@@ -305,62 +306,63 @@ class FullParseHandler {
   void addArrayElement(ListNodeType literal, Node element) {
     if (!element->isConstant()) {
       literal->setHasNonConstInitializer();
     }
     addList(/* list = */ literal, /* kid = */ element);
   }
 
   BinaryNodeType newCall(Node callee, Node args) {
-    return new_<BinaryNode>(ParseNodeKind::Call, JSOP_CALL, callee, args);
+    return new_<BinaryNode>(ParseNodeKind::CallExpr, JSOP_CALL, callee, args);
   }
 
   ListNodeType newArguments(const TokenPos& pos) {
     return new_<ListNode>(ParseNodeKind::Arguments, JSOP_NOP, pos);
   }
 
   BinaryNodeType newSuperCall(Node callee, Node args) {
-    return new_<BinaryNode>(ParseNodeKind::SuperCall, JSOP_SUPERCALL, callee,
-                            args);
+    return new_<BinaryNode>(ParseNodeKind::SuperCallExpr, JSOP_SUPERCALL,
+                            callee, args);
   }
 
   BinaryNodeType newTaggedTemplate(Node tag, Node args) {
-    return new_<BinaryNode>(ParseNodeKind::TaggedTemplate, JSOP_CALL, tag,
+    return new_<BinaryNode>(ParseNodeKind::TaggedTemplateExpr, JSOP_CALL, tag,
                             args);
   }
 
   ListNodeType newObjectLiteral(uint32_t begin) {
-    return new_<ListNode>(ParseNodeKind::Object, TokenPos(begin, begin + 1));
+    return new_<ListNode>(ParseNodeKind::ObjectExpr,
+                          TokenPos(begin, begin + 1));
   }
 
   ClassNodeType newClass(Node name, Node heritage, Node memberBlock,
                          const TokenPos& pos) {
     return new_<ClassNode>(name, heritage, memberBlock, pos);
   }
   ListNodeType newClassMemberList(uint32_t begin) {
     return new_<ListNode>(ParseNodeKind::ClassMemberList,
                           TokenPos(begin, begin + 1));
   }
   ClassNamesType newClassNames(Node outer, Node inner, const TokenPos& pos) {
     return new_<ClassNames>(outer, inner, pos);
   }
   BinaryNodeType newNewTarget(NullaryNodeType newHolder,
                               NullaryNodeType targetHolder) {
-    return new_<BinaryNode>(ParseNodeKind::NewTarget, JSOP_NOP, newHolder,
+    return new_<BinaryNode>(ParseNodeKind::NewTargetExpr, JSOP_NOP, newHolder,
                             targetHolder);
   }
   NullaryNodeType newPosHolder(const TokenPos& pos) {
     return new_<NullaryNode>(ParseNodeKind::PosHolder, pos);
   }
   UnaryNodeType newSuperBase(Node thisName, const TokenPos& pos) {
     return new_<UnaryNode>(ParseNodeKind::SuperBase, pos, thisName);
   }
   MOZ_MUST_USE bool addPrototypeMutation(ListNodeType literal, uint32_t begin,
                                          Node expr) {
-    MOZ_ASSERT(literal->isKind(ParseNodeKind::Object));
+    MOZ_ASSERT(literal->isKind(ParseNodeKind::ObjectExpr));
 
     // Object literals with mutated [[Prototype]] are non-constant so that
     // singleton objects will have Object.prototype as their [[Prototype]].
     literal->setHasNonConstInitializer();
 
     UnaryNode* mutation = newUnary(ParseNodeKind::MutateProto, begin, expr);
     if (!mutation) {
       return false;
@@ -371,17 +373,17 @@ class FullParseHandler {
 
   BinaryNodeType newPropertyDefinition(Node key, Node val) {
     MOZ_ASSERT(isUsableAsObjectPropertyName(key));
     checkAndSetIsDirectRHSAnonFunction(val);
     return newBinary(ParseNodeKind::Colon, key, val, JSOP_INITPROP);
   }
 
   void addPropertyDefinition(ListNodeType literal, BinaryNodeType propdef) {
-    MOZ_ASSERT(literal->isKind(ParseNodeKind::Object));
+    MOZ_ASSERT(literal->isKind(ParseNodeKind::ObjectExpr));
     MOZ_ASSERT(propdef->isKind(ParseNodeKind::Colon));
 
     if (!propdef->right()->isConstant()) {
       literal->setHasNonConstInitializer();
     }
 
     addList(/* list = */ literal, /* kid = */ propdef);
   }
@@ -393,34 +395,34 @@ class FullParseHandler {
       return false;
     }
     addPropertyDefinition(literal, propdef);
     return true;
   }
 
   MOZ_MUST_USE bool addShorthand(ListNodeType literal, NameNodeType name,
                                  NameNodeType expr) {
-    MOZ_ASSERT(literal->isKind(ParseNodeKind::Object));
+    MOZ_ASSERT(literal->isKind(ParseNodeKind::ObjectExpr));
     MOZ_ASSERT(name->isKind(ParseNodeKind::ObjectPropertyName));
     MOZ_ASSERT(expr->isKind(ParseNodeKind::Name));
     MOZ_ASSERT(name->atom() == expr->atom());
 
     literal->setHasNonConstInitializer();
     BinaryNode* propdef =
         newBinary(ParseNodeKind::Shorthand, name, expr, JSOP_INITPROP);
     if (!propdef) {
       return false;
     }
     addList(/* list = */ literal, /* kid = */ propdef);
     return true;
   }
 
   MOZ_MUST_USE bool addSpreadProperty(ListNodeType literal, uint32_t begin,
                                       Node inner) {
-    MOZ_ASSERT(literal->isKind(ParseNodeKind::Object));
+    MOZ_ASSERT(literal->isKind(ParseNodeKind::ObjectExpr));
 
     literal->setHasNonConstInitializer();
     ParseNode* spread = newSpread(begin, inner);
     if (!spread) {
       return false;
     }
     addList(/* list = */ literal, /* kid = */ spread);
     return true;
@@ -477,37 +479,37 @@ class FullParseHandler {
 
   UnaryNodeType newInitialYieldExpression(uint32_t begin, Node gen) {
     TokenPos pos(begin, begin + 1);
     return new_<UnaryNode>(ParseNodeKind::InitialYield, pos, gen);
   }
 
   UnaryNodeType newYieldExpression(uint32_t begin, Node value) {
     TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
-    return new_<UnaryNode>(ParseNodeKind::Yield, pos, value);
+    return new_<UnaryNode>(ParseNodeKind::YieldExpr, pos, value);
   }
 
   UnaryNodeType newYieldStarExpression(uint32_t begin, Node value) {
     TokenPos pos(begin, value->pn_pos.end);
-    return new_<UnaryNode>(ParseNodeKind::YieldStar, pos, value);
+    return new_<UnaryNode>(ParseNodeKind::YieldStarExpr, pos, value);
   }
 
   UnaryNodeType newAwaitExpression(uint32_t begin, Node value) {
     TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
-    return new_<UnaryNode>(ParseNodeKind::Await, pos, value);
+    return new_<UnaryNode>(ParseNodeKind::AwaitExpr, pos, value);
   }
 
   // Statements
 
   ListNodeType newStatementList(const TokenPos& pos) {
     return new_<ListNode>(ParseNodeKind::StatementList, pos);
   }
 
   MOZ_MUST_USE bool isFunctionStmt(Node stmt) {
-    while (stmt->isKind(ParseNodeKind::Label)) {
+    while (stmt->isKind(ParseNodeKind::LabelStmt)) {
       stmt = stmt->as<LabeledStatement>().statement();
     }
     return stmt->isKind(ParseNodeKind::Function);
   }
 
   void addStatementToList(ListNodeType list, Node stmt) {
     MOZ_ASSERT(list->isKind(ParseNodeKind::StatementList));
 
@@ -543,17 +545,17 @@ class FullParseHandler {
         new_<NullaryNode>(ParseNodeKind::Generator, yieldPos);
     if (!makeGen) {
       return false;
     }
 
     MOZ_ASSERT(genName->getOp() == JSOP_GETNAME);
     genName->setOp(JSOP_SETNAME);
     ParseNode* genInit =
-        newAssignment(ParseNodeKind::Assign, /* lhs = */ genName,
+        newAssignment(ParseNodeKind::AssignExpr, /* lhs = */ genName,
                       /* rhs = */ makeGen);
     if (!genInit) {
       return false;
     }
 
     UnaryNode* initialYield =
         newInitialYieldExpression(yieldPos.begin, genInit);
     if (!initialYield) {
@@ -566,36 +568,36 @@ class FullParseHandler {
 
   BinaryNodeType newSetThis(Node thisName, Node value) {
     MOZ_ASSERT(thisName->getOp() == JSOP_GETNAME);
     thisName->setOp(JSOP_SETNAME);
     return newBinary(ParseNodeKind::SetThis, thisName, value);
   }
 
   NullaryNodeType newEmptyStatement(const TokenPos& pos) {
-    return new_<NullaryNode>(ParseNodeKind::EmptyStatement, pos);
+    return new_<NullaryNode>(ParseNodeKind::EmptyStmt, pos);
   }
 
   BinaryNodeType newImportDeclaration(Node importSpecSet, Node moduleSpec,
                                       const TokenPos& pos) {
-    return new_<BinaryNode>(ParseNodeKind::Import, JSOP_NOP, pos, importSpecSet,
-                            moduleSpec);
+    return new_<BinaryNode>(ParseNodeKind::ImportDecl, JSOP_NOP, pos,
+                            importSpecSet, moduleSpec);
   }
 
   BinaryNodeType newImportSpec(Node importNameNode, Node bindingName) {
     return newBinary(ParseNodeKind::ImportSpec, importNameNode, bindingName);
   }
 
   UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) {
-    return new_<UnaryNode>(ParseNodeKind::Export, pos, kid);
+    return new_<UnaryNode>(ParseNodeKind::ExportStmt, pos, kid);
   }
 
   BinaryNodeType newExportFromDeclaration(uint32_t begin, Node exportSpecSet,
                                           Node moduleSpec) {
-    BinaryNode* decl = new_<BinaryNode>(ParseNodeKind::ExportFrom, JSOP_NOP,
+    BinaryNode* decl = new_<BinaryNode>(ParseNodeKind::ExportFromStmt, JSOP_NOP,
                                         exportSpecSet, moduleSpec);
     if (!decl) {
       return nullptr;
     }
     decl->pn_pos.begin = begin;
     return decl;
   }
 
@@ -603,64 +605,66 @@ class FullParseHandler {
                                              const TokenPos& pos) {
     if (maybeBinding) {
       MOZ_ASSERT(maybeBinding->isKind(ParseNodeKind::Name));
       MOZ_ASSERT(!maybeBinding->isInParens());
 
       checkAndSetIsDirectRHSAnonFunction(kid);
     }
 
-    return new_<BinaryNode>(ParseNodeKind::ExportDefault, JSOP_NOP, pos, kid,
-                            maybeBinding);
+    return new_<BinaryNode>(ParseNodeKind::ExportDefaultStmt, JSOP_NOP, pos,
+                            kid, maybeBinding);
   }
 
   BinaryNodeType newExportSpec(Node bindingName, Node exportName) {
     return newBinary(ParseNodeKind::ExportSpec, bindingName, exportName);
   }
 
   NullaryNodeType newExportBatchSpec(const TokenPos& pos) {
-    return new_<NullaryNode>(ParseNodeKind::ExportBatchSpec, JSOP_NOP, pos);
+    return new_<NullaryNode>(ParseNodeKind::ExportBatchSpecStmt, JSOP_NOP, pos);
   }
 
   BinaryNodeType newImportMeta(NullaryNodeType importHolder,
                                NullaryNodeType metaHolder) {
-    return new_<BinaryNode>(ParseNodeKind::ImportMeta, JSOP_NOP, importHolder,
-                            metaHolder);
+    return new_<BinaryNode>(ParseNodeKind::ImportMetaExpr, JSOP_NOP,
+                            importHolder, metaHolder);
   }
 
   BinaryNodeType newCallImport(NullaryNodeType importHolder, Node singleArg) {
-    return new_<BinaryNode>(ParseNodeKind::CallImport, JSOP_DYNAMIC_IMPORT,
+    return new_<BinaryNode>(ParseNodeKind::CallImportExpr, JSOP_DYNAMIC_IMPORT,
                             importHolder, singleArg);
   }
 
   UnaryNodeType newExprStatement(Node expr, uint32_t end) {
     MOZ_ASSERT(expr->pn_pos.end <= end);
-    return new_<UnaryNode>(ParseNodeKind::ExpressionStatement,
+    return new_<UnaryNode>(ParseNodeKind::ExpressionStmt,
                            TokenPos(expr->pn_pos.begin, end), expr);
   }
 
   TernaryNodeType newIfStatement(uint32_t begin, Node cond, Node thenBranch,
                                  Node elseBranch) {
     TernaryNode* node =
-        new_<TernaryNode>(ParseNodeKind::If, cond, thenBranch, elseBranch);
+        new_<TernaryNode>(ParseNodeKind::IfStmt, cond, thenBranch, elseBranch);
     if (!node) {
       return nullptr;
     }
     node->pn_pos.begin = begin;
     return node;
   }
 
   BinaryNodeType newDoWhileStatement(Node body, Node cond,
                                      const TokenPos& pos) {
-    return new_<BinaryNode>(ParseNodeKind::DoWhile, JSOP_NOP, pos, body, cond);
+    return new_<BinaryNode>(ParseNodeKind::DoWhileStmt, JSOP_NOP, pos, body,
+                            cond);
   }
 
   BinaryNodeType newWhileStatement(uint32_t begin, Node cond, Node body) {
     TokenPos pos(begin, body->pn_pos.end);
-    return new_<BinaryNode>(ParseNodeKind::While, JSOP_NOP, pos, cond, body);
+    return new_<BinaryNode>(ParseNodeKind::WhileStmt, JSOP_NOP, pos, cond,
+                            body);
   }
 
   ForNodeType newForStatement(uint32_t begin, TernaryNodeType forHead,
                               Node body, unsigned iflags) {
     return new_<ForNode>(TokenPos(begin, body->pn_pos.end), forHead, body,
                          iflags);
   }
 
@@ -693,50 +697,50 @@ class FullParseHandler {
 
   BreakStatementType newBreakStatement(PropertyName* label,
                                        const TokenPos& pos) {
     return new_<BreakStatement>(label, pos);
   }
 
   UnaryNodeType newReturnStatement(Node expr, const TokenPos& pos) {
     MOZ_ASSERT_IF(expr, pos.encloses(expr->pn_pos));
-    return new_<UnaryNode>(ParseNodeKind::Return, pos, expr);
+    return new_<UnaryNode>(ParseNodeKind::ReturnStmt, pos, expr);
   }
 
   UnaryNodeType newExpressionBody(Node expr) {
-    return new_<UnaryNode>(ParseNodeKind::Return, expr->pn_pos, expr);
+    return new_<UnaryNode>(ParseNodeKind::ReturnStmt, expr->pn_pos, expr);
   }
 
   BinaryNodeType newWithStatement(uint32_t begin, Node expr, Node body) {
-    return new_<BinaryNode>(ParseNodeKind::With, JSOP_NOP,
+    return new_<BinaryNode>(ParseNodeKind::WithStmt, JSOP_NOP,
                             TokenPos(begin, body->pn_pos.end), expr, body);
   }
 
   LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt,
                                            uint32_t begin) {
     return new_<LabeledStatement>(label, stmt, begin);
   }
 
   UnaryNodeType newThrowStatement(Node expr, const TokenPos& pos) {
     MOZ_ASSERT(pos.encloses(expr->pn_pos));
-    return new_<UnaryNode>(ParseNodeKind::Throw, pos, expr);
+    return new_<UnaryNode>(ParseNodeKind::ThrowStmt, pos, expr);
   }
 
   TernaryNodeType newTryStatement(uint32_t begin, Node body,
                                   LexicalScopeNodeType catchScope,
                                   Node finallyBlock) {
     return new_<TryNode>(begin, body, catchScope, finallyBlock);
   }
 
   DebuggerStatementType newDebuggerStatement(const TokenPos& pos) {
     return new_<DebuggerStatement>(pos);
   }
 
   NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) {
-    return new_<NameNode>(ParseNodeKind::PropertyName, JSOP_NOP, name, pos);
+    return new_<NameNode>(ParseNodeKind::PropertyNameExpr, JSOP_NOP, name, pos);
   }
 
   PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
     return new_<PropertyAccess>(expr, key, expr->pn_pos.begin, key->pn_pos.end);
   }
 
   PropertyByValueType newPropertyByValue(Node lhs, Node index, uint32_t end) {
     return new_<PropertyByValue>(lhs, index, lhs->pn_pos.begin, end);
@@ -813,70 +817,71 @@ class FullParseHandler {
   }
 
   LexicalScopeNodeType newLexicalScope(LexicalScope::Data* bindings,
                                        Node body) {
     return new_<LexicalScopeNode>(bindings, body);
   }
 
   BinaryNodeType newNewExpression(uint32_t begin, Node ctor, Node args) {
-    return new_<BinaryNode>(ParseNodeKind::New, JSOP_NEW,
+    return new_<BinaryNode>(ParseNodeKind::NewExpr, JSOP_NEW,
                             TokenPos(begin, args->pn_pos.end), ctor, args);
   }
 
   AssignmentNodeType newAssignment(ParseNodeKind kind, Node lhs, Node rhs) {
-    if (kind == ParseNodeKind::Assign && lhs->isKind(ParseNodeKind::Name) &&
+    if (kind == ParseNodeKind::AssignExpr && lhs->isKind(ParseNodeKind::Name) &&
         !lhs->isInParens()) {
       checkAndSetIsDirectRHSAnonFunction(rhs);
     }
 
     return new_<AssignmentNode>(kind, JSOP_NOP, lhs, rhs);
   }
 
   bool isUnparenthesizedAssignment(Node node) {
-    if (node->isKind(ParseNodeKind::Assign) && !node->isInParens()) {
+    if (node->isKind(ParseNodeKind::AssignExpr) && !node->isInParens()) {
       // ParseNodeKind::Assign is also (mis)used for things like
       // |var name = expr;|. But this method is only called on actual
       // expressions, so we can just assert the node's op is the one used
       // for plain assignment.
       MOZ_ASSERT(node->isOp(JSOP_NOP));
       return true;
     }
 
     return false;
   }
 
   bool isUnparenthesizedUnaryExpression(Node node) {
     if (!node->isInParens()) {
       ParseNodeKind kind = node->getKind();
-      return kind == ParseNodeKind::Void || kind == ParseNodeKind::Not ||
-             kind == ParseNodeKind::BitNot || kind == ParseNodeKind::Pos ||
-             kind == ParseNodeKind::Neg || IsTypeofKind(kind) ||
-             IsDeleteKind(kind);
+      return kind == ParseNodeKind::VoidExpr ||
+             kind == ParseNodeKind::NotExpr ||
+             kind == ParseNodeKind::BitNotExpr ||
+             kind == ParseNodeKind::PosExpr || kind == ParseNodeKind::NegExpr ||
+             IsTypeofKind(kind) || IsDeleteKind(kind);
     }
     return false;
   }
 
   bool isReturnStatement(Node node) {
-    return node->isKind(ParseNodeKind::Return);
+    return node->isKind(ParseNodeKind::ReturnStmt);
   }
 
   bool isStatementPermittedAfterReturnStatement(Node node) {
     ParseNodeKind kind = node->getKind();
-    return kind == ParseNodeKind::Function || kind == ParseNodeKind::Var ||
-           kind == ParseNodeKind::Break || kind == ParseNodeKind::Throw ||
-           kind == ParseNodeKind::EmptyStatement;
+    return kind == ParseNodeKind::Function || kind == ParseNodeKind::VarStmt ||
+           kind == ParseNodeKind::BreakStmt ||
+           kind == ParseNodeKind::ThrowStmt || kind == ParseNodeKind::EmptyStmt;
   }
 
   bool isSuperBase(Node node) { return node->isKind(ParseNodeKind::SuperBase); }
 
   bool isUsableAsObjectPropertyName(Node node) {
-    return node->isKind(ParseNodeKind::Number) ||
+    return node->isKind(ParseNodeKind::NumberExpr) ||
            node->isKind(ParseNodeKind::ObjectPropertyName) ||
-           node->isKind(ParseNodeKind::String) ||
+           node->isKind(ParseNodeKind::StringExpr) ||
            node->isKind(ParseNodeKind::ComputedName);
   }
 
   inline MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode,
                                                        Node init);
 
   void setBeginPosition(Node pn, Node oth) {
     setBeginPosition(pn, oth->pn_pos.begin);
@@ -894,18 +899,18 @@ class FullParseHandler {
     MOZ_ASSERT(pn->pn_pos.begin <= pn->pn_pos.end);
   }
 
   uint32_t getFunctionNameOffset(Node func, TokenStreamAnyChars& ts) {
     return func->pn_pos.begin;
   }
 
   bool isDeclarationKind(ParseNodeKind kind) {
-    return kind == ParseNodeKind::Var || kind == ParseNodeKind::Let ||
-           kind == ParseNodeKind::Const;
+    return kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||
+           kind == ParseNodeKind::ConstDecl;
   }
 
   ListNodeType newList(ParseNodeKind kind, const TokenPos& pos) {
     MOZ_ASSERT(!isDeclarationKind(kind));
     return new_<ListNode>(kind, JSOP_NOP, pos);
   }
 
  public:
@@ -925,17 +930,17 @@ class FullParseHandler {
 
   Node singleBindingFromDeclaration(ListNodeType decl) {
     MOZ_ASSERT(isDeclarationList(decl));
     MOZ_ASSERT(decl->count() == 1);
     return decl->head();
   }
 
   ListNodeType newCommaExpressionList(Node kid) {
-    return new_<ListNode>(ParseNodeKind::Comma, JSOP_NOP, kid);
+    return new_<ListNode>(ParseNodeKind::CommaExpr, JSOP_NOP, kid);
   }
 
   void addList(ListNodeType list, Node kid) {
     if (sourceKind_ == SourceKind::Text) {
       list->append(kid);
     } else {
       list->appendWithoutOrderAssumption(kid);
     }
@@ -1010,17 +1015,17 @@ class FullParseHandler {
   }
 };
 
 inline bool FullParseHandler::setLastFunctionFormalParameterDefault(
     CodeNodeType funNode, Node defaultValue) {
   MOZ_ASSERT(funNode->isKind(ParseNodeKind::Function));
   ListNode* body = funNode->body();
   ParseNode* arg = body->last();
-  ParseNode* pn = newAssignment(ParseNodeKind::Assign, arg, defaultValue);
+  ParseNode* pn = newAssignment(ParseNodeKind::AssignExpr, arg, defaultValue);
   if (!pn) {
     return false;
   }
 
   body->replaceLast(pn);
   return true;
 }
 
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -26,17 +26,17 @@ class NameResolver {
   JSContext* cx;
   size_t nparents; /* number of parents in the parents array */
   MOZ_INIT_OUTSIDE_CTOR
   ParseNode*
       parents[MaxParents]; /* history of ParseNodes we've been looking at */
   StringBuffer* buf;       /* when resolving, buffer to append to */
 
   /* Test whether a ParseNode represents a function invocation */
-  bool call(ParseNode* pn) { return pn && pn->isKind(ParseNodeKind::Call); }
+  bool call(ParseNode* pn) { return pn && pn->isKind(ParseNodeKind::CallExpr); }
 
   /*
    * Append a reference to a property named |name| to |buf|. If |name| is
    * a proper identifier name, then we append '.name'; otherwise, we
    * append '["name"]'.
    *
    * Note that we need the IsIdentifier check for atoms from both
    * ParseNodeKind::Name nodes and ParseNodeKind::String nodes:
@@ -69,54 +69,54 @@ class NameResolver {
   /*
    * Walk over the given ParseNode, attempting to convert it to a stringified
    * name that respresents where the function is being assigned to.
    *
    * |*foundName| is set to true if a name is found for the expression.
    */
   bool nameExpression(ParseNode* n, bool* foundName) {
     switch (n->getKind()) {
-      case ParseNodeKind::Dot: {
+      case ParseNodeKind::DotExpr: {
         PropertyAccess* prop = &n->as<PropertyAccess>();
         if (!nameExpression(&prop->expression(), foundName)) {
           return false;
         }
         if (!*foundName) {
           return true;
         }
         return appendPropertyReference(prop->right()->as<NameNode>().atom());
       }
 
       case ParseNodeKind::Name:
       case ParseNodeKind::PrivateName:
         *foundName = true;
         return buf->append(n->as<NameNode>().atom());
 
-      case ParseNodeKind::This:
+      case ParseNodeKind::ThisExpr:
         *foundName = true;
         return buf->append("this");
 
-      case ParseNodeKind::Elem: {
+      case ParseNodeKind::ElemExpr: {
         PropertyByValue* elem = &n->as<PropertyByValue>();
         if (!nameExpression(&elem->expression(), foundName)) {
           return false;
         }
         if (!*foundName) {
           return true;
         }
         if (!buf->append('[') || !nameExpression(elem->right(), foundName)) {
           return false;
         }
         if (!*foundName) {
           return true;
         }
         return buf->append(']');
       }
 
-      case ParseNodeKind::Number:
+      case ParseNodeKind::NumberExpr:
         *foundName = true;
         return appendNumber(n->as<NumericLiteral>().value());
 
       default:
         /* We're confused as to what to call this function. */
         *foundName = false;
         return true;
     }
@@ -143,22 +143,22 @@ class NameResolver {
       if (cur->is<AssignmentNode>()) {
         return cur;
       }
 
       switch (cur->getKind()) {
         case ParseNodeKind::PrivateName:
         case ParseNodeKind::Name:
           return cur; /* found the initialized declaration */
-        case ParseNodeKind::This:
+        case ParseNodeKind::ThisExpr:
           return cur; /* Setting a property of 'this'. */
         case ParseNodeKind::Function:
           return nullptr; /* won't find an assignment or declaration */
 
-        case ParseNodeKind::Return:
+        case ParseNodeKind::ReturnStmt:
           /*
            * Normally the relevant parent of a node is its direct parent, but
            * sometimes with code like:
            *
            *    var foo = (function() { return function() {}; })();
            *
            * the outer function is just a helper to create a scope for the
            * returned function. Hence the name of the returned function should
@@ -259,21 +259,21 @@ class NameResolver {
      */
     for (int pos = size - 1; pos >= 0; pos--) {
       ParseNode* node = toName[pos];
 
       if (node->isKind(ParseNodeKind::Colon) ||
           node->isKind(ParseNodeKind::Shorthand)) {
         ParseNode* left = node->as<BinaryNode>().left();
         if (left->isKind(ParseNodeKind::ObjectPropertyName) ||
-            left->isKind(ParseNodeKind::String)) {
+            left->isKind(ParseNodeKind::StringExpr)) {
           if (!appendPropertyReference(left->as<NameNode>().atom())) {
             return false;
           }
-        } else if (left->isKind(ParseNodeKind::Number)) {
+        } else if (left->isKind(ParseNodeKind::NumberExpr)) {
           if (!appendNumericPropertyReference(
                   left->as<NumericLiteral>().value())) {
             return false;
           }
         } else {
           MOZ_ASSERT(left->isKind(ParseNodeKind::ComputedName));
         }
       } else {
@@ -321,36 +321,36 @@ class NameResolver {
    * for new variables and then return an anonymous function using this scope.
    */
   bool isDirectCall(int pos, ParseNode* cur) {
     return pos >= 0 && call(parents[pos]) &&
            parents[pos]->as<BinaryNode>().left() == cur;
   }
 
   bool resolveTemplateLiteral(ListNode* node, HandleAtom prefix) {
-    MOZ_ASSERT(node->isKind(ParseNodeKind::TemplateStringList));
+    MOZ_ASSERT(node->isKind(ParseNodeKind::TemplateStringListExpr));
     ParseNode* element = node->head();
     while (true) {
-      MOZ_ASSERT(element->isKind(ParseNodeKind::TemplateString));
+      MOZ_ASSERT(element->isKind(ParseNodeKind::TemplateStringExpr));
 
       element = element->pn_next;
       if (!element) {
         return true;
       }
 
       if (!resolve(element, prefix)) {
         return false;
       }
 
       element = element->pn_next;
     }
   }
 
   bool resolveTaggedTemplate(BinaryNode* taggedTemplate, HandleAtom prefix) {
-    MOZ_ASSERT(taggedTemplate->isKind(ParseNodeKind::TaggedTemplate));
+    MOZ_ASSERT(taggedTemplate->isKind(ParseNodeKind::TaggedTemplateExpr));
 
     ParseNode* tag = taggedTemplate->left();
 
     // The leading expression, e.g. |tag| in |tag`foo`|,
     // that might contain functions.
     if (!resolve(tag, prefix)) {
       return false;
     }
@@ -358,23 +358,23 @@ class NameResolver {
     // The callsite object node is first.  This node only contains
     // internal strings or undefined and an array -- no user-controlled
     // expressions.
     CallSiteNode* element =
         &taggedTemplate->right()->as<ListNode>().head()->as<CallSiteNode>();
 #ifdef DEBUG
     {
       ListNode* rawNodes = &element->head()->as<ListNode>();
-      MOZ_ASSERT(rawNodes->isKind(ParseNodeKind::Array));
+      MOZ_ASSERT(rawNodes->isKind(ParseNodeKind::ArrayExpr));
       for (ParseNode* raw : rawNodes->contents()) {
-        MOZ_ASSERT(raw->isKind(ParseNodeKind::TemplateString));
+        MOZ_ASSERT(raw->isKind(ParseNodeKind::TemplateStringExpr));
       }
       for (ParseNode* cooked : element->contentsFrom(rawNodes->pn_next)) {
-        MOZ_ASSERT(cooked->isKind(ParseNodeKind::TemplateString) ||
-                   cooked->isKind(ParseNodeKind::RawUndefined));
+        MOZ_ASSERT(cooked->isKind(ParseNodeKind::TemplateStringExpr) ||
+                   cooked->isKind(ParseNodeKind::RawUndefinedExpr));
       }
     }
 #endif
 
     // Next come any interpolated expressions in the tagged template.
     ParseNode* interpolated = element->pn_next;
     for (; interpolated; interpolated = interpolated->pn_next) {
       if (!resolve(interpolated, prefix)) {
@@ -422,132 +422,132 @@ class NameResolver {
 
     auto initialParents = nparents;
     parents[initialParents] = cur;
     nparents++;
 
     switch (cur->getKind()) {
       // Nodes with no children that might require name resolution need no
       // further work.
-      case ParseNodeKind::EmptyStatement:
-      case ParseNodeKind::True:
-      case ParseNodeKind::False:
-      case ParseNodeKind::Null:
-      case ParseNodeKind::RawUndefined:
+      case ParseNodeKind::EmptyStmt:
+      case ParseNodeKind::TrueExpr:
+      case ParseNodeKind::FalseExpr:
+      case ParseNodeKind::NullExpr:
+      case ParseNodeKind::RawUndefinedExpr:
       case ParseNodeKind::Elision:
       case ParseNodeKind::Generator:
-      case ParseNodeKind::ExportBatchSpec:
+      case ParseNodeKind::ExportBatchSpecStmt:
       case ParseNodeKind::PosHolder:
         MOZ_ASSERT(cur->is<NullaryNode>());
         break;
 
-      case ParseNodeKind::Debugger:
+      case ParseNodeKind::DebuggerStmt:
         MOZ_ASSERT(cur->is<DebuggerStatement>());
         break;
 
-      case ParseNodeKind::Break:
+      case ParseNodeKind::BreakStmt:
         MOZ_ASSERT(cur->is<BreakStatement>());
         break;
 
-      case ParseNodeKind::Continue:
+      case ParseNodeKind::ContinueStmt:
         MOZ_ASSERT(cur->is<ContinueStatement>());
         break;
 
       case ParseNodeKind::ObjectPropertyName:
       case ParseNodeKind::PrivateName:  // TODO(khyperia): Implement private
                                         // field access.
-      case ParseNodeKind::String:
-      case ParseNodeKind::TemplateString:
+      case ParseNodeKind::StringExpr:
+      case ParseNodeKind::TemplateStringExpr:
         MOZ_ASSERT(cur->is<NameNode>());
         break;
 
-      case ParseNodeKind::RegExp:
+      case ParseNodeKind::RegExpExpr:
         MOZ_ASSERT(cur->is<RegExpLiteral>());
         break;
 
-      case ParseNodeKind::Number:
+      case ParseNodeKind::NumberExpr:
         MOZ_ASSERT(cur->is<NumericLiteral>());
         break;
 
 #ifdef ENABLE_BIGINT
       case ParseNodeKind::BigInt:
         MOZ_ASSERT(cur->is<BigIntLiteral>());
         break;
 #endif
 
-      case ParseNodeKind::TypeOfName:
+      case ParseNodeKind::TypeOfNameExpr:
       case ParseNodeKind::SuperBase:
         MOZ_ASSERT(cur->as<UnaryNode>().kid()->isKind(ParseNodeKind::Name));
         MOZ_ASSERT(!cur->as<UnaryNode>().kid()->as<NameNode>().initializer());
         break;
 
-      case ParseNodeKind::NewTarget:
-      case ParseNodeKind::ImportMeta: {
+      case ParseNodeKind::NewTargetExpr:
+      case ParseNodeKind::ImportMetaExpr: {
         MOZ_ASSERT(
             cur->as<BinaryNode>().left()->isKind(ParseNodeKind::PosHolder));
         MOZ_ASSERT(
             cur->as<BinaryNode>().right()->isKind(ParseNodeKind::PosHolder));
         break;
       }
 
       // Nodes with a single non-null child requiring name resolution.
-      case ParseNodeKind::ExpressionStatement:
+      case ParseNodeKind::ExpressionStmt:
       case ParseNodeKind::TypeOfExpr:
-      case ParseNodeKind::Void:
-      case ParseNodeKind::Not:
-      case ParseNodeKind::BitNot:
-      case ParseNodeKind::Throw:
-      case ParseNodeKind::DeleteName:
-      case ParseNodeKind::DeleteProp:
-      case ParseNodeKind::DeleteElem:
+      case ParseNodeKind::VoidExpr:
+      case ParseNodeKind::NotExpr:
+      case ParseNodeKind::BitNotExpr:
+      case ParseNodeKind::ThrowStmt:
+      case ParseNodeKind::DeleteNameExpr:
+      case ParseNodeKind::DeletePropExpr:
+      case ParseNodeKind::DeleteElemExpr:
       case ParseNodeKind::DeleteExpr:
-      case ParseNodeKind::Neg:
-      case ParseNodeKind::Pos:
-      case ParseNodeKind::PreIncrement:
-      case ParseNodeKind::PostIncrement:
-      case ParseNodeKind::PreDecrement:
-      case ParseNodeKind::PostDecrement:
+      case ParseNodeKind::NegExpr:
+      case ParseNodeKind::PosExpr:
+      case ParseNodeKind::PreIncrementExpr:
+      case ParseNodeKind::PostIncrementExpr:
+      case ParseNodeKind::PreDecrementExpr:
+      case ParseNodeKind::PostDecrementExpr:
       case ParseNodeKind::ComputedName:
       case ParseNodeKind::Spread:
       case ParseNodeKind::MutateProto:
-      case ParseNodeKind::Export:
+      case ParseNodeKind::ExportStmt:
         if (!resolve(cur->as<UnaryNode>().kid(), prefix)) {
           return false;
         }
         break;
 
       // Nodes with a single nullable child.
-      case ParseNodeKind::This:
+      case ParseNodeKind::ThisExpr:
         if (ParseNode* expr = cur->as<ThisLiteral>().kid()) {
           if (!resolve(expr, prefix)) {
             return false;
           }
         }
         break;
 
       // Binary nodes with two non-null children.
-      case ParseNodeKind::Assign:
-      case ParseNodeKind::AddAssign:
-      case ParseNodeKind::SubAssign:
-      case ParseNodeKind::BitOrAssign:
-      case ParseNodeKind::BitXorAssign:
-      case ParseNodeKind::BitAndAssign:
-      case ParseNodeKind::LshAssign:
-      case ParseNodeKind::RshAssign:
-      case ParseNodeKind::UrshAssign:
-      case ParseNodeKind::MulAssign:
-      case ParseNodeKind::DivAssign:
-      case ParseNodeKind::ModAssign:
-      case ParseNodeKind::PowAssign:
+      case ParseNodeKind::AssignExpr:
+      case ParseNodeKind::AddAssignExpr:
+      case ParseNodeKind::SubAssignExpr:
+      case ParseNodeKind::BitOrAssignExpr:
+      case ParseNodeKind::BitXorAssignExpr:
+      case ParseNodeKind::BitAndAssignExpr:
+      case ParseNodeKind::LshAssignExpr:
+      case ParseNodeKind::RshAssignExpr:
+      case ParseNodeKind::UrshAssignExpr:
+      case ParseNodeKind::MulAssignExpr:
+      case ParseNodeKind::DivAssignExpr:
+      case ParseNodeKind::ModAssignExpr:
+      case ParseNodeKind::PowAssignExpr:
       case ParseNodeKind::Colon:
       case ParseNodeKind::Shorthand:
-      case ParseNodeKind::DoWhile:
-      case ParseNodeKind::While:
-      case ParseNodeKind::Switch:
-      case ParseNodeKind::For:
+      case ParseNodeKind::DoWhileStmt:
+      case ParseNodeKind::WhileStmt:
+      case ParseNodeKind::SwitchStmt:
+      case ParseNodeKind::ForStmt:
       case ParseNodeKind::ClassMethod:
       case ParseNodeKind::SetThis: {
         BinaryNode* node = &cur->as<BinaryNode>();
         if (!resolve(node->left(), prefix)) {
           return false;
         }
         if (!resolve(node->right(), prefix)) {
           return false;
@@ -565,28 +565,28 @@ class NameResolver {
           if (!resolve(&node->initializer(), prefix)) {
             return false;
           }
         }
 
         break;
       }
 
-      case ParseNodeKind::Elem: {
+      case ParseNodeKind::ElemExpr: {
         PropertyByValue* elem = &cur->as<PropertyByValue>();
         if (!elem->isSuper() && !resolve(&elem->expression(), prefix)) {
           return false;
         }
         if (!resolve(&elem->key(), prefix)) {
           return false;
         }
         break;
       }
 
-      case ParseNodeKind::With: {
+      case ParseNodeKind::WithStmt: {
         BinaryNode* node = &cur->as<BinaryNode>();
         if (!resolve(node->left(), prefix)) {
           return false;
         }
         if (!resolve(node->right(), prefix)) {
           return false;
         }
         break;
@@ -610,56 +610,56 @@ class NameResolver {
         AssignmentNode* assignNode =
             &cur->as<UnaryNode>().kid()->as<AssignmentNode>();
         MOZ_ASSERT(assignNode->left()->isKind(ParseNodeKind::Name));
         MOZ_ASSERT(assignNode->right()->isKind(ParseNodeKind::Generator));
 #endif
         break;
       }
 
-      case ParseNodeKind::YieldStar:
+      case ParseNodeKind::YieldStarExpr:
         if (!resolve(cur->as<UnaryNode>().kid(), prefix)) {
           return false;
         }
         break;
 
-      case ParseNodeKind::Yield:
-      case ParseNodeKind::Await:
+      case ParseNodeKind::YieldExpr:
+      case ParseNodeKind::AwaitExpr:
         if (ParseNode* expr = cur->as<UnaryNode>().kid()) {
           if (!resolve(expr, prefix)) {
             return false;
           }
         }
         break;
 
-      case ParseNodeKind::Return:
+      case ParseNodeKind::ReturnStmt:
         if (ParseNode* returnValue = cur->as<UnaryNode>().kid()) {
           if (!resolve(returnValue, prefix)) {
             return false;
           }
         }
         break;
 
-      case ParseNodeKind::Import:
-      case ParseNodeKind::ExportFrom:
-      case ParseNodeKind::ExportDefault: {
+      case ParseNodeKind::ImportDecl:
+      case ParseNodeKind::ExportFromStmt:
+      case ParseNodeKind::ExportDefaultStmt: {
         BinaryNode* node = &cur->as<BinaryNode>();
         // The left halves of Import and ExportFrom don't contain any
         // unconstrained expressions, but it's very hard to assert this to
         // safely rely on it. So recur anyway.
         if (!resolve(node->left(), prefix)) {
           return false;
         }
-        MOZ_ASSERT_IF(!node->isKind(ParseNodeKind::ExportDefault),
-                      node->right()->isKind(ParseNodeKind::String));
+        MOZ_ASSERT_IF(!node->isKind(ParseNodeKind::ExportDefaultStmt),
+                      node->right()->isKind(ParseNodeKind::StringExpr));
         break;
       }
 
       // Ternary nodes with three expression children.
-      case ParseNodeKind::Conditional: {
+      case ParseNodeKind::ConditionalExpr: {
         TernaryNode* condNode = &cur->as<TernaryNode>();
         if (!resolve(condNode->kid1(), prefix)) {
           return false;
         }
         if (!resolve(condNode->kid2(), prefix)) {
           return false;
         }
         if (!resolve(condNode->kid3(), prefix)) {
@@ -707,17 +707,17 @@ class NameResolver {
           }
         }
         break;
       }
 
       // The first child of a class is a pair of names referring to it,
       // inside and outside the class.  The second is the class's heritage,
       // if any.  The third is the class body.
-      case ParseNodeKind::Class: {
+      case ParseNodeKind::ClassDecl: {
         ClassNode* classNode = &cur->as<ClassNode>();
 #ifdef DEBUG
         if (classNode->names()) {
           ClassNames* names = classNode->names();
           if (NameNode* outerBinding = names->outerBinding()) {
             MOZ_ASSERT(outerBinding->isKind(ParseNodeKind::Name));
             MOZ_ASSERT(!outerBinding->initializer());
           }
@@ -735,17 +735,17 @@ class NameResolver {
         if (!resolve(classNode->memberList(), prefix)) {
           return false;
         }
         break;
       }
 
       // The condition and consequent are non-optional, but the alternative
       // might be omitted.
-      case ParseNodeKind::If: {
+      case ParseNodeKind::IfStmt: {
         TernaryNode* ifNode = &cur->as<TernaryNode>();
         if (!resolve(ifNode->kid1(), prefix)) {
           return false;
         }
         if (!resolve(ifNode->kid2(), prefix)) {
           return false;
         }
         if (ParseNode* alternative = ifNode->kid3()) {
@@ -754,17 +754,17 @@ class NameResolver {
           }
         }
         break;
       }
 
       // The statements in the try-block are mandatory.  The catch-blocks
       // and finally block are optional (but at least one or the other must
       // be present).
-      case ParseNodeKind::Try: {
+      case ParseNodeKind::TryStmt: {
         TryNode* tryNode = &cur->as<TryNode>();
         if (!resolve(tryNode->body(), prefix)) {
           return false;
         }
         MOZ_ASSERT(tryNode->catchScope() || tryNode->finallyBlock());
         if (LexicalScopeNode* catchScope = tryNode->catchScope()) {
           MOZ_ASSERT(catchScope->scopeBody()->isKind(ParseNodeKind::Catch));
           MOZ_ASSERT(catchScope->scopeBody()->is<BinaryNode>());
@@ -793,83 +793,83 @@ class NameResolver {
         }
         if (!resolve(node->right(), prefix)) {
           return false;
         }
         break;
       }
 
       // Nodes with arbitrary-expression children.
-      case ParseNodeKind::Or:
-      case ParseNodeKind::And:
-      case ParseNodeKind::BitOr:
-      case ParseNodeKind::BitXor:
-      case ParseNodeKind::BitAnd:
-      case ParseNodeKind::StrictEq:
-      case ParseNodeKind::Eq:
-      case ParseNodeKind::StrictNe:
-      case ParseNodeKind::Ne:
-      case ParseNodeKind::Lt:
-      case ParseNodeKind::Le:
-      case ParseNodeKind::Gt:
-      case ParseNodeKind::Ge:
-      case ParseNodeKind::InstanceOf:
-      case ParseNodeKind::In:
-      case ParseNodeKind::Lsh:
-      case ParseNodeKind::Rsh:
-      case ParseNodeKind::Ursh:
-      case ParseNodeKind::Add:
-      case ParseNodeKind::Sub:
-      case ParseNodeKind::Star:
-      case ParseNodeKind::Div:
-      case ParseNodeKind::Mod:
-      case ParseNodeKind::Pow:
-      case ParseNodeKind::Pipeline:
-      case ParseNodeKind::Comma:
-      case ParseNodeKind::Array:
+      case ParseNodeKind::OrExpr:
+      case ParseNodeKind::AndExpr:
+      case ParseNodeKind::BitOrExpr:
+      case ParseNodeKind::BitXorExpr:
+      case ParseNodeKind::BitAndExpr:
+      case ParseNodeKind::StrictEqExpr:
+      case ParseNodeKind::EqExpr:
+      case ParseNodeKind::StrictNeExpr:
+      case ParseNodeKind::NeExpr:
+      case ParseNodeKind::LtExpr:
+      case ParseNodeKind::LeExpr:
+      case ParseNodeKind::GtExpr:
+      case ParseNodeKind::GeExpr:
+      case ParseNodeKind::InstanceOfExpr:
+      case ParseNodeKind::InExpr:
+      case ParseNodeKind::LshExpr:
+      case ParseNodeKind::RshExpr:
+      case ParseNodeKind::UrshExpr:
+      case ParseNodeKind::AddExpr:
+      case ParseNodeKind::SubExpr:
+      case ParseNodeKind::MulExpr:
+      case ParseNodeKind::DivExpr:
+      case ParseNodeKind::ModExpr:
+      case ParseNodeKind::PowExpr:
+      case ParseNodeKind::PipelineExpr:
+      case ParseNodeKind::CommaExpr:
+      case ParseNodeKind::ArrayExpr:
       case ParseNodeKind::StatementList:
       case ParseNodeKind::ParamsBody:
       // Initializers for individual variables, and computed property names
       // within destructuring patterns, may contain unnamed functions.
-      case ParseNodeKind::Var:
-      case ParseNodeKind::Const:
-      case ParseNodeKind::Let:
+      case ParseNodeKind::VarStmt:
+      case ParseNodeKind::ConstDecl:
+      case ParseNodeKind::LetDecl:
         for (ParseNode* element : cur->as<ListNode>().contents()) {
           if (!resolve(element, prefix)) {
             return false;
           }
         }
         break;
 
-      case ParseNodeKind::Object:
+      case ParseNodeKind::ObjectExpr:
       case ParseNodeKind::ClassMemberList:
         for (ParseNode* element : cur->as<ListNode>().contents()) {
           if (!resolve(element, prefix)) {
             return false;
           }
         }
         break;
 
       // A template string list's contents alternate raw template string
       // contents with expressions interpolated into the overall literal.
-      case ParseNodeKind::TemplateStringList:
+      case ParseNodeKind::TemplateStringListExpr:
         if (!resolveTemplateLiteral(&cur->as<ListNode>(), prefix)) {
           return false;
         }
         break;
 
-      case ParseNodeKind::TaggedTemplate:
+      case ParseNodeKind::TaggedTemplateExpr:
         if (!resolveTaggedTemplate(&cur->as<BinaryNode>(), prefix)) {
           return false;
         }
         break;
 
-      case ParseNodeKind::New:
-      case ParseNodeKind::Call:
-      case ParseNodeKind::SuperCall: {
+      case ParseNodeKind::NewExpr:
+      case ParseNodeKind::CallExpr:
+      case ParseNodeKind::SuperCallExpr: {
         BinaryNode* callNode = &cur->as<BinaryNode>();
         if (!resolve(callNode->left(), prefix)) {
           return false;
         }
         if (!resolve(callNode->right(), prefix)) {
           return false;
         }
         break;
@@ -890,54 +890,55 @@ class NameResolver {
       // only pairs of names. Alternatively, an export spec lists may
       // contain a single export batch specifier.
       case ParseNodeKind::ExportSpecList:
       case ParseNodeKind::ImportSpecList: {
 #ifdef DEBUG
         bool isImport = cur->isKind(ParseNodeKind::ImportSpecList);
         ListNode* list = &cur->as<ListNode>();
         ParseNode* item = list->head();
-        if (!isImport && item && item->isKind(ParseNodeKind::ExportBatchSpec)) {
+        if (!isImport && item &&
+            item->isKind(ParseNodeKind::ExportBatchSpecStmt)) {
           MOZ_ASSERT(item->is<NullaryNode>());
           break;
         }
         for (ParseNode* item : list->contents()) {
           BinaryNode* spec = &item->as<BinaryNode>();
           MOZ_ASSERT(spec->isKind(isImport ? ParseNodeKind::ImportSpec
                                            : ParseNodeKind::ExportSpec));
           MOZ_ASSERT(spec->left()->isKind(ParseNodeKind::Name));
           MOZ_ASSERT(!spec->left()->as<NameNode>().initializer());
           MOZ_ASSERT(spec->right()->isKind(ParseNodeKind::Name));
           MOZ_ASSERT(!spec->right()->as<NameNode>().initializer());
         }
 #endif
         break;
       }
 
-      case ParseNodeKind::CallImport: {
+      case ParseNodeKind::CallImportExpr: {
         BinaryNode* node = &cur->as<BinaryNode>();
         if (!resolve(node->right(), prefix)) {
           return false;
         }
         break;
       }
 
-      case ParseNodeKind::Dot: {
+      case ParseNodeKind::DotExpr: {
         // Super prop nodes do not have a meaningful LHS
         PropertyAccess* prop = &cur->as<PropertyAccess>();
         if (prop->isSuper()) {
           break;
         }
         if (!resolve(&prop->expression(), prefix)) {
           return false;
         }
         break;
       }
 
-      case ParseNodeKind::Label:
+      case ParseNodeKind::LabelStmt:
         if (!resolve(cur->as<LabeledStatement>().statement(), prefix)) {
           return false;
         }
         break;
 
       case ParseNodeKind::Name:
         if (ParseNode* init = cur->as<NameNode>().initializer()) {
           if (!resolve(init, prefix)) {
@@ -958,21 +959,21 @@ class NameResolver {
           if (!resolve(body, prefix)) {
             return false;
           }
         }
         break;
 
         // Kinds that should be handled by parent node resolution.
 
-      case ParseNodeKind::ImportSpec:    // by ParseNodeKind::ImportSpecList
-      case ParseNodeKind::ExportSpec:    // by ParseNodeKind::ExportSpecList
-      case ParseNodeKind::CallSiteObj:   // by ParseNodeKind::TaggedTemplate
-      case ParseNodeKind::ClassNames:    // by ParseNodeKind::Class
-      case ParseNodeKind::PropertyName:  // by ParseNodeKind::Dot
+      case ParseNodeKind::ImportSpec:        // by ParseNodeKind::ImportSpecList
+      case ParseNodeKind::ExportSpec:        // by ParseNodeKind::ExportSpecList
+      case ParseNodeKind::CallSiteObjExpr:   // by ParseNodeKind::TaggedTemplate
+      case ParseNodeKind::ClassNames:        // by ParseNodeKind::ClassDecl
+      case ParseNodeKind::PropertyNameExpr:  // by ParseNodeKind::Dot
         MOZ_CRASH("should have been handled by a parent node");
 
       case ParseNodeKind::Limit:  // invalid sentinel value
         MOZ_CRASH("invalid node kind");
     }
 
     nparents--;
     MOZ_ASSERT(initialParents == nparents, "nparents imbalance detected");
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -73,18 +73,18 @@ ParseNode* ParseNode::appendOrCreateList
     //
     // (**) is right-associative; per spec |a ** b ** c| parses as
     // (** a (** b c)). But we treat this the same way, creating a list
     // node: (** a b c). All consumers must understand that this must be
     // processed with a right fold, whereas the list (+ a b c) must be
     // processed with a left fold because (+) is left-associative.
     //
     if (left->isKind(kind) &&
-        (kind == ParseNodeKind::Pow ? !left->pn_parens
-                                    : left->isBinaryOperation())) {
+        (kind == ParseNodeKind::PowExpr ? !left->pn_parens
+                                        : left->isBinaryOperation())) {
       ListNode* list = &left->as<ListNode>();
 
       list->append(right);
       list->pn_pos.end = right->pn_pos.end;
 
       return list;
     }
   }
@@ -181,26 +181,26 @@ void ParseNode::dump(GenericPrinter& out
       as<LexicalScopeNode>().dump(out, indent);
       return;
   }
   out.printf("#<BAD NODE %p, kind=%u>", (void*)this, unsigned(getKind()));
 }
 
 void NullaryNode::dump(GenericPrinter& out) {
   switch (getKind()) {
-    case ParseNodeKind::True:
+    case ParseNodeKind::TrueExpr:
       out.put("#true");
       break;
-    case ParseNodeKind::False:
+    case ParseNodeKind::FalseExpr:
       out.put("#false");
       break;
-    case ParseNodeKind::Null:
+    case ParseNodeKind::NullExpr:
       out.put("#null");
       break;
-    case ParseNodeKind::RawUndefined:
+    case ParseNodeKind::RawUndefinedExpr:
       out.put("#undefined");
       break;
 
     default:
       out.printf("(%s)", parseNodeNames[size_t(getKind())]);
   }
 }
 
@@ -241,17 +241,17 @@ void UnaryNode::dump(GenericPrinter& out
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s ", name);
   indent += strlen(name) + 2;
   DumpParseTree(kid(), out, indent);
   out.printf(")");
 }
 
 void BinaryNode::dump(GenericPrinter& out, int indent) {
-  if (isKind(ParseNodeKind::Dot)) {
+  if (isKind(ParseNodeKind::DotExpr)) {
     out.put("(.");
 
     DumpParseTree(right(), out, indent + 2);
 
     out.putChar(' ');
     if (as<PropertyAccess>().isSuper()) {
       out.put("super");
     } else {
@@ -320,26 +320,26 @@ static void DumpName(GenericPrinter& out
     } else {
       out.printf("\\u%04x", unsigned(c));
     }
   }
 }
 
 void NameNode::dump(GenericPrinter& out, int indent) {
   switch (getKind()) {
-    case ParseNodeKind::String:
-    case ParseNodeKind::TemplateString:
+    case ParseNodeKind::StringExpr:
+    case ParseNodeKind::TemplateStringExpr:
     case ParseNodeKind::ObjectPropertyName:
       atom()->dumpCharsNoNewline(out);
       return;
 
     case ParseNodeKind::Name:
     case ParseNodeKind::PrivateName:  // atom() already includes the '#', no
                                       // need to specially include it.
-    case ParseNodeKind::PropertyName:
+    case ParseNodeKind::PropertyNameExpr:
       if (!atom()) {
         out.put("#<null name>");
       } else if (getOp() == JSOP_GETARG && atom()->length() == 0) {
         // Dump destructuring parameter.
         static const char ZeroLengthPrefix[] = "(#<zero-length name> ";
         constexpr size_t ZeroLengthPrefixLength =
             ArrayLength(ZeroLengthPrefix) - 1;
         out.put(ZeroLengthPrefix);
@@ -350,17 +350,17 @@ void NameNode::dump(GenericPrinter& out,
         if (atom()->hasLatin1Chars()) {
           DumpName(out, atom()->latin1Chars(nogc), atom()->length());
         } else {
           DumpName(out, atom()->twoByteChars(nogc), atom()->length());
         }
       }
       return;
 
-    case ParseNodeKind::Label: {
+    case ParseNodeKind::LabelStmt: {
       const char* name = parseNodeNames[size_t(getKind())];
       out.printf("(%s ", name);
       atom()->dumpCharsNoNewline(out);
       indent += strlen(name) + atom()->length() + 2;
       DumpParseTree(initializer(), out, indent);
       out.printf(")");
       return;
     }
@@ -471,17 +471,17 @@ void FunctionBox::trace(JSTracer* trc) {
     TraceRoot(trc, &enclosingScope_, "funbox-enclosingScope");
   }
 }
 
 bool js::frontend::IsAnonymousFunctionDefinition(ParseNode* pn) {
   // ES 2017 draft
   // 12.15.2 (ArrowFunction, AsyncArrowFunction).
   // 14.1.12 (FunctionExpression).
-  // 14.4.8 (GeneratorExpression).
+  // 14.4.8 (Generatoression).
   // 14.6.8 (AsyncFunctionExpression)
   if (pn->isKind(ParseNodeKind::Function) &&
       !pn->as<CodeNode>().funbox()->function()->explicitName()) {
     return true;
   }
 
   // 14.5.8 (ClassExpression)
   if (pn->is<ClassNode>() && !pn->as<ClassNode>().names()) {
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -48,220 +48,222 @@ class ParseContext;
 class FullParseHandler;
 class FunctionBox;
 class ObjectBox;
 #ifdef ENABLE_BIGINT
 class BigIntBox;
 #endif
 
 #define FOR_EACH_PARSE_NODE_KIND(F)                                          \
-  F(EmptyStatement, PN_NULLARY)                                              \
-  F(ExpressionStatement, PN_UNARY)                                           \
-  F(Comma, PN_LIST)                                                          \
-  F(Conditional, PN_TERNARY)                                                 \
+  F(EmptyStmt, PN_NULLARY)                                                   \
+  F(ExpressionStmt, PN_UNARY)                                                \
+  F(CommaExpr, PN_LIST)                                                      \
+  F(ConditionalExpr, PN_TERNARY)                                             \
   F(Colon, PN_BINARY)                                                        \
   F(Shorthand, PN_BINARY)                                                    \
-  F(Pos, PN_UNARY)                                                           \
-  F(Neg, PN_UNARY)                                                           \
-  F(PreIncrement, PN_UNARY)                                                  \
-  F(PostIncrement, PN_UNARY)                                                 \
-  F(PreDecrement, PN_UNARY)                                                  \
-  F(PostDecrement, PN_UNARY)                                                 \
-  F(PropertyName, PN_NAME)                                                   \
-  F(Dot, PN_BINARY)                                                          \
-  F(Elem, PN_BINARY)                                                         \
-  F(Array, PN_LIST)                                                          \
+  F(PosExpr, PN_UNARY)                                                       \
+  F(NegExpr, PN_UNARY)                                                       \
+  F(PreIncrementExpr, PN_UNARY)                                              \
+  F(PostIncrementExpr, PN_UNARY)                                             \
+  F(PreDecrementExpr, PN_UNARY)                                              \
+  F(PostDecrementExpr, PN_UNARY)                                             \
+  F(PropertyNameExpr, PN_NAME)                                               \
+  F(DotExpr, PN_BINARY)                                                      \
+  F(ElemExpr, PN_BINARY)                                                     \
+  F(ArrayExpr, PN_LIST)                                                      \
   F(Elision, PN_NULLARY)                                                     \
   F(StatementList, PN_LIST)                                                  \
-  F(Label, PN_NAME)                                                          \
-  F(Object, PN_LIST)                                                         \
-  F(Call, PN_BINARY)                                                         \
+  F(LabelStmt, PN_NAME)                                                      \
+  F(ObjectExpr, PN_LIST)                                                     \
+  F(CallExpr, PN_BINARY)                                                     \
   F(Arguments, PN_LIST)                                                      \
   F(Name, PN_NAME)                                                           \
   F(ObjectPropertyName, PN_NAME)                                             \
   F(PrivateName, PN_NAME)                                                    \
   F(ComputedName, PN_UNARY)                                                  \
-  F(Number, PN_NUMBER)                                                       \
-  IF_BIGINT(F(BigInt, PN_BIGINT), /**/)                                      \
-  F(String, PN_NAME)                                                         \
-  F(TemplateStringList, PN_LIST)                                             \
-  F(TemplateString, PN_NAME)                                                 \
-  F(TaggedTemplate, PN_BINARY)                                               \
-  F(CallSiteObj, PN_LIST)                                                    \
-  F(RegExp, PN_REGEXP)                                                       \
-  F(True, PN_NULLARY)                                                        \
-  F(False, PN_NULLARY)                                                       \
-  F(Null, PN_NULLARY)                                                        \
-  F(RawUndefined, PN_NULLARY)                                                \
-  F(This, PN_UNARY)                                                          \
+  F(NumberExpr, PN_NUMBER)                                                   \
+  IF_BIGINT(F(BigIntExpr, PN_BIGINT), /**/)                                  \
+  F(StringExpr, PN_NAME)                                                     \
+  F(TemplateStringListExpr, PN_LIST)                                         \
+  F(TemplateStringExpr, PN_NAME)                                             \
+  F(TaggedTemplateExpr, PN_BINARY)                                           \
+  F(CallSiteObjExpr, PN_LIST)                                                \
+  F(RegExpExpr, PN_REGEXP)                                                   \
+  F(TrueExpr, PN_NULLARY)                                                    \
+  F(FalseExpr, PN_NULLARY)                                                   \
+  F(NullExpr, PN_NULLARY)                                                    \
+  F(RawUndefinedExpr, PN_NULLARY)                                            \
+  F(ThisExpr, PN_UNARY)                                                      \
   F(Function, PN_CODE)                                                       \
   F(Module, PN_CODE)                                                         \
-  F(If, PN_TERNARY)                                                          \
-  F(Switch, PN_BINARY)                                                       \
+  F(IfStmt, PN_TERNARY)                                                      \
+  F(SwitchStmt, PN_BINARY)                                                   \
   F(Case, PN_BINARY)                                                         \
-  F(While, PN_BINARY)                                                        \
-  F(DoWhile, PN_BINARY)                                                      \
-  F(For, PN_BINARY)                                                          \
-  F(Break, PN_LOOP)                                                          \
-  F(Continue, PN_LOOP)                                                       \
-  F(Var, PN_LIST)                                                            \
-  F(Const, PN_LIST)                                                          \
-  F(With, PN_BINARY)                                                         \
-  F(Return, PN_UNARY)                                                        \
-  F(New, PN_BINARY)                                                          \
+  F(WhileStmt, PN_BINARY)                                                    \
+  F(DoWhileStmt, PN_BINARY)                                                  \
+  F(ForStmt, PN_BINARY)                                                      \
+  F(BreakStmt, PN_LOOP)                                                      \
+  F(ContinueStmt, PN_LOOP)                                                   \
+  F(VarStmt, PN_LIST)                                                        \
+  F(ConstDecl, PN_LIST)                                                      \
+  F(WithStmt, PN_BINARY)                                                     \
+  F(ReturnStmt, PN_UNARY)                                                    \
+  F(NewExpr, PN_BINARY)                                                      \
   /* Delete operations.  These must be sequential. */                        \
-  F(DeleteName, PN_UNARY)                                                    \
-  F(DeleteProp, PN_UNARY)                                                    \
-  F(DeleteElem, PN_UNARY)                                                    \
+  F(DeleteNameExpr, PN_UNARY)                                                \
+  F(DeletePropExpr, PN_UNARY)                                                \
+  F(DeleteElemExpr, PN_UNARY)                                                \
   F(DeleteExpr, PN_UNARY)                                                    \
-  F(Try, PN_TERNARY)                                                         \
+  F(TryStmt, PN_TERNARY)                                                     \
   F(Catch, PN_BINARY)                                                        \
-  F(Throw, PN_UNARY)                                                         \
-  F(Debugger, PN_NULLARY)                                                    \
+  F(ThrowStmt, PN_UNARY)                                                     \
+  F(DebuggerStmt, PN_NULLARY)                                                \
   F(Generator, PN_NULLARY)                                                   \
   F(InitialYield, PN_UNARY)                                                  \
-  F(Yield, PN_UNARY)                                                         \
-  F(YieldStar, PN_UNARY)                                                     \
+  F(YieldExpr, PN_UNARY)                                                     \
+  F(YieldStarExpr, PN_UNARY)                                                 \
   F(LexicalScope, PN_SCOPE)                                                  \
-  F(Let, PN_LIST)                                                            \
-  F(Import, PN_BINARY)                                                       \
+  F(LetDecl, PN_LIST)                                                        \
+  F(ImportDecl, PN_BINARY)                                                   \
   F(ImportSpecList, PN_LIST)                                                 \
   F(ImportSpec, PN_BINARY)                                                   \
-  F(Export, PN_UNARY)                                                        \
-  F(ExportFrom, PN_BINARY)                                                   \
-  F(ExportDefault, PN_BINARY)                                                \
+  F(ExportStmt, PN_UNARY)                                                    \
+  F(ExportFromStmt, PN_BINARY)                                               \
+  F(ExportDefaultStmt, PN_BINARY)                                            \
   F(ExportSpecList, PN_LIST)                                                 \
   F(ExportSpec, PN_BINARY)                                                   \
-  F(ExportBatchSpec, PN_NULLARY)                                             \
+  F(ExportBatchSpecStmt, PN_NULLARY)                                         \
   F(ForIn, PN_TERNARY)                                                       \
   F(ForOf, PN_TERNARY)                                                       \
   F(ForHead, PN_TERNARY)                                                     \
   F(ParamsBody, PN_LIST)                                                     \
   F(Spread, PN_UNARY)                                                        \
   F(MutateProto, PN_UNARY)                                                   \
-  F(Class, PN_TERNARY)                                                       \
+  F(ClassDecl, PN_TERNARY)                                                   \
   F(ClassMethod, PN_BINARY)                                                  \
   F(ClassField, PN_FIELD)                                                    \
   F(ClassMemberList, PN_LIST)                                                \
   F(ClassNames, PN_BINARY)                                                   \
-  F(NewTarget, PN_BINARY)                                                    \
+  F(NewTargetExpr, PN_BINARY)                                                \
   F(PosHolder, PN_NULLARY)                                                   \
   F(SuperBase, PN_UNARY)                                                     \
-  F(SuperCall, PN_BINARY)                                                    \
+  F(SuperCallExpr, PN_BINARY)                                                \
   F(SetThis, PN_BINARY)                                                      \
-  F(ImportMeta, PN_BINARY)                                                   \
-  F(CallImport, PN_BINARY)                                                   \
+  F(ImportMetaExpr, PN_BINARY)                                               \
+  F(CallImportExpr, PN_BINARY)                                               \
                                                                              \
   /* Unary operators. */                                                     \
-  F(TypeOfName, PN_UNARY)                                                    \
+  F(TypeOfNameExpr, PN_UNARY)                                                \
   F(TypeOfExpr, PN_UNARY)                                                    \
-  F(Void, PN_UNARY)                                                          \
-  F(Not, PN_UNARY)                                                           \
-  F(BitNot, PN_UNARY)                                                        \
-  F(Await, PN_UNARY)                                                         \
+  F(VoidExpr, PN_UNARY)                                                      \
+  F(NotExpr, PN_UNARY)                                                       \
+  F(BitNotExpr, PN_UNARY)                                                    \
+  F(AwaitExpr, PN_UNARY)                                                     \
                                                                              \
   /*                                                                         \
    * Binary operators.                                                       \
    * These must be in the same order as TOK_OR and friends in TokenStream.h. \
    */                                                                        \
-  F(Pipeline, PN_LIST)                                                       \
-  F(Or, PN_LIST)                                                             \
-  F(And, PN_LIST)                                                            \
-  F(BitOr, PN_LIST)                                                          \
-  F(BitXor, PN_LIST)                                                         \
-  F(BitAnd, PN_LIST)                                                         \
-  F(StrictEq, PN_LIST)                                                       \
-  F(Eq, PN_LIST)                                                             \
-  F(StrictNe, PN_LIST)                                                       \
-  F(Ne, PN_LIST)                                                             \
-  F(Lt, PN_LIST)                                                             \
-  F(Le, PN_LIST)                                                             \
-  F(Gt, PN_LIST)                                                             \
-  F(Ge, PN_LIST)                                                             \
-  F(InstanceOf, PN_LIST)                                                     \
-  F(In, PN_LIST)                                                             \
-  F(Lsh, PN_LIST)                                                            \
-  F(Rsh, PN_LIST)                                                            \
-  F(Ursh, PN_LIST)                                                           \
-  F(Add, PN_LIST)                                                            \
-  F(Sub, PN_LIST)                                                            \
-  F(Star, PN_LIST)                                                           \
-  F(Div, PN_LIST)                                                            \
-  F(Mod, PN_LIST)                                                            \
-  F(Pow, PN_LIST)                                                            \
+  F(PipelineExpr, PN_LIST)                                                   \
+  F(OrExpr, PN_LIST)                                                         \
+  F(AndExpr, PN_LIST)                                                        \
+  F(BitOrExpr, PN_LIST)                                                      \
+  F(BitXorExpr, PN_LIST)                                                     \
+  F(BitAndExpr, PN_LIST)                                                     \
+  F(StrictEqExpr, PN_LIST)                                                   \
+  F(EqExpr, PN_LIST)                                                         \
+  F(StrictNeExpr, PN_LIST)                                                   \
+  F(NeExpr, PN_LIST)                                                         \
+  F(LtExpr, PN_LIST)                                                         \
+  F(LeExpr, PN_LIST)                                                         \
+  F(GtExpr, PN_LIST)                                                         \
+  F(GeExpr, PN_LIST)                                                         \
+  F(InstanceOfExpr, PN_LIST)                                                 \
+  F(InExpr, PN_LIST)                                                         \
+  F(LshExpr, PN_LIST)                                                        \
+  F(RshExpr, PN_LIST)                                                        \
+  F(UrshExpr, PN_LIST)                                                       \
+  F(AddExpr, PN_LIST)                                                        \
+  F(SubExpr, PN_LIST)                                                        \
+  F(MulExpr, PN_LIST)                                                        \
+  F(DivExpr, PN_LIST)                                                        \
+  F(ModExpr, PN_LIST)                                                        \
+  F(PowExpr, PN_LIST)                                                        \
                                                                              \
   /* Assignment operators (= += -= etc.). */                                 \
   /* ParseNode::isAssignment assumes all these are consecutive. */           \
-  F(Assign, PN_BINARY)                                                       \
-  F(AddAssign, PN_BINARY)                                                    \
-  F(SubAssign, PN_BINARY)                                                    \
-  F(BitOrAssign, PN_BINARY)                                                  \
-  F(BitXorAssign, PN_BINARY)                                                 \
-  F(BitAndAssign, PN_BINARY)                                                 \
-  F(LshAssign, PN_BINARY)                                                    \
-  F(RshAssign, PN_BINARY)                                                    \
-  F(UrshAssign, PN_BINARY)                                                   \
-  F(MulAssign, PN_BINARY)                                                    \
-  F(DivAssign, PN_BINARY)                                                    \
-  F(ModAssign, PN_BINARY)                                                    \
-  F(PowAssign, PN_BINARY)
+  F(AssignExpr, PN_BINARY)                                                   \
+  F(AddAssignExpr, PN_BINARY)                                                \
+  F(SubAssignExpr, PN_BINARY)                                                \
+  F(BitOrAssignExpr, PN_BINARY)                                              \
+  F(BitXorAssignExpr, PN_BINARY)                                             \
+  F(BitAndAssignExpr, PN_BINARY)                                             \
+  F(LshAssignExpr, PN_BINARY)                                                \
+  F(RshAssignExpr, PN_BINARY)                                                \
+  F(UrshAssignExpr, PN_BINARY)                                               \
+  F(MulAssignExpr, PN_BINARY)                                                \
+  F(DivAssignExpr, PN_BINARY)                                                \
+  F(ModAssignExpr, PN_BINARY)                                                \
+  F(PowAssignExpr, PN_BINARY)
 
 /*
  * Parsing builds a tree of nodes that directs code generation.  This tree is
  * not a concrete syntax tree in all respects (for example, || and && are left
  * associative, but (A && B && C) translates into the right-associated tree
  * <A && <B && C>> so that code generation can emit a left-associative branch
  * around <B && C> when A is false).  Nodes are labeled by kind, with a
  * secondary JSOp label when needed.
  *
  * The long comment after this enum block describes the kinds in detail.
  */
 enum class ParseNodeKind : uint16_t {
 #define EMIT_ENUM(name, _arity) name,
   FOR_EACH_PARSE_NODE_KIND(EMIT_ENUM)
 #undef EMIT_ENUM
       Limit, /* domain size */
-  BinOpFirst = ParseNodeKind::Pipeline,
-  BinOpLast = ParseNodeKind::Pow,
-  AssignmentStart = ParseNodeKind::Assign,
-  AssignmentLast = ParseNodeKind::PowAssign
+  BinOpFirst = ParseNodeKind::PipelineExpr,
+  BinOpLast = ParseNodeKind::PowExpr,
+  AssignmentStart = ParseNodeKind::AssignExpr,
+  AssignmentLast = ParseNodeKind::PowAssignExpr,
 };
 
 inline bool IsDeleteKind(ParseNodeKind kind) {
-  return ParseNodeKind::DeleteName <= kind && kind <= ParseNodeKind::DeleteExpr;
+  return ParseNodeKind::DeleteNameExpr <= kind &&
+         kind <= ParseNodeKind::DeleteExpr;
 }
 
 inline bool IsTypeofKind(ParseNodeKind kind) {
-  return ParseNodeKind::TypeOfName <= kind && kind <= ParseNodeKind::TypeOfExpr;
+  return ParseNodeKind::TypeOfNameExpr <= kind &&
+         kind <= ParseNodeKind::TypeOfExpr;
 }
 
 /*
  * <Definitions>
  * Function (CodeNode)
  *   funbox: ptr to js::FunctionBox holding function object containing arg and
  *           var properties.  We create the function object at parse (not emit)
  *           time to specialize arg and var bytecodes early.
  *   body: ParamsBody or null for lazily-parsed function, ordinarily;
  *         ParseNodeKind::LexicalScope for implicit function in genexpr
  * ParamsBody (ListNode)
  *   head: list of formal parameters with
  *           * Name node with non-empty name for SingleNameBinding without
  *             Initializer
- *           * Assign node for SingleNameBinding with Initializer
+ *           * AssignExpr node for SingleNameBinding with Initializer
  *           * Name node with empty name for destructuring
  *               expr: Array or Object for BindingPattern without
  *                     Initializer, Assign for BindingPattern with
  *                     Initializer
  *         followed by either:
  *           * StatementList node for function body statements
- *           * Return for expression closure
+ *           * ReturnStmt for expression closure
  *   count: number of formal parameters + 1
  * Spread (UnaryNode)
  *   kid: expression being spread
- * Class (ClassNode)
+ * ClassDecl (ClassNode)
  *   kid1: ClassNames for class name. can be null for anonymous class.
  *   kid2: expression after `extends`. null if no expression
  *   kid3: either of
  *           * ClassMemberList, if anonymous class
  *           * LexicalScopeNode which contains ClassMemberList as scopeBody,
  *             if named class
  * ClassNames (ClassNames)
  *   left: Name node for outer binding, or null if the class is an expression
@@ -276,35 +278,35 @@ inline bool IsTypeofKind(ParseNodeKind k
  * Module (CodeNode)
  *   funbox: ?
  *   body: ?
  *
  * <Statements>
  * StatementList (ListNode)
  *   head: list of N statements
  *   count: N >= 0
- * If (TernaryNode)
+ * IfStmt (TernaryNode)
  *   kid1: cond
  *   kid2: then
  *   kid3: else or null
- * Switch (SwitchStatement)
+ * SwitchStmt (SwitchStatement)
  *   left: discriminant
  *   right: LexicalScope node that contains the list of Case nodes, with at
  *          most one default node.
  *   hasDefault: true if there's a default case
  * Case (CaseClause)
  *   left: case-expression if CaseClause, or null if DefaultClause
  *   right: StatementList node for this case's statements
- * While (BinaryNode)
+ * WhileStmt (BinaryNode)
  *   left: cond
  *   right: body
- * DoWhile (BinaryNode)
+ * DoWhileStmt (BinaryNode)
  *   left: body
  *   right: cond
- * For (ForNode)
+ * ForStmt (ForNode)
  *   left: one of
  *           * ForIn: for (x in y) ...
  *           * ForOf: for (x of x) ...
  *           * ForHead: for (;;) ...
  *   right: body
  * ForIn (TernaryNode)
  *   kid1: declaration or expression to left of 'in'
  *   kid2: null
@@ -312,145 +314,148 @@ inline bool IsTypeofKind(ParseNodeKind k
  * ForOf (TernaryNode)
  *   kid1: declaration or expression to left of 'of'
  *   kid2: null
  *   kid3: expr to right of 'of'
  * ForHead (TernaryNode)
  *   kid1:  init expr before first ';' or nullptr
  *   kid2:  cond expr before second ';' or nullptr
  *   kid3:  update expr after second ';' or nullptr
- * Throw (UnaryNode)
+ * ThrowStmt (UnaryNode)
  *   kid: thrown exception
- * Try (TernaryNode)
+ * TryStmt (TernaryNode)
  *   kid1: try block
  *   kid2: null or LexicalScope for catch-block with scopeBody pointing to a
  *         Catch node
  *   kid3: null or finally block
  * Catch (BinaryNode)
  *   left: Name, Array, or Object catch var node
  *         (Array or Object if destructuring),
  *         or null if optional catch binding
  *   right: catch block statements
- * Break (BreakStatement)
+ * BreakStmt (BreakStatement)
  *   label: label or null
- * Continue (ContinueStatement)
+ * ContinueStmt (ContinueStatement)
  *   label: label or null
- * With (BinaryNode)
+ * WithStmt (BinaryNode)
  *   left: head expr
  *   right: body
- * Var, Let, Const (ListNode)
- *   head: list of N Name or Assign nodes
+ * VarStmt, LetDecl, ConstDecl (ListNode)
+ *   head: list of N Name or AssignExpr nodes
  *         each name node has either
  *           atom: variable name
  *           expr: initializer or null
  *         or
  *           atom: variable name
  *         each assignment node has
  *           left: pattern
  *           right: initializer
  *   count: N > 0
- * Return (UnaryNode)
+ * ReturnStmt (UnaryNode)
  *   kid: returned expression, or null if none
- * ExpressionStatement (UnaryNode)
+ * ExpressionStmt (UnaryNode)
  *   kid: expr
  *   prologue: true if Directive Prologue member in original source, not
  *             introduced via constant folding or other tree rewriting
- * EmptyStatement (NullaryNode)
+ * EmptyStmt (NullaryNode)
  *   (no fields)
- * Label (LabeledStatement)
+ * LabelStmt (LabeledStatement)
  *   atom: label
  *   expr: labeled statement
- * Import (BinaryNode)
+ * ImportDecl (BinaryNode)
  *   left: ImportSpecList import specifiers
  *   right: String module specifier
  * ImportSpecList (ListNode)
  *   head: list of N ImportSpec nodes
  *   count: N >= 0 (N = 0 for `import {} from ...`)
  * ImportSpec (BinaryNode)
  *   left: import name
  *   right: local binding name
- * Export (UnaryNode)
+ * ExportStmt (UnaryNode)
  *   kid: declaration expression
- * ExportFrom (BinaryNode)
+ * ExportFromStmt (BinaryNode)
  *   left: ExportSpecList export specifiers
  *   right: String module specifier
  * ExportSpecList (ListNode)
  *   head: list of N ExportSpec nodes
  *   count: N >= 0 (N = 0 for `export {}`)
  * ExportSpec (BinaryNode)
  *   left: local binding name
  *   right: export name
- * ExportDefault (BinaryNode)
+ * ExportDefaultStmt (BinaryNode)
  *   left: export default declaration or expression
  *   right: Name node for assignment
  *
  * <Expressions>
  * All left-associated binary trees of the same type are optimized into lists
  * to avoid recursion when processing expression chains.
- * Comma (ListNode)
+ * CommaExpr (ListNode)
  *   head: list of N comma-separated exprs
  *   count: N >= 2
- * Assign (BinaryNode)
+ * AssignExpr (BinaryNode)
  *   left: target of assignment
  *   right: value to assign
- * AddAssign, SubAssign, BitOrAssign, BitXorAssign, BitAndAssign,
- * LshAssign, RshAssign, UrshAssign, MulAssign, DivAssign, ModAssign,
- * PowAssign (AssignmentNode)
+ * AddAssignExpr, SubAssignExpr, BitOrAssignExpr, BitXorAssignExpr,
+ * BitAndAssignExpr, LshAssignExpr, RshAssignExpr, UrshAssignExpr,
+ * MulAssignExpr, DivAssignExpr, ModAssignExpr, PowAssignExpr (AssignmentNode)
  *   left: target of assignment
  *   right: value to assign
  *   pn_op: JSOP_ADD for +=, etc
- * Conditional (ConditionalExpression)
+ * ConditionalExpr (ConditionalExpression)
  *   (cond ? thenExpr : elseExpr)
  *   kid1: cond
  *   kid2: thenExpr
  *   kid3: elseExpr
- * Pipeline, Or, And, BitOr, BitXor, BitAnd, StrictEq, Eq, StrictNe, Ne,
- * Lt, Le, Gt, Ge, InstanceOf, In, Lsh, Rsh, Ursh, Add, Sub, Star, Div, Mod,
- * Pow (ListNode)
+ * PipelineExpr, OrExpr, AndExpr, BitOrExpr, BitXorExpr, BitAndExpr,
+ * StrictEqExpr, EqExpr, StrictNeExpr, NeExpr, LtExpr, LeExpr, GtExpr, GeExpr,
+ * InstanceOfExpr, InExpr, LshExpr, RshExpr, UrshExpr, AddExpr, SubExpr,
+ * MulExpr, DivExpr, ModExpr, PowExpr (ListNode)
  *   head: list of N subexpressions
  *         All of these operators are left-associative except Pow which is
  *         right-associative, but still forms a list (see comments in
  *         ParseNode::appendOrCreateList).
  *   count: N >= 2
- * Pos, Neg, Void, Not, BitNot, TypeOfName, TypeOfExpr (UnaryNode)
+ * PosExpr, NegExpr, VoidExpr, NotExpr, BitNotExpr, TypeOfNameExpr,
+ * TypeOfExpr (UnaryNode)
  *   kid: unary expr
- * PreIncrement PostIncrement, PreDecrement, PostDecrement (UnaryNode)
+ * PreIncrementExpr, PostIncrementExpr, PreDecrementExpr,
+ * PostDecrementExpr (UnaryNode)
  *   kid: member expr
- * New (BinaryNode)
+ * NewExpr (BinaryNode)
  *   left: ctor expression on the left of the '('
  *   right: Arguments
- * DeleteName, DeleteProp, DeleteElem, DeleteExpr (UnaryNode)
+ * DeleteNameExpr, DeletePropExpr, DeleteElemExpr, DeleteExpr (UnaryNode)
  *   kid: expression that's evaluated, then the overall delete evaluates to
  *        true; can't be a kind for a more-specific ParseNodeKind::Delete*
  *        unless constant folding (or a similar parse tree manipulation) has
  *        occurred
- *          * DeleteName: Name expr
- *          * DeleteProp: Dot expr
- *          * DeleteElem: Elem expr
+ *          * DeleteNameExpr: Name expr
+ *          * DeletePropExpr: Dot expr
+ *          * DeleteElemExpr: Elem expr
  *          * DeleteExpr: Member expr
- * PropertyName (NameNode)
+ * PropertyNameExpr (NameNode)
  *   atom: property name being accessed
- * Dot (PropertyAccess)
+ * DotExpr (PropertyAccess)
  *   left: MEMBER expr to left of '.'
  *   right: PropertyName to right of '.'
- * Elem (PropertyByValue)
+ * ElemExpr (PropertyByValue)
  *   left: MEMBER expr to left of '['
  *   right: expr between '[' and ']'
- * Call (BinaryNode)
+ * CallExpr (BinaryNode)
  *   left: callee expression on the left of the '('
  *   right: Arguments
  * Arguments (ListNode)
  *   head: list of arg1, arg2, ... argN
  *   count: N >= 0
- * Array (ListNode)
+ * ArrayExpr (ListNode)
  *   head: list of N array element expressions
  *         holes ([,,]) are represented by Elision nodes,
  *         spread elements ([...X]) are represented by Spread nodes
  *   count: N >= 0
- * Object (ListNode)
+ * ObjectExpr (ListNode)
  *   head: list of N nodes, each item is one of:
  *           * MutateProto
  *           * Colon
  *           * Shorthand
  *           * Spread
  *   count: N >= 0
  * Colon (BinaryNode)
  *   key-value pair in object initializer or destructuring lhs
@@ -462,68 +467,67 @@ inline bool IsTypeofKind(ParseNodeKind k
  * ComputedName (UnaryNode)
  *   ES6 ComputedPropertyName.
  *   kid: the AssignmentExpression inside the square brackets
  * Name (NameNode)
  *   atom: name, or object atom
  *   pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT
  *          If JSOP_GETNAME, pn_op may be JSOP_*ARG or JSOP_*VAR telling
  *          const-ness and static analysis results
- * String (NameNode)
+ * StringExpr (NameNode)
  *   atom: string
- * TemplateStringList (ListNode)
+ * TemplateStringListExpr (ListNode)
  *   head: list of alternating expr and template strings
  *           TemplateString [, expression, TemplateString]+
  *         there's at least one expression.  If the template literal contains
  *         no ${}-delimited expression, it's parsed as a single TemplateString
- * TemplateString (NameNode)
+ * TemplateStringExpr (NameNode)
  *   atom: template string atom
- * TaggedTemplate (BinaryNode)
+ * TaggedTemplateExpr (BinaryNode)
  *   left: tag expression
  *   right: Arguments, with the first being the call site object, then
  *          arg1, arg2, ... argN
- * CallSiteObj (CallSiteNode)
+ * CallSiteObjExpr (CallSiteNode)
  *   head:  an Array of raw TemplateString, then corresponding cooked
  *          TemplateString nodes
  *            Array [, cooked TemplateString]+
  *          where the Array is
  *            [raw TemplateString]+
- * RegExp (RegExpLiteral)
+ * RegExpExpr (RegExpLiteral)
  *   regexp: RegExp model object
- * Number (NumericLiteral)
+ * NumberExpr (NumericLiteral)
  *   value: double value of numeric literal
- * BigInt (BigIntLiteral)
+ * BigIntExpr (BigIntLiteral)
  *   box: BigIntBox holding BigInt* value
- * True, False (BooleanLiteral)
+ * TrueExpr, FalseExpr (BooleanLiteral)
  *   pn_op: JSOp bytecode
- * Null (NullLiteral)
+ * NullExpr (NullLiteral)
  *   pn_op: JSOp bytecode
- * RawUndefined (RawUndefinedLiteral)
+ * RawUndefinedExpr (RawUndefinedLiteral)
  *   pn_op: JSOp bytecode
  *
- * This (UnaryNode)
+ * ThisExpr (UnaryNode)
  *   kid: '.this' Name if function `this`, else nullptr
  * SuperBase (UnaryNode)
  *   kid: '.this' Name
- * SuperCall (BinaryNode)
+ * SuperCallExpr (BinaryNode)
  *   left: SuperBase
  *   right: Arguments
  * SetThis (BinaryNode)
  *   left: '.this' Name
  *   right: SuperCall
  *
  * LexicalScope (LexicalScopeNode)
  *   scopeBindings: scope bindings
  *   scopeBody: scope body
  * Generator (NullaryNode)
  * InitialYield (UnaryNode)
  *   kid: generator object
- * Yield, YieldStar, Await (UnaryNode)
+ * YieldExpr, YieldStarExpr, AwaitExpr (UnaryNode)
  *   kid: expr or null
- * Nop (NullaryNode)
  */
 enum ParseNodeArity {
   PN_NULLARY, /* 0 kids */
   PN_UNARY,   /* one kid, plus a couple of scalars */
   PN_BINARY,  /* two kids, plus a couple of scalars */
   PN_TERNARY, /* three kids */
   PN_CODE,    /* module or function definition node */
   PN_LIST,    /* generic singly linked list */
@@ -763,23 +767,25 @@ class ParseNode {
    */
   static ParseNode* appendOrCreateList(ParseNodeKind kind, ParseNode* left,
                                        ParseNode* right,
                                        FullParseHandler* handler,
                                        ParseContext* pc);
 
   /* True if pn is a parsenode representing a literal constant. */
   bool isLiteral() const {
-    return isKind(ParseNodeKind::Number) ||
+    return isKind(ParseNodeKind::NumberExpr) ||
 #ifdef ENABLE_BIGINT
-           isKind(ParseNodeKind::BigInt) ||
+           isKind(ParseNodeKind::BigIntExpr) ||
 #endif
-           isKind(ParseNodeKind::String) || isKind(ParseNodeKind::True) ||
-           isKind(ParseNodeKind::False) || isKind(ParseNodeKind::Null) ||
-           isKind(ParseNodeKind::RawUndefined);
+           isKind(ParseNodeKind::StringExpr) ||
+           isKind(ParseNodeKind::TrueExpr) ||
+           isKind(ParseNodeKind::FalseExpr) ||
+           isKind(ParseNodeKind::NullExpr) ||
+           isKind(ParseNodeKind::RawUndefinedExpr);
   }
 
   // True iff this is a for-in/of loop variable declaration (var/let/const).
   inline bool isForLoopDeclaration() const;
 
   enum AllowConstantObjects {
     DontAllowObjects = 0,
     AllowObjects,
@@ -927,18 +933,18 @@ class UnaryNode : public ParseNode {
    * a directive prologue.
    *
    * Note that a Directive Prologue can contain statements that cannot
    * themselves be directives (string literals that include escape sequences
    * or escaped newlines, say). This member function returns true for such
    * nodes; we use it to determine the extent of the prologue.
    */
   JSAtom* isStringExprStatement() const {
-    if (isKind(ParseNodeKind::ExpressionStatement)) {
-      if (kid()->isKind(ParseNodeKind::String) && !kid()->isInParens()) {
+    if (isKind(ParseNodeKind::ExpressionStmt)) {
+      if (kid()->isKind(ParseNodeKind::StringExpr) && !kid()->isInParens()) {
         return kid()->as<NameNode>().atom();
       }
     }
     return nullptr;
   }
 
   // Methods used by FoldConstants.cpp.
   ParseNode** unsafeKidReference() { return &pn_u.unary.kid; }
@@ -992,27 +998,27 @@ class AssignmentNode : public BinaryNode
     return match;
   }
 };
 
 class ForNode : public BinaryNode {
  public:
   ForNode(const TokenPos& pos, ParseNode* forHead, ParseNode* body,
           unsigned iflags)
-      : BinaryNode(ParseNodeKind::For,
+      : BinaryNode(ParseNodeKind::ForStmt,
                    forHead->isKind(ParseNodeKind::ForIn) ? JSOP_ITER : JSOP_NOP,
                    pos, forHead, body) {
     MOZ_ASSERT(forHead->isKind(ParseNodeKind::ForIn) ||
                forHead->isKind(ParseNodeKind::ForOf) ||
                forHead->isKind(ParseNodeKind::ForHead));
     pn_u.binary.iflags = iflags;
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::For);
+    bool match = node.isKind(ParseNodeKind::ForStmt);
     MOZ_ASSERT_IF(match, node.is<BinaryNode>());
     return match;
   }
 
   TernaryNode* head() const { return &left()->as<TernaryNode>(); }
 
   ParseNode* body() const { return right(); }
 
@@ -1130,38 +1136,40 @@ class ListNode : public ParseNode {
   bool empty() const { return count() == 0; }
 
   MOZ_MUST_USE bool hasTopLevelFunctionDeclarations() const {
     MOZ_ASSERT(isKind(ParseNodeKind::StatementList));
     return pn_u.list.xflags & hasTopLevelFunctionDeclarationsBit;
   }
 
   MOZ_MUST_USE bool hasArrayHoleOrSpread() const {
-    MOZ_ASSERT(isKind(ParseNodeKind::Array));
+    MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr));
     return pn_u.list.xflags & hasArrayHoleOrSpreadBit;
   }
 
   MOZ_MUST_USE bool hasNonConstInitializer() const {
-    MOZ_ASSERT(isKind(ParseNodeKind::Array) || isKind(ParseNodeKind::Object) ||
+    MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr) ||
+               isKind(ParseNodeKind::ObjectExpr) ||
                isKind(ParseNodeKind::ClassMemberList));
     return pn_u.list.xflags & hasNonConstInitializerBit;
   }
 
   void setHasTopLevelFunctionDeclarations() {
     MOZ_ASSERT(isKind(ParseNodeKind::StatementList));
     pn_u.list.xflags |= hasTopLevelFunctionDeclarationsBit;
   }
 
   void setHasArrayHoleOrSpread() {
-    MOZ_ASSERT(isKind(ParseNodeKind::Array));
+    MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr));
     pn_u.list.xflags |= hasArrayHoleOrSpreadBit;
   }
 
   void setHasNonConstInitializer() {
-    MOZ_ASSERT(isKind(ParseNodeKind::Array) || isKind(ParseNodeKind::Object) ||
+    MOZ_ASSERT(isKind(ParseNodeKind::ArrayExpr) ||
+               isKind(ParseNodeKind::ObjectExpr) ||
                isKind(ParseNodeKind::ClassMemberList));
     pn_u.list.xflags |= hasNonConstInitializerBit;
   }
 
   /*
    * Compute a pointer to the last element in a singly-linked list. NB: list
    * must be non-empty -- this is asserted!
    */
@@ -1335,18 +1343,18 @@ class ListNode : public ParseNode {
 
   const range contentsTo(ParseNode* end) const {
     MOZ_ASSERT_IF(end, contains(end));
     return range(head(), end);
   }
 };
 
 inline bool ParseNode::isForLoopDeclaration() const {
-  if (isKind(ParseNodeKind::Var) || isKind(ParseNodeKind::Let) ||
-      isKind(ParseNodeKind::Const)) {
+  if (isKind(ParseNodeKind::VarStmt) || isKind(ParseNodeKind::LetDecl) ||
+      isKind(ParseNodeKind::ConstDecl)) {
     MOZ_ASSERT(!as<ListNode>().empty());
     return true;
   }
 
   return false;
 }
 
 class CodeNode : public ParseNode {
@@ -1400,23 +1408,23 @@ class CodeNode : public ParseNode {
         isOp(JSOP_INITLEXICAL));    // block-level function stmt
     return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN);
   }
 };
 
 class NumericLiteral : public ParseNode {
  public:
   NumericLiteral(double value, DecimalPoint decimalPoint, const TokenPos& pos)
-      : ParseNode(ParseNodeKind::Number, JSOP_NOP, pos) {
+      : ParseNode(ParseNodeKind::NumberExpr, JSOP_NOP, pos) {
     pn_u.number.value = value;
     pn_u.number.decimalPoint = decimalPoint;
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Number);
+    bool match = node.isKind(ParseNodeKind::NumberExpr);
     MOZ_ASSERT_IF(match, node.isArity(PN_NUMBER));
     return match;
   }
 
 #ifdef DEBUG
   void dump(GenericPrinter& out, int indent);
 #endif
 
@@ -1484,25 +1492,25 @@ class LexicalScopeNode : public ParseNod
   bool isEmptyScope() const { return !pn_u.scope.bindings; }
 
   ParseNode** unsafeScopeBodyReference() { return &pn_u.scope.body; }
 };
 
 class LabeledStatement : public NameNode {
  public:
   LabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin)
-      : NameNode(ParseNodeKind::Label, JSOP_NOP, label, stmt,
+      : NameNode(ParseNodeKind::LabelStmt, JSOP_NOP, label, stmt,
                  TokenPos(begin, stmt->pn_pos.end)) {}
 
   PropertyName* label() const { return atom()->asPropertyName(); }
 
   ParseNode* statement() const { return initializer(); }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Label);
+    bool match = node.isKind(ParseNodeKind::LabelStmt);
     MOZ_ASSERT_IF(match, node.isArity(PN_NAME));
     MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
     return match;
   }
 
   // Methods used by FoldConstants.cpp.
   ParseNode** unsafeStatementReference() {
     return unsafeInitializerReference();
@@ -1532,220 +1540,222 @@ class CaseClause : public BinaryNode {
   }
 };
 
 class LoopControlStatement : public ParseNode {
  protected:
   LoopControlStatement(ParseNodeKind kind, PropertyName* label,
                        const TokenPos& pos)
       : ParseNode(kind, JSOP_NOP, pos) {
-    MOZ_ASSERT(kind == ParseNodeKind::Break || kind == ParseNodeKind::Continue);
+    MOZ_ASSERT(kind == ParseNodeKind::BreakStmt ||
+               kind == ParseNodeKind::ContinueStmt);
     pn_u.loopControl.label = label;
     MOZ_ASSERT(is<LoopControlStatement>());
   }
 
  public:
   /* Label associated with this break/continue statement, if any. */
   PropertyName* label() const { return pn_u.loopControl.label; }
 
 #ifdef DEBUG
   void dump(GenericPrinter& out, int indent);
 #endif
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Break) ||
-                 node.isKind(ParseNodeKind::Continue);
+    bool match = node.isKind(ParseNodeKind::BreakStmt) ||
+                 node.isKind(ParseNodeKind::ContinueStmt);
     MOZ_ASSERT_IF(match, node.isArity(PN_LOOP));
     MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
     return match;
   }
 };
 
 class BreakStatement : public LoopControlStatement {
  public:
   BreakStatement(PropertyName* label, const TokenPos& pos)
-      : LoopControlStatement(ParseNodeKind::Break, label, pos) {}
+      : LoopControlStatement(ParseNodeKind::BreakStmt, label, pos) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Break);
+    bool match = node.isKind(ParseNodeKind::BreakStmt);
     MOZ_ASSERT_IF(match, node.is<LoopControlStatement>());
     MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
     return match;
   }
 };
 
 class ContinueStatement : public LoopControlStatement {
  public:
   ContinueStatement(PropertyName* label, const TokenPos& pos)
-      : LoopControlStatement(ParseNodeKind::Continue, label, pos) {}
+      : LoopControlStatement(ParseNodeKind::ContinueStmt, label, pos) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Continue);
+    bool match = node.isKind(ParseNodeKind::ContinueStmt);
     MOZ_ASSERT_IF(match, node.is<LoopControlStatement>());
     MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
     return match;
   }
 };
 
 class DebuggerStatement : public NullaryNode {
  public:
   explicit DebuggerStatement(const TokenPos& pos)
-      : NullaryNode(ParseNodeKind::Debugger, JSOP_NOP, pos) {}
+      : NullaryNode(ParseNodeKind::DebuggerStmt, JSOP_NOP, pos) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Debugger);
+    bool match = node.isKind(ParseNodeKind::DebuggerStmt);
     MOZ_ASSERT_IF(match, node.is<NullaryNode>());
     return match;
   }
 };
 
 class ConditionalExpression : public TernaryNode {
  public:
   ConditionalExpression(ParseNode* condition, ParseNode* thenExpr,
                         ParseNode* elseExpr)
-      : TernaryNode(ParseNodeKind::Conditional, condition, thenExpr, elseExpr,
+      : TernaryNode(ParseNodeKind::ConditionalExpr, condition, thenExpr,
+                    elseExpr,
                     TokenPos(condition->pn_pos.begin, elseExpr->pn_pos.end)) {
     MOZ_ASSERT(condition);
     MOZ_ASSERT(thenExpr);
     MOZ_ASSERT(elseExpr);
   }
 
   ParseNode& condition() const { return *kid1(); }
 
   ParseNode& thenExpression() const { return *kid2(); }
 
   ParseNode& elseExpression() const { return *kid3(); }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Conditional);
+    bool match = node.isKind(ParseNodeKind::ConditionalExpr);
     MOZ_ASSERT_IF(match, node.is<TernaryNode>());
     MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
     return match;
   }
 };
 
 class TryNode : public TernaryNode {
  public:
   TryNode(uint32_t begin, ParseNode* body, LexicalScopeNode* catchScope,
           ParseNode* finallyBlock)
       : TernaryNode(
-            ParseNodeKind::Try, body, catchScope, finallyBlock,
+            ParseNodeKind::TryStmt, body, catchScope, finallyBlock,
             TokenPos(begin,
                      (finallyBlock ? finallyBlock : catchScope)->pn_pos.end)) {
     MOZ_ASSERT(body);
     MOZ_ASSERT(catchScope || finallyBlock);
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Try);
+    bool match = node.isKind(ParseNodeKind::TryStmt);
     MOZ_ASSERT_IF(match, node.is<TernaryNode>());
     return match;
   }
 
   ParseNode* body() const { return kid1(); }
 
   LexicalScopeNode* catchScope() const {
     return kid2() ? &kid2()->as<LexicalScopeNode>() : nullptr;
   }
 
   ParseNode* finallyBlock() const { return kid3(); }
 };
 
 class ThisLiteral : public UnaryNode {
  public:
   ThisLiteral(const TokenPos& pos, ParseNode* thisName)
-      : UnaryNode(ParseNodeKind::This, pos, thisName) {}
+      : UnaryNode(ParseNodeKind::ThisExpr, pos, thisName) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::This);
+    bool match = node.isKind(ParseNodeKind::ThisExpr);
     MOZ_ASSERT_IF(match, node.is<UnaryNode>());
     return match;
   }
 };
 
 class NullLiteral : public NullaryNode {
  public:
   explicit NullLiteral(const TokenPos& pos)
-      : NullaryNode(ParseNodeKind::Null, JSOP_NULL, pos) {}
+      : NullaryNode(ParseNodeKind::NullExpr, JSOP_NULL, pos) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Null);
+    bool match = node.isKind(ParseNodeKind::NullExpr);
     MOZ_ASSERT_IF(match, node.is<NullaryNode>());
     return match;
   }
 };
 
 // This is only used internally, currently just for tagged templates.
 // It represents the value 'undefined' (aka `void 0`), like NullLiteral
 // represents the value 'null'.
 class RawUndefinedLiteral : public NullaryNode {
  public:
   explicit RawUndefinedLiteral(const TokenPos& pos)
-      : NullaryNode(ParseNodeKind::RawUndefined, JSOP_UNDEFINED, pos) {}
+      : NullaryNode(ParseNodeKind::RawUndefinedExpr, JSOP_UNDEFINED, pos) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::RawUndefined);
+    bool match = node.isKind(ParseNodeKind::RawUndefinedExpr);
     MOZ_ASSERT_IF(match, node.is<NullaryNode>());
     return match;
   }
 };
 
 class BooleanLiteral : public NullaryNode {
  public:
   BooleanLiteral(bool b, const TokenPos& pos)
-      : NullaryNode(b ? ParseNodeKind::True : ParseNodeKind::False,
+      : NullaryNode(b ? ParseNodeKind::TrueExpr : ParseNodeKind::FalseExpr,
                     b ? JSOP_TRUE : JSOP_FALSE, pos) {}
 
   static bool test(const ParseNode& node) {
-    bool match =
-        node.isKind(ParseNodeKind::True) || node.isKind(ParseNodeKind::False);
+    bool match = node.isKind(ParseNodeKind::TrueExpr) ||
+                 node.isKind(ParseNodeKind::FalseExpr);
     MOZ_ASSERT_IF(match, node.is<NullaryNode>());
     return match;
   }
 };
 
 class RegExpLiteral : public ParseNode {
  public:
   RegExpLiteral(ObjectBox* reobj, const TokenPos& pos)
-      : ParseNode(ParseNodeKind::RegExp, JSOP_REGEXP, pos) {
+      : ParseNode(ParseNodeKind::RegExpExpr, JSOP_REGEXP, pos) {
     pn_u.regexp.objbox = reobj;
   }
 
   ObjectBox* objbox() const { return pn_u.regexp.objbox; }
 
 #ifdef DEBUG
   void dump(GenericPrinter& out, int indent);
 #endif
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::RegExp);
+    bool match = node.isKind(ParseNodeKind::RegExpExpr);
     MOZ_ASSERT_IF(match, node.isArity(PN_REGEXP));
     MOZ_ASSERT_IF(match, node.isOp(JSOP_REGEXP));
     return match;
   }
 };
 
 class PropertyAccess : public BinaryNode {
  public:
   /*
    * PropertyAccess nodes can have any expression/'super' as left-hand
    * side, but the name must be a ParseNodeKind::PropertyName node.
    */
   PropertyAccess(ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end)
-      : BinaryNode(ParseNodeKind::Dot, JSOP_NOP, TokenPos(begin, end), lhs,
+      : BinaryNode(ParseNodeKind::DotExpr, JSOP_NOP, TokenPos(begin, end), lhs,
                    name) {
     MOZ_ASSERT(lhs);
     MOZ_ASSERT(name);
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Dot);
+    bool match = node.isKind(ParseNodeKind::DotExpr);
     MOZ_ASSERT_IF(match, node.is<BinaryNode>());
     MOZ_ASSERT_IF(match, node.as<BinaryNode>().right()->isKind(
-                             ParseNodeKind::PropertyName));
+                             ParseNodeKind::PropertyNameExpr));
     return match;
   }
 
   ParseNode& expression() const { return *left(); }
 
   NameNode& key() const { return right()->as<NameNode>(); }
 
   // Method used by BytecodeEmitter::emitPropLHS for optimization.
@@ -1764,21 +1774,21 @@ class PropertyAccess : public BinaryNode
     return expression().isKind(ParseNodeKind::SuperBase);
   }
 };
 
 class PropertyByValue : public BinaryNode {
  public:
   PropertyByValue(ParseNode* lhs, ParseNode* propExpr, uint32_t begin,
                   uint32_t end)
-      : BinaryNode(ParseNodeKind::Elem, JSOP_NOP, TokenPos(begin, end), lhs,
+      : BinaryNode(ParseNodeKind::ElemExpr, JSOP_NOP, TokenPos(begin, end), lhs,
                    propExpr) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Elem);
+    bool match = node.isKind(ParseNodeKind::ElemExpr);
     MOZ_ASSERT_IF(match, node.is<BinaryNode>());
     return match;
   }
 
   ParseNode& expression() const { return *left(); }
 
   ParseNode& key() const { return *right(); }
 
@@ -1787,20 +1797,20 @@ class PropertyByValue : public BinaryNod
 
 /*
  * A CallSiteNode represents the implicit call site object argument in a
  * TaggedTemplate.
  */
 class CallSiteNode : public ListNode {
  public:
   explicit CallSiteNode(uint32_t begin)
-      : ListNode(ParseNodeKind::CallSiteObj, TokenPos(begin, begin + 1)) {}
+      : ListNode(ParseNodeKind::CallSiteObjExpr, TokenPos(begin, begin + 1)) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::CallSiteObj);
+    bool match = node.isKind(ParseNodeKind::CallSiteObjExpr);
     MOZ_ASSERT_IF(match, node.is<ListNode>());
     return match;
   }
 
   MOZ_MUST_USE bool getRawArrayValue(JSContext* cx, MutableHandleValue vp) {
     return head()->getConstantValue(cx, AllowObjects, vp);
   }
 
@@ -1866,17 +1876,17 @@ class ClassField : public ParseNode {
 
   ParseNode** unsafeInitializerReference() { return &pn_u.field.initializer; }
 };
 
 class SwitchStatement : public BinaryNode {
  public:
   SwitchStatement(uint32_t begin, ParseNode* discriminant,
                   LexicalScopeNode* lexicalForCaseList, bool hasDefault)
-      : BinaryNode(ParseNodeKind::Switch, JSOP_NOP,
+      : BinaryNode(ParseNodeKind::SwitchStmt, JSOP_NOP,
                    TokenPos(begin, lexicalForCaseList->pn_pos.end),
                    discriminant, lexicalForCaseList) {
 #ifdef DEBUG
     ListNode* cases = &lexicalForCaseList->scopeBody()->as<ListNode>();
     MOZ_ASSERT(cases->isKind(ParseNodeKind::StatementList));
     bool found = false;
     for (ParseNode* item : cases->contents()) {
       CaseClause* caseNode = &item->as<CaseClause>();
@@ -1887,17 +1897,17 @@ class SwitchStatement : public BinaryNod
     }
     MOZ_ASSERT(found == hasDefault);
 #endif
 
     pn_u.binary.hasDefault = hasDefault;
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Switch);
+    bool match = node.isKind(ParseNodeKind::SwitchStmt);
     MOZ_ASSERT_IF(match, node.is<BinaryNode>());
     return match;
   }
 
   ParseNode& discriminant() const { return *left(); }
 
   LexicalScopeNode& lexicalForCaseList() const {
     return right()->as<LexicalScopeNode>();
@@ -1941,25 +1951,25 @@ class ClassNames : public BinaryNode {
 
   NameNode* innerBinding() const { return &right()->as<NameNode>(); }
 };
 
 class ClassNode : public TernaryNode {
  public:
   ClassNode(ParseNode* names, ParseNode* heritage, ParseNode* membersOrBlock,
             const TokenPos& pos)
-      : TernaryNode(ParseNodeKind::Class, names, heritage, membersOrBlock,
+      : TernaryNode(ParseNodeKind::ClassDecl, names, heritage, membersOrBlock,
                     pos) {
     MOZ_ASSERT_IF(names, names->is<ClassNames>());
     MOZ_ASSERT(membersOrBlock->is<LexicalScopeNode>() ||
                membersOrBlock->isKind(ParseNodeKind::ClassMemberList));
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Class);
+    bool match = node.isKind(ParseNodeKind::ClassDecl);
     MOZ_ASSERT_IF(match, node.is<TernaryNode>());
     return match;
   }
 
   ClassNames* names() const {
     return kid1() ? &kid1()->as<ClassNames>() : nullptr;
   }
   ParseNode* heritage() const { return kid2(); }
@@ -1993,26 +2003,26 @@ class ParseNodeAllocator {
 
  private:
   JSContext* cx;
   LifoAlloc& alloc;
 };
 
 inline bool ParseNode::isConstant() {
   switch (pn_type) {
-    case ParseNodeKind::Number:
-    case ParseNodeKind::String:
-    case ParseNodeKind::TemplateString:
-    case ParseNodeKind::Null:
-    case ParseNodeKind::RawUndefined:
-    case ParseNodeKind::False:
-    case ParseNodeKind::True:
+    case ParseNodeKind::NumberExpr:
+    case ParseNodeKind::StringExpr:
+    case ParseNodeKind::TemplateStringExpr:
+    case ParseNodeKind::NullExpr:
+    case ParseNodeKind::RawUndefinedExpr:
+    case ParseNodeKind::FalseExpr:
+    case ParseNodeKind::TrueExpr:
       return true;
-    case ParseNodeKind::Array:
-    case ParseNodeKind::Object:
+    case ParseNodeKind::ArrayExpr:
+    case ParseNodeKind::ObjectExpr:
       return !as<ListNode>().hasNonConstInitializer();
     default:
       return false;
   }
 }
 
 class TraceListNode {
  protected:
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2787,17 +2787,17 @@ typename ParseHandler::ListNodeType
 GeneralParser<ParseHandler, Unit>::templateLiteral(
     YieldHandling yieldHandling) {
   NameNodeType literal = noSubstitutionUntaggedTemplate();
   if (!literal) {
     return null();
   }
 
   ListNodeType nodeList =
-      handler.newList(ParseNodeKind::TemplateStringList, literal);
+      handler.newList(ParseNodeKind::TemplateStringListExpr, literal);
   if (!nodeList) {
     return null();
   }
 
   TokenKind tt;
   do {
     if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
       return null();
@@ -3924,17 +3924,17 @@ GeneralParser<ParseHandler, Unit>::bindi
   }
 
   Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
   if (!rhs) {
     return null();
   }
 
   BinaryNodeType assign =
-      handler.newAssignment(ParseNodeKind::Assign, lhs, rhs);
+      handler.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs);
   if (!assign) {
     return null();
   }
 
   if (foldConstants) {
     Node node = assign;
     if (!FoldConstants(context, &node, this)) {
       return null();
@@ -4365,17 +4365,17 @@ GeneralParser<ParseHandler, Unit>::decla
   }
 
   Node init = assignExpr(forHeadKind ? InProhibited : InAllowed, yieldHandling,
                          TripledotProhibited);
   if (!init) {
     return null();
   }
 
-  return handler.newAssignment(ParseNodeKind::Assign, pattern, init);
+  return handler.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
 }
 
 template <class ParseHandler, typename Unit>
 bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
     NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
     YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
     Node* forInOrOfExpression) {
   MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign));
@@ -4527,28 +4527,28 @@ GeneralParser<ParseHandler, Unit>::decla
 }
 
 template <class ParseHandler, typename Unit>
 typename ParseHandler::ListNodeType
 GeneralParser<ParseHandler, Unit>::declarationList(
     YieldHandling yieldHandling, ParseNodeKind kind,
     ParseNodeKind* forHeadKind /* = nullptr */,
     Node* forInOrOfExpression /* = nullptr */) {
-  MOZ_ASSERT(kind == ParseNodeKind::Var || kind == ParseNodeKind::Let ||
-             kind == ParseNodeKind::Const);
+  MOZ_ASSERT(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||
+             kind == ParseNodeKind::ConstDecl);
 
   DeclarationKind declKind;
   switch (kind) {
-    case ParseNodeKind::Var:
+    case ParseNodeKind::VarStmt:
       declKind = DeclarationKind::Var;
       break;
-    case ParseNodeKind::Const:
+    case ParseNodeKind::ConstDecl:
       declKind = DeclarationKind::Const;
       break;
-    case ParseNodeKind::Let:
+    case ParseNodeKind::LetDecl:
       declKind = DeclarationKind::Let;
       break;
     default:
       MOZ_CRASH("Unknown declaration kind");
   }
 
   ListNodeType decl = handler.newDeclarationList(kind, pos());
   if (!decl) {
@@ -4609,18 +4609,18 @@ GeneralParser<ParseHandler, Unit>::lexic
    * the same environment record as vars.
    *
    * However, they cannot be parsed exactly as vars, as ES6
    * requires that uninitialized lets throw ReferenceError on use.
    *
    * See 8.1.1.1.6 and the note in 13.2.1.
    */
   ListNodeType decl = declarationList(
-      yieldHandling, kind == DeclarationKind::Const ? ParseNodeKind::Const
-                                                    : ParseNodeKind::Let);
+      yieldHandling, kind == DeclarationKind::Const ? ParseNodeKind::ConstDecl
+                                                    : ParseNodeKind::LetDecl);
   if (!decl || !matchOrInsertSemicolon()) {
     return null();
   }
 
   return decl;
 }
 
 template <typename Unit>
@@ -4932,27 +4932,27 @@ template <class ParseHandler, typename U
 inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
     JSAtom* exportName) {
   return asFinalParser()->checkExportedName(exportName);
 }
 
 template <typename Unit>
 bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
     ListNode* array) {
-  MOZ_ASSERT(array->isKind(ParseNodeKind::Array));
+  MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr));
 
   for (ParseNode* node : array->contents()) {
     if (node->isKind(ParseNodeKind::Elision)) {
       continue;
     }
 
     ParseNode* binding;
     if (node->isKind(ParseNodeKind::Spread)) {
       binding = node->as<UnaryNode>().kid();
-    } else if (node->isKind(ParseNodeKind::Assign)) {
+    } else if (node->isKind(ParseNodeKind::AssignExpr)) {
       binding = node->as<AssignmentNode>().left();
     } else {
       binding = node;
     }
 
     if (!checkExportedNamesForDeclaration(binding)) {
       return false;
     }
@@ -4973,17 +4973,17 @@ inline bool
 GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
     ListNodeType array) {
   return asFinalParser()->checkExportedNamesForArrayBinding(array);
 }
 
 template <typename Unit>
 bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
     ListNode* obj) {
-  MOZ_ASSERT(obj->isKind(ParseNodeKind::Object));
+  MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr));
 
   for (ParseNode* node : obj->contents()) {
     MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||
                node->isKind(ParseNodeKind::Colon) ||
                node->isKind(ParseNodeKind::Shorthand) ||
                node->isKind(ParseNodeKind::Spread));
 
     ParseNode* target;
@@ -4991,17 +4991,17 @@ bool Parser<FullParseHandler, Unit>::che
       target = node->as<UnaryNode>().kid();
     } else {
       if (node->isKind(ParseNodeKind::MutateProto)) {
         target = node->as<UnaryNode>().kid();
       } else {
         target = node->as<BinaryNode>().right();
       }
 
-      if (target->isKind(ParseNodeKind::Assign)) {
+      if (target->isKind(ParseNodeKind::AssignExpr)) {
         target = target->as<AssignmentNode>().left();
       }
     }
 
     if (!checkExportedNamesForDeclaration(target)) {
       return false;
     }
   }
@@ -5025,22 +5025,22 @@ GeneralParser<ParseHandler, Unit>::check
 
 template <typename Unit>
 bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclaration(
     ParseNode* node) {
   if (node->isKind(ParseNodeKind::Name)) {
     if (!checkExportedName(node->as<NameNode>().atom())) {
       return false;
     }
-  } else if (node->isKind(ParseNodeKind::Array)) {
+  } else if (node->isKind(ParseNodeKind::ArrayExpr)) {
     if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) {
       return false;
     }
   } else {
-    MOZ_ASSERT(node->isKind(ParseNodeKind::Object));
+    MOZ_ASSERT(node->isKind(ParseNodeKind::ObjectExpr));
     if (!checkExportedNamesForObjectBinding(&node->as<ListNode>())) {
       return false;
     }
   }
 
   return true;
 }
 
@@ -5056,17 +5056,17 @@ inline bool GeneralParser<ParseHandler, 
     Node node) {
   return asFinalParser()->checkExportedNamesForDeclaration(node);
 }
 
 template <typename Unit>
 bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclarationList(
     ListNode* node) {
   for (ParseNode* binding : node->contents()) {
-    if (binding->isKind(ParseNodeKind::Assign)) {
+    if (binding->isKind(ParseNodeKind::AssignExpr)) {
       binding = binding->as<AssignmentNode>().left();
     } else {
       MOZ_ASSERT(binding->isKind(ParseNodeKind::Name));
     }
 
     if (!checkExportedNamesForDeclaration(binding)) {
       return false;
     }
@@ -5397,17 +5397,17 @@ template <class ParseHandler, typename U
 typename ParseHandler::UnaryNodeType
 GeneralParser<ParseHandler, Unit>::exportVariableStatement(uint32_t begin) {
   if (!abortIfSyntaxParser()) {
     return null();
   }
 
   MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Var));
 
-  ListNodeType kid = declarationList(YieldIsName, ParseNodeKind::Var);
+  ListNodeType kid = declarationList(YieldIsName, ParseNodeKind::VarStmt);
   if (!kid) {
     return null();
   }
   if (!matchOrInsertSemicolon()) {
     return null();
   }
   if (!checkExportedNamesForDeclarationList(kid)) {
     return null();
@@ -5977,17 +5977,17 @@ bool GeneralParser<ParseHandler, Unit>::
 
   // Parsing after |for (var| is also relatively simple (from this method's
   // point of view).  No block-related work complicates matters, so delegate
   // to Parser::declaration.
   if (tt == TokenKind::Var) {
     tokenStream.consumeKnownToken(tt, TokenStream::Operand);
 
     // Pass null for block object because |var| declarations don't use one.
-    *forInitialPart = declarationList(yieldHandling, ParseNodeKind::Var,
+    *forInitialPart = declarationList(yieldHandling, ParseNodeKind::VarStmt,
                                       forHeadKind, forInOrOfExpression);
     return *forInitialPart != null();
   }
 
   // Otherwise we have a lexical declaration or an expression.
 
   // For-in loop backwards compatibility requires that |let| starting a
   // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
@@ -6022,20 +6022,21 @@ bool GeneralParser<ParseHandler, Unit>::
       return false;
     }
 
     // Push a temporary ForLoopLexicalHead Statement that allows for
     // lexical declarations, as they are usually allowed only in braced
     // statements.
     ParseContext::Statement forHeadStmt(pc, StatementKind::ForLoopLexicalHead);
 
-    *forInitialPart = declarationList(
-        yieldHandling,
-        tt == TokenKind::Const ? ParseNodeKind::Const : ParseNodeKind::Let,
-        forHeadKind, forInOrOfExpression);
+    *forInitialPart =
+        declarationList(yieldHandling,
+                        tt == TokenKind::Const ? ParseNodeKind::ConstDecl
+                                               : ParseNodeKind::LetDecl,
+                        forHeadKind, forInOrOfExpression);
     return *forInitialPart != null();
   }
 
   uint32_t exprOffset;
   if (!tokenStream.peekOffset(&exprOffset, TokenStream::Operand)) {
     return false;
   }
 
@@ -6560,17 +6561,17 @@ GeneralParser<ParseHandler, Unit>::yield
   uint32_t begin = pos().begin;
 
   MOZ_ASSERT(pc->isGenerator());
   MOZ_ASSERT(pc->isFunctionBox());
 
   pc->lastYieldOffset = begin;
 
   Node exprNode;
-  ParseNodeKind kind = ParseNodeKind::Yield;
+  ParseNodeKind kind = ParseNodeKind::YieldExpr;
   TokenKind tt = TokenKind::Eof;
   if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand)) {
     return null();
   }
   switch (tt) {
     // TokenKind::Eol is special; it implements the [no LineTerminator here]
     // quirk in the grammar.
     case TokenKind::Eol:
@@ -6586,26 +6587,26 @@ GeneralParser<ParseHandler, Unit>::yield
     case TokenKind::Colon:
     case TokenKind::Comma:
     case TokenKind::In:
       // No value.
       exprNode = null();
       anyChars.addModifierException(TokenStream::NoneIsOperand);
       break;
     case TokenKind::Mul:
-      kind = ParseNodeKind::YieldStar;
+      kind = ParseNodeKind::YieldStarExpr;
       tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::Operand);
       MOZ_FALLTHROUGH;
     default:
       exprNode = assignExpr(inHandling, YieldIsKeyword, TripledotProhibited);
       if (!exprNode) {
         return null();
       }
   }
-  if (kind == ParseNodeKind::YieldStar) {
+  if (kind == ParseNodeKind::YieldStarExpr) {
     return handler.newYieldStarExpression(begin, exprNode);
   }
   return handler.newYieldExpression(begin, exprNode);
 }
 
 template <class ParseHandler, typename Unit>
 typename ParseHandler::BinaryNodeType
 GeneralParser<ParseHandler, Unit>::withStatement(YieldHandling yieldHandling) {
@@ -7339,17 +7340,17 @@ bool ParserBase::nextTokenContinuesLetDe
   // Otherwise a let declaration must have a name.
   return TokenKindIsPossibleIdentifier(next);
 }
 
 template <class ParseHandler, typename Unit>
 typename ParseHandler::Node
 GeneralParser<ParseHandler, Unit>::variableStatement(
     YieldHandling yieldHandling) {
-  ListNodeType vars = declarationList(yieldHandling, ParseNodeKind::Var);
+  ListNodeType vars = declarationList(yieldHandling, ParseNodeKind::VarStmt);
   if (!vars) {
     return null();
   }
   if (!matchOrInsertSemicolon()) {
     return null();
   }
   return vars;
 }
@@ -8229,53 +8230,53 @@ typename ParseHandler::Node GeneralParse
                               GeneratorKind::NotGenerator, asyncKind);
   }
 
   MOZ_ALWAYS_TRUE(tokenStream.getToken(&tokenAfterLHS, TokenStream::Operand));
 
   ParseNodeKind kind;
   switch (tokenAfterLHS) {
     case TokenKind::Assign:
-      kind = ParseNodeKind::Assign;
+      kind = ParseNodeKind::AssignExpr;
       break;
     case TokenKind::AddAssign:
-      kind = ParseNodeKind::AddAssign;
+      kind = ParseNodeKind::AddAssignExpr;
       break;
     case TokenKind::SubAssign:
-      kind = ParseNodeKind::SubAssign;
+      kind = ParseNodeKind::SubAssignExpr;
       break;
     case TokenKind::BitOrAssign:
-      kind = ParseNodeKind::BitOrAssign;
+      kind = ParseNodeKind::BitOrAssignExpr;
       break;
     case TokenKind::BitXorAssign:
-      kind = ParseNodeKind::BitXorAssign;
+      kind = ParseNodeKind::BitXorAssignExpr;
       break;
     case TokenKind::BitAndAssign:
-      kind = ParseNodeKind::BitAndAssign;
+      kind = ParseNodeKind::BitAndAssignExpr;
       break;
     case TokenKind::LshAssign:
-      kind = ParseNodeKind::LshAssign;
+      kind = ParseNodeKind::LshAssignExpr;
       break;
     case TokenKind::RshAssign:
-      kind = ParseNodeKind::RshAssign;
+      kind = ParseNodeKind::RshAssignExpr;
       break;
     case TokenKind::UrshAssign:
-      kind = ParseNodeKind::UrshAssign;
+      kind = ParseNodeKind::UrshAssignExpr;
       break;
     case TokenKind::MulAssign:
-      kind = ParseNodeKind::MulAssign;
+      kind = ParseNodeKind::MulAssignExpr;
       break;
     case TokenKind::DivAssign:
-      kind = ParseNodeKind::DivAssign;
+      kind = ParseNodeKind::DivAssignExpr;
       break;
     case TokenKind::ModAssign:
-      kind = ParseNodeKind::ModAssign;
+      kind = ParseNodeKind::ModAssignExpr;
       break;
     case TokenKind::PowAssign:
-      kind = ParseNodeKind::PowAssign;
+      kind = ParseNodeKind::PowAssignExpr;
       break;
 
     default:
       MOZ_ASSERT(!anyChars.isCurrentTokenAssignment());
       if (!possibleError) {
         if (!possibleErrorInner.checkForExpressionError()) {
           return null();
         }
@@ -8284,17 +8285,17 @@ typename ParseHandler::Node GeneralParse
       }
 
       anyChars.ungetToken();
       return lhs;
   }
 
   // Verify the left-hand side expression doesn't have a forbidden form.
   if (handler.isUnparenthesizedDestructuringPattern(lhs)) {
-    if (kind != ParseNodeKind::Assign) {
+    if (kind != ParseNodeKind::AssignExpr) {
       error(JSMSG_BAD_DESTRUCT_ASS);
       return null();
     }
 
     if (!possibleErrorInner.checkForDestructuringErrorOrWarning()) {
       return null();
     }
   } else if (handler.isName(lhs)) {
@@ -8430,25 +8431,25 @@ typename ParseHandler::Node GeneralParse
 
   TokenKind tt;
   if (!tokenStream.getToken(&tt, TokenStream::Operand)) {
     return null();
   }
   uint32_t begin = pos().begin;
   switch (tt) {
     case TokenKind::Void:
-      return unaryOpExpr(yieldHandling, ParseNodeKind::Void, begin);
+      return unaryOpExpr(yieldHandling, ParseNodeKind::VoidExpr, begin);
     case TokenKind::Not:
-      return unaryOpExpr(yieldHandling, ParseNodeKind::Not, begin);
+      return unaryOpExpr(yieldHandling, ParseNodeKind::NotExpr, begin);
     case TokenKind::BitNot:
-      return unaryOpExpr(yieldHandling, ParseNodeKind::BitNot, begin);
+      return unaryOpExpr(yieldHandling, ParseNodeKind::BitNotExpr, begin);
     case TokenKind::Add:
-      return unaryOpExpr(yieldHandling, ParseNodeKind::Pos, begin);
+      return unaryOpExpr(yieldHandling, ParseNodeKind::PosExpr, begin);
     case TokenKind::Sub:
-      return unaryOpExpr(yieldHandling, ParseNodeKind::Neg, begin);
+      return unaryOpExpr(yieldHandling, ParseNodeKind::NegExpr, begin);
 
     case TokenKind::TypeOf: {
       // The |typeof| operator is specially parsed to distinguish its
       // application to a name, from its application to a non-name
       // expression:
       //
       //   // Looks up the name, doesn't find it and so evaluates to
       //   // "undefined".
@@ -8472,18 +8473,19 @@ typename ParseHandler::Node GeneralParse
         return null();
       }
 
       uint32_t operandOffset = pos().begin;
       Node operand = memberExpr(yieldHandling, TripledotProhibited, tt2);
       if (!operand || !checkIncDecOperand(operand, operandOffset)) {
         return null();
       }
-      ParseNodeKind pnk = (tt == TokenKind::Inc) ? ParseNodeKind::PreIncrement
-                                                 : ParseNodeKind::PreDecrement;
+      ParseNodeKind pnk = (tt == TokenKind::Inc)
+                              ? ParseNodeKind::PreIncrementExpr
+                              : ParseNodeKind::PreDecrementExpr;
       return handler.newUpdate(pnk, begin, operand);
     }
 
     case TokenKind::Delete: {
       uint32_t exprOffset;
       if (!tokenStream.peekOffset(&exprOffset, TokenStream::Operand)) {
         return null();
       }
@@ -8541,18 +8543,19 @@ typename ParseHandler::Node GeneralParse
         return expr;
       }
 
       tokenStream.consumeKnownToken(tt);
       if (!checkIncDecOperand(expr, begin)) {
         return null();
       }
 
-      ParseNodeKind pnk = (tt == TokenKind::Inc) ? ParseNodeKind::PostIncrement
-                                                 : ParseNodeKind::PostDecrement;
+      ParseNodeKind pnk = (tt == TokenKind::Inc)
+                              ? ParseNodeKind::PostIncrementExpr
+                              : ParseNodeKind::PostDecrementExpr;
       return handler.newUpdate(pnk, begin, expr);
     }
   }
 }
 
 template <class ParseHandler, typename Unit>
 typename ParseHandler::Node
 GeneralParser<ParseHandler, Unit>::assignExprWithoutYieldOrAwait(
@@ -9903,17 +9906,17 @@ GeneralParser<ParseHandler, Unit>::objec
         }
 
         Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
         if (!rhs) {
           return null();
         }
 
         BinaryNodeType propExpr =
-            handler.newAssignment(ParseNodeKind::Assign, lhs, rhs);
+            handler.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs);
         if (!propExpr) {
           return null();
         }
 
         if (!handler.addPropertyDefinition(literal, propName, propExpr)) {
           return null();
         }
       } else {
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -535,31 +535,32 @@ class SyntaxParseHandler {
     //     we may not *have* that function name around, because of how lazy
     //     parsing works -- the actual name could be outside
     //     |tokenStream.userbuf|'s observed region.  So the current offset
     //     is the best we can do.
     return ts.currentToken().pos.begin;
   }
 
   ListNodeType newList(ParseNodeKind kind, const TokenPos& pos) {
-    MOZ_ASSERT(kind != ParseNodeKind::Var);
-    MOZ_ASSERT(kind != ParseNodeKind::Let);
-    MOZ_ASSERT(kind != ParseNodeKind::Const);
+    MOZ_ASSERT(kind != ParseNodeKind::VarStmt);
+    MOZ_ASSERT(kind != ParseNodeKind::LetDecl);
+    MOZ_ASSERT(kind != ParseNodeKind::ConstDecl);
     return NodeGeneric;
   }
 
   ListNodeType newList(ParseNodeKind kind, Node kid) {
     return newList(kind, TokenPos());
   }
 
   ListNodeType newDeclarationList(ParseNodeKind kind, const TokenPos& pos) {
-    if (kind == ParseNodeKind::Var) {
+    if (kind == ParseNodeKind::VarStmt) {
       return NodeVarDeclaration;
     }
-    MOZ_ASSERT(kind == ParseNodeKind::Let || kind == ParseNodeKind::Const);
+    MOZ_ASSERT(kind == ParseNodeKind::LetDecl ||
+               kind == ParseNodeKind::ConstDecl);
     return NodeLexicalDeclaration;
   }
 
   bool isDeclarationList(Node node) {
     return node == NodeVarDeclaration || node == NodeLexicalDeclaration;
   }
 
   // This method should only be called from parsers using FullParseHandler.
@@ -574,18 +575,18 @@ class SyntaxParseHandler {
                list == NodeFunctionCall);
   }
 
   BinaryNodeType newNewExpression(uint32_t begin, Node ctor, Node args) {
     return NodeGeneric;
   }
 
   AssignmentNodeType newAssignment(ParseNodeKind kind, Node lhs, Node rhs) {
-    return kind == ParseNodeKind::Assign ? NodeUnparenthesizedAssignment
-                                         : NodeGeneric;
+    return kind == ParseNodeKind::AssignExpr ? NodeUnparenthesizedAssignment
+                                             : NodeGeneric;
   }
 
   bool isUnparenthesizedAssignment(Node node) {
     return node == NodeUnparenthesizedAssignment;
   }
 
   bool isUnparenthesizedUnaryExpression(Node node) {
     return node == NodeUnparenthesizedUnary;
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -403,17 +403,17 @@ static inline ParseNode* BinaryRight(Par
   return pn->as<BinaryNode>().right();
 }
 
 static inline ParseNode* BinaryLeft(ParseNode* pn) {
   return pn->as<BinaryNode>().left();
 }
 
 static inline ParseNode* ReturnExpr(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Return));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::ReturnStmt));
   return UnaryKid(pn);
 }
 
 static inline ParseNode* TernaryKid1(ParseNode* pn) {
   return pn->as<TernaryNode>().kid1();
 }
 
 static inline ParseNode* TernaryKid2(ParseNode* pn) {
@@ -428,33 +428,33 @@ static inline ParseNode* ListHead(ParseN
   return pn->as<ListNode>().head();
 }
 
 static inline unsigned ListLength(ParseNode* pn) {
   return pn->as<ListNode>().count();
 }
 
 static inline ParseNode* CallCallee(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Call));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::CallExpr));
   return BinaryLeft(pn);
 }
 
 static inline unsigned CallArgListLength(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Call));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::CallExpr));
   return ListLength(BinaryRight(pn));
 }
 
 static inline ParseNode* CallArgList(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Call));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::CallExpr));
   return ListHead(BinaryRight(pn));
 }
 
 static inline ParseNode* VarListHead(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Var) ||
-             pn->isKind(ParseNodeKind::Const));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::VarStmt) ||
+             pn->isKind(ParseNodeKind::ConstDecl));
   return ListHead(pn);
 }
 
 static inline bool IsDefaultCase(ParseNode* pn) {
   return pn->as<CaseClause>().isDefault();
 }
 
 static inline ParseNode* CaseExpr(ParseNode* pn) {
@@ -479,65 +479,69 @@ static inline ParseNode* BinaryOpRight(P
 
 static inline ParseNode* BitwiseLeft(ParseNode* pn) { return BinaryOpLeft(pn); }
 
 static inline ParseNode* BitwiseRight(ParseNode* pn) {
   return BinaryOpRight(pn);
 }
 
 static inline ParseNode* MultiplyLeft(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Star));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::MulExpr));
   return BinaryOpLeft(pn);
 }
 
 static inline ParseNode* MultiplyRight(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Star));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::MulExpr));
   return BinaryOpRight(pn);
 }
 
 static inline ParseNode* AddSubLeft(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Add) || pn->isKind(ParseNodeKind::Sub));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::AddExpr) ||
+             pn->isKind(ParseNodeKind::SubExpr));
   return BinaryOpLeft(pn);
 }
 
 static inline ParseNode* AddSubRight(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Add) || pn->isKind(ParseNodeKind::Sub));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::AddExpr) ||
+             pn->isKind(ParseNodeKind::SubExpr));
   return BinaryOpRight(pn);
 }
 
 static inline ParseNode* DivOrModLeft(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Div) || pn->isKind(ParseNodeKind::Mod));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::DivExpr) ||
+             pn->isKind(ParseNodeKind::ModExpr));
   return BinaryOpLeft(pn);
 }
 
 static inline ParseNode* DivOrModRight(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Div) || pn->isKind(ParseNodeKind::Mod));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::DivExpr) ||
+             pn->isKind(ParseNodeKind::ModExpr));
   return BinaryOpRight(pn);
 }
 
 static inline ParseNode* ComparisonLeft(ParseNode* pn) {
   return BinaryOpLeft(pn);
 }
 
 static inline ParseNode* ComparisonRight(ParseNode* pn) {
   return BinaryOpRight(pn);
 }
 
 static inline bool IsExpressionStatement(ParseNode* pn) {
-  return pn->isKind(ParseNodeKind::ExpressionStatement);
+  return pn->isKind(ParseNodeKind::ExpressionStmt);
 }
 
 static inline ParseNode* ExpressionStatementExpr(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::ExpressionStatement));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::ExpressionStmt));
   return UnaryKid(pn);
 }
 
 static inline PropertyName* LoopControlMaybeLabel(ParseNode* pn) {
-  MOZ_ASSERT(pn->isKind(ParseNodeKind::Break) ||
-             pn->isKind(ParseNodeKind::Continue));
+  MOZ_ASSERT(pn->isKind(ParseNodeKind::BreakStmt) ||
+             pn->isKind(ParseNodeKind::ContinueStmt));
   return pn->as<LoopControlStatement>().label();
 }
 
 static inline PropertyName* LabeledStatementLabel(ParseNode* pn) {
   return pn->as<LabeledStatement>().label();
 }
 
 static inline ParseNode* LabeledStatementStatement(ParseNode* pn) {
@@ -614,23 +618,23 @@ static inline bool IsUseOfName(ParseNode
   return pn->isName(name);
 }
 
 static inline bool IsIgnoredDirectiveName(JSContext* cx, JSAtom* atom) {
   return atom != cx->names().useStrict;
 }
 
 static inline bool IsIgnoredDirective(JSContext* cx, ParseNode* pn) {
-  return pn->isKind(ParseNodeKind::ExpressionStatement) &&
-         UnaryKid(pn)->isKind(ParseNodeKind::String) &&
+  return pn->isKind(ParseNodeKind::ExpressionStmt) &&
+         UnaryKid(pn)->isKind(ParseNodeKind::StringExpr) &&
          IsIgnoredDirectiveName(cx, UnaryKid(pn)->as<NameNode>().atom());
 }
 
 static inline bool IsEmptyStatement(ParseNode* pn) {
-  return pn->isKind(ParseNodeKind::EmptyStatement);
+  return pn->isKind(ParseNodeKind::EmptyStmt);
 }
 
 static inline ParseNode* SkipEmptyStatements(ParseNode* pn) {
   while (pn && IsEmptyStatement(pn)) {
     pn = pn->pn_next;
   }
   return pn;
 }
@@ -680,18 +684,18 @@ static bool ParseVarOrConstStatement(Asm
     return true;
   }
 
   *var = parser.statementListItem(YieldIsName);
   if (!*var) {
     return false;
   }
 
-  MOZ_ASSERT((*var)->isKind(ParseNodeKind::Var) ||
-             (*var)->isKind(ParseNodeKind::Const));
+  MOZ_ASSERT((*var)->isKind(ParseNodeKind::VarStmt) ||
+             (*var)->isKind(ParseNodeKind::ConstDecl));
   return true;
 }
 
 /*****************************************************************************/
 
 // Represents the type and value of an asm.js numeric literal.
 //
 // A literal is a double iff the literal contains a decimal point (even if the
@@ -2122,24 +2126,24 @@ class MOZ_STACK_CLASS JS_HAZ_ROOTED Modu
 };
 
 /*****************************************************************************/
 // Numeric literal utilities
 
 static bool IsNumericNonFloatLiteral(ParseNode* pn) {
   // Note: '-' is never rolled into the number; numbers are always positive
   // and negations must be applied manually.
-  return pn->isKind(ParseNodeKind::Number) ||
-         (pn->isKind(ParseNodeKind::Neg) &&
-          UnaryKid(pn)->isKind(ParseNodeKind::Number));
+  return pn->isKind(ParseNodeKind::NumberExpr) ||
+         (pn->isKind(ParseNodeKind::NegExpr) &&
+          UnaryKid(pn)->isKind(ParseNodeKind::NumberExpr));
 }
 
 static bool IsCallToGlobal(ModuleValidator& m, ParseNode* pn,
                            const ModuleValidator::Global** global) {
-  if (!pn->isKind(ParseNodeKind::Call)) {
+  if (!pn->isKind(ParseNodeKind::CallExpr)) {
     return false;
   }
 
   ParseNode* callee = CallCallee(pn);
   if (!callee->isKind(ParseNodeKind::Name)) {
     return false;
   }
 
@@ -2198,31 +2202,31 @@ static bool IsNumericLiteral(ModuleValid
 // The JS grammar treats -42 as -(42) (i.e., with separate grammar
 // productions) for the unary - and literal 42). However, the asm.js spec
 // recognizes -42 (modulo parens, so -(42) and -((42))) as a single literal
 // so fold the two potential parse nodes into a single double value.
 static double ExtractNumericNonFloatValue(ParseNode* pn,
                                           ParseNode** out = nullptr) {
   MOZ_ASSERT(IsNumericNonFloatLiteral(pn));
 
-  if (pn->isKind(ParseNodeKind::Neg)) {
+  if (pn->isKind(ParseNodeKind::NegExpr)) {
     pn = UnaryKid(pn);
     if (out) {
       *out = pn;
     }
     return -NumberNodeValue(pn);
   }
 
   return NumberNodeValue(pn);
 }
 
 static NumLit ExtractNumericLiteral(ModuleValidator& m, ParseNode* pn) {
   MOZ_ASSERT(IsNumericLiteral(m, pn));
 
-  if (pn->isKind(ParseNodeKind::Call)) {
+  if (pn->isKind(ParseNodeKind::CallExpr)) {
     // Float literals are explicitly coerced and thus the coerced literal may be
     // any valid (non-float) numeric literal.
     MOZ_ASSERT(CallArgListLength(pn) == 1);
     pn = CallArgList(pn);
     double d = ExtractNumericNonFloatValue(pn);
     return NumLit(NumLit::Float, DoubleValue(d));
   }
 
@@ -2719,36 +2723,36 @@ static bool CheckGlobalVariableInitConst
 
   return m.addGlobalVarInit(varName, lit, canonicalType, isConst);
 }
 
 static bool CheckTypeAnnotation(ModuleValidator& m, ParseNode* coercionNode,
                                 Type* coerceTo,
                                 ParseNode** coercedExpr = nullptr) {
   switch (coercionNode->getKind()) {
-    case ParseNodeKind::BitOr: {
+    case ParseNodeKind::BitOrExpr: {
       ParseNode* rhs = BitwiseRight(coercionNode);
       uint32_t i;
       if (!IsLiteralInt(m, rhs, &i) || i != 0) {
         return m.fail(rhs, "must use |0 for argument/return coercion");
       }
       *coerceTo = Type::Int;
       if (coercedExpr) {
         *coercedExpr = BitwiseLeft(coercionNode);
       }
       return true;
     }
-    case ParseNodeKind::Pos: {
+    case ParseNodeKind::PosExpr: {
       *coerceTo = Type::Double;
       if (coercedExpr) {
         *coercedExpr = UnaryKid(coercionNode);
       }
       return true;
     }
-    case ParseNodeKind::Call: {
+    case ParseNodeKind::CallExpr: {
       if (IsCoercionCall(m, coercionNode, coerceTo, coercedExpr)) {
         return true;
       }
       break;
     }
     default:;
   }
 
@@ -2759,17 +2763,17 @@ static bool CheckGlobalVariableInitImpor
                                           PropertyName* varName,
                                           ParseNode* initNode, bool isConst) {
   Type coerceTo;
   ParseNode* coercedExpr;
   if (!CheckTypeAnnotation(m, initNode, &coerceTo, &coercedExpr)) {
     return false;
   }
 
-  if (!coercedExpr->isKind(ParseNodeKind::Dot)) {
+  if (!coercedExpr->isKind(ParseNodeKind::DotExpr)) {
     return m.failName(coercedExpr, "invalid import expression for global '%s'",
                       varName);
   }
 
   if (!coerceTo.isGlobalVarType()) {
     return m.fail(initNode, "global variable type not allowed");
   }
 
@@ -2845,17 +2849,17 @@ static bool CheckNewArrayView(ModuleVali
     return m.fail(newExpr,
                   "cannot create array view without an asm.js heap parameter");
   }
 
   ParseNode* ctorExpr = BinaryLeft(newExpr);
 
   PropertyName* field;
   Scalar::Type type;
-  if (ctorExpr->isKind(ParseNodeKind::Dot)) {
+  if (ctorExpr->isKind(ParseNodeKind::DotExpr)) {
     ParseNode* base = DotBase(ctorExpr);
 
     if (!IsUseOfName(base, globalName)) {
       return m.failName(base, "expecting '%s.*Array", globalName);
     }
 
     field = DotMember(ctorExpr);
     if (!IsArrayViewCtorName(m, field, &type)) {
@@ -2910,28 +2914,28 @@ static bool CheckGlobalMathImport(Module
   MOZ_CRASH("unexpected or uninitialized math builtin type");
 }
 
 static bool CheckGlobalDotImport(ModuleValidator& m, PropertyName* varName,
                                  ParseNode* initNode) {
   ParseNode* base = DotBase(initNode);
   PropertyName* field = DotMember(initNode);
 
-  if (base->isKind(ParseNodeKind::Dot)) {
+  if (base->isKind(ParseNodeKind::DotExpr)) {
     ParseNode* global = DotBase(base);
     PropertyName* math = DotMember(base);
 
     PropertyName* globalName = m.globalArgumentName();
     if (!globalName) {
       return m.fail(
           base, "import statement requires the module have a stdlib parameter");
     }
 
     if (!IsUseOfName(global, globalName)) {
-      if (global->isKind(ParseNodeKind::Dot)) {
+      if (global->isKind(ParseNodeKind::DotExpr)) {
         return m.failName(base,
                           "imports can have at most two dot accesses "
                           "(e.g. %s.Math.sin)",
                           globalName);
       }
       return m.failName(base, "expecting %s.*", globalName);
     }
 
@@ -2985,27 +2989,27 @@ static bool CheckModuleGlobal(ModuleVali
   if (!initNode) {
     return m.fail(var, "module import needs initializer");
   }
 
   if (IsNumericLiteral(m, initNode)) {
     return CheckGlobalVariableInitConstant(m, varName, initNode, isConst);
   }
 
-  if (initNode->isKind(ParseNodeKind::BitOr) ||
-      initNode->isKind(ParseNodeKind::Pos) ||
-      initNode->isKind(ParseNodeKind::Call)) {
+  if (initNode->isKind(ParseNodeKind::BitOrExpr) ||
+      initNode->isKind(ParseNodeKind::PosExpr) ||
+      initNode->isKind(ParseNodeKind::CallExpr)) {
     return CheckGlobalVariableInitImport(m, varName, initNode, isConst);
   }
 
-  if (initNode->isKind(ParseNodeKind::New)) {
+  if (initNode->isKind(ParseNodeKind::NewExpr)) {
     return CheckNewArrayView(m, varName, initNode);
   }
 
-  if (initNode->isKind(ParseNodeKind::Dot)) {
+  if (initNode->isKind(ParseNodeKind::DotExpr)) {
     return CheckGlobalDotImport(m, varName, initNode);
   }
 
   return m.fail(initNode, "unsupported import expression");
 }
 
 static bool CheckModuleProcessingDirectives(ModuleValidator& m) {
   auto& ts = m.parser().tokenStream;
@@ -3039,17 +3043,18 @@ static bool CheckModuleGlobals(ModuleVal
     ParseNode* varStmt;
     if (!ParseVarOrConstStatement(m.parser(), &varStmt)) {
       return false;
     }
     if (!varStmt) {
       break;
     }
     for (ParseNode* var = VarListHead(varStmt); var; var = NextNode(var)) {
-      if (!CheckModuleGlobal(m, var, varStmt->isKind(ParseNodeKind::Const))) {
+      if (!CheckModuleGlobal(m, var,
+                             varStmt->isKind(ParseNodeKind::ConstDecl))) {
         return false;
       }
     }
   }
 
   return true;
 }
 
@@ -3063,17 +3068,17 @@ static bool ArgFail(FunctionValidator& f
 
 static bool CheckArgumentType(FunctionValidator& f, ParseNode* stmt,
                               PropertyName* name, Type* type) {
   if (!stmt || !IsExpressionStatement(stmt)) {
     return ArgFail(f, name, stmt ? stmt : f.fn());
   }
 
   ParseNode* initNode = ExpressionStatementExpr(stmt);
-  if (!initNode->isKind(ParseNodeKind::Assign)) {
+  if (!initNode->isKind(ParseNodeKind::AssignExpr)) {
     return ArgFail(f, name, stmt);
   }
 
   ParseNode* argNode = BinaryLeft(initNode);
   ParseNode* coercionNode = BinaryRight(initNode);
 
   if (!IsUseOfName(argNode, name)) {
     return ArgFail(f, name, stmt);
@@ -3166,17 +3171,17 @@ static bool CheckFinalReturn(FunctionVal
     return false;
   }
 
   if (!f.hasAlreadyReturned()) {
     f.setReturnedType(ExprType::Void);
     return true;
   }
 
-  if (!lastNonEmptyStmt->isKind(ParseNodeKind::Return) &&
+  if (!lastNonEmptyStmt->isKind(ParseNodeKind::ReturnStmt) &&
       !IsVoid(f.returnedType())) {
     return f.fail(lastNonEmptyStmt,
                   "void incompatible with previous return type");
   }
 
   return true;
 }
 
@@ -3218,17 +3223,17 @@ static bool CheckVariable(FunctionValida
 static bool CheckVariables(FunctionValidator& f, ParseNode** stmtIter) {
   ParseNode* stmt = *stmtIter;
 
   uint32_t firstVar = f.numLocals();
 
   ValTypeVector types;
   Vector<NumLit> inits(f.cx());
 
-  for (; stmt && stmt->isKind(ParseNodeKind::Var);
+  for (; stmt && stmt->isKind(ParseNodeKind::VarStmt);
        stmt = NextNonEmptyStatement(stmt)) {
     for (ParseNode* var = VarListHead(stmt); var; var = NextNode(var)) {
       if (!CheckVariable(f, var, &types, &inits)) {
         return false;
       }
     }
   }
 
@@ -3350,17 +3355,17 @@ static bool CheckArrayAccess(FunctionVal
     return f.writeInt32Lit(byteOffset);
   }
 
   // Mask off the low bits to account for the clearing effect of a right shift
   // followed by the left shift implicit in the array access. E.g., H32[i>>2]
   // loses the low two bits.
   int32_t mask = ~(TypedArrayElemSize(*viewType) - 1);
 
-  if (indexExpr->isKind(ParseNodeKind::Rsh)) {
+  if (indexExpr->isKind(ParseNodeKind::RshExpr)) {
     ParseNode* shiftAmountNode = BitwiseRight(indexExpr);
 
     uint32_t shift;
     if (!IsLiteralInt(f.m(), shiftAmountNode, &shift)) {
       return f.failf(shiftAmountNode, "shift amount must be constant");
     }
 
     unsigned requiredShift = TypedArrayShift(*viewType);
@@ -3630,22 +3635,22 @@ static bool CheckAssignName(FunctionVali
     return true;
   }
 
   return f.failName(lhs, "'%s' not found in local or asm.js module scope",
                     name);
 }
 
 static bool CheckAssign(FunctionValidator& f, ParseNode* assign, Type* type) {
-  MOZ_ASSERT(assign->isKind(ParseNodeKind::Assign));
+  MOZ_ASSERT(assign->isKind(ParseNodeKind::AssignExpr));
 
   ParseNode* lhs = BinaryLeft(assign);
   ParseNode* rhs = BinaryRight(assign);
 
-  if (lhs->getKind() == ParseNodeKind::Elem) {
+  if (lhs->getKind() == ParseNodeKind::ElemExpr) {
     return CheckStoreArray(f, lhs, rhs, type);
   }
 
   if (lhs->getKind() == ParseNodeKind::Name) {
     return CheckAssignName(f, lhs, rhs, type);
   }
 
   return f.fail(
@@ -3984,17 +3989,17 @@ static bool CheckFuncPtrCall(FunctionVal
   PropertyName* name = tableNode->as<NameNode>().name();
   if (const ModuleValidator::Global* existing = f.lookupGlobal(name)) {
     if (existing->which() != ModuleValidator::Global::Table) {
       return f.failName(
           tableNode, "'%s' is not the name of a function-pointer array", name);
     }
   }
 
-  if (!indexExpr->isKind(ParseNodeKind::BitAnd)) {
+  if (!indexExpr->isKind(ParseNodeKind::BitAndExpr)) {
     return f.fail(indexExpr,
                   "function-pointer table index expression needs & mask");
   }
 
   ParseNode* indexNode = BitwiseLeft(indexExpr);
   ParseNode* maskNode = BitwiseRight(indexExpr);
 
   uint32_t mask;
@@ -4106,17 +4111,17 @@ static bool CheckFloatCoercionArg(Functi
 
 static bool CheckCoercedCall(FunctionValidator& f, ParseNode* call, Type ret,
                              Type* type);
 
 static bool CheckCoercionArg(FunctionValidator& f, ParseNode* arg,
                              Type expected, Type* type) {
   MOZ_ASSERT(expected.isCanonicalValType());
 
-  if (arg->isKind(ParseNodeKind::Call)) {
+  if (arg->isKind(ParseNodeKind::CallExpr)) {
     return CheckCoercedCall(f, arg, expected, type);
   }
 
   Type argType;
   if (!CheckExpr(f, arg, &argType)) {
     return false;
   }
 
@@ -4297,17 +4302,17 @@ static bool CheckMathBuiltinCall(Functio
   }
 
   *type = opIsDouble ? Type::Double : Type::Floatish;
   return true;
 }
 
 static bool CheckUncoercedCall(FunctionValidator& f, ParseNode* expr,
                                Type* type) {
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::Call));
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::CallExpr));
 
   const ModuleValidator::Global* global;
   if (IsCallToGlobal(f.m(), expr, &global) && global->isMathFunction()) {
     return CheckMathBuiltinCall(f, expr, global->mathBuiltinFunction(), type);
   }
 
   return f.fail(
       expr,
@@ -4393,17 +4398,17 @@ static bool CheckCoercedCall(FunctionVal
     if (!f.writeConstExpr(lit)) {
       return false;
     }
     return CoerceResult(f, call, ret, Type::lit(lit), type);
   }
 
   ParseNode* callee = CallCallee(call);
 
-  if (callee->isKind(ParseNodeKind::Elem)) {
+  if (callee->isKind(ParseNodeKind::ElemExpr)) {
     return CheckFuncPtrCall(f, call, ret, type);
   }
 
   if (!callee->isKind(ParseNodeKind::Name)) {
     return f.fail(callee, "unexpected callee expression type");
   }
 
   PropertyName* calleeName = callee->as<NameNode>().name();
@@ -4426,33 +4431,33 @@ static bool CheckCoercedCall(FunctionVal
         break;
     }
   }
 
   return CheckInternalCall(f, call, calleeName, ret, type);
 }
 
 static bool CheckPos(FunctionValidator& f, ParseNode* pos, Type* type) {
-  MOZ_ASSERT(pos->isKind(ParseNodeKind::Pos));
+  MOZ_ASSERT(pos->isKind(ParseNodeKind::PosExpr));
   ParseNode* operand = UnaryKid(pos);
 
-  if (operand->isKind(ParseNodeKind::Call)) {
+  if (operand->isKind(ParseNodeKind::CallExpr)) {
     return CheckCoercedCall(f, operand, Type::Double, type);
   }
 
   Type actual;
   if (!CheckExpr(f, operand, &actual)) {
     return false;
   }
 
   return CoerceResult(f, operand, Type::Double, actual, type);
 }
 
 static bool CheckNot(FunctionValidator& f, ParseNode* expr, Type* type) {
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::Not));
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::NotExpr));
   ParseNode* operand = UnaryKid(expr);
 
   Type operandType;
   if (!CheckExpr(f, operand, &operandType)) {
     return false;
   }
 
   if (!operandType.isInt()) {
@@ -4460,17 +4465,17 @@ static bool CheckNot(FunctionValidator& 
                    operandType.toChars());
   }
 
   *type = Type::Int;
   return f.encoder().writeOp(Op::I32Eqz);
 }
 
 static bool CheckNeg(FunctionValidator& f, ParseNode* expr, Type* type) {
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::Neg));
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::NegExpr));
   ParseNode* operand = UnaryKid(expr);
 
   Type operandType;
   if (!CheckExpr(f, operand, &operandType)) {
     return false;
   }
 
   if (operandType.isInt()) {
@@ -4489,17 +4494,17 @@ static bool CheckNeg(FunctionValidator& 
   }
 
   return f.failf(operand, "%s is not a subtype of int, float? or double?",
                  operandType.toChars());
 }
 
 static bool CheckCoerceToInt(FunctionValidator& f, ParseNode* expr,
                              Type* type) {
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::BitNot));
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::BitNotExpr));
   ParseNode* operand = UnaryKid(expr);
 
   Type operandType;
   if (!CheckExpr(f, operand, &operandType)) {
     return false;
   }
 
   if (operandType.isMaybeDouble() || operandType.isMaybeFloat()) {
@@ -4514,20 +4519,20 @@ static bool CheckCoerceToInt(FunctionVal
                    operandType.toChars());
   }
 
   *type = Type::Signed;
   return true;
 }
 
 static bool CheckBitNot(FunctionValidator& f, ParseNode* neg, Type* type) {
-  MOZ_ASSERT(neg->isKind(ParseNodeKind::BitNot));
+  MOZ_ASSERT(neg->isKind(ParseNodeKind::BitNotExpr));
   ParseNode* operand = UnaryKid(neg);
 
-  if (operand->isKind(ParseNodeKind::BitNot)) {
+  if (operand->isKind(ParseNodeKind::BitNotExpr)) {
     return CheckCoerceToInt(f, operand, type);
   }
 
   Type operandType;
   if (!CheckExpr(f, operand, &operandType)) {
     return false;
   }
 
@@ -4542,17 +4547,17 @@ static bool CheckBitNot(FunctionValidato
 
   *type = Type::Signed;
   return true;
 }
 
 static bool CheckAsExprStatement(FunctionValidator& f, ParseNode* exprStmt);
 
 static bool CheckComma(FunctionValidator& f, ParseNode* comma, Type* type) {
-  MOZ_ASSERT(comma->isKind(ParseNodeKind::Comma));
+  MOZ_ASSERT(comma->isKind(ParseNodeKind::CommaExpr));
   ParseNode* operands = ListHead(comma);
 
   // The block depth isn't taken into account here, because a comma list can't
   // contain breaks and continues and nested control flow structures.
   if (!f.encoder().writeOp(Op::Block)) {
     return false;
   }
 
@@ -4575,17 +4580,17 @@ static bool CheckComma(FunctionValidator
   f.encoder().patchFixedU7(typeAt,
                            uint8_t(type->toWasmBlockSignatureType().code()));
 
   return f.encoder().writeOp(Op::End);
 }
 
 static bool CheckConditional(FunctionValidator& f, ParseNode* ternary,
                              Type* type) {
-  MOZ_ASSERT(ternary->isKind(ParseNodeKind::Conditional));
+  MOZ_ASSERT(ternary->isKind(ParseNodeKind::ConditionalExpr));
 
   ParseNode* cond = TernaryKid1(ternary);
   ParseNode* thenExpr = TernaryKid2(ternary);
   ParseNode* elseExpr = TernaryKid3(ternary);
 
   Type condType;
   if (!CheckExpr(f, cond, &condType)) {
     return false;
@@ -4654,17 +4659,17 @@ static bool IsValidIntMultiplyConstant(M
     case NumLit::OutOfRangeInt:
       return false;
   }
 
   MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Bad literal");
 }
 
 static bool CheckMultiply(FunctionValidator& f, ParseNode* star, Type* type) {
-  MOZ_ASSERT(star->isKind(ParseNodeKind::Star));
+  MOZ_ASSERT(star->isKind(ParseNodeKind::MulExpr));
   ParseNode* lhs = MultiplyLeft(star);
   ParseNode* rhs = MultiplyRight(star);
 
   Type lhsType;
   if (!CheckExpr(f, lhs, &lhsType)) {
     return false;
   }
 
@@ -4699,39 +4704,41 @@ static bool CheckMultiply(FunctionValida
 }
 
 static bool CheckAddOrSub(FunctionValidator& f, ParseNode* expr, Type* type,
                           unsigned* numAddOrSubOut = nullptr) {
   if (!CheckRecursionLimitDontReport(f.cx())) {
     return f.m().failOverRecursed();
   }
 
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::Add) ||
-             expr->isKind(ParseNodeKind::Sub));
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::AddExpr) ||
+             expr->isKind(ParseNodeKind::SubExpr));
   ParseNode* lhs = AddSubLeft(expr);
   ParseNode* rhs = AddSubRight(expr);
 
   Type lhsType, rhsType;
   unsigned lhsNumAddOrSub, rhsNumAddOrSub;
 
-  if (lhs->isKind(ParseNodeKind::Add) || lhs->isKind(ParseNodeKind::Sub)) {
+  if (lhs->isKind(ParseNodeKind::AddExpr) ||
+      lhs->isKind(ParseNodeKind::SubExpr)) {
     if (!CheckAddOrSub(f, lhs, &lhsType, &lhsNumAddOrSub)) {
       return false;
     }
     if (lhsType == Type::Intish) {
       lhsType = Type::Int;
     }
   } else {
     if (!CheckExpr(f, lhs, &lhsType)) {
       return false;
     }
     lhsNumAddOrSub = 0;
   }
 
-  if (rhs->isKind(ParseNodeKind::Add) || rhs->isKind(ParseNodeKind::Sub)) {
+  if (rhs->isKind(ParseNodeKind::AddExpr) ||
+      rhs->isKind(ParseNodeKind::SubExpr)) {
     if (!CheckAddOrSub(f, rhs, &rhsType, &rhsNumAddOrSub)) {
       return false;
     }
     if (rhsType == Type::Intish) {
       rhsType = Type::Int;
     }
   } else {
     if (!CheckExpr(f, rhs, &rhsType)) {
@@ -4741,30 +4748,30 @@ static bool CheckAddOrSub(FunctionValida
   }
 
   unsigned numAddOrSub = lhsNumAddOrSub + rhsNumAddOrSub + 1;
   if (numAddOrSub > (1 << 20)) {
     return f.fail(expr, "too many + or - without intervening coercion");
   }
 
   if (lhsType.isInt() && rhsType.isInt()) {
-    if (!f.encoder().writeOp(expr->isKind(ParseNodeKind::Add) ? Op::I32Add
-                                                              : Op::I32Sub)) {
+    if (!f.encoder().writeOp(
+            expr->isKind(ParseNodeKind::AddExpr) ? Op::I32Add : Op::I32Sub)) {
       return false;
     }
     *type = Type::Intish;
   } else if (lhsType.isMaybeDouble() && rhsType.isMaybeDouble()) {
-    if (!f.encoder().writeOp(expr->isKind(ParseNodeKind::Add) ? Op::F64Add
-                                                              : Op::F64Sub)) {
+    if (!f.encoder().writeOp(
+            expr->isKind(ParseNodeKind::AddExpr) ? Op::F64Add : Op::F64Sub)) {
       return false;
     }
     *type = Type::Double;
   } else if (lhsType.isMaybeFloat() && rhsType.isMaybeFloat()) {
-    if (!f.encoder().writeOp(expr->isKind(ParseNodeKind::Add) ? Op::F32Add
-                                                              : Op::F32Sub)) {
+    if (!f.encoder().writeOp(
+            expr->isKind(ParseNodeKind::AddExpr) ? Op::F32Add : Op::F32Sub)) {
       return false;
     }
     *type = Type::Floatish;
   } else {
     return f.failf(
         expr,
         "operands to + or - must both be int, float? or double?, got %s and %s",
         lhsType.toChars(), rhsType.toChars());
@@ -4772,71 +4779,73 @@ static bool CheckAddOrSub(FunctionValida
 
   if (numAddOrSubOut) {
     *numAddOrSubOut = numAddOrSub;
   }
   return true;
 }
 
 static bool CheckDivOrMod(FunctionValidator& f, ParseNode* expr, Type* type) {
-  MOZ_ASSERT(expr->isKind(ParseNodeKind::Div) ||
-             expr->isKind(ParseNodeKind::Mod));
+  MOZ_ASSERT(expr->isKind(ParseNodeKind::DivExpr) ||
+             expr->isKind(ParseNodeKind::ModExpr));
 
   ParseNode* lhs = DivOrModLeft(expr);
   ParseNode* rhs = DivOrModRight(expr);
 
   Type lhsType, rhsType;
   if (!CheckExpr(f, lhs, &lhsType)) {
     return false;
   }
   if (!CheckExpr(f, rhs, &rhsType)) {
     return false;
   }
 
   if (lhsType.isMaybeDouble() && rhsType.isMaybeDouble()) {
     *type = Type::Double;
-    if (expr->isKind(ParseNodeKind::Div)) {
+    if (expr->isKind(ParseNodeKind::DivExpr)) {
       return f.encoder().writeOp(Op::F64Div);
     }
     return f.encoder().writeOp(MozOp::F64Mod);
   }
 
   if (lhsType.is