Chromium Code Reviews| 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 |