Revert "harmony-scoping: Allow 'const' iteration variables in strict mode."
authordslomov@chromium.org <dslomov@chromium.org>
Thu, 23 Oct 2014 11:55:19 +0000 (11:55 +0000)
committerdslomov@chromium.org <dslomov@chromium.org>
Thu, 23 Oct 2014 11:55:19 +0000 (11:55 +0000)
This reverts commit r24834 for breaking debug tests.

TBR=bmeurer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24839 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/parser.cc
src/preparser.cc
src/preparser.h
test/cctest/test-parsing.cc
test/mjsunit/regress/regress-2506.js [deleted file]

index b63d76d..bec0a4b 100644 (file)
@@ -2156,7 +2156,6 @@ Block* Parser::ParseVariableDeclarations(
   Block* block = factory()->NewBlock(NULL, 1, true, pos);
   int nvars = 0;  // the number of variables declared
   const AstRawString* name = NULL;
-  bool is_for_iteration_variable;
   do {
     if (fni_ != NULL) fni_->Enter();
 
@@ -2180,13 +2179,6 @@ Block* Parser::ParseVariableDeclarations(
     // For let/const declarations in harmony mode, we can also immediately
     // pre-resolve the proxy because it resides in the same scope as the
     // declaration.
-    is_for_iteration_variable =
-        var_context == kForStatement &&
-        (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
-    if (is_for_iteration_variable && mode == CONST) {
-      needs_init = false;
-    }
-
     Interface* interface =
         is_const ? Interface::NewConst() : Interface::NewValue();
     VariableProxy* proxy = NewUnresolved(name, mode, interface);
@@ -2232,8 +2224,7 @@ Block* Parser::ParseVariableDeclarations(
     Expression* value = NULL;
     int pos = -1;
     // Harmony consts have non-optional initializers.
-    if (peek() == Token::ASSIGN ||
-        (mode == CONST && !is_for_iteration_variable)) {
+    if (peek() == Token::ASSIGN || mode == CONST) {
       Expect(Token::ASSIGN, CHECK_OK);
       pos = position();
       value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
@@ -2366,7 +2357,7 @@ Block* Parser::ParseVariableDeclarations(
 
   // If there was a single non-const declaration, return it in the output
   // parameter for possible use by for/in.
-  if (nvars == 1 && (!is_const || is_for_iteration_variable)) {
+  if (nvars == 1 && !is_const) {
     *out = name;
   }
 
@@ -3103,8 +3094,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
   Expect(Token::LPAREN, CHECK_OK);
   for_scope->set_start_position(scanner()->location().beg_pos);
   if (peek() != Token::SEMICOLON) {
-    if (peek() == Token::VAR ||
-        (peek() == Token::CONST && strict_mode() == SLOPPY)) {
+    if (peek() == Token::VAR || peek() == Token::CONST) {
       bool is_const = peek() == Token::CONST;
       const AstRawString* name = NULL;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
@@ -3141,10 +3131,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
       } else {
         init = variable_statement;
       }
-    } else if ((peek() == Token::LET || peek() == Token::CONST) &&
-               strict_mode() == STRICT) {
+    } else if (peek() == Token::LET && strict_mode() == STRICT) {
       DCHECK(allow_harmony_scoping());
-      bool is_const = peek() == Token::CONST;
       const AstRawString* name = NULL;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       Block* variable_statement =
@@ -3157,13 +3145,13 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
       if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
         // Rewrite a for-in statement of the form
         //
-        //   for (let/const x in e) b
+        //   for (let x in e) b
         //
         // into
         //
         //   <let x' be a temporary variable>
         //   for (x' in e) {
-        //     let/const x;
+        //     let x;
         //     x = x';
         //     b;
         //   }
@@ -3183,13 +3171,13 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
         scope_ = for_scope;
         Expect(Token::RPAREN, CHECK_OK);
 
-        VariableProxy* each = scope_->NewUnresolved(factory(), name);
+        VariableProxy* each =
+            scope_->NewUnresolved(factory(), name, Interface::NewValue());
         Statement* body = ParseStatement(NULL, CHECK_OK);
         Block* body_block =
             factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
-        Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
         Assignment* assignment = factory()->NewAssignment(
-            init_op, each, temp_proxy, RelocInfo::kNoPosition);
+            Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
         Statement* assignment_statement = factory()->NewExpressionStatement(
             assignment, RelocInfo::kNoPosition);
         body_block->AddStatement(variable_statement, zone());
index 316f129..987900a 100644 (file)
@@ -409,7 +409,6 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
   // ConstBinding ::
   //   BindingPattern '=' AssignmentExpression
   bool require_initializer = false;
-  bool is_strict_const = false;
   if (peek() == Token::VAR) {
     Consume(Token::VAR);
   } else if (peek() == Token::CONST) {
@@ -431,8 +430,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
           *ok = false;
           return Statement::Default();
         }
-        is_strict_const = true;
-        require_initializer = var_context != kForStatement;
+        require_initializer = true;
       } else {
         Scanner::Location location = scanner()->peek_location();
         ReportMessageAt(location, "strict_const");
@@ -462,9 +460,7 @@ PreParser::Statement PreParser::ParseVariableDeclarations(
     if (nvars > 0) Consume(Token::COMMA);
     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
     nvars++;
-    if (peek() == Token::ASSIGN || require_initializer ||
-        // require initializers for multiple consts.
-        (is_strict_const && peek() == Token::COMMA)) {
+    if (peek() == Token::ASSIGN || require_initializer) {
       Expect(Token::ASSIGN, CHECK_OK);
       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
       if (decl_props != NULL) *decl_props = kHasInitializers;
@@ -682,14 +678,13 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
   if (peek() != Token::SEMICOLON) {
     if (peek() == Token::VAR || peek() == Token::CONST ||
         (peek() == Token::LET && strict_mode() == STRICT)) {
-      bool is_lexical = peek() == Token::LET ||
-                        (peek() == Token::CONST && strict_mode() == STRICT);
+      bool is_let = peek() == Token::LET;
       int decl_count;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       ParseVariableDeclarations(
           kForStatement, &decl_props, &decl_count, CHECK_OK);
       bool has_initializers = decl_props == kHasInitializers;
-      bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
+      bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
       bool accept_OF = !has_initializers;
       if (accept_IN && CheckInOrOf(accept_OF)) {
         ParseExpression(true, CHECK_OK);
index a53abfe..fd82651 100644 (file)
@@ -344,18 +344,14 @@ class ParserBase : public Traits {
   }
 
   bool CheckContextualKeyword(Vector<const char> keyword) {
-    if (PeekContextualKeyword(keyword)) {
+    if (peek() == Token::IDENTIFIER &&
+        scanner()->is_next_contextual_keyword(keyword)) {
       Consume(Token::IDENTIFIER);
       return true;
     }
     return false;
   }
 
-  bool PeekContextualKeyword(Vector<const char> keyword) {
-    return peek() == Token::IDENTIFIER &&
-           scanner()->is_next_contextual_keyword(keyword);
-  }
-
   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
     Expect(Token::IDENTIFIER, ok);
     if (!*ok) return;
index 7ab4722..700d104 100644 (file)
@@ -4205,42 +4205,3 @@ TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
   RunParserSyncTest(context_data, name_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
-
-
-TEST(ConstParsingInForIn) {
-  const char* context_data[][2] = {{"'use strict';", ""},
-                                   {"function foo(){ 'use strict';", "}"},
-                                   {NULL, NULL}};
-
-  const char* data[] = {
-      "for(const x = 1; ; ) {}",
-      "for(const x = 1, y = 2;;){}",
-      "for(const x in [1,2,3]) {}",
-      "for(const x of [1,2,3]) {}",
-      NULL};
-  static const ParserFlag always_flags[] = {kAllowHarmonyScoping};
-  RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
-                    arraysize(always_flags));
-}
-
-
-TEST(ConstParsingInForInError) {
-  const char* context_data[][2] = {{"'use strict';", ""},
-                                   {"function foo(){ 'use strict';", "}"},
-                                   {NULL, NULL}};
-
-  const char* data[] = {
-      "for(const x,y = 1; ; ) {}",
-      "for(const x = 4 in [1,2,3]) {}",
-      "for(const x = 4, y in [1,2,3]) {}",
-      "for(const x = 4 of [1,2,3]) {}",
-      "for(const x = 4, y of [1,2,3]) {}",
-      "for(const x = 1, y = 2 in []) {}",
-      "for(const x,y in []) {}",
-      "for(const x = 1, y = 2 of []) {}",
-      "for(const x,y of []) {}",
-      NULL};
-  static const ParserFlag always_flags[] = {kAllowHarmonyScoping};
-  RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
-                    arraysize(always_flags));
-}
diff --git a/test/mjsunit/regress/regress-2506.js b/test/mjsunit/regress/regress-2506.js
deleted file mode 100644 (file)
index e6b37d3..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2014 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.
-//
-// Flags: --harmony-scoping
-
-'use strict';
-
-// Top-level code
-let s = 0;
-let f = [undefined, undefined, undefined]
-for (const x of [1,2,3]) {
-  s += x;
-  f[x-1] = function() { return x; }
-}
-assertEquals(6, s);
-assertEquals(1, f[0]());
-assertEquals(2, f[1]());
-assertEquals(3, f[2]());
-
-let x = 1;
-s = 0;
-for (const x of [x, x+1, x+2]) {
-  s += x;
-}
-assertEquals(6, s);
-
-s = 0;
-var q = 1;
-for (const q of [q, q+1, q+2]) {
-  s += q;
-}
-assertEquals(6, s);
-
-let z = 1;
-s = 0;
-for (const x = 1; z < 2; z++) {
-  s += x + z;
-}
-assertEquals(2, s);
-
-
-s = "";
-for (const x in [1,2,3]) {
-  s += x;
-}
-assertEquals("012", s);
-
-assertThrows(function() { for(const x in [1,2,3]) { x++ } }, SyntaxError);
-
-// Function scope
-(function() {
-  let s = 0;
-  for (const x of [1,2,3]) {
-    s += x;
-  }
-  assertEquals(6, s);
-
-  let x = 1;
-  s = 0;
-  for (const x of [x, x+1, x+2]) {
-    s += x;
-  }
-  assertEquals(6, s);
-
-  s = 0;
-  var q = 1;
-  for (const q of [q, q+1, q+2]) {
-    s += q;
-  }
-  assertEquals(6, s);
-
-  s = "";
-  for (const x in [1,2,3]) {
-    s += x;
-  }
-  assertEquals("012", s);
-}());