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

Side by Side Diff: src/parser.cc

Issue 713413003: harmony-scoping: better error messages for let declarations in sloppy mode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Patch for landing Created 6 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « src/messages.js ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 2461 matching lines...) Expand 10 before | Expand all | Expand 10 after
2472 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 2472 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2473 expr->AsVariableProxy() != NULL && 2473 expr->AsVariableProxy() != NULL &&
2474 expr->AsVariableProxy()->raw_name() == 2474 expr->AsVariableProxy()->raw_name() ==
2475 ast_value_factory()->native_string() && 2475 ast_value_factory()->native_string() &&
2476 !scanner()->literal_contains_escapes()) { 2476 !scanner()->literal_contains_escapes()) {
2477 return ParseNativeDeclaration(ok); 2477 return ParseNativeDeclaration(ok);
2478 } 2478 }
2479 2479
2480 // Parsed expression statement, or the context-sensitive 'module' keyword. 2480 // Parsed expression statement, or the context-sensitive 'module' keyword.
2481 // Only expect semicolon in the former case. 2481 // Only expect semicolon in the former case.
2482 // Also detect attempts at 'let' declarations in sloppy mode.
2482 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || 2483 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER ||
2483 scanner()->HasAnyLineTerminatorBeforeNext() || 2484 scanner()->HasAnyLineTerminatorBeforeNext() ||
2484 expr->AsVariableProxy() == NULL || 2485 expr->AsVariableProxy() == NULL ||
2485 expr->AsVariableProxy()->raw_name() != 2486 expr->AsVariableProxy()->raw_name() !=
2486 ast_value_factory()->module_string() || 2487 ast_value_factory()->module_string() ||
2487 scanner()->literal_contains_escapes()) { 2488 scanner()->literal_contains_escapes()) {
2489 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
2490 expr->AsVariableProxy()->raw_name() ==
2491 ast_value_factory()->let_string()) {
2492 ReportMessage("lexical_strict_mode", NULL);
2493 *ok = false;
2494 return NULL;
2495 }
2488 ExpectSemicolon(CHECK_OK); 2496 ExpectSemicolon(CHECK_OK);
2489 } 2497 }
2490 return factory()->NewExpressionStatement(expr, pos); 2498 return factory()->NewExpressionStatement(expr, pos);
2491 } 2499 }
2492 2500
2493 2501
2494 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, 2502 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2495 bool* ok) { 2503 bool* ok) {
2496 // IfStatement :: 2504 // IfStatement ::
2497 // 'if' '(' Expression ')' Statement ('else' Statement)? 2505 // 'if' '(' Expression ')' Statement ('else' Statement)?
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
3207 ZoneList<const AstRawString*> let_bindings(1, zone()); 3215 ZoneList<const AstRawString*> let_bindings(1, zone());
3208 3216
3209 // Create an in-between scope for let-bound iteration variables. 3217 // Create an in-between scope for let-bound iteration variables.
3210 Scope* saved_scope = scope_; 3218 Scope* saved_scope = scope_;
3211 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3219 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3212 scope_ = for_scope; 3220 scope_ = for_scope;
3213 3221
3214 Expect(Token::FOR, CHECK_OK); 3222 Expect(Token::FOR, CHECK_OK);
3215 Expect(Token::LPAREN, CHECK_OK); 3223 Expect(Token::LPAREN, CHECK_OK);
3216 for_scope->set_start_position(scanner()->location().beg_pos); 3224 for_scope->set_start_position(scanner()->location().beg_pos);
3225 bool is_let_identifier_expression = false;
3217 if (peek() != Token::SEMICOLON) { 3226 if (peek() != Token::SEMICOLON) {
3218 if (peek() == Token::VAR || 3227 if (peek() == Token::VAR ||
3219 (peek() == Token::CONST && strict_mode() == SLOPPY)) { 3228 (peek() == Token::CONST && strict_mode() == SLOPPY)) {
3220 bool is_const = peek() == Token::CONST; 3229 bool is_const = peek() == Token::CONST;
3221 const AstRawString* name = NULL; 3230 const AstRawString* name = NULL;
3222 VariableDeclarationProperties decl_props = kHasNoInitializers; 3231 VariableDeclarationProperties decl_props = kHasNoInitializers;
3223 Block* variable_statement = 3232 Block* variable_statement =
3224 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 3233 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3225 CHECK_OK); 3234 CHECK_OK);
3226 bool accept_OF = decl_props == kHasNoInitializers; 3235 bool accept_OF = decl_props == kHasNoInitializers;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
3318 return loop; 3327 return loop;
3319 3328
3320 } else { 3329 } else {
3321 init = variable_statement; 3330 init = variable_statement;
3322 } 3331 }
3323 } else { 3332 } else {
3324 Scanner::Location lhs_location = scanner()->peek_location(); 3333 Scanner::Location lhs_location = scanner()->peek_location();
3325 Expression* expression = ParseExpression(false, CHECK_OK); 3334 Expression* expression = ParseExpression(false, CHECK_OK);
3326 ForEachStatement::VisitMode mode; 3335 ForEachStatement::VisitMode mode;
3327 bool accept_OF = expression->IsVariableProxy(); 3336 bool accept_OF = expression->IsVariableProxy();
3337 is_let_identifier_expression =
3338 expression->IsVariableProxy() &&
3339 expression->AsVariableProxy()->raw_name() ==
3340 ast_value_factory()->let_string();
3328 3341
3329 if (CheckInOrOf(accept_OF, &mode)) { 3342 if (CheckInOrOf(accept_OF, &mode)) {
3330 expression = this->CheckAndRewriteReferenceExpression( 3343 expression = this->CheckAndRewriteReferenceExpression(
3331 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK); 3344 expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
3332 3345
3333 ForEachStatement* loop = 3346 ForEachStatement* loop =
3334 factory()->NewForEachStatement(mode, labels, stmt_pos); 3347 factory()->NewForEachStatement(mode, labels, stmt_pos);
3335 Target target(&this->target_stack_, loop); 3348 Target target(&this->target_stack_, loop);
3336 3349
3337 Expression* enumerable = ParseExpression(true, CHECK_OK); 3350 Expression* enumerable = ParseExpression(true, CHECK_OK);
(...skipping 12 matching lines...) Expand all
3350 init = factory()->NewExpressionStatement(expression, position()); 3363 init = factory()->NewExpressionStatement(expression, position());
3351 } 3364 }
3352 } 3365 }
3353 } 3366 }
3354 3367
3355 // Standard 'for' loop 3368 // Standard 'for' loop
3356 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3369 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3357 Target target(&this->target_stack_, loop); 3370 Target target(&this->target_stack_, loop);
3358 3371
3359 // Parsed initializer at this point. 3372 // Parsed initializer at this point.
3373 // Detect attempts at 'let' declarations in sloppy mode.
3374 if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY &&
3375 is_let_identifier_expression) {
3376 ReportMessage("lexical_strict_mode", NULL);
3377 *ok = false;
3378 return NULL;
3379 }
3360 Expect(Token::SEMICOLON, CHECK_OK); 3380 Expect(Token::SEMICOLON, CHECK_OK);
3361 3381
3362 // If there are let bindings, then condition and the next statement of the 3382 // If there are let bindings, then condition and the next statement of the
3363 // for loop must be parsed in a new scope. 3383 // for loop must be parsed in a new scope.
3364 Scope* inner_scope = NULL; 3384 Scope* inner_scope = NULL;
3365 if (let_bindings.length() > 0) { 3385 if (let_bindings.length() > 0) {
3366 inner_scope = NewScope(for_scope, BLOCK_SCOPE); 3386 inner_scope = NewScope(for_scope, BLOCK_SCOPE);
3367 inner_scope->set_start_position(scanner()->location().beg_pos); 3387 inner_scope->set_start_position(scanner()->location().beg_pos);
3368 scope_ = inner_scope; 3388 scope_ = inner_scope;
3369 } 3389 }
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after
5286 5306
5287 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( 5307 const AstRawString* raw_str = ast_value_factory()->GetOneByteString(
5288 OneByteVector(raw_chars.get(), to_index)); 5308 OneByteVector(raw_chars.get(), to_index));
5289 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); 5309 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1);
5290 raw_strings->Add(raw_lit, zone()); 5310 raw_strings->Add(raw_lit, zone());
5291 } 5311 }
5292 5312
5293 return raw_strings; 5313 return raw_strings;
5294 } 5314 }
5295 } } // namespace v8::internal 5315 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/messages.js ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698