| 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 = |
| 414 NULL, | 414 ParseVariableDeclarations(var_context, NULL, NULL, NULL, 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, |
| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 } else { | 472 } else { |
| 476 *ok = false; | 473 *ok = false; |
| 477 return Statement::Default(); | 474 return Statement::Default(); |
| 478 } | 475 } |
| 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 |
| 482 bool initializer_recorded = false; |
| 485 do { | 483 do { |
| 486 // Parse variable name. | 484 // Parse variable name. |
| 487 if (nvars > 0) Consume(Token::COMMA); | 485 if (nvars > 0) Consume(Token::COMMA); |
| 488 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 486 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 487 Scanner::Location variable_loc = scanner()->location(); |
| 489 nvars++; | 488 nvars++; |
| 490 if (peek() == Token::ASSIGN || require_initializer || | 489 if (peek() == Token::ASSIGN || require_initializer || |
| 491 // require initializers for multiple consts. | 490 // require initializers for multiple consts. |
| 492 (is_strict_const && peek() == Token::COMMA)) { | 491 (is_strict_const && peek() == Token::COMMA)) { |
| 493 Expect(Token::ASSIGN, CHECK_OK); | 492 Expect(Token::ASSIGN, CHECK_OK); |
| 494 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 493 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 494 |
| 495 variable_loc.end_pos = scanner()->location().end_pos; |
| 496 if (first_initializer_loc && !initializer_recorded) { |
| 497 *first_initializer_loc = variable_loc; |
| 498 initializer_recorded = true; |
| 499 } |
| 500 |
| 495 if (decl_props != NULL) *decl_props = kHasInitializers; | 501 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 496 } | 502 } |
| 497 } while (peek() == Token::COMMA); | 503 } while (peek() == Token::COMMA); |
| 498 | 504 |
| 499 if (num_decl != NULL) *num_decl = nvars; | 505 if (num_decl != NULL) *num_decl = nvars; |
| 500 return Statement::Default(); | 506 return Statement::Default(); |
| 501 } | 507 } |
| 502 | 508 |
| 503 | 509 |
| 504 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 510 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 Expect(Token::LPAREN, CHECK_OK); | 734 Expect(Token::LPAREN, CHECK_OK); |
| 729 bool is_let_identifier_expression = false; | 735 bool is_let_identifier_expression = false; |
| 730 if (peek() != Token::SEMICOLON) { | 736 if (peek() != Token::SEMICOLON) { |
| 731 ForEachStatement::VisitMode visit_mode; | 737 ForEachStatement::VisitMode visit_mode; |
| 732 if (peek() == Token::VAR || peek() == Token::CONST || | 738 if (peek() == Token::VAR || peek() == Token::CONST || |
| 733 (peek() == Token::LET && is_strict(language_mode()))) { | 739 (peek() == Token::LET && is_strict(language_mode()))) { |
| 734 bool is_lexical = peek() == Token::LET || | 740 bool is_lexical = peek() == Token::LET || |
| 735 (peek() == Token::CONST && is_strict(language_mode())); | 741 (peek() == Token::CONST && is_strict(language_mode())); |
| 736 int decl_count; | 742 int decl_count; |
| 737 VariableDeclarationProperties decl_props = kHasNoInitializers; | 743 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 738 ParseVariableDeclarations( | 744 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); |
| 739 kForStatement, &decl_props, &decl_count, CHECK_OK); | 745 ParseVariableDeclarations(kForStatement, &decl_props, &decl_count, |
| 746 &first_initializer_loc, CHECK_OK); |
| 740 bool has_initializers = decl_props == kHasInitializers; | 747 bool has_initializers = decl_props == kHasInitializers; |
| 741 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); | 748 bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers); |
| 742 bool accept_OF = !has_initializers; | 749 bool accept_OF = true; |
| 743 if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) { | 750 if (accept_IN && CheckInOrOf(accept_OF, &visit_mode, ok)) { |
| 744 if (!*ok) return Statement::Default(); | 751 if (!*ok) return Statement::Default(); |
| 752 if (first_initializer_loc.IsValid() && |
| 753 (is_strict(language_mode()) || |
| 754 visit_mode == ForEachStatement::ITERATE)) { |
| 755 if (visit_mode == ForEachStatement::ITERATE) { |
| 756 ReportMessageAt(first_initializer_loc, "for_of_loop_initializer"); |
| 757 } else { |
| 758 ReportMessageAt(first_initializer_loc, |
| 759 "strict_for_in_loop_initializer"); |
| 760 } |
| 761 *ok = false; |
| 762 return Statement::Default(); |
| 763 } |
| 745 ParseExpression(true, CHECK_OK); | 764 ParseExpression(true, CHECK_OK); |
| 746 Expect(Token::RPAREN, CHECK_OK); | 765 Expect(Token::RPAREN, CHECK_OK); |
| 747 ParseSubStatement(CHECK_OK); | 766 ParseSubStatement(CHECK_OK); |
| 748 return Statement::Default(); | 767 return Statement::Default(); |
| 749 } | 768 } |
| 750 } else { | 769 } else { |
| 751 Expression lhs = ParseExpression(false, CHECK_OK); | 770 Expression lhs = ParseExpression(false, CHECK_OK); |
| 752 is_let_identifier_expression = | 771 is_let_identifier_expression = |
| 753 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); | 772 lhs.IsIdentifier() && lhs.AsIdentifier().IsLet(); |
| 754 if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) { | 773 if (CheckInOrOf(lhs.IsIdentifier(), &visit_mode, ok)) { |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 1064 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1046 ParseArguments(ok); | 1065 ParseArguments(ok); |
| 1047 | 1066 |
| 1048 return Expression::Default(); | 1067 return Expression::Default(); |
| 1049 } | 1068 } |
| 1050 | 1069 |
| 1051 #undef CHECK_OK | 1070 #undef CHECK_OK |
| 1052 | 1071 |
| 1053 | 1072 |
| 1054 } } // v8::internal | 1073 } } // v8::internal |
| OLD | NEW |