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 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 2200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2211 bool is_get = false; | 2211 bool is_get = false; |
2212 bool is_set = false; | 2212 bool is_set = false; |
2213 bool is_generator = false; | 2213 bool is_generator = false; |
2214 bool is_async = false; | 2214 bool is_async = false; |
2215 *is_static = false; | 2215 *is_static = false; |
2216 *property_kind = ClassLiteralProperty::METHOD; | 2216 *property_kind = ClassLiteralProperty::METHOD; |
2217 PropertyKind kind = PropertyKind::kNotSet; | 2217 PropertyKind kind = PropertyKind::kNotSet; |
2218 | 2218 |
2219 Token::Value name_token = peek(); | 2219 Token::Value name_token = peek(); |
2220 | 2220 |
2221 int function_token_position = scanner()->peek_location().beg_pos; | |
2221 IdentifierT name = impl()->EmptyIdentifier(); | 2222 IdentifierT name = impl()->EmptyIdentifier(); |
2222 ExpressionT name_expression; | 2223 ExpressionT name_expression; |
2223 if (name_token == Token::STATIC) { | 2224 if (name_token == Token::STATIC) { |
2224 Consume(Token::STATIC); | 2225 Consume(Token::STATIC); |
2226 function_token_position = scanner()->peek_location().beg_pos; | |
2225 if (peek() == Token::LPAREN) { | 2227 if (peek() == Token::LPAREN) { |
2226 kind = PropertyKind::kMethodProperty; | 2228 kind = PropertyKind::kMethodProperty; |
2227 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2229 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2228 name_expression = factory()->NewStringLiteral(name, position()); | 2230 name_expression = factory()->NewStringLiteral(name, position()); |
2229 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || | 2231 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || |
2230 peek() == Token::RBRACE) { | 2232 peek() == Token::RBRACE) { |
2231 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2233 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2232 name_expression = factory()->NewStringLiteral(name, position()); | 2234 name_expression = factory()->NewStringLiteral(name, position()); |
2233 } else { | 2235 } else { |
2234 *is_static = true; | 2236 *is_static = true; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2291 : FunctionKind::kConciseMethod; | 2293 : FunctionKind::kConciseMethod; |
2292 | 2294 |
2293 if (!*is_static && impl()->IsConstructor(name)) { | 2295 if (!*is_static && impl()->IsConstructor(name)) { |
2294 *has_seen_constructor = true; | 2296 *has_seen_constructor = true; |
2295 kind = has_extends ? FunctionKind::kDerivedConstructor | 2297 kind = has_extends ? FunctionKind::kDerivedConstructor |
2296 : FunctionKind::kBaseConstructor; | 2298 : FunctionKind::kBaseConstructor; |
2297 } | 2299 } |
2298 | 2300 |
2299 ExpressionT value = impl()->ParseFunctionLiteral( | 2301 ExpressionT value = impl()->ParseFunctionLiteral( |
2300 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2302 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2301 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2303 FLAG_harmony_function_tostring ? function_token_position |
2302 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2304 : kNoSourcePosition, |
2305 FunctionLiteral::kAccessorOrMethod, language_mode(), | |
2306 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | |
2303 | 2307 |
2304 *property_kind = ClassLiteralProperty::METHOD; | 2308 *property_kind = ClassLiteralProperty::METHOD; |
2305 return factory()->NewClassLiteralProperty(name_expression, value, | 2309 return factory()->NewClassLiteralProperty(name_expression, value, |
2306 *property_kind, *is_static, | 2310 *property_kind, *is_static, |
2307 *is_computed_name); | 2311 *is_computed_name); |
2308 } | 2312 } |
2309 | 2313 |
2310 case PropertyKind::kAccessorProperty: { | 2314 case PropertyKind::kAccessorProperty: { |
2311 DCHECK((is_get || is_set) && !is_generator && !is_async); | 2315 DCHECK((is_get || is_set) && !is_generator && !is_async); |
2312 | 2316 |
2313 if (!*is_computed_name) { | 2317 if (!*is_computed_name) { |
2314 checker->CheckClassMethodName( | 2318 checker->CheckClassMethodName( |
2315 name_token, PropertyKind::kAccessorProperty, false, false, | 2319 name_token, PropertyKind::kAccessorProperty, false, false, |
2316 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2320 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2317 // Make sure the name expression is a string since we need a Name for | 2321 // Make sure the name expression is a string since we need a Name for |
2318 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2322 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2319 // this statically we can skip the extra runtime check. | 2323 // this statically we can skip the extra runtime check. |
2320 name_expression = | 2324 name_expression = |
2321 factory()->NewStringLiteral(name, name_expression->position()); | 2325 factory()->NewStringLiteral(name, name_expression->position()); |
2322 } | 2326 } |
2323 | 2327 |
2324 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2328 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
2325 : FunctionKind::kSetterFunction; | 2329 : FunctionKind::kSetterFunction; |
2326 | 2330 |
2327 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2331 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2328 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2332 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2329 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2333 FLAG_harmony_function_tostring ? function_token_position |
2330 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2334 : kNoSourcePosition, |
2335 FunctionLiteral::kAccessorOrMethod, language_mode(), | |
2336 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | |
2331 | 2337 |
2332 if (!*is_computed_name) { | 2338 if (!*is_computed_name) { |
2333 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2339 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2334 } | 2340 } |
2335 | 2341 |
2336 *property_kind = | 2342 *property_kind = |
2337 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; | 2343 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
2338 return factory()->NewClassLiteralProperty(name_expression, value, | 2344 return factory()->NewClassLiteralProperty(name_expression, value, |
2339 *property_kind, *is_static, | 2345 *property_kind, *is_static, |
2340 *is_computed_name); | 2346 *is_computed_name); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2515 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2521 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2516 MessageTemplate::kInvalidDestructuringTarget); | 2522 MessageTemplate::kInvalidDestructuringTarget); |
2517 | 2523 |
2518 FunctionKind kind = is_generator | 2524 FunctionKind kind = is_generator |
2519 ? FunctionKind::kConciseGeneratorMethod | 2525 ? FunctionKind::kConciseGeneratorMethod |
2520 : is_async ? FunctionKind::kAsyncConciseMethod | 2526 : is_async ? FunctionKind::kAsyncConciseMethod |
2521 : FunctionKind::kConciseMethod; | 2527 : FunctionKind::kConciseMethod; |
2522 | 2528 |
2523 ExpressionT value = impl()->ParseFunctionLiteral( | 2529 ExpressionT value = impl()->ParseFunctionLiteral( |
2524 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2530 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2525 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2531 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, |
2526 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2532 FunctionLiteral::kAccessorOrMethod, language_mode(), |
2533 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2527 | 2534 |
2528 return factory()->NewObjectLiteralProperty( | 2535 return factory()->NewObjectLiteralProperty( |
2529 name_expression, value, ObjectLiteralProperty::COMPUTED, | 2536 name_expression, value, ObjectLiteralProperty::COMPUTED, |
2530 *is_computed_name); | 2537 *is_computed_name); |
2531 } | 2538 } |
2532 | 2539 |
2533 case PropertyKind::kAccessorProperty: { | 2540 case PropertyKind::kAccessorProperty: { |
2534 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && | 2541 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && |
2535 !is_async); | 2542 !is_async); |
2536 | 2543 |
2537 classifier()->RecordPatternError( | 2544 classifier()->RecordPatternError( |
2538 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2545 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2539 MessageTemplate::kInvalidDestructuringTarget); | 2546 MessageTemplate::kInvalidDestructuringTarget); |
2540 | 2547 |
2541 if (!*is_computed_name) { | 2548 if (!*is_computed_name) { |
2542 // Make sure the name expression is a string since we need a Name for | 2549 // Make sure the name expression is a string since we need a Name for |
2543 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2550 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2544 // this statically we can skip the extra runtime check. | 2551 // this statically we can skip the extra runtime check. |
2545 name_expression = | 2552 name_expression = |
2546 factory()->NewStringLiteral(name, name_expression->position()); | 2553 factory()->NewStringLiteral(name, name_expression->position()); |
2547 } | 2554 } |
2548 | 2555 |
2549 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2556 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
2550 : FunctionKind::kSetterFunction; | 2557 : FunctionKind::kSetterFunction; |
2551 | 2558 |
2552 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2559 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2553 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2560 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2554 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2561 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, |
2555 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2562 FunctionLiteral::kAccessorOrMethod, language_mode(), |
2563 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2556 | 2564 |
2557 if (!*is_computed_name) { | 2565 if (!*is_computed_name) { |
2558 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2566 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2559 } | 2567 } |
2560 | 2568 |
2561 return factory()->NewObjectLiteralProperty( | 2569 return factory()->NewObjectLiteralProperty( |
2562 name_expression, value, is_get ? ObjectLiteralProperty::GETTER | 2570 name_expression, value, is_get ? ObjectLiteralProperty::GETTER |
2563 : ObjectLiteralProperty::SETTER, | 2571 : ObjectLiteralProperty::SETTER, |
2564 *is_computed_name); | 2572 *is_computed_name); |
2565 } | 2573 } |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3410 } | 3418 } |
3411 | 3419 |
3412 FunctionKind function_kind = Check(Token::MUL) | 3420 FunctionKind function_kind = Check(Token::MUL) |
3413 ? FunctionKind::kGeneratorFunction | 3421 ? FunctionKind::kGeneratorFunction |
3414 : FunctionKind::kNormalFunction; | 3422 : FunctionKind::kNormalFunction; |
3415 IdentifierT name = impl()->EmptyIdentifier(); | 3423 IdentifierT name = impl()->EmptyIdentifier(); |
3416 bool is_strict_reserved_name = false; | 3424 bool is_strict_reserved_name = false; |
3417 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3425 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3418 FunctionLiteral::FunctionType function_type = | 3426 FunctionLiteral::FunctionType function_type = |
3419 FunctionLiteral::kAnonymousExpression; | 3427 FunctionLiteral::kAnonymousExpression; |
3420 if (peek_any_identifier()) { | 3428 if (impl()->ParsingDynamicFunctionDeclaration()) { |
3429 // Consume and discard the next token, which is always the identifier | |
3430 // "anonymous". | |
3431 Consume(Token::IDENTIFIER); | |
Dan Ehrenberg
2017/02/13 17:32:32
Optional: You could put a DCHECK here that it actu
jwolfe
2017/02/13 21:31:05
Done.
| |
3432 } else if (peek_any_identifier()) { | |
3421 name = ParseIdentifierOrStrictReservedWord( | 3433 name = ParseIdentifierOrStrictReservedWord( |
3422 function_kind, &is_strict_reserved_name, CHECK_OK); | 3434 function_kind, &is_strict_reserved_name, CHECK_OK); |
3423 function_name_location = scanner()->location(); | 3435 function_name_location = scanner()->location(); |
3424 function_type = FunctionLiteral::kNamedExpression; | 3436 function_type = FunctionLiteral::kNamedExpression; |
3425 } | 3437 } |
3426 result = impl()->ParseFunctionLiteral( | 3438 result = impl()->ParseFunctionLiteral( |
3427 name, function_name_location, | 3439 name, function_name_location, |
3428 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3440 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
3429 : kFunctionNameValidityUnknown, | 3441 : kFunctionNameValidityUnknown, |
3430 function_kind, function_token_position, function_type, language_mode(), | 3442 function_kind, function_token_position, function_type, language_mode(), |
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4439 // | 4451 // |
4440 // async [no LineTerminator here] function BindingIdentifier[Await] | 4452 // async [no LineTerminator here] function BindingIdentifier[Await] |
4441 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 4453 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
4442 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 4454 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
4443 int pos = position(); | 4455 int pos = position(); |
4444 Expect(Token::FUNCTION, CHECK_OK); | 4456 Expect(Token::FUNCTION, CHECK_OK); |
4445 bool is_strict_reserved = false; | 4457 bool is_strict_reserved = false; |
4446 IdentifierT name = impl()->EmptyIdentifier(); | 4458 IdentifierT name = impl()->EmptyIdentifier(); |
4447 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | 4459 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
4448 | 4460 |
4449 if (peek_any_identifier()) { | 4461 if (impl()->ParsingDynamicFunctionDeclaration()) { |
4462 // Consume and discard the next token, which is always the identifier | |
4463 // "anonymous". | |
4464 Consume(Token::IDENTIFIER); | |
4465 } else if (peek_any_identifier()) { | |
4450 type = FunctionLiteral::kNamedExpression; | 4466 type = FunctionLiteral::kNamedExpression; |
4451 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, | 4467 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, |
4452 &is_strict_reserved, CHECK_OK); | 4468 &is_strict_reserved, CHECK_OK); |
4453 } | 4469 } |
4454 return impl()->ParseFunctionLiteral( | 4470 return impl()->ParseFunctionLiteral( |
4455 name, scanner()->location(), | 4471 name, scanner()->location(), |
4456 is_strict_reserved ? kFunctionNameIsStrictReserved | 4472 is_strict_reserved ? kFunctionNameIsStrictReserved |
4457 : kFunctionNameValidityUnknown, | 4473 : kFunctionNameValidityUnknown, |
4458 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); | 4474 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); |
4459 } | 4475 } |
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5772 } | 5788 } |
5773 | 5789 |
5774 #undef CHECK_OK | 5790 #undef CHECK_OK |
5775 #undef CHECK_OK_CUSTOM | 5791 #undef CHECK_OK_CUSTOM |
5776 #undef CHECK_OK_VOID | 5792 #undef CHECK_OK_VOID |
5777 | 5793 |
5778 } // namespace internal | 5794 } // namespace internal |
5779 } // namespace v8 | 5795 } // namespace v8 |
5780 | 5796 |
5781 #endif // V8_PARSING_PARSER_BASE_H | 5797 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |