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

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: delete decl_props Created 5 years, 8 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
« no previous file with comments | « 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 a23547ee3462d18754509c520f614e30e1c0ba3c..608a6bdaf0435aebb24edeac1bd9a21160a120f7 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -2218,7 +2218,7 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
const AstRawString* ignore;
Block* result =
- ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
+ ParseVariableDeclarations(var_context, names, &ignore, nullptr, CHECK_OK);
ExpectSemicolon(CHECK_OK);
return result;
}
@@ -2231,10 +2231,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
// of 'for-in' loops.
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)?)+[',']
//
@@ -2314,6 +2312,7 @@ Block* Parser::ParseVariableDeclarations(
// 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 +2387,12 @@ 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 && !first_initializer_loc->IsValid()) {
+ *first_initializer_loc = variable_loc;
+ }
+
// Don't infer if it is "a = function(){...}();"-like expression.
if (fni_ != NULL &&
value->AsCall() == NULL &&
@@ -2396,7 +2401,6 @@ Block* Parser::ParseVariableDeclarations(
} else {
fni_->RemoveLastFunction();
}
- if (decl_props != NULL) *decl_props = kHasInitializers;
// End position of the initializer is after the assignment expression.
var->set_initializer_position(scanner()->location().end_pos);
} else {
@@ -3363,17 +3367,27 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
if (peek() == Token::VAR ||
(peek() == Token::CONST && is_sloppy(language_mode()))) {
const AstRawString* name = NULL;
- VariableDeclarationProperties decl_props = kHasNoInitializers;
- Block* variable_statement =
- ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
- CHECK_OK);
- bool accept_OF = decl_props == kHasNoInitializers;
+ Scanner::Location first_initializer_loc = Scanner::Location::invalid();
+ Block* variable_statement = ParseVariableDeclarations(
+ kForStatement, nullptr, &name, &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 {
+ // TODO(caitp): This should be an error in sloppy mode too.
+ ReportMessageAt(first_initializer_loc, "for_in_loop_initializer");
+ }
+ *ok = false;
+ return nullptr;
+ }
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
Target target(&this->target_stack_, loop);
@@ -3402,19 +3416,28 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
is_strict(language_mode())) {
is_const = peek() == Token::CONST;
const AstRawString* name = NULL;
- VariableDeclarationProperties decl_props = kHasNoInitializers;
+ Scanner::Location first_initializer_loc = Scanner::Location::invalid();
Block* variable_statement =
- ParseVariableDeclarations(kForStatement, &decl_props,
- &lexical_bindings, &name, CHECK_OK);
- bool accept_IN = name != NULL && decl_props != kHasInitializers;
- bool accept_OF = decl_props == kHasNoInitializers;
+ ParseVariableDeclarations(kForStatement, &lexical_bindings, &name,
+ &first_initializer_loc, CHECK_OK);
+ bool accept_IN = name != NULL;
+ bool accept_OF = true;
ForEachStatement::VisitMode mode;
int each_beg_pos = scanner()->location().beg_pos;
int each_end_pos = scanner()->location().end_pos;
if (accept_IN && 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, "for_in_loop_initializer");
+ }
+ *ok = false;
+ return nullptr;
+ }
// Rewrite a for-in statement of the form
//
// for (let/const x in e) b
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698