OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <cmath> | 5 #include <cmath> |
6 | 6 |
7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 return Statement::Default(); | 403 return Statement::Default(); |
404 } | 404 } |
405 | 405 |
406 | 406 |
407 PreParser::Statement PreParser::ParseVariableStatement( | 407 PreParser::Statement PreParser::ParseVariableStatement( |
408 VariableDeclarationContext var_context, | 408 VariableDeclarationContext var_context, |
409 bool* ok) { | 409 bool* ok) { |
410 // VariableStatement :: | 410 // VariableStatement :: |
411 // VariableDeclarations ';' | 411 // VariableDeclarations ';' |
412 | 412 |
413 Statement result = ParseVariableDeclarations(var_context, | 413 Statement result = ParseVariableDeclarations(var_context, nullptr, nullptr, |
414 NULL, | 414 nullptr, CHECK_OK); |
415 NULL, | |
416 CHECK_OK); | |
417 ExpectSemicolon(CHECK_OK); | 415 ExpectSemicolon(CHECK_OK); |
418 return result; | 416 return result; |
419 } | 417 } |
420 | 418 |
421 | 419 |
422 // If the variable declaration declares exactly one non-const | 420 // If the variable declaration declares exactly one non-const |
423 // variable, then *var is set to that variable. In all other cases, | 421 // variable, then *var is set to that variable. In all other cases, |
424 // *var is untouched; in particular, it is the caller's responsibility | 422 // *var is untouched; in particular, it is the caller's responsibility |
425 // to initialize it properly. This mechanism is also used for the parsing | 423 // to initialize it properly. This mechanism is also used for the parsing |
426 // of 'for-in' loops. | 424 // of 'for-in' loops. |
427 PreParser::Statement PreParser::ParseVariableDeclarations( | 425 PreParser::Statement PreParser::ParseVariableDeclarations( |
428 VariableDeclarationContext var_context, | 426 VariableDeclarationContext var_context, |
429 VariableDeclarationProperties* decl_props, | 427 VariableDeclarationProperties* decl_props, int* num_decl, |
marja
2015/04/07 08:30:34
Ditto
| |
430 int* num_decl, | 428 Scanner::Location* first_initializer_loc, bool* ok) { |
431 bool* ok) { | |
432 // VariableDeclarations :: | 429 // VariableDeclarations :: |
433 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 430 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
434 // | 431 // |
435 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 432 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
436 // | 433 // |
437 // ConstDeclaration :: | 434 // ConstDeclaration :: |
438 // const ConstBinding (',' ConstBinding)* ';' | 435 // const ConstBinding (',' ConstBinding)* ';' |
439 // ConstBinding :: | 436 // ConstBinding :: |
440 // Identifier '=' AssignmentExpression | 437 // Identifier '=' AssignmentExpression |
441 // | 438 // |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 | 476 |
480 // The scope of a var/const declared variable anywhere inside a function | 477 // The scope of a var/const declared variable anywhere inside a function |
481 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 478 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
482 // of a let declared variable is the scope of the immediately enclosing | 479 // of a let declared variable is the scope of the immediately enclosing |
483 // block. | 480 // block. |
484 int nvars = 0; // the number of variables declared | 481 int nvars = 0; // the number of variables declared |
485 do { | 482 do { |
486 // Parse variable name. | 483 // Parse variable name. |
487 if (nvars > 0) Consume(Token::COMMA); | 484 if (nvars > 0) Consume(Token::COMMA); |
488 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 485 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
486 Scanner::Location variable_loc = scanner()->location(); | |
489 nvars++; | 487 nvars++; |
490 if (peek() == Token::ASSIGN || require_initializer || | 488 if (peek() == Token::ASSIGN || require_initializer || |
491 // require initializers for multiple consts. | 489 // require initializers for multiple consts. |
492 (is_strict_const && peek() == Token::COMMA)) { | 490 (is_strict_const && peek() == Token::COMMA)) { |
493 Expect(Token::ASSIGN, CHECK_OK); | 491 Expect(Token::ASSIGN, CHECK_OK); |
494 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 492 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
493 | |
494 variable_loc.end_pos = scanner()->location().end_pos; | |
495 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | |
496 *first_initializer_loc = variable_loc; | |
497 } | |
498 | |
495 if (decl_props != NULL) *decl_props = kHasInitializers; | 499 if (decl_props != NULL) *decl_props = kHasInitializers; |
496 } | 500 } |
497 } while (peek() == Token::COMMA); | 501 } while (peek() == Token::COMMA); |
498 | 502 |
499 if (num_decl != NULL) *num_decl = nvars; | 503 if (num_decl != NULL) *num_decl = nvars; |
500 return Statement::Default(); | 504 return Statement::Default(); |
501 } | 505 } |
502 | 506 |
503 | 507 |
504 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 508 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 | 725 |
722 | 726 |
723 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 727 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
724 // ForStatement :: | 728 // ForStatement :: |
725 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 729 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
726 | 730 |
727 Expect(Token::FOR, CHECK_OK); | 731 Expect(Token::FOR, CHECK_OK); |
728 Expect(Token::LPAREN, CHECK_OK); | 732 Expect(Token::LPAREN, CHECK_OK); |
729 bool is_let_identifier_expression = false; | 733 bool is_let_identifier_expression = false; |
730 if (peek() != Token::SEMICOLON) { | 734 if (peek() != Token::SEMICOLON) { |
731 ForEachStatement::VisitMode visit_mode; | 735 ForEachStatement::VisitMode mode; |
marja
2015/04/07 08:30:34
Why this change?
caitp (gmail)
2015/04/07 11:56:20
It matches the version of this code in parser.cc,
| |
732 if (peek() == Token::VAR || peek() == Token::CONST || | 736 if (peek() == Token::VAR || peek() == Token::CONST || |
733 (peek() == Token::LET && is_strict(language_mode()))) { | 737 (peek() == Token::LET && is_strict(language_mode()))) { |
734 bool is_lexical = peek() == Token::LET || | 738 bool is_lexical = peek() == Token::LET || |
735 (peek() == Token::CONST && is_strict(language_mode())); | 739 (peek() == Token::CONST && is_strict(language_mode())); |
736 int decl_count; | 740 int decl_count; |
737 VariableDeclarationProperties decl_props = kHasNoInitializers; | 741 VariableDeclarationProperties decl_props = kHasNoInitializers; |
738 ParseVariableDeclarations( | 742 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); |
739 kForStatement, &decl_props, &decl_count, CHECK_OK); | 743 ParseVariableDeclarations(kForStatement, &decl_props, &decl_count, |
744 &first_initializer_loc, CHECK_OK); | |
740 bool has_initializers = decl_props == kHasInitializers; | 745 bool has_initializers = decl_props == kHasInitializers; |
741 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); | 746 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); |
742 bool accept_OF = !has_initializers; | 747 bool accept_OF = true; |
743 if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) { | 748 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { |
744 if (!*ok) return Statement::Default(); | 749 if (!*ok) return Statement::Default(); |
750 if (first_initializer_loc.IsValid() && | |
751 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) { | |
752 if (mode == ForEachStatement::ITERATE) { | |
753 ReportMessageAt(first_initializer_loc, "for_of_loop_initializer"); | |
754 } else { | |
755 // TODO(caitp): This should be an error in sloppy mode, too. | |
756 ReportMessageAt(first_initializer_loc, "for_in_loop_initializer"); | |
757 } | |
758 *ok = false; | |
759 return Statement::Default(); | |
760 } | |
745 ParseExpression(true, CHECK_OK); | 761 ParseExpression(true, CHECK_OK); |
746 Expect(Token::RPAREN, CHECK_OK); | 762 Expect(Token::RPAREN, CHECK_OK); |
747 ParseSubStatement(CHECK_OK); | 763 ParseSubStatement(CHECK_OK); |
748 return Statement::Default(); | 764 return Statement::Default(); |
749 } | 765 } |
750 } else { | 766 } else { |
751 Expression lhs = ParseExpression(false, CHECK_OK); | 767 Expression lhs = ParseExpression(false, CHECK_OK); |
752 is_let_identifier_expression = | 768 is_let_identifier_expression = |
753 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); | 769 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); |
754 if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) { | 770 if (CheckInOrOf(lhs.IsIdentifier(), &mode, ok)) { |
755 if (!*ok) return Statement::Default(); | 771 if (!*ok) return Statement::Default(); |
756 ParseExpression(true, CHECK_OK); | 772 ParseExpression(true, CHECK_OK); |
757 Expect(Token::RPAREN, CHECK_OK); | 773 Expect(Token::RPAREN, CHECK_OK); |
758 ParseSubStatement(CHECK_OK); | 774 ParseSubStatement(CHECK_OK); |
759 return Statement::Default(); | 775 return Statement::Default(); |
760 } | 776 } |
761 } | 777 } |
762 } | 778 } |
763 | 779 |
764 // Parsed initializer at this point. | 780 // Parsed initializer at this point. |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1061 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1046 ParseArguments(ok); | 1062 ParseArguments(ok); |
1047 | 1063 |
1048 return Expression::Default(); | 1064 return Expression::Default(); |
1049 } | 1065 } |
1050 | 1066 |
1051 #undef CHECK_OK | 1067 #undef CHECK_OK |
1052 | 1068 |
1053 | 1069 |
1054 } } // v8::internal | 1070 } } // v8::internal |
OLD | NEW |