OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2355 // | 2355 // |
2356 // TODO(ES6): | 2356 // TODO(ES6): |
2357 // ConstBinding :: | 2357 // ConstBinding :: |
2358 // BindingPattern '=' AssignmentExpression | 2358 // BindingPattern '=' AssignmentExpression |
2359 | 2359 |
2360 parsing_result->descriptor.parser = this; | 2360 parsing_result->descriptor.parser = this; |
2361 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 2361 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
2362 parsing_result->descriptor.declaration_pos = peek_position(); | 2362 parsing_result->descriptor.declaration_pos = peek_position(); |
2363 parsing_result->descriptor.initialization_pos = peek_position(); | 2363 parsing_result->descriptor.initialization_pos = peek_position(); |
2364 parsing_result->descriptor.mode = VAR; | 2364 parsing_result->descriptor.mode = VAR; |
2365 // True if the binding needs initialization. 'let' and 'const' declared | |
2366 // bindings are created uninitialized by their declaration nodes and | |
2367 // need initialization. 'var' declared bindings are always initialized | |
2368 // immediately by their declaration nodes. | |
2369 parsing_result->descriptor.needs_init = false; | |
2370 if (peek() == Token::VAR) { | 2365 if (peek() == Token::VAR) { |
2371 if (is_strong(language_mode())) { | 2366 if (is_strong(language_mode())) { |
2372 Scanner::Location location = scanner()->peek_location(); | 2367 Scanner::Location location = scanner()->peek_location(); |
2373 ReportMessageAt(location, MessageTemplate::kStrongVar); | 2368 ReportMessageAt(location, MessageTemplate::kStrongVar); |
2374 *ok = false; | 2369 *ok = false; |
2375 return; | 2370 return; |
2376 } | 2371 } |
2377 Consume(Token::VAR); | 2372 Consume(Token::VAR); |
2378 } else if (peek() == Token::CONST && allow_const()) { | 2373 } else if (peek() == Token::CONST && allow_const()) { |
2379 Consume(Token::CONST); | 2374 Consume(Token::CONST); |
2380 if (is_sloppy(language_mode()) && allow_legacy_const()) { | 2375 if (is_sloppy(language_mode()) && allow_legacy_const()) { |
2381 parsing_result->descriptor.mode = CONST_LEGACY; | 2376 parsing_result->descriptor.mode = CONST_LEGACY; |
2382 ++use_counts_[v8::Isolate::kLegacyConst]; | 2377 ++use_counts_[v8::Isolate::kLegacyConst]; |
2383 } else { | 2378 } else { |
2384 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy()); | 2379 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy()); |
2385 DCHECK(var_context != kStatement); | 2380 DCHECK(var_context != kStatement); |
2386 parsing_result->descriptor.mode = CONST; | 2381 parsing_result->descriptor.mode = CONST; |
2387 } | 2382 } |
2388 parsing_result->descriptor.needs_init = true; | |
2389 } else if (peek() == Token::LET && allow_let()) { | 2383 } else if (peek() == Token::LET && allow_let()) { |
2390 Consume(Token::LET); | 2384 Consume(Token::LET); |
2391 DCHECK(var_context != kStatement); | 2385 DCHECK(var_context != kStatement); |
2392 parsing_result->descriptor.mode = LET; | 2386 parsing_result->descriptor.mode = LET; |
2393 parsing_result->descriptor.needs_init = true; | |
2394 } else { | 2387 } else { |
2395 UNREACHABLE(); // by current callers | 2388 UNREACHABLE(); // by current callers |
2396 } | 2389 } |
2397 | 2390 |
2398 parsing_result->descriptor.scope = scope_; | 2391 parsing_result->descriptor.scope = scope_; |
2399 parsing_result->descriptor.hoist_scope = nullptr; | 2392 parsing_result->descriptor.hoist_scope = nullptr; |
2400 | 2393 |
2401 | 2394 |
2402 bool first_declaration = true; | 2395 bool first_declaration = true; |
2403 int bindings_start = peek_position(); | 2396 int bindings_start = peek_position(); |
2404 bool is_for_iteration_variable; | |
2405 do { | 2397 do { |
2406 FuncNameInferrer::State fni_state(fni_); | 2398 FuncNameInferrer::State fni_state(fni_); |
2407 | 2399 |
2408 // Parse name. | 2400 // Parse name. |
2409 if (!first_declaration) Consume(Token::COMMA); | 2401 if (!first_declaration) Consume(Token::COMMA); |
2410 | 2402 |
2411 Expression* pattern; | 2403 Expression* pattern; |
2412 int decl_pos = peek_position(); | 2404 int decl_pos = peek_position(); |
2413 { | 2405 { |
2414 ExpressionClassifier pattern_classifier; | 2406 ExpressionClassifier pattern_classifier; |
2415 Token::Value next = peek(); | 2407 Token::Value next = peek(); |
2416 pattern = ParsePrimaryExpression(&pattern_classifier, ok); | 2408 pattern = ParsePrimaryExpression(&pattern_classifier, ok); |
2417 if (!*ok) return; | 2409 if (!*ok) return; |
2418 ValidateBindingPattern(&pattern_classifier, ok); | 2410 ValidateBindingPattern(&pattern_classifier, ok); |
2419 if (!*ok) return; | 2411 if (!*ok) return; |
2420 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) { | 2412 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) { |
2421 ValidateLetPattern(&pattern_classifier, ok); | 2413 ValidateLetPattern(&pattern_classifier, ok); |
2422 if (!*ok) return; | 2414 if (!*ok) return; |
2423 } | 2415 } |
2424 if (!allow_harmony_destructuring_bind() && !pattern->IsVariableProxy()) { | 2416 if (!allow_harmony_destructuring_bind() && !pattern->IsVariableProxy()) { |
2425 ReportUnexpectedToken(next); | 2417 ReportUnexpectedToken(next); |
2426 *ok = false; | 2418 *ok = false; |
2427 return; | 2419 return; |
2428 } | 2420 } |
2429 } | 2421 } |
2430 | 2422 |
2431 bool is_pattern = | |
2432 (pattern->IsObjectLiteral() || pattern->IsArrayLiteral()) && | |
2433 !pattern->is_parenthesized(); | |
2434 | |
2435 Scanner::Location variable_loc = scanner()->location(); | 2423 Scanner::Location variable_loc = scanner()->location(); |
2436 const AstRawString* single_name = | 2424 const AstRawString* single_name = |
2437 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name() | 2425 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name() |
2438 : nullptr; | 2426 : nullptr; |
2439 if (single_name != nullptr) { | 2427 if (single_name != nullptr) { |
2440 if (fni_ != NULL) fni_->PushVariableName(single_name); | 2428 if (fni_ != NULL) fni_->PushVariableName(single_name); |
2441 } | 2429 } |
2442 | 2430 |
2443 is_for_iteration_variable = | |
2444 var_context == kForStatement && | |
2445 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); | |
2446 if (is_for_iteration_variable && | |
2447 (parsing_result->descriptor.mode == CONST || | |
2448 parsing_result->descriptor.mode == CONST_LEGACY)) { | |
2449 parsing_result->descriptor.needs_init = false; | |
2450 } | |
2451 | |
2452 Expression* value = NULL; | 2431 Expression* value = NULL; |
2453 // Harmony consts have non-optional initializers. | |
2454 int initializer_position = RelocInfo::kNoPosition; | 2432 int initializer_position = RelocInfo::kNoPosition; |
2455 if (Check(Token::ASSIGN)) { | 2433 if (Check(Token::ASSIGN)) { |
2456 ExpressionClassifier classifier; | 2434 ExpressionClassifier classifier; |
2457 value = ParseAssignmentExpression(var_context != kForStatement, | 2435 value = ParseAssignmentExpression(var_context != kForStatement, |
2458 &classifier, ok); | 2436 &classifier, ok); |
2459 if (!*ok) return; | 2437 if (!*ok) return; |
2460 value = ParserTraits::RewriteNonPattern(value, &classifier, ok); | 2438 value = ParserTraits::RewriteNonPattern(value, &classifier, ok); |
2461 if (!*ok) return; | 2439 if (!*ok) return; |
2462 variable_loc.end_pos = scanner()->location().end_pos; | 2440 variable_loc.end_pos = scanner()->location().end_pos; |
2463 | 2441 |
(...skipping 11 matching lines...) Expand all Loading... |
2475 } | 2453 } |
2476 } | 2454 } |
2477 | 2455 |
2478 if (allow_harmony_function_name()) { | 2456 if (allow_harmony_function_name()) { |
2479 ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern); | 2457 ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern); |
2480 } | 2458 } |
2481 | 2459 |
2482 // End position of the initializer is after the assignment expression. | 2460 // End position of the initializer is after the assignment expression. |
2483 initializer_position = scanner()->location().end_pos; | 2461 initializer_position = scanner()->location().end_pos; |
2484 } else { | 2462 } else { |
2485 if ((parsing_result->descriptor.mode == CONST || is_pattern) && | 2463 // Initializers may be either required or implied unless this is a |
2486 !is_for_iteration_variable) { | 2464 // for-in/of iteration variable. |
2487 ParserTraits::ReportMessageAt( | 2465 if (var_context != kForStatement || !PeekInOrOf()) { |
2488 Scanner::Location(decl_pos, scanner()->location().end_pos), | 2466 // ES6 'const' and binding patterns require initializers. |
2489 MessageTemplate::kDeclarationMissingInitializer, | 2467 if (parsing_result->descriptor.mode == CONST || |
2490 is_pattern ? "destructuring" : "const"); | 2468 !pattern->IsVariableProxy()) { |
2491 *ok = false; | 2469 ParserTraits::ReportMessageAt( |
2492 return; | 2470 Scanner::Location(decl_pos, scanner()->location().end_pos), |
| 2471 MessageTemplate::kDeclarationMissingInitializer, |
| 2472 !pattern->IsVariableProxy() ? "destructuring" : "const"); |
| 2473 *ok = false; |
| 2474 return; |
| 2475 } |
| 2476 |
| 2477 // 'let x' and (legacy) 'const x' initialize 'x' to undefined. |
| 2478 if (parsing_result->descriptor.mode == LET || |
| 2479 parsing_result->descriptor.mode == CONST_LEGACY) { |
| 2480 value = GetLiteralUndefined(position()); |
| 2481 } |
2493 } | 2482 } |
| 2483 |
2494 // End position of the initializer is after the variable. | 2484 // End position of the initializer is after the variable. |
2495 initializer_position = position(); | 2485 initializer_position = position(); |
2496 } | 2486 } |
2497 | 2487 |
2498 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | |
2499 if (value == NULL && parsing_result->descriptor.needs_init) { | |
2500 value = GetLiteralUndefined(position()); | |
2501 } | |
2502 | |
2503 parsing_result->declarations.Add(DeclarationParsingResult::Declaration( | 2488 parsing_result->declarations.Add(DeclarationParsingResult::Declaration( |
2504 pattern, initializer_position, value)); | 2489 pattern, initializer_position, value)); |
2505 first_declaration = false; | 2490 first_declaration = false; |
2506 } while (peek() == Token::COMMA); | 2491 } while (peek() == Token::COMMA); |
2507 | 2492 |
2508 parsing_result->bindings_loc = | 2493 parsing_result->bindings_loc = |
2509 Scanner::Location(bindings_start, scanner()->location().end_pos); | 2494 Scanner::Location(bindings_start, scanner()->location().end_pos); |
2510 } | 2495 } |
2511 | 2496 |
2512 | 2497 |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3083 BlockState block_state(&scope_, block_scope); | 3068 BlockState block_state(&scope_, block_scope); |
3084 Target target(&this->target_stack_, catch_block); | 3069 Target target(&this->target_stack_, catch_block); |
3085 | 3070 |
3086 if (!is_simple) { | 3071 if (!is_simple) { |
3087 DeclarationDescriptor descriptor; | 3072 DeclarationDescriptor descriptor; |
3088 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 3073 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
3089 descriptor.parser = this; | 3074 descriptor.parser = this; |
3090 descriptor.scope = scope_; | 3075 descriptor.scope = scope_; |
3091 descriptor.hoist_scope = nullptr; | 3076 descriptor.hoist_scope = nullptr; |
3092 descriptor.mode = LET; | 3077 descriptor.mode = LET; |
3093 descriptor.needs_init = true; | |
3094 descriptor.declaration_pos = pattern->position(); | 3078 descriptor.declaration_pos = pattern->position(); |
3095 descriptor.initialization_pos = pattern->position(); | 3079 descriptor.initialization_pos = pattern->position(); |
3096 | 3080 |
3097 DeclarationParsingResult::Declaration decl( | 3081 DeclarationParsingResult::Declaration decl( |
3098 pattern, pattern->position(), | 3082 pattern, pattern->position(), |
3099 factory()->NewVariableProxy(catch_variable)); | 3083 factory()->NewVariableProxy(catch_variable)); |
3100 | 3084 |
3101 PatternRewriter::DeclareAndInitializeVariables( | 3085 PatternRewriter::DeclareAndInitializeVariables( |
3102 catch_block, &descriptor, &decl, nullptr, CHECK_OK); | 3086 catch_block, &descriptor, &decl, nullptr, CHECK_OK); |
3103 } | 3087 } |
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4553 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 4537 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
4554 for (int i = 0; i < parameters.params.length(); ++i) { | 4538 for (int i = 0; i < parameters.params.length(); ++i) { |
4555 auto parameter = parameters.params[i]; | 4539 auto parameter = parameters.params[i]; |
4556 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; | 4540 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; |
4557 DeclarationDescriptor descriptor; | 4541 DeclarationDescriptor descriptor; |
4558 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; | 4542 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
4559 descriptor.parser = this; | 4543 descriptor.parser = this; |
4560 descriptor.scope = scope_; | 4544 descriptor.scope = scope_; |
4561 descriptor.hoist_scope = nullptr; | 4545 descriptor.hoist_scope = nullptr; |
4562 descriptor.mode = LET; | 4546 descriptor.mode = LET; |
4563 descriptor.needs_init = true; | |
4564 descriptor.declaration_pos = parameter.pattern->position(); | 4547 descriptor.declaration_pos = parameter.pattern->position(); |
4565 // The position that will be used by the AssignmentExpression | 4548 // The position that will be used by the AssignmentExpression |
4566 // which copies from the temp parameter to the pattern. | 4549 // which copies from the temp parameter to the pattern. |
4567 // | 4550 // |
4568 // TODO(adamk): Should this be RelocInfo::kNoPosition, since | 4551 // TODO(adamk): Should this be RelocInfo::kNoPosition, since |
4569 // it's just copying from a temp var to the real param var? | 4552 // it's just copying from a temp var to the real param var? |
4570 descriptor.initialization_pos = parameter.pattern->position(); | 4553 descriptor.initialization_pos = parameter.pattern->position(); |
4571 // The initializer position which will end up in, | 4554 // The initializer position which will end up in, |
4572 // Variable::initializer_position(), used for hole check elimination. | 4555 // Variable::initializer_position(), used for hole check elimination. |
4573 int initializer_position = parameter.pattern->position(); | 4556 int initializer_position = parameter.pattern->position(); |
(...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5779 function->set_raw_name(name); | 5762 function->set_raw_name(name); |
5780 } else { | 5763 } else { |
5781 DCHECK(value->IsClassLiteral()); | 5764 DCHECK(value->IsClassLiteral()); |
5782 value->AsClassLiteral()->constructor()->set_raw_name(name); | 5765 value->AsClassLiteral()->constructor()->set_raw_name(name); |
5783 } | 5766 } |
5784 } | 5767 } |
5785 | 5768 |
5786 | 5769 |
5787 } // namespace internal | 5770 } // namespace internal |
5788 } // namespace v8 | 5771 } // namespace v8 |
OLD | NEW |