Bug 1529772 - Part 3: Implement ASI for fields that have initializers. r=jwalden
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 15 Apr 2019 20:55:05 +0000
changeset 469566 e771e63200c6
parent 469565 0f4a343adc59
child 469567 27f0cd20a8b0
push id35874
push userccoroiu@mozilla.com
push dateTue, 16 Apr 2019 04:04:58 +0000
treeherdermozilla-central@be3f40425b52 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1529772
milestone68.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 1529772 - Part 3: Implement ASI for fields that have initializers. r=jwalden Differential Revision: https://phabricator.services.mozilla.com/D26037
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/js.msg
js/src/tests/jstests.list
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2022,19 +2022,20 @@ JSFunction* ParserBase::newFunction(Hand
                                     GeneratorKind generatorKind,
                                     FunctionAsyncKind asyncKind,
                                     HandleObject proto /* = nullptr */) {
   return AllocNewFunction(cx_, atom, kind, generatorKind, asyncKind, proto,
                           options().selfHostingMode, pc_->isFunctionBox());
 }
 
 template <class ParseHandler, typename Unit>
-bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon() {
+bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
+    Modifier modifier /* = TokenStream::SlashIsRegExp */) {
   TokenKind tt = TokenKind::Eof;
-  if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
+  if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
     return false;
   }
   if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
       tt != TokenKind::RightCurly) {
     /*
      * When current token is `await` and it's outside of async function,
      * it's possibly intended to be an await expression.
      *
@@ -2052,23 +2053,22 @@ bool GeneralParser<ParseHandler, Unit>::
     }
     if (!yieldExpressionsSupported() &&
         anyChars.currentToken().type == TokenKind::Yield) {
       error(JSMSG_YIELD_OUTSIDE_GENERATOR);
       return false;
     }
 
     /* Advance the scanner for proper error location reporting. */
-    tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
+    tokenStream.consumeKnownToken(tt, modifier);
     error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
     return false;
   }
   bool matched;
-  return tokenStream.matchToken(&matched, TokenKind::Semi,
-                                TokenStream::SlashIsRegExp);
+  return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
 }
 
 bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
   MOZ_ASSERT(pc_ != outerpc);
 
   // If the current function allows super.property but cannot have a home
   // object, i.e., it is an arrow function, we need to propagate the flag to
   // the outer ParseContext.
@@ -6806,23 +6806,17 @@ bool GeneralParser<ParseHandler, Unit>::
     numFields++;
 
     FunctionNodeType initializer = fieldInitializerOpt(
         yieldHandling, hasHeritage, propName, propAtom, numFieldKeys);
     if (!initializer) {
       return false;
     }
 
