Simplify error message logic in ParseImportNames
authoradamk <adamk@chromium.org>
Wed, 25 Feb 2015 19:40:39 +0000 (11:40 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 25 Feb 2015 19:40:54 +0000 (19:40 +0000)
The new logic ensures that the error messages are the same in the
"import { <reserved word> }" and "import { foo as <reserved ord> }"
cases.

Also prepares ParseImportNames for returning both the import and local
names to ParseImportClause.

BUG=v8:1569
LOG=n

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

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

src/parser.cc
src/parser.h
test/message/import-as-eval.js [new file with mode: 0644]
test/message/import-as-eval.out [new file with mode: 0644]
test/message/import-as-reserved-word.js [new file with mode: 0644]
test/message/import-as-reserved-word.out [new file with mode: 0644]
test/message/import-eval.js [new file with mode: 0644]
test/message/import-eval.out [new file with mode: 0644]
test/message/import-reserved-word.js [new file with mode: 0644]
test/message/import-reserved-word.out [new file with mode: 0644]

index 32f73cf..070bb3b 100644 (file)
@@ -1338,7 +1338,8 @@ void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
 }
 
 
-void* Parser::ParseNamedImports(ZoneList<const AstRawString*>* names,
+void* Parser::ParseNamedImports(ZoneList<const AstRawString*>* import_names,
+                                ZoneList<const AstRawString*>* local_names,
                                 bool* ok) {
   // NamedImports :
   //   '{' '}'
@@ -1355,27 +1356,26 @@ void* Parser::ParseNamedImports(ZoneList<const AstRawString*>* names,
 
   Expect(Token::LBRACE, CHECK_OK);
 
-  Token::Value name_tok;
-  while ((name_tok = peek()) != Token::RBRACE) {
-    const AstRawString* name = ParseIdentifierName(CHECK_OK);
-    const AstRawString* import_name = NULL;
+  while (peek() != Token::RBRACE) {
+    const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
+    const AstRawString* local_name = import_name;
     // In the presence of 'as', the left-side of the 'as' can
     // be any IdentifierName. But without 'as', it must be a valid
-    // BindingIdentiifer.
+    // BindingIdentifier.
     if (CheckContextualKeyword(CStrVector("as"))) {
-      import_name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
-    } else if (!Token::IsIdentifier(name_tok, STRICT, false)) {
+      local_name = ParseIdentifierName(CHECK_OK);
+    }
+    if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
       *ok = false;
-      ReportMessageAt(scanner()->location(), "unexpected_reserved");
+      ReportMessage("unexpected_reserved");
       return NULL;
-    } else if (IsEvalOrArguments(name)) {
+    } else if (IsEvalOrArguments(local_name)) {
       *ok = false;
-      ReportMessageAt(scanner()->location(), "strict_eval_arguments");
+      ReportMessage("strict_eval_arguments");
       return NULL;
     }
-    // TODO(ES6): Return the import_name as well as the name.
-    names->Add(name, zone());
-    USE(import_name);
+    import_names->Add(import_name, zone());
+    local_names->Add(local_name, zone());
     if (peek() == Token::RBRACE) break;
     Expect(Token::COMMA, CHECK_OK);
   }
@@ -1408,8 +1408,10 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
 
   // 'import' ModuleSpecifier ';'
   if (tok == Token::STRING) {
-    ParseModuleSpecifier(CHECK_OK);
+    Literal* module_specifier = ParseModuleSpecifier(CHECK_OK);
     ExpectSemicolon(CHECK_OK);
+    // TODO(ES6): Add module to the requested modules of scope_->module().
+    USE(module_specifier);
     return factory()->NewEmptyStatement(pos);
   }
 
@@ -1421,7 +1423,8 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
   }
 
   const AstRawString* module_instance_binding = NULL;
-  ZoneList<const AstRawString*> names(1, zone());
+  ZoneList<const AstRawString*> local_names(1, zone());
+  ZoneList<const AstRawString*> import_names(1, zone());
   if (imported_default_binding == NULL || Check(Token::COMMA)) {
     switch (peek()) {
       case Token::MUL: {
@@ -1433,7 +1436,7 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
       }
 
       case Token::LBRACE:
-        ParseNamedImports(&names, CHECK_OK);
+        ParseNamedImports(&import_names, &local_names, CHECK_OK);
         break;
 
       default:
@@ -1457,7 +1460,9 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
     // TODO(ES6): Add an appropriate declaration.
   }
 
-  for (int i = 0; i < names.length(); ++i) {
+  const int length = import_names.length();
+  DCHECK_EQ(length, local_names.length());
+  for (int i = 0; i < length; ++i) {
     // TODO(ES6): Add an appropriate declaration for each name
   }
 
index f5bb792..a10a18e 100644 (file)
@@ -714,7 +714,8 @@ class Parser : public ParserBase<ParserTraits> {
                           ZoneList<Scanner::Location>* export_locations,
                           ZoneList<const AstRawString*>* local_names,
                           Scanner::Location* reserved_loc, bool* ok);
-  void* ParseNamedImports(ZoneList<const AstRawString*>* names, bool* ok);
+  void* ParseNamedImports(ZoneList<const AstRawString*>* import_names,
+                          ZoneList<const AstRawString*>* local_names, bool* ok);
   Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
   Statement* ParseSubStatement(ZoneList<const AstRawString*>* labels, bool* ok);
   Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
diff --git a/test/message/import-as-eval.js b/test/message/import-as-eval.js
new file mode 100644 (file)
index 0000000..66adc32
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MODULE
+
+import { foo as eval } from "mod";
diff --git a/test/message/import-as-eval.out b/test/message/import-as-eval.out
new file mode 100644 (file)
index 0000000..622f7fe
--- /dev/null
@@ -0,0 +1,7 @@
+# Copyright 2015 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+*%(basename)s:7: SyntaxError: Unexpected eval or arguments in strict mode
+import { foo as eval } from "mod";
+                ^^^^
+SyntaxError: Unexpected eval or arguments in strict mode
diff --git a/test/message/import-as-reserved-word.js b/test/message/import-as-reserved-word.js
new file mode 100644 (file)
index 0000000..562699d
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MODULE
+
+import { foo as import } from "mod";
diff --git a/test/message/import-as-reserved-word.out b/test/message/import-as-reserved-word.out
new file mode 100644 (file)
index 0000000..1ee8d41
--- /dev/null
@@ -0,0 +1,7 @@
+# Copyright 2015 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+*%(basename)s:7: SyntaxError: Unexpected reserved word
+import { foo as import } from "mod";
+                ^^^^^^
+SyntaxError: Unexpected reserved word
diff --git a/test/message/import-eval.js b/test/message/import-eval.js
new file mode 100644 (file)
index 0000000..8ab35ba
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MODULE
+
+import { eval } from "mod";
diff --git a/test/message/import-eval.out b/test/message/import-eval.out
new file mode 100644 (file)
index 0000000..148662a
--- /dev/null
@@ -0,0 +1,7 @@
+# Copyright 2015 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+*%(basename)s:7: SyntaxError: Unexpected eval or arguments in strict mode
+import { eval } from "mod";
+         ^^^^
+SyntaxError: Unexpected eval or arguments in strict mode
diff --git a/test/message/import-reserved-word.js b/test/message/import-reserved-word.js
new file mode 100644 (file)
index 0000000..1fd7ba2
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// MODULE
+
+import { import } from "mod";
diff --git a/test/message/import-reserved-word.out b/test/message/import-reserved-word.out
new file mode 100644 (file)
index 0000000..5b990e9
--- /dev/null
@@ -0,0 +1,7 @@
+# Copyright 2015 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+*%(basename)s:7: SyntaxError: Unexpected reserved word
+import { import } from "mod";
+         ^^^^^^
+SyntaxError: Unexpected reserved word