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 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 bool is_get = false; | 2184 bool is_get = false; |
2185 bool is_set = false; | 2185 bool is_set = false; |
2186 bool is_generator = false; | 2186 bool is_generator = false; |
2187 bool is_async = false; | 2187 bool is_async = false; |
2188 *is_static = false; | 2188 *is_static = false; |
2189 *property_kind = ClassLiteralProperty::METHOD; | 2189 *property_kind = ClassLiteralProperty::METHOD; |
2190 PropertyKind kind = PropertyKind::kNotSet; | 2190 PropertyKind kind = PropertyKind::kNotSet; |
2191 | 2191 |
2192 Token::Value name_token = peek(); | 2192 Token::Value name_token = peek(); |
2193 | 2193 |
| 2194 int function_token_position = scanner()->peek_location().beg_pos; |
2194 IdentifierT name = impl()->EmptyIdentifier(); | 2195 IdentifierT name = impl()->EmptyIdentifier(); |
2195 ExpressionT name_expression; | 2196 ExpressionT name_expression; |
2196 if (name_token == Token::STATIC) { | 2197 if (name_token == Token::STATIC) { |
2197 Consume(Token::STATIC); | 2198 Consume(Token::STATIC); |
| 2199 function_token_position = scanner()->peek_location().beg_pos; |
2198 if (peek() == Token::LPAREN) { | 2200 if (peek() == Token::LPAREN) { |
2199 kind = PropertyKind::kMethodProperty; | 2201 kind = PropertyKind::kMethodProperty; |
2200 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2202 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2201 name_expression = factory()->NewStringLiteral(name, position()); | 2203 name_expression = factory()->NewStringLiteral(name, position()); |
2202 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || | 2204 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || |
2203 peek() == Token::RBRACE) { | 2205 peek() == Token::RBRACE) { |
2204 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2206 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2205 name_expression = factory()->NewStringLiteral(name, position()); | 2207 name_expression = factory()->NewStringLiteral(name, position()); |
2206 } else { | 2208 } else { |
2207 *is_static = true; | 2209 *is_static = true; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2264 : FunctionKind::kConciseMethod; | 2266 : FunctionKind::kConciseMethod; |
2265 | 2267 |
2266 if (!*is_static && impl()->IsConstructor(name)) { | 2268 if (!*is_static && impl()->IsConstructor(name)) { |
2267 *has_seen_constructor = true; | 2269 *has_seen_constructor = true; |
2268 kind = has_extends ? FunctionKind::kDerivedConstructor | 2270 kind = has_extends ? FunctionKind::kDerivedConstructor |
2269 : FunctionKind::kBaseConstructor; | 2271 : FunctionKind::kBaseConstructor; |
2270 } | 2272 } |
2271 | 2273 |
2272 ExpressionT value = impl()->ParseFunctionLiteral( | 2274 ExpressionT value = impl()->ParseFunctionLiteral( |
2273 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2275 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2274 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2276 FLAG_harmony_function_tostring ? function_token_position |
2275 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2277 : kNoSourcePosition, |
| 2278 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2279 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2276 | 2280 |
2277 *property_kind = ClassLiteralProperty::METHOD; | 2281 *property_kind = ClassLiteralProperty::METHOD; |
2278 return factory()->NewClassLiteralProperty(name_expression, value, | 2282 return factory()->NewClassLiteralProperty(name_expression, value, |
2279 *property_kind, *is_static, | 2283 *property_kind, *is_static, |
2280 *is_computed_name); | 2284 *is_computed_name); |
2281 } | 2285 } |
2282 | 2286 |
2283 case PropertyKind::kAccessorProperty: { | 2287 case PropertyKind::kAccessorProperty: { |
2284 DCHECK((is_get || is_set) && !is_generator && !is_async); | 2288 DCHECK((is_get || is_set) && !is_generator && !is_async); |
2285 | 2289 |
2286 if (!*is_computed_name) { | 2290 if (!*is_computed_name) { |
2287 checker->CheckClassMethodName( | 2291 checker->CheckClassMethodName( |
2288 name_token, PropertyKind::kAccessorProperty, false, false, | 2292 name_token, PropertyKind::kAccessorProperty, false, false, |
2289 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2293 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2290 // Make sure the name expression is a string since we need a Name for | 2294 // Make sure the name expression is a string since we need a Name for |
2291 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2295 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2292 // this statically we can skip the extra runtime check. | 2296 // this statically we can skip the extra runtime check. |
2293 name_expression = | 2297 name_expression = |
2294 factory()->NewStringLiteral(name, name_expression->position()); | 2298 factory()->NewStringLiteral(name, name_expression->position()); |
2295 } | 2299 } |
2296 | 2300 |
2297 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2301 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
2298 : FunctionKind::kSetterFunction; | 2302 : FunctionKind::kSetterFunction; |
2299 | 2303 |
2300 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2304 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2301 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2305 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2302 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2306 FLAG_harmony_function_tostring ? function_token_position |
2303 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2307 : kNoSourcePosition, |
| 2308 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2309 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2304 | 2310 |
2305 if (!*is_computed_name) { | 2311 if (!*is_computed_name) { |
2306 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2312 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2307 } | 2313 } |
2308 | 2314 |
2309 *property_kind = | 2315 *property_kind = |
2310 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; | 2316 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
2311 return factory()->NewClassLiteralProperty(name_expression, value, | 2317 return factory()->NewClassLiteralProperty(name_expression, value, |
2312 *property_kind, *is_static, | 2318 *property_kind, *is_static, |
2313 *is_computed_name); | 2319 *is_computed_name); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2493 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2488 MessageTemplate::kInvalidDestructuringTarget); | 2494 MessageTemplate::kInvalidDestructuringTarget); |
2489 | 2495 |
2490 FunctionKind kind = is_generator | 2496 FunctionKind kind = is_generator |
2491 ? FunctionKind::kConciseGeneratorMethod | 2497 ? FunctionKind::kConciseGeneratorMethod |
2492 : is_async ? FunctionKind::kAsyncConciseMethod | 2498 : is_async ? FunctionKind::kAsyncConciseMethod |
2493 : FunctionKind::kConciseMethod; | 2499 : FunctionKind::kConciseMethod; |
2494 | 2500 |
2495 ExpressionT value = impl()->ParseFunctionLiteral( | 2501 ExpressionT value = impl()->ParseFunctionLiteral( |
2496 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2502 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2497 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2503 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, |
2498 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2504 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2505 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2499 | 2506 |
2500 return factory()->NewObjectLiteralProperty( | 2507 return factory()->NewObjectLiteralProperty( |
2501 name_expression, value, ObjectLiteralProperty::COMPUTED, | 2508 name_expression, value, ObjectLiteralProperty::COMPUTED, |
2502 *is_computed_name); | 2509 *is_computed_name); |
2503 } | 2510 } |
2504 | 2511 |
2505 case PropertyKind::kAccessorProperty: { | 2512 case PropertyKind::kAccessorProperty: { |
2506 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && | 2513 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && |
2507 !is_async); | 2514 !is_async); |
2508 | 2515 |
2509 classifier()->RecordPatternError( | 2516 classifier()->RecordPatternError( |
2510 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2517 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2511 MessageTemplate::kInvalidDestructuringTarget); | 2518 MessageTemplate::kInvalidDestructuringTarget); |
2512 | 2519 |
2513 if (!*is_computed_name) { | 2520 if (!*is_computed_name) { |
2514 // Make sure the name expression is a string since we need a Name for | 2521 // Make sure the name expression is a string since we need a Name for |
2515 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2522 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2516 // this statically we can skip the extra runtime check. | 2523 // this statically we can skip the extra runtime check. |
2517 name_expression = | 2524 name_expression = |
2518 factory()->NewStringLiteral(name, name_expression->position()); | 2525 factory()->NewStringLiteral(name, name_expression->position()); |
2519 } | 2526 } |
2520 | 2527 |
2521 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2528 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
2522 : FunctionKind::kSetterFunction; | 2529 : FunctionKind::kSetterFunction; |
2523 | 2530 |
2524 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2531 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2525 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2532 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2526 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2533 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, |
2527 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2534 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2535 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2528 | 2536 |
2529 if (!*is_computed_name) { | 2537 if (!*is_computed_name) { |
2530 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2538 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2531 } | 2539 } |
2532 | 2540 |
2533 return factory()->NewObjectLiteralProperty( | 2541 return factory()->NewObjectLiteralProperty( |
2534 name_expression, value, is_get ? ObjectLiteralProperty::GETTER | 2542 name_expression, value, is_get ? ObjectLiteralProperty::GETTER |
2535 : ObjectLiteralProperty::SETTER, | 2543 : ObjectLiteralProperty::SETTER, |
2536 *is_computed_name); | 2544 *is_computed_name); |
2537 } | 2545 } |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3356 } | 3364 } |
3357 | 3365 |
3358 FunctionKind function_kind = Check(Token::MUL) | 3366 FunctionKind function_kind = Check(Token::MUL) |
3359 ? FunctionKind::kGeneratorFunction | 3367 ? FunctionKind::kGeneratorFunction |
3360 : FunctionKind::kNormalFunction; | 3368 : FunctionKind::kNormalFunction; |
3361 IdentifierT name = impl()->EmptyIdentifier(); | 3369 IdentifierT name = impl()->EmptyIdentifier(); |
3362 bool is_strict_reserved_name = false; | 3370 bool is_strict_reserved_name = false; |
3363 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3371 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3364 FunctionLiteral::FunctionType function_type = | 3372 FunctionLiteral::FunctionType function_type = |
3365 FunctionLiteral::kAnonymousExpression; | 3373 FunctionLiteral::kAnonymousExpression; |
3366 if (peek_any_identifier()) { | 3374 if (impl()->ParsingDynamicFunctionDeclaration()) { |
| 3375 // We don't want dynamic functions to actually declare their name |
| 3376 // "anonymous". We just want that name in the toString(). |
| 3377 Consume(Token::IDENTIFIER); |
| 3378 DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9)); |
| 3379 } else if (peek_any_identifier()) { |
3367 name = ParseIdentifierOrStrictReservedWord( | 3380 name = ParseIdentifierOrStrictReservedWord( |
3368 function_kind, &is_strict_reserved_name, CHECK_OK); | 3381 function_kind, &is_strict_reserved_name, CHECK_OK); |
3369 function_name_location = scanner()->location(); | 3382 function_name_location = scanner()->location(); |
3370 function_type = FunctionLiteral::kNamedExpression; | 3383 function_type = FunctionLiteral::kNamedExpression; |
3371 } | 3384 } |
3372 result = impl()->ParseFunctionLiteral( | 3385 result = impl()->ParseFunctionLiteral( |
3373 name, function_name_location, | 3386 name, function_name_location, |
3374 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3387 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
3375 : kFunctionNameValidityUnknown, | 3388 : kFunctionNameValidityUnknown, |
3376 function_kind, function_token_position, function_type, language_mode(), | 3389 function_kind, function_token_position, function_type, language_mode(), |
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4369 // | 4382 // |
4370 // async [no LineTerminator here] function BindingIdentifier[Await] | 4383 // async [no LineTerminator here] function BindingIdentifier[Await] |
4371 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 4384 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
4372 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 4385 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
4373 int pos = position(); | 4386 int pos = position(); |
4374 Expect(Token::FUNCTION, CHECK_OK); | 4387 Expect(Token::FUNCTION, CHECK_OK); |
4375 bool is_strict_reserved = false; | 4388 bool is_strict_reserved = false; |
4376 IdentifierT name = impl()->EmptyIdentifier(); | 4389 IdentifierT name = impl()->EmptyIdentifier(); |
4377 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | 4390 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
4378 | 4391 |
4379 if (peek_any_identifier()) { | 4392 if (impl()->ParsingDynamicFunctionDeclaration()) { |
| 4393 // We don't want dynamic functions to actually declare their name |
| 4394 // "anonymous". We just want that name in the toString(). |
| 4395 Consume(Token::IDENTIFIER); |
| 4396 DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9)); |
| 4397 } else if (peek_any_identifier()) { |
4380 type = FunctionLiteral::kNamedExpression; | 4398 type = FunctionLiteral::kNamedExpression; |
4381 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, | 4399 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, |
4382 &is_strict_reserved, CHECK_OK); | 4400 &is_strict_reserved, CHECK_OK); |
4383 } | 4401 } |
4384 return impl()->ParseFunctionLiteral( | 4402 return impl()->ParseFunctionLiteral( |
4385 name, scanner()->location(), | 4403 name, scanner()->location(), |
4386 is_strict_reserved ? kFunctionNameIsStrictReserved | 4404 is_strict_reserved ? kFunctionNameIsStrictReserved |
4387 : kFunctionNameValidityUnknown, | 4405 : kFunctionNameValidityUnknown, |
4388 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); | 4406 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); |
4389 } | 4407 } |
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5847 } | 5865 } |
5848 | 5866 |
5849 #undef CHECK_OK | 5867 #undef CHECK_OK |
5850 #undef CHECK_OK_CUSTOM | 5868 #undef CHECK_OK_CUSTOM |
5851 #undef CHECK_OK_VOID | 5869 #undef CHECK_OK_VOID |
5852 | 5870 |
5853 } // namespace internal | 5871 } // namespace internal |
5854 } // namespace v8 | 5872 } // namespace v8 |
5855 | 5873 |
5856 #endif // V8_PARSING_PARSER_BASE_H | 5874 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |