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-visitor.h" | 9 #include "src/ast/ast-expression-visitor.h" |
10 #include "src/ast/ast-literal-reindexer.h" | 10 #include "src/ast/ast-literal-reindexer.h" |
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2246 // GeneratorDeclaration :: | 2246 // GeneratorDeclaration :: |
2247 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 2247 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
2248 // '{' FunctionBody '}' | 2248 // '{' FunctionBody '}' |
2249 Expect(Token::FUNCTION, CHECK_OK); | 2249 Expect(Token::FUNCTION, CHECK_OK); |
2250 int pos = position(); | 2250 int pos = position(); |
2251 bool is_generator = Check(Token::MUL); | 2251 bool is_generator = Check(Token::MUL); |
2252 bool is_strict_reserved = false; | 2252 bool is_strict_reserved = false; |
2253 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2253 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
2254 &is_strict_reserved, CHECK_OK); | 2254 &is_strict_reserved, CHECK_OK); |
2255 | 2255 |
2256 if (fni_ != NULL) { | 2256 FuncNameInferrer::State fni_state(fni_); |
2257 fni_->Enter(); | 2257 if (fni_ != NULL) fni_->PushEnclosingName(name); |
2258 fni_->PushEnclosingName(name); | |
2259 } | |
2260 FunctionLiteral* fun = ParseFunctionLiteral( | 2258 FunctionLiteral* fun = ParseFunctionLiteral( |
2261 name, scanner()->location(), | 2259 name, scanner()->location(), |
2262 is_strict_reserved ? kFunctionNameIsStrictReserved | 2260 is_strict_reserved ? kFunctionNameIsStrictReserved |
2263 : kFunctionNameValidityUnknown, | 2261 : kFunctionNameValidityUnknown, |
2264 is_generator ? FunctionKind::kGeneratorFunction | 2262 is_generator ? FunctionKind::kGeneratorFunction |
2265 : FunctionKind::kNormalFunction, | 2263 : FunctionKind::kNormalFunction, |
2266 pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY, | 2264 pos, FunctionLiteral::DECLARATION, FunctionLiteral::NORMAL_ARITY, |
2267 language_mode(), CHECK_OK); | 2265 language_mode(), CHECK_OK); |
2268 if (fni_ != NULL) fni_->Leave(); | |
2269 | 2266 |
2270 // Even if we're not at the top-level of the global or a function | 2267 // Even if we're not at the top-level of the global or a function |
2271 // scope, we treat it as such and introduce the function with its | 2268 // scope, we treat it as such and introduce the function with its |
2272 // initial value upon entering the corresponding scope. | 2269 // initial value upon entering the corresponding scope. |
2273 // In ES6, a function behaves as a lexical binding, except in | 2270 // In ES6, a function behaves as a lexical binding, except in |
2274 // a script scope, or the initial scope of eval or another function. | 2271 // a script scope, or the initial scope of eval or another function. |
2275 VariableMode mode = | 2272 VariableMode mode = |
2276 is_strong(language_mode()) | 2273 is_strong(language_mode()) |
2277 ? CONST | 2274 ? CONST |
2278 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) && | 2275 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) && |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2488 } | 2485 } |
2489 | 2486 |
2490 parsing_result->descriptor.scope = scope_; | 2487 parsing_result->descriptor.scope = scope_; |
2491 parsing_result->descriptor.hoist_scope = nullptr; | 2488 parsing_result->descriptor.hoist_scope = nullptr; |
2492 | 2489 |
2493 | 2490 |
2494 bool first_declaration = true; | 2491 bool first_declaration = true; |
2495 int bindings_start = peek_position(); | 2492 int bindings_start = peek_position(); |
2496 bool is_for_iteration_variable; | 2493 bool is_for_iteration_variable; |
2497 do { | 2494 do { |
2498 if (fni_ != NULL) fni_->Enter(); | 2495 FuncNameInferrer::State fni_state(fni_); |
2499 | 2496 |
2500 // Parse name. | 2497 // Parse name. |
2501 if (!first_declaration) Consume(Token::COMMA); | 2498 if (!first_declaration) Consume(Token::COMMA); |
2502 | 2499 |
2503 Expression* pattern; | 2500 Expression* pattern; |
2504 int decl_pos = peek_position(); | 2501 int decl_pos = peek_position(); |
2505 { | 2502 { |
2506 ExpressionClassifier pattern_classifier; | 2503 ExpressionClassifier pattern_classifier; |
2507 Token::Value next = peek(); | 2504 Token::Value next = peek(); |
2508 pattern = ParsePrimaryExpression(&pattern_classifier, ok); | 2505 pattern = ParsePrimaryExpression(&pattern_classifier, ok); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2578 } | 2575 } |
2579 // End position of the initializer is after the variable. | 2576 // End position of the initializer is after the variable. |
2580 initializer_position = position(); | 2577 initializer_position = position(); |
2581 } | 2578 } |
2582 | 2579 |
2583 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 2580 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
2584 if (value == NULL && parsing_result->descriptor.needs_init) { | 2581 if (value == NULL && parsing_result->descriptor.needs_init) { |
2585 value = GetLiteralUndefined(position()); | 2582 value = GetLiteralUndefined(position()); |
2586 } | 2583 } |
2587 | 2584 |
2588 if (single_name && fni_ != NULL) fni_->Leave(); | |
adamk
2015/12/10 01:56:53
Pretty sure this was a bug before.
Dan Ehrenberg
2015/12/10 18:22:41
Awesome!
| |
2589 parsing_result->declarations.Add(DeclarationParsingResult::Declaration( | 2585 parsing_result->declarations.Add(DeclarationParsingResult::Declaration( |
2590 pattern, initializer_position, value)); | 2586 pattern, initializer_position, value)); |
2591 first_declaration = false; | 2587 first_declaration = false; |
2592 } while (peek() == Token::COMMA); | 2588 } while (peek() == Token::COMMA); |
2593 | 2589 |
2594 parsing_result->bindings_loc = | 2590 parsing_result->bindings_loc = |
2595 Scanner::Location(bindings_start, scanner()->location().end_pos); | 2591 Scanner::Location(bindings_start, scanner()->location().end_pos); |
2596 } | 2592 } |
2597 | 2593 |
2598 | 2594 |
(...skipping 2337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4936 ClassLiteralChecker checker(this); | 4932 ClassLiteralChecker checker(this); |
4937 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); | 4933 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); |
4938 FunctionLiteral* constructor = NULL; | 4934 FunctionLiteral* constructor = NULL; |
4939 bool has_seen_constructor = false; | 4935 bool has_seen_constructor = false; |
4940 | 4936 |
4941 Expect(Token::LBRACE, CHECK_OK); | 4937 Expect(Token::LBRACE, CHECK_OK); |
4942 | 4938 |
4943 const bool has_extends = extends != nullptr; | 4939 const bool has_extends = extends != nullptr; |
4944 while (peek() != Token::RBRACE) { | 4940 while (peek() != Token::RBRACE) { |
4945 if (Check(Token::SEMICOLON)) continue; | 4941 if (Check(Token::SEMICOLON)) continue; |
4946 if (fni_ != NULL) fni_->Enter(); | 4942 FuncNameInferrer::State fni_state(fni_); |
4947 const bool in_class = true; | 4943 const bool in_class = true; |
4948 const bool is_static = false; | 4944 const bool is_static = false; |
4949 bool is_computed_name = false; // Classes do not care about computed | 4945 bool is_computed_name = false; // Classes do not care about computed |
4950 // property names here. | 4946 // property names here. |
4951 ExpressionClassifier classifier; | 4947 ExpressionClassifier classifier; |
4952 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4948 ObjectLiteral::Property* property = ParsePropertyDefinition( |
4953 &checker, in_class, has_extends, is_static, &is_computed_name, | 4949 &checker, in_class, has_extends, is_static, &is_computed_name, |
4954 &has_seen_constructor, &classifier, CHECK_OK); | 4950 &has_seen_constructor, &classifier, CHECK_OK); |
4955 ValidateExpression(&classifier, CHECK_OK); | 4951 ValidateExpression(&classifier, CHECK_OK); |
4956 | 4952 |
4957 if (has_seen_constructor && constructor == NULL) { | 4953 if (has_seen_constructor && constructor == NULL) { |
4958 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4954 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
4959 DCHECK_NOT_NULL(constructor); | 4955 DCHECK_NOT_NULL(constructor); |
4960 } else { | 4956 } else { |
4961 properties->Add(property, zone()); | 4957 properties->Add(property, zone()); |
4962 } | 4958 } |
4963 | 4959 |
4964 if (fni_ != NULL) { | 4960 if (fni_ != NULL) fni_->Infer(); |
4965 fni_->Infer(); | |
4966 fni_->Leave(); | |
4967 } | |
4968 } | 4961 } |
4969 | 4962 |
4970 Expect(Token::RBRACE, CHECK_OK); | 4963 Expect(Token::RBRACE, CHECK_OK); |
4971 int end_pos = scanner()->location().end_pos; | 4964 int end_pos = scanner()->location().end_pos; |
4972 | 4965 |
4973 if (constructor == NULL) { | 4966 if (constructor == NULL) { |
4974 constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos, | 4967 constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos, |
4975 block_scope->language_mode()); | 4968 block_scope->language_mode()); |
4976 } | 4969 } |
4977 | 4970 |
(...skipping 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6541 | 6534 |
6542 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 6535 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
6543 DCHECK(expr->IsRewritableAssignmentExpression()); | 6536 DCHECK(expr->IsRewritableAssignmentExpression()); |
6544 parser_->function_state_->AddDestructuringAssignment( | 6537 parser_->function_state_->AddDestructuringAssignment( |
6545 Parser::DestructuringAssignment(expr, parser_->scope_)); | 6538 Parser::DestructuringAssignment(expr, parser_->scope_)); |
6546 } | 6539 } |
6547 | 6540 |
6548 | 6541 |
6549 } // namespace internal | 6542 } // namespace internal |
6550 } // namespace v8 | 6543 } // namespace v8 |
OLD | NEW |