 Chromium Code Reviews
 Chromium Code Reviews Issue 1416753009:
  [parser] early error when declaration Pattern missing Initializer  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1416753009:
  [parser] early error when declaration Pattern missing Initializer  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 // * It is a Syntax Error if the code that matches this production is not | 550 // * It is a Syntax Error if the code that matches this production is not | 
| 551 // contained in extended code. | 551 // contained in extended code. | 
| 552 // | 552 // | 
| 553 // However disallowing const in sloppy mode will break compatibility with | 553 // However disallowing const in sloppy mode will break compatibility with | 
| 554 // existing pages. Therefore we keep allowing const with the old | 554 // existing pages. Therefore we keep allowing const with the old | 
| 555 // non-harmony semantics in sloppy mode. | 555 // non-harmony semantics in sloppy mode. | 
| 556 Consume(Token::CONST); | 556 Consume(Token::CONST); | 
| 557 if (is_strict(language_mode()) || | 557 if (is_strict(language_mode()) || | 
| 558 (allow_harmony_sloppy() && !allow_legacy_const())) { | 558 (allow_harmony_sloppy() && !allow_legacy_const())) { | 
| 559 DCHECK(var_context != kStatement); | 559 DCHECK(var_context != kStatement); | 
| 560 is_strict_const = true; | 560 is_strict_const = true; | 
| 
adamk
2015/11/04 00:37:54
This means "is not legacy const".
 | |
| 561 require_initializer = var_context != kForStatement; | 561 require_initializer = true; | 
| 
adamk
2015/11/04 00:37:54
Seems like "is_const" would be a better name for t
 | |
| 562 lexical = true; | 562 lexical = true; | 
| 563 } | 563 } | 
| 564 } else if (peek() == Token::LET && allow_let()) { | 564 } else if (peek() == Token::LET && allow_let()) { | 
| 565 Consume(Token::LET); | 565 Consume(Token::LET); | 
| 566 DCHECK(var_context != kStatement); | 566 DCHECK(var_context != kStatement); | 
| 567 lexical = true; | 567 lexical = true; | 
| 568 } else { | 568 } else { | 
| 569 *ok = false; | 569 *ok = false; | 
| 570 return Statement::Default(); | 570 return Statement::Default(); | 
| 571 } | 571 } | 
| 572 | 572 | 
| 573 // The scope of a var/const declared variable anywhere inside a function | 573 // The scope of a var/const declared variable anywhere inside a function | 
| 574 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 574 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 
| 575 // of a let declared variable is the scope of the immediately enclosing | 575 // of a let declared variable is the scope of the immediately enclosing | 
| 576 // block. | 576 // block. | 
| 577 int nvars = 0; // the number of variables declared | 577 int nvars = 0; // the number of variables declared | 
| 578 int bindings_start = peek_position(); | 578 int bindings_start = peek_position(); | 
| 579 do { | 579 do { | 
| 580 // Parse binding pattern. | 580 // Parse binding pattern. | 
| 581 if (nvars > 0) Consume(Token::COMMA); | 581 if (nvars > 0) Consume(Token::COMMA); | 
| 582 int decl_pos = peek_position(); | |
| 583 bool is_pattern = false; | |
| 582 { | 584 { | 
| 583 ExpressionClassifier pattern_classifier; | 585 ExpressionClassifier pattern_classifier; | 
| 584 Token::Value next = peek(); | 586 Token::Value next = peek(); | 
| 585 PreParserExpression pattern = | 587 PreParserExpression pattern = | 
| 586 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 588 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); | 
| 589 is_pattern = pattern.IsObjectLiteral(); // (or pattern.IsArrayLiteral()); | |
| 
adamk
2015/11/04 00:37:54
I'd rather you just add the bit for ArrayLiteral t
 
caitp (gmail)
2015/11/04 15:07:28
Done, although I think it will mean adding an extr
 | |
| 590 | |
| 587 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 591 ValidateBindingPattern(&pattern_classifier, CHECK_OK); | 
| 588 if (lexical) { | 592 if (lexical) { | 
| 589 ValidateLetPattern(&pattern_classifier, CHECK_OK); | 593 ValidateLetPattern(&pattern_classifier, CHECK_OK); | 
| 590 } | 594 } | 
| 591 | 595 | 
| 592 if (!allow_harmony_destructuring() && !pattern.IsIdentifier()) { | 596 if (!allow_harmony_destructuring() && !pattern.IsIdentifier()) { | 
| 593 ReportUnexpectedToken(next); | 597 ReportUnexpectedToken(next); | 
| 594 *ok = false; | 598 *ok = false; | 
| 595 return Statement::Default(); | 599 return Statement::Default(); | 
| 596 } | 600 } | 
| 597 } | 601 } | 
| 598 | 602 | 
| 603 bool is_for_iteration_variable = | |
| 604 var_context == kForStatement && | |
| 605 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); | |
| 606 | |
| 599 Scanner::Location variable_loc = scanner()->location(); | 607 Scanner::Location variable_loc = scanner()->location(); | 
| 600 nvars++; | 608 nvars++; | 
| 601 if (peek() == Token::ASSIGN || require_initializer || | 609 if (peek() == Token::ASSIGN || | 
| 610 (!is_for_iteration_variable && (require_initializer || is_pattern)) || | |
| 
adamk
2015/11/04 00:37:54
Maybe put this in the same order as in the parser
 
rossberg
2015/11/04 10:52:36
Same comment as in the parser: move this to else b
 | |
| 602 // require initializers for multiple consts. | 611 // require initializers for multiple consts. | 
| 603 (is_strict_const && peek() == Token::COMMA)) { | 612 (is_strict_const && peek() == Token::COMMA)) { | 
| 
adamk
2015/11/04 00:37:54
I think this bit is now redundant with your is_for
 
caitp (gmail)
2015/11/04 15:07:28
Well, this was the only place the variable was use
 | |
| 604 Expect(Token::ASSIGN, CHECK_OK); | 613 if (peek() != Token::ASSIGN) { | 
| 
adamk
2015/11/04 00:37:54
Same note here as in the parser, you can use if (!
 | |
| 614 PreParserTraits::ReportMessageAt( | |
| 615 Scanner::Location(decl_pos, scanner()->location().end_pos), | |
| 616 MessageTemplate::kDeclarationMissingInitializer, | |
| 617 is_pattern ? "destructuring" : "const"); | |
| 618 *ok = false; | |
| 619 return Statement::Default(); | |
| 620 } | |
| 621 Consume(Token::ASSIGN); | |
| 605 ExpressionClassifier classifier; | 622 ExpressionClassifier classifier; | 
| 606 ParseAssignmentExpression(var_context != kForStatement, &classifier, | 623 ParseAssignmentExpression(var_context != kForStatement, &classifier, | 
| 607 CHECK_OK); | 624 CHECK_OK); | 
| 608 ValidateExpression(&classifier, CHECK_OK); | 625 ValidateExpression(&classifier, CHECK_OK); | 
| 609 | 626 | 
| 610 variable_loc.end_pos = scanner()->location().end_pos; | 627 variable_loc.end_pos = scanner()->location().end_pos; | 
| 611 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 628 if (first_initializer_loc && !first_initializer_loc->IsValid()) { | 
| 612 *first_initializer_loc = variable_loc; | 629 *first_initializer_loc = variable_loc; | 
| 613 } | 630 } | 
| 614 } | 631 } | 
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1254 Expect(Token::RBRACE, CHECK_OK); | 1271 Expect(Token::RBRACE, CHECK_OK); | 
| 1255 return PreParserExpression::Default(); | 1272 return PreParserExpression::Default(); | 
| 1256 } | 1273 } | 
| 1257 } | 1274 } | 
| 1258 | 1275 | 
| 1259 #undef CHECK_OK | 1276 #undef CHECK_OK | 
| 1260 | 1277 | 
| 1261 | 1278 | 
| 1262 } // namespace internal | 1279 } // namespace internal | 
| 1263 } // namespace v8 | 1280 } // namespace v8 | 
| OLD | NEW |