Chromium Code Reviews| 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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 return final; | 488 return final; |
| 489 } | 489 } |
| 490 | 490 |
| 491 | 491 |
| 492 PreParser::Statement PreParser::ParseVariableStatement( | 492 PreParser::Statement PreParser::ParseVariableStatement( |
| 493 VariableDeclarationContext var_context, | 493 VariableDeclarationContext var_context, |
| 494 bool* ok) { | 494 bool* ok) { |
| 495 // VariableStatement :: | 495 // VariableStatement :: |
| 496 // VariableDeclarations ';' | 496 // VariableDeclarations ';' |
| 497 | 497 |
| 498 Statement result = ParseVariableDeclarations(var_context, nullptr, nullptr, | 498 Statement result = ParseVariableDeclarations( |
| 499 nullptr, CHECK_OK); | 499 var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK); |
| 500 ExpectSemicolon(CHECK_OK); | 500 ExpectSemicolon(CHECK_OK); |
| 501 return result; | 501 return result; |
| 502 } | 502 } |
| 503 | 503 |
| 504 | 504 |
| 505 // If the variable declaration declares exactly one non-const | 505 // If the variable declaration declares exactly one non-const |
| 506 // variable, then *var is set to that variable. In all other cases, | 506 // variable, then *var is set to that variable. In all other cases, |
| 507 // *var is untouched; in particular, it is the caller's responsibility | 507 // *var is untouched; in particular, it is the caller's responsibility |
| 508 // to initialize it properly. This mechanism is also used for the parsing | 508 // to initialize it properly. This mechanism is also used for the parsing |
| 509 // of 'for-in' loops. | 509 // of 'for-in' loops. |
| 510 PreParser::Statement PreParser::ParseVariableDeclarations( | 510 PreParser::Statement PreParser::ParseVariableDeclarations( |
| 511 VariableDeclarationContext var_context, int* num_decl, | 511 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical, |
| 512 Scanner::Location* first_initializer_loc, Scanner::Location* bindings_loc, | 512 bool* is_binding_pattern, Scanner::Location* first_initializer_loc, |
| 513 bool* ok) { | 513 Scanner::Location* bindings_loc, bool* ok) { |
| 514 // VariableDeclarations :: | 514 // VariableDeclarations :: |
| 515 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 515 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 516 // | 516 // |
| 517 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 517 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 518 // | 518 // |
| 519 // ConstDeclaration :: | 519 // ConstDeclaration :: |
| 520 // const ConstBinding (',' ConstBinding)* ';' | 520 // const ConstBinding (',' ConstBinding)* ';' |
| 521 // ConstBinding :: | 521 // ConstBinding :: |
| 522 // Identifier '=' AssignmentExpression | 522 // Identifier '=' AssignmentExpression |
| 523 // | 523 // |
| 524 // TODO(ES6): | 524 // TODO(ES6): |
| 525 // ConstBinding :: | 525 // ConstBinding :: |
| 526 // BindingPattern '=' AssignmentExpression | 526 // BindingPattern '=' AssignmentExpression |
| 527 bool require_initializer = false; | 527 bool require_initializer = false; |
| 528 bool lexical = false; | 528 bool lexical = false; |
| 529 bool is_pattern = false; | |
|
Dan Ehrenberg
2015/11/25 01:02:58
Nit: Not sure why you moved the initialization up
adamk
2015/11/25 01:13:12
I moved this up to put the passing to the out-para
| |
| 529 if (peek() == Token::VAR) { | 530 if (peek() == Token::VAR) { |
| 530 if (is_strong(language_mode())) { | 531 if (is_strong(language_mode())) { |
| 531 Scanner::Location location = scanner()->peek_location(); | 532 Scanner::Location location = scanner()->peek_location(); |
| 532 ReportMessageAt(location, MessageTemplate::kStrongVar); | 533 ReportMessageAt(location, MessageTemplate::kStrongVar); |
| 533 *ok = false; | 534 *ok = false; |
| 534 return Statement::Default(); | 535 return Statement::Default(); |
| 535 } | 536 } |
| 536 Consume(Token::VAR); | 537 Consume(Token::VAR); |
| 537 } else if (peek() == Token::CONST && allow_const()) { | 538 } else if (peek() == Token::CONST && allow_const()) { |
| 538 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: | 539 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 ValidateLetPattern(&pattern_classifier, CHECK_OK); | 583 ValidateLetPattern(&pattern_classifier, CHECK_OK); |
| 583 } | 584 } |
| 584 | 585 |
| 585 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) { | 586 if (!allow_harmony_destructuring_bind() && !pattern.IsIdentifier()) { |
| 586 ReportUnexpectedToken(next); | 587 ReportUnexpectedToken(next); |
| 587 *ok = false; | 588 *ok = false; |
| 588 return Statement::Default(); | 589 return Statement::Default(); |
| 589 } | 590 } |
| 590 } | 591 } |
| 591 | 592 |
| 592 bool is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); | 593 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); |
| 593 | 594 |
| 594 bool is_for_iteration_variable = | 595 bool is_for_iteration_variable = |
| 595 var_context == kForStatement && | 596 var_context == kForStatement && |
| 596 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); | 597 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); |
| 597 | 598 |
| 598 Scanner::Location variable_loc = scanner()->location(); | 599 Scanner::Location variable_loc = scanner()->location(); |
| 599 nvars++; | 600 nvars++; |
| 600 if (Check(Token::ASSIGN)) { | 601 if (Check(Token::ASSIGN)) { |
| 601 ExpressionClassifier classifier; | 602 ExpressionClassifier classifier; |
| 602 ParseAssignmentExpression(var_context != kForStatement, &classifier, | 603 ParseAssignmentExpression(var_context != kForStatement, &classifier, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 616 *ok = false; | 617 *ok = false; |
| 617 return Statement::Default(); | 618 return Statement::Default(); |
| 618 } | 619 } |
| 619 } while (peek() == Token::COMMA); | 620 } while (peek() == Token::COMMA); |
| 620 | 621 |
| 621 if (bindings_loc) { | 622 if (bindings_loc) { |
| 622 *bindings_loc = | 623 *bindings_loc = |
| 623 Scanner::Location(bindings_start, scanner()->location().end_pos); | 624 Scanner::Location(bindings_start, scanner()->location().end_pos); |
| 624 } | 625 } |
| 625 | 626 |
| 626 if (num_decl != NULL) *num_decl = nvars; | 627 if (num_decl != nullptr) *num_decl = nvars; |
| 628 if (is_lexical != nullptr) *is_lexical = lexical; | |
| 629 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; | |
| 627 return Statement::Default(); | 630 return Statement::Default(); |
| 628 } | 631 } |
| 629 | 632 |
| 630 | 633 |
| 631 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 634 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
| 632 // ExpressionStatement | LabelledStatement :: | 635 // ExpressionStatement | LabelledStatement :: |
| 633 // Expression ';' | 636 // Expression ';' |
| 634 // Identifier ':' Statement | 637 // Identifier ':' Statement |
| 635 | 638 |
| 636 switch (peek()) { | 639 switch (peek()) { |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 905 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 908 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 906 | 909 |
| 907 Expect(Token::FOR, CHECK_OK); | 910 Expect(Token::FOR, CHECK_OK); |
| 908 Expect(Token::LPAREN, CHECK_OK); | 911 Expect(Token::LPAREN, CHECK_OK); |
| 909 bool is_let_identifier_expression = false; | 912 bool is_let_identifier_expression = false; |
| 910 if (peek() != Token::SEMICOLON) { | 913 if (peek() != Token::SEMICOLON) { |
| 911 ForEachStatement::VisitMode mode; | 914 ForEachStatement::VisitMode mode; |
| 912 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || | 915 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || |
| 913 (peek() == Token::LET && IsNextLetKeyword())) { | 916 (peek() == Token::LET && IsNextLetKeyword())) { |
| 914 int decl_count; | 917 int decl_count; |
| 918 bool is_lexical; | |
| 919 bool is_binding_pattern; | |
| 915 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); | 920 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); |
| 916 Scanner::Location bindings_loc = Scanner::Location::invalid(); | 921 Scanner::Location bindings_loc = Scanner::Location::invalid(); |
| 917 ParseVariableDeclarations(kForStatement, &decl_count, | 922 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, |
| 918 &first_initializer_loc, &bindings_loc, | 923 &is_binding_pattern, &first_initializer_loc, |
| 919 CHECK_OK); | 924 &bindings_loc, CHECK_OK); |
| 920 bool accept_IN = decl_count >= 1; | 925 bool accept_IN = decl_count >= 1; |
| 921 if (accept_IN && CheckInOrOf(&mode, ok)) { | 926 if (accept_IN && CheckInOrOf(&mode, ok)) { |
| 922 if (!*ok) return Statement::Default(); | 927 if (!*ok) return Statement::Default(); |
| 923 if (decl_count != 1) { | 928 if (decl_count != 1) { |
| 924 const char* loop_type = | 929 const char* loop_type = |
| 925 mode == ForEachStatement::ITERATE ? "for-of" : "for-in"; | 930 mode == ForEachStatement::ITERATE ? "for-of" : "for-in"; |
| 926 PreParserTraits::ReportMessageAt( | 931 PreParserTraits::ReportMessageAt( |
| 927 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, | 932 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, |
| 928 loop_type); | 933 loop_type); |
| 929 *ok = false; | 934 *ok = false; |
| 930 return Statement::Default(); | 935 return Statement::Default(); |
| 931 } | 936 } |
| 932 if (first_initializer_loc.IsValid() && | 937 if (first_initializer_loc.IsValid() && |
| 933 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE)) { | 938 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || |
| 939 is_lexical || is_binding_pattern)) { | |
| 934 if (mode == ForEachStatement::ITERATE) { | 940 if (mode == ForEachStatement::ITERATE) { |
| 935 ReportMessageAt(first_initializer_loc, | 941 ReportMessageAt(first_initializer_loc, |
| 936 MessageTemplate::kForOfLoopInitializer); | 942 MessageTemplate::kForOfLoopInitializer); |
| 937 } else { | 943 } else { |
| 938 // TODO(caitp): This should be an error in sloppy mode, too. | 944 // TODO(caitp): This should be an error in sloppy mode, too. |
| 939 ReportMessageAt(first_initializer_loc, | 945 ReportMessageAt(first_initializer_loc, |
| 940 MessageTemplate::kForInLoopInitializer); | 946 MessageTemplate::kForInLoopInitializer); |
| 941 } | 947 } |
| 942 *ok = false; | 948 *ok = false; |
| 943 return Statement::Default(); | 949 return Statement::Default(); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1260 Expect(Token::RBRACE, CHECK_OK); | 1266 Expect(Token::RBRACE, CHECK_OK); |
| 1261 return PreParserExpression::Default(); | 1267 return PreParserExpression::Default(); |
| 1262 } | 1268 } |
| 1263 } | 1269 } |
| 1264 | 1270 |
| 1265 #undef CHECK_OK | 1271 #undef CHECK_OK |
| 1266 | 1272 |
| 1267 | 1273 |
| 1268 } // namespace internal | 1274 } // namespace internal |
| 1269 } // namespace v8 | 1275 } // namespace v8 |
| OLD | NEW |