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 |