-    if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
-      return false;
-    }
-
-    // TODO(khyperia): Implement ASI
-    if (tt != TokenKind::Semi) {
-      error(JSMSG_MISSING_SEMI_FIELD);
+    if (!matchOrInsertSemicolon(TokenStream::SlashIsInvalid)) {
       return false;
     }
 
     return handler_.addClassFieldDefinition(classMembers, propName,
                                             initializer);
   }
 
   if (propType != PropertyType::Getter && propType != PropertyType::Setter &&
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1421,17 +1421,27 @@ class MOZ_STACK_CLASS GeneralParser : pu
 
   MOZ_MUST_USE FunctionNodeType innerFunction(
       FunctionNodeType funNode, ParseContext* outerpc, HandleFunction fun,
       uint32_t toStringStart, InHandling inHandling,
       YieldHandling yieldHandling, FunctionSyntaxKind kind,
       GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
       Directives inheritedDirectives, Directives* newDirectives);
 
-  bool matchOrInsertSemicolon();
+  // Implements Automatic Semicolon Insertion.
+  //
+  // Use this to match `;` in contexts where ASI is allowed. Call this after
+  // ruling out all other possibilities except `;`, by peeking ahead if
+  // necessary.
+  //
+  // Unlike most optional Modifiers, this method's `modifier` argument defaults
+  // to SlashIsRegExp, since that's by far the most common case: usually an
+  // optional semicolon is at the end of a statement or declaration, and the
+  // next token could be a RegExp literal beginning a new ExpressionStatement.
+  bool matchOrInsertSemicolon(Modifier modifier = TokenStream::SlashIsRegExp);
 
   bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind,
                         TokenPos pos);
 
  private:
   inline bool asmJS(ListNodeType list);
 };
 
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -348,17 +348,16 @@ MSG_DEF(JSMSG_VAR_HIDES_ARG,           1
 MSG_DEF(JSMSG_WHILE_AFTER_DO,          0, JSEXN_SYNTAXERR, "missing while after do-loop body")
 MSG_DEF(JSMSG_YIELD_IN_PARAMETER,      0, JSEXN_SYNTAXERR, "yield expression can't be used in parameter")
 MSG_DEF(JSMSG_YIELD_OUTSIDE_GENERATOR, 0, JSEXN_SYNTAXERR, "yield expression is only valid in generators")
 MSG_DEF(JSMSG_BAD_COLUMN_NUMBER,       0, JSEXN_RANGEERR, "column number out of range")
 MSG_DEF(JSMSG_COMPUTED_NAME_IN_PATTERN,0, JSEXN_SYNTAXERR, "computed property names aren't supported in this destructuring declaration")
 MSG_DEF(JSMSG_DEFAULT_IN_PATTERN,      0, JSEXN_SYNTAXERR, "destructuring defaults aren't supported in this destructuring declaration")
 MSG_DEF(JSMSG_BAD_NEWTARGET,           0, JSEXN_SYNTAXERR, "new.target only allowed within functions")
 MSG_DEF(JSMSG_ESCAPED_KEYWORD,         0, JSEXN_SYNTAXERR, "keywords must be written literally, without embedded escapes")
-MSG_DEF(JSMSG_MISSING_SEMI_FIELD,      0, JSEXN_SYNTAXERR, "missing ; after field definition")
 MSG_DEF(JSMSG_FIELDS_NOT_SUPPORTED,    0, JSEXN_SYNTAXERR, "fields are not currently supported")
 
 // UTF-8 source text encoding errors
 MSG_DEF(JSMSG_BAD_LEADING_UTF8_UNIT,   1, JSEXN_SYNTAXERR, "{0} byte doesn't begin a valid UTF-8 code point")
 MSG_DEF(JSMSG_NOT_ENOUGH_CODE_UNITS,   5, JSEXN_SYNTAXERR, "{0} byte in UTF-8 must be followed by {1} byte{2}, but {3} byte{4} present")
 MSG_DEF(JSMSG_BAD_TRAILING_UTF8_UNIT,  1, JSEXN_SYNTAXERR, "bad trailing UTF-8 byte {0} doesn't match the pattern 0b10xxxxxx")
 MSG_DEF(JSMSG_FORBIDDEN_UTF8_CODE_POINT,2,JSEXN_SYNTAXERR, "{0} isn't a valid code point because {1}")
 MSG_DEF(JSMSG_BAD_CODE_UNITS,          1, JSEXN_NOTE, "the code units comprising this invalid code point were: {0}")
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -560,95 +560,56 @@ skip script test262/language/expressions
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1529772
 skip script test262/language/expressions/class/elements/after-same-line-gen-literal-names-asi.js
 skip script test262/language/expressions/class/elements/after-same-line-method-literal-names-asi.js
 skip script test262/language/expressions/class/elements/after-same-line-static-async-gen-literal-names-asi.js
 skip script test262/language/expressions/class/elements/after-same-line-static-async-method-literal-names-asi.js
 skip script test262/language/expressions/class/elements/after-same-line-static-gen-literal-names-asi.js
 skip script test262/language/expressions/class/elements/after-same-line-static-method-literal-names-asi.js
-skip script test262/language/expressions/class/elements/fields-asi-1.js
-skip script test262/language/expressions/class/elements/fields-asi-2.js
-skip script test262/language/expressions/class/elements/fields-asi-5.js
 skip script test262/language/expressions/class/elements/multiple-definitions-computed-names.js
-skip script test262/language/expressions/class/elements/multiple-definitions-computed-symbol-names.js
 skip script test262/language/expressions/class/elements/multiple-definitions-literal-names-asi.js
-skip script test262/language/expressions/class/elements/multiple-definitions-literal-names.js
-skip script test262/language/expressions/class/elements/multiple-definitions-rs-field-identifier-initializer.js
 skip script test262/language/expressions/class/elements/multiple-definitions-rs-field-identifier.js
-skip script test262/language/expressions/class/elements/multiple-definitions-string-literal-names.js
 skip script test262/language/expressions/class/elements/multiple-stacked-definitions-computed-names.js
-skip script test262/language/expressions/class/elements/multiple-stacked-definitions-computed-symbol-names.js
 skip script test262/language/expressions/class/elements/multiple-stacked-definitions-literal-names-asi.js
-skip script test262/language/expressions/class/elements/multiple-stacked-definitions-literal-names.js
-skip script test262/language/expressions/class/elements/multiple-stacked-definitions-rs-field-identifier-initializer.js
 skip script test262/language/expressions/class/elements/multiple-stacked-definitions-rs-field-identifier.js
-skip script test262/language/expressions/class/elements/multiple-stacked-definitions-string-literal-names.js
 skip script test262/language/expressions/class/elements/new-no-sc-line-method-computed-names.js
-skip script test262/language/expressions/class/elements/new-no-sc-line-method-computed-symbol-names.js
 skip script test262/language/expressions/class/elements/new-no-sc-line-method-literal-names-asi.js
-skip script test262/language/expressions/class/elements/new-no-sc-line-method-literal-names.js
-skip script test262/language/expressions/class/elements/new-no-sc-line-method-rs-field-identifier-initializer.js
 skip script test262/language/expressions/class/elements/new-no-sc-line-method-rs-field-identifier.js
-skip script test262/language/expressions/class/elements/new-no-sc-line-method-string-literal-names.js
 skip script test262/language/expressions/class/elements/new-sc-line-gen-literal-names-asi.js
 skip script test262/language/expressions/class/elements/new-sc-line-method-literal-names-asi.js
 skip script test262/language/expressions/class/elements/regular-definitions-computed-names.js
-skip script test262/language/expressions/class/elements/regular-definitions-computed-symbol-names.js
 skip script test262/language/expressions/class/elements/regular-definitions-literal-names-asi.js
-skip script test262/language/expressions/class/elements/regular-definitions-literal-names.js
-skip script test262/language/expressions/class/elements/regular-definitions-rs-field-identifier-initializer.js
 skip script test262/language/expressions/class/elements/regular-definitions-rs-field-identifier.js
-skip script test262/language/expressions/class/elements/regular-definitions-string-literal-names.js
 skip script test262/language/expressions/class/elements/same-line-async-gen-literal-names-asi.js
 skip script test262/language/expressions/class/elements/same-line-async-method-literal-names-asi.js
 skip script test262/language/expressions/class/elements/same-line-gen-literal-names-asi.js
 skip script test262/language/expressions/class/elements/same-line-method-literal-names-asi.js
 skip script test262/language/expressions/class/elements/syntax/valid/grammar-fields-multi-line.js
 skip script test262/language/expressions/class/elements/wrapped-in-sc-literal-names-asi.js
-skip script test262/language/statements/class/classelementname-abrupt-completion.js
 skip script test262/language/statements/class/elements/after-same-line-gen-literal-names-asi.js
 skip script test262/language/statements/class/elements/after-same-line-method-literal-names-asi.js
 skip script test262/language/statements/class/elements/after-same-line-static-async-gen-literal-names-asi.js
 skip script test262/language/statements/class/elements/after-same-line-static-async-method-literal-names-asi.js
 skip script test262/language/statements/class/elements/after-same-line-static-gen-literal-names-asi.js
 skip script test262/language/statements/class/elements/after-same-line-static-method-literal-names-asi.js
-skip script test262/language/statements/class/elements/fields-asi-1.js
-skip script test262/language/statements/class/elements/fields-asi-2.js
-skip script test262/language/statements/class/elements/fields-asi-5.js
 skip script test262/language/statements/class/elements/multiple-definitions-computed-names.js
-skip script test262/language/statements/class/elements/multiple-definitions-computed-symbol-names.js
 skip script test262/language/statements/class/elements/multiple-definitions-literal-names-asi.js
-skip script test262/language/statements/class/elements/multiple-definitions-literal-names.js
-skip script test262/language/statements/class/elements/multiple-definitions-rs-field-identifier-initializer.js
 skip script test262/language/statements/class/elements/multiple-definitions-rs-field-identifier.js
-skip script test262/language/statements/class/elements/multiple-definitions-string-literal-names.js
 skip script test262/language/statements/class/elements/multiple-stacked-definitions-computed-names.js
-skip script test262/language/statements/class/elements/multiple-stacked-definitions-computed-symbol-names.js
 skip script test262/language/statements/class/elements/multiple-stacked-definitions-literal-names-asi.js
-skip script test262/language/statements/class/elements/multiple-stacked-definitions-literal-names.js
-skip script test262/language/statements/class/elements/multiple-stacked-definitions-rs-field-identifier-initializer.js
 skip script test262/language/statements/class/elements/multiple-stacked-definitions-rs-field-identifier.js
-skip script test262/language/statements/class/elements/multiple-stacked-definitions-string-literal-names.js
 skip script test262/language/statements/class/elements/new-no-sc-line-method-computed-names.js
-skip script test262/language/statements/class/elements/new-no-sc-line-method-computed-symbol-names.js
 skip script test262/language/statements/class/elements/new-no-sc-line-method-literal-names-asi.js
-skip script test262/language/statements/class/elements/new-no-sc-line-method-literal-names.js
-skip script test262/language/statements/class/elements/new-no-sc-line-method-rs-field-identifier-initializer.js
 skip script test262/language/statements/class/elements/new-no-sc-line-method-rs-field-identifier.js
-skip script test262/language/statements/class/elements/new-no-sc-line-method-string-literal-names.js
 skip script test262/language/statements/class/elements/new-sc-line-gen-literal-names-asi.js
 skip script test262/language/statements/class/elements/new-sc-line-method-literal-names-asi.js
 skip script test262/language/statements/class/elements/regular-definitions-computed-names.js
-skip script test262/language/statements/class/elements/regular-definitions-computed-symbol-names.js
 skip script test262/language/statements/class/elements/regular-definitions-literal-names-asi.js
-skip script test262/language/statements/class/elements/regular-definitions-literal-names.js
-skip script test262/language/statements/class/elements/regular-definitions-rs-field-identifier-initializer.js
 skip script test262/language/statements/class/elements/regular-definitions-rs-field-identifier.js
-skip script test262/language/statements/class/elements/regular-definitions-string-literal-names.js
 skip script test262/language/statements/class/elements/same-line-async-gen-literal-names-asi.js
 skip script test262/language/statements/class/elements/same-line-async-method-literal-names-asi.js
 skip script test262/language/statements/class/elements/same-line-gen-literal-names-asi.js
 skip script test262/language/statements/class/elements/same-line-method-literal-names-asi.js
 skip script test262/language/statements/class/elements/syntax/valid/grammar-fields-multi-line.js
 skip script test262/language/statements/class/elements/wrapped-in-sc-literal-names-asi.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1542406