From: rossberg Date: Thu, 19 Feb 2015 13:50:33 +0000 (-0800) Subject: [strong] Deprecate for-in X-Git-Tag: upstream/4.7.83~4289 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7d089a59293cf8dd6b8ef579bba3a63350da90b2;p=platform%2Fupstream%2Fv8.git [strong] Deprecate for-in R=marja@chromium.org BUG= Review URL: https://codereview.chromium.org/939063002 Cr-Commit-Position: refs/heads/master@{#26751} --- diff --git a/src/messages.js b/src/messages.js index 19d6104..510147f 100644 --- a/src/messages.js +++ b/src/messages.js @@ -164,6 +164,7 @@ var kMessages = { strong_equal: ["Please don't use '==' or '!=' in strong mode, use '===' or '!==' instead"], strong_delete: ["Please don't use 'delete' in strong mode, use maps or sets instead"], strong_var: ["Please don't use 'var' in strong mode, use 'let' or 'const' instead"], + strong_for_in: ["Please don't use 'for'-'in' loops in strong mode, use 'for'-'of' instead"], strong_empty: ["Please don't use empty sub-statements in strong mode, make them explicit with '{}' instead"], sloppy_lexical: ["Block-scoped declarations (let, const, function, class) not yet supported outside strict mode"], malformed_arrow_function_parameter_list: ["Malformed arrow function parameter list"], diff --git a/src/parser.cc b/src/parser.cc index bb8cb52..1fc131c 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -2881,19 +2881,6 @@ WhileStatement* Parser::ParseWhileStatement( } -bool Parser::CheckInOrOf(bool accept_OF, - ForEachStatement::VisitMode* visit_mode) { - if (Check(Token::IN)) { - *visit_mode = ForEachStatement::ENUMERATE; - return true; - } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { - *visit_mode = ForEachStatement::ITERATE; - return true; - } - return false; -} - - void Parser::InitializeForEachStatement(ForEachStatement* stmt, Expression* each, Expression* subject, @@ -3222,7 +3209,8 @@ Statement* Parser::ParseForStatement(ZoneList* labels, ForEachStatement::VisitMode mode; int each_pos = position(); - if (name != NULL && CheckInOrOf(accept_OF, &mode)) { + if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { + if (!*ok) return nullptr; ForEachStatement* loop = factory()->NewForEachStatement(mode, labels, stmt_pos); Target target(&this->target_stack_, loop); @@ -3259,7 +3247,9 @@ Statement* Parser::ParseForStatement(ZoneList* labels, ForEachStatement::VisitMode mode; int each_pos = position(); - if (accept_IN && CheckInOrOf(accept_OF, &mode)) { + if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { + if (!*ok) return nullptr; + // Rewrite a for-in statement of the form // // for (let/const x in e) b @@ -3321,7 +3311,8 @@ Statement* Parser::ParseForStatement(ZoneList* labels, expression->AsVariableProxy()->raw_name() == ast_value_factory()->let_string(); - if (CheckInOrOf(accept_OF, &mode)) { + if (CheckInOrOf(accept_OF, &mode, ok)) { + if (!*ok) return nullptr; expression = this->CheckAndRewriteReferenceExpression( expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); diff --git a/src/parser.h b/src/parser.h index ff36fe9..bdfe440 100644 --- a/src/parser.h +++ b/src/parser.h @@ -781,8 +781,6 @@ class Parser : public ParserBase { // Magical syntax support. Expression* ParseV8Intrinsic(bool* ok); - bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode); - // Get odd-ball literals. Literal* GetLiteralUndefined(int position); diff --git a/src/preparser.cc b/src/preparser.cc index 00332ad..154a9ae 100644 --- a/src/preparser.cc +++ b/src/preparser.cc @@ -715,15 +715,6 @@ PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { } -bool PreParser::CheckInOrOf(bool accept_OF) { - if (Check(Token::IN) || - (accept_OF && CheckContextualKeyword(CStrVector("of")))) { - return true; - } - return false; -} - - PreParser::Statement PreParser::ParseForStatement(bool* ok) { // ForStatement :: // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement @@ -732,6 +723,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { Expect(Token::LPAREN, CHECK_OK); bool is_let_identifier_expression = false; if (peek() != Token::SEMICOLON) { + ForEachStatement::VisitMode visit_mode; if (peek() == Token::VAR || peek() == Token::CONST || (peek() == Token::LET && is_strict(language_mode()))) { bool is_lexical = peek() == Token::LET || @@ -743,10 +735,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { bool has_initializers = decl_props == kHasInitializers; bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); bool accept_OF = !has_initializers; - if (accept_IN && CheckInOrOf(accept_OF)) { + if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) { + if (!*ok) return Statement::Default(); ParseExpression(true, CHECK_OK); Expect(Token::RPAREN, CHECK_OK); - ParseSubStatement(CHECK_OK); return Statement::Default(); } @@ -754,10 +746,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { Expression lhs = ParseExpression(false, CHECK_OK); is_let_identifier_expression = lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); - if (CheckInOrOf(lhs.IsIdentifier())) { + if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) { + if (!*ok) return Statement::Default(); ParseExpression(true, CHECK_OK); Expect(Token::RPAREN, CHECK_OK); - ParseSubStatement(CHECK_OK); return Statement::Default(); } diff --git a/src/preparser.h b/src/preparser.h index 1cd5dad..0f9cb46 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -420,6 +420,23 @@ class ParserBase : public Traits { } } + bool CheckInOrOf( + bool accept_OF, ForEachStatement::VisitMode* visit_mode, bool* ok) { + if (Check(Token::IN)) { + if (is_strong(language_mode())) { + ReportMessageAt(scanner()->location(), "strong_for_in"); + *ok = false; + } else { + *visit_mode = ForEachStatement::ENUMERATE; + } + return true; + } else if (accept_OF && CheckContextualKeyword(CStrVector("of"))) { + *visit_mode = ForEachStatement::ITERATE; + return true; + } + return false; + } + // Checks whether an octal literal was last seen between beg_pos and end_pos. // If so, reports an error. Only called for strict mode and template strings. void CheckOctalLiteral(int beg_pos, int end_pos, const char* error, @@ -1613,8 +1630,6 @@ class PreParser : public ParserBase { Scanner::Location class_name_location, bool name_is_strict_reserved, int pos, bool* ok); - - bool CheckInOrOf(bool accept_OF); }; diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index b6c427f..1a17475 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -5548,3 +5548,25 @@ TEST(StrongEmptySubStatements) { RunParserSyncTest(strong_context_data, data, kError, NULL, 0, always_flags, arraysize(always_flags)); } + + +TEST(StrongForIn) { + const char* sloppy_context_data[][2] = {{"", ""}, {NULL}}; + const char* strict_context_data[][2] = {{"'use strict';", ""}, {NULL}}; + const char* strong_context_data[][2] = {{"'use strong';", ""}, {NULL}}; + + const char* data[] = { + "for (x in []) {}", + "for (const x in []) {}", + NULL}; + + static const ParserFlag always_flags[] = { + kAllowStrongMode, kAllowHarmonyScoping + }; + RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); + RunParserSyncTest(strict_context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); + RunParserSyncTest(strong_context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); +} diff --git a/test/mjsunit/strong/empty-statement.js b/test/mjsunit/strong/empty-statement.js index b63fead..65edf74 100644 --- a/test/mjsunit/strong/empty-statement.js +++ b/test/mjsunit/strong/empty-statement.js @@ -15,5 +15,4 @@ assertThrows("'use strong'; for (let x;;);", SyntaxError); assertThrows("'use strong'; for (let x in []);", SyntaxError); assertThrows("'use strong'; for (let x of []);", SyntaxError); - assertThrows("'use strong'; with ({});", SyntaxError); })(); diff --git a/test/mjsunit/strong/for-in.js b/test/mjsunit/strong/for-in.js new file mode 100644 index 0000000..8fa9010 --- /dev/null +++ b/test/mjsunit/strong/for-in.js @@ -0,0 +1,17 @@ +// 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. + +// Flags: --strong-mode + +(function NoForInStatement() { + assertThrows("'use strong'; for (x in []) {}", SyntaxError); + assertThrows("'use strong'; for (let x in []) {}", SyntaxError); + assertThrows("'use strong'; for (const x in []) {}", SyntaxError); +})(); + +(function ForOfStatement() { + assertTrue(eval("'use strong'; for (x of []) {} true")); + assertTrue(eval("'use strong'; for (let x of []) {} true")); + assertTrue(eval("'use strong'; for (const x of []) {} true")); +})();