Improve parsing errors related to destructuring bind
authorlittledan <littledan@chromium.org>
Tue, 14 Jul 2015 21:57:40 +0000 (14:57 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 14 Jul 2015 21:57:51 +0000 (21:57 +0000)
For destructuring bind, the parser needs to complain about things
which are inappropriate to have on the left-hand side.

Previously, regexp literals and template literals were let through
the parser inappropriately. This patch turns those into errors.

This patch also fixes off-by-one errors in reporting the location
of this type of error for strings and numbers. Before the patch,
the error would look like:

d8> var {x: 3} = {x: 4}
(d8):1: SyntaxError: Unexpected number
var {x: 3} = {x: 4}
      ^
SyntaxError: Unexpected number

And with the patch, the error is

d8> var {x: 3} = {x: 4}
(d8):1: SyntaxError: Unexpected number
var {x: 3} = {x: 4}
        ^
SyntaxError: Unexpected number

R=rossberg

Review URL: https://codereview.chromium.org/1236803003

Cr-Commit-Position: refs/heads/master@{#29661}

src/messages.h
src/preparser.h
test/cctest/test-parsing.cc

index a27078e..d50c5b5 100644 (file)
@@ -411,6 +411,7 @@ class CallSite {
   T(UnexpectedTokenIdentifier, "Unexpected identifier")                        \
   T(UnexpectedTokenNumber, "Unexpected number")                                \
   T(UnexpectedTokenString, "Unexpected string")                                \
+  T(UnexpectedTokenRegExp, "Unexpected regular expression")                    \
   T(UnknownLabel, "Undefined label '%'")                                       \
   T(UnterminatedArgList, "missing ) after argument list")                      \
   T(UnterminatedRegExp, "Invalid regular expression: missing /")               \
index 9f58646..506e29d 100644 (file)
@@ -2170,7 +2170,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
     case Token::SMI:
     case Token::NUMBER:
       classifier->RecordBindingPatternError(
-          scanner()->location(), MessageTemplate::kUnexpectedTokenNumber);
+          scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber);
       Next();
       result =
           this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
@@ -2190,17 +2190,21 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
 
     case Token::STRING: {
       classifier->RecordBindingPatternError(
-          scanner()->location(), MessageTemplate::kUnexpectedTokenString);
+          scanner()->peek_location(), MessageTemplate::kUnexpectedTokenString);
       Consume(Token::STRING);
       result = this->ExpressionFromString(beg_pos, scanner(), factory());
       break;
     }
 
     case Token::ASSIGN_DIV:
+      classifier->RecordBindingPatternError(
+          scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
       result = this->ParseRegExpLiteral(true, classifier, CHECK_OK);
       break;
 
     case Token::DIV:
+      classifier->RecordBindingPatternError(
+          scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp);
       result = this->ParseRegExpLiteral(false, classifier, CHECK_OK);
       break;
 
@@ -2302,6 +2306,9 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
 
     case Token::TEMPLATE_SPAN:
     case Token::TEMPLATE_TAIL:
+      classifier->RecordBindingPatternError(
+          scanner()->peek_location(),
+          MessageTemplate::kUnexpectedTemplateString);
       result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
                                           classifier, CHECK_OK);
       break;
index 43737cb..e14b6f6 100644 (file)
@@ -6449,6 +6449,8 @@ TEST(DestructuringNegativeTests) {
         "false",
         "1",
         "'abc'",
+        "/abc/",
+        "`abc`",
         "class {}",
         "{+2 : x}",
         "{-2 : x}",
@@ -6469,6 +6471,10 @@ TEST(DestructuringNegativeTests) {
         "[...rest,...rest1]",
         "[a,b,...rest,...rest1]",
         "[a,,..rest,...rest1]",
+        "{ x : 3 }",
+        "{ x : 'foo' }",
+        "{ x : /foo/ }",
+        "{ x : `foo` }",
         NULL};
     // clang-format on
     RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,