| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index 8155dcc42889c1973ae76d7466f66ba3ebcf6c1d..e3b7ab5a1357ce0cc6272fac1a3feef99a52bd6d 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -2362,11 +2362,6 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
| parsing_result->descriptor.declaration_pos = peek_position();
|
| parsing_result->descriptor.initialization_pos = peek_position();
|
| parsing_result->descriptor.mode = VAR;
|
| - // True if the binding needs initialization. 'let' and 'const' declared
|
| - // bindings are created uninitialized by their declaration nodes and
|
| - // need initialization. 'var' declared bindings are always initialized
|
| - // immediately by their declaration nodes.
|
| - parsing_result->descriptor.needs_init = false;
|
| if (peek() == Token::VAR) {
|
| if (is_strong(language_mode())) {
|
| Scanner::Location location = scanner()->peek_location();
|
| @@ -2385,12 +2380,10 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
| DCHECK(var_context != kStatement);
|
| parsing_result->descriptor.mode = CONST;
|
| }
|
| - parsing_result->descriptor.needs_init = true;
|
| } else if (peek() == Token::LET && allow_let()) {
|
| Consume(Token::LET);
|
| DCHECK(var_context != kStatement);
|
| parsing_result->descriptor.mode = LET;
|
| - parsing_result->descriptor.needs_init = true;
|
| } else {
|
| UNREACHABLE(); // by current callers
|
| }
|
| @@ -2401,7 +2394,6 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
|
|
| bool first_declaration = true;
|
| int bindings_start = peek_position();
|
| - bool is_for_iteration_variable;
|
| do {
|
| FuncNameInferrer::State fni_state(fni_);
|
|
|
| @@ -2428,10 +2420,6 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
| }
|
| }
|
|
|
| - bool is_pattern =
|
| - (pattern->IsObjectLiteral() || pattern->IsArrayLiteral()) &&
|
| - !pattern->is_parenthesized();
|
| -
|
| Scanner::Location variable_loc = scanner()->location();
|
| const AstRawString* single_name =
|
| pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
|
| @@ -2440,17 +2428,7 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
| if (fni_ != NULL) fni_->PushVariableName(single_name);
|
| }
|
|
|
| - is_for_iteration_variable =
|
| - var_context == kForStatement &&
|
| - (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
|
| - if (is_for_iteration_variable &&
|
| - (parsing_result->descriptor.mode == CONST ||
|
| - parsing_result->descriptor.mode == CONST_LEGACY)) {
|
| - parsing_result->descriptor.needs_init = false;
|
| - }
|
| -
|
| Expression* value = NULL;
|
| - // Harmony consts have non-optional initializers.
|
| int initializer_position = RelocInfo::kNoPosition;
|
| if (Check(Token::ASSIGN)) {
|
| ExpressionClassifier classifier;
|
| @@ -2482,24 +2460,31 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
| // End position of the initializer is after the assignment expression.
|
| initializer_position = scanner()->location().end_pos;
|
| } else {
|
| - if ((parsing_result->descriptor.mode == CONST || is_pattern) &&
|
| - !is_for_iteration_variable) {
|
| - ParserTraits::ReportMessageAt(
|
| - Scanner::Location(decl_pos, scanner()->location().end_pos),
|
| - MessageTemplate::kDeclarationMissingInitializer,
|
| - is_pattern ? "destructuring" : "const");
|
| - *ok = false;
|
| - return;
|
| + // Initializers may be either required or implied unless this is a
|
| + // for-in/of iteration variable.
|
| + if (var_context != kForStatement || !PeekInOrOf()) {
|
| + // ES6 'const' and binding patterns require initializers.
|
| + if (parsing_result->descriptor.mode == CONST ||
|
| + !pattern->IsVariableProxy()) {
|
| + ParserTraits::ReportMessageAt(
|
| + Scanner::Location(decl_pos, scanner()->location().end_pos),
|
| + MessageTemplate::kDeclarationMissingInitializer,
|
| + !pattern->IsVariableProxy() ? "destructuring" : "const");
|
| + *ok = false;
|
| + return;
|
| + }
|
| +
|
| + // 'let x' and (legacy) 'const x' initialize 'x' to undefined.
|
| + if (parsing_result->descriptor.mode == LET ||
|
| + parsing_result->descriptor.mode == CONST_LEGACY) {
|
| + value = GetLiteralUndefined(position());
|
| + }
|
| }
|
| +
|
| // End position of the initializer is after the variable.
|
| initializer_position = position();
|
| }
|
|
|
| - // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
|
| - if (value == NULL && parsing_result->descriptor.needs_init) {
|
| - value = GetLiteralUndefined(position());
|
| - }
|
| -
|
| parsing_result->declarations.Add(DeclarationParsingResult::Declaration(
|
| pattern, initializer_position, value));
|
| first_declaration = false;
|
| @@ -3090,7 +3075,6 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
| descriptor.scope = scope_;
|
| descriptor.hoist_scope = nullptr;
|
| descriptor.mode = LET;
|
| - descriptor.needs_init = true;
|
| descriptor.declaration_pos = pattern->position();
|
| descriptor.initialization_pos = pattern->position();
|
|
|
| @@ -4560,7 +4544,6 @@ Block* Parser::BuildParameterInitializationBlock(
|
| descriptor.scope = scope_;
|
| descriptor.hoist_scope = nullptr;
|
| descriptor.mode = LET;
|
| - descriptor.needs_init = true;
|
| descriptor.declaration_pos = parameter.pattern->position();
|
| // The position that will be used by the AssignmentExpression
|
| // which copies from the temp parameter to the pattern.
|
|
|