Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(881)

Unified Diff: src/parser.cc

Issue 1033823002: [es6] emit error when for-in loop declarations are initialized in strict mode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/messages.js ('K') | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 8ed20ee2121cfec8d313b042ac5ea878e66be628..2d0f1e59b2f386c8db37ffe62d4a2da70a5d5ece 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -2218,8 +2218,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
// VariableDeclarations ';'
const AstRawString* ignore;
- Block* result =
- ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
+ Block* result = ParseVariableDeclarations(var_context, NULL, names, &ignore,
arv (Not doing code reviews) 2015/03/25 09:17:43 NULL -> nullptr
caitp (gmail) 2015/03/25 11:22:42 Acknowledged.
+ nullptr, CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
@@ -2233,9 +2233,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
Block* Parser::ParseVariableDeclarations(
VariableDeclarationContext var_context,
VariableDeclarationProperties* decl_props,
- ZoneList<const AstRawString*>* names,
- const AstRawString** out,
- bool* ok) {
+ ZoneList<const AstRawString*>* names, const AstRawString** out,
+ Scanner::Location* first_initializer_loc, bool* ok) {
// VariableDeclarations ::
// ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
//
@@ -2249,7 +2248,6 @@ Block* Parser::ParseVariableDeclarations(
// TODO(ES6):
// ConstBinding ::
// BindingPattern '=' AssignmentExpression
-
int pos = peek_position();
VariableMode mode = VAR;
// True if the binding needs initialization. 'let' and 'const' declared
@@ -2308,12 +2306,14 @@ Block* Parser::ParseVariableDeclarations(
int nvars = 0; // the number of variables declared
const AstRawString* name = NULL;
bool is_for_iteration_variable;
+ bool initializer_recorded = false;
do {
if (fni_ != NULL) fni_->Enter();
// Parse variable name.
if (nvars > 0) Consume(Token::COMMA);
name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
+ Scanner::Location variable_loc = scanner()->location();
if (fni_ != NULL) fni_->PushVariableName(name);
// Declare variable.
@@ -2388,6 +2388,13 @@ Block* Parser::ParseVariableDeclarations(
Expect(Token::ASSIGN, CHECK_OK);
pos = position();
value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
+ variable_loc.end_pos = scanner()->location().end_pos;
+
+ if (first_initializer_loc && !initializer_recorded) {
arv (Not doing code reviews) 2015/03/25 09:17:43 Can you use IsValid here instead of adding the boo
caitp (gmail) 2015/03/25 11:22:42 Acknowledged.
+ *first_initializer_loc = variable_loc;
+ initializer_recorded = true;
+ }
+
// Don't infer if it is "a = function(){...}();"-like expression.
if (fni_ != NULL &&
value->AsCall() == NULL &&
@@ -3364,16 +3371,28 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
(peek() == Token::CONST && is_sloppy(language_mode()))) {
const AstRawString* name = NULL;
VariableDeclarationProperties decl_props = kHasNoInitializers;
+ Scanner::Location first_initializer_loc = Scanner::Location::invalid();
Block* variable_statement =
ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
- CHECK_OK);
- bool accept_OF = decl_props == kHasNoInitializers;
+ &first_initializer_loc, CHECK_OK);
+ bool accept_OF = true;
ForEachStatement::VisitMode mode;
int each_beg_pos = scanner()->location().beg_pos;
int each_end_pos = scanner()->location().end_pos;
if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) {
if (!*ok) return nullptr;
+ if (first_initializer_loc.IsValid() &&
+ (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) {
+ if (mode == ForEachStatement::ITERATE) {
+ ReportMessageAt(first_initializer_loc, "for_of_loop_initializer");
+ } else {
+ ReportMessageAt(first_initializer_loc,
+ "strict_for_in_loop_initializer");
+ }
+ *ok = false;
+ return nullptr;
+ }
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
Target target(&this->target_stack_, loop);
@@ -3403,9 +3422,9 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
is_const = peek() == Token::CONST;
const AstRawString* name = NULL;
VariableDeclarationProperties decl_props = kHasNoInitializers;
- Block* variable_statement =
- ParseVariableDeclarations(kForStatement, &decl_props,
- &lexical_bindings, &name, CHECK_OK);
+ Block* variable_statement = ParseVariableDeclarations(
+ kForStatement, &decl_props, &lexical_bindings, &name, nullptr,
+ CHECK_OK);
bool accept_IN = name != NULL && decl_props != kHasInitializers;
bool accept_OF = decl_props == kHasNoInitializers;
ForEachStatement::VisitMode mode;
« src/messages.js ('K') | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698