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 2135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 bool is_get = false; | 2146 bool is_get = false; |
2147 bool is_set = false; | 2147 bool is_set = false; |
2148 bool is_generator = false; | 2148 bool is_generator = false; |
2149 bool is_async = false; | 2149 bool is_async = false; |
2150 *is_static = false; | 2150 *is_static = false; |
2151 *property_kind = ClassLiteralProperty::METHOD; | 2151 *property_kind = ClassLiteralProperty::METHOD; |
2152 PropertyKind kind = PropertyKind::kNotSet; | 2152 PropertyKind kind = PropertyKind::kNotSet; |
2153 | 2153 |
2154 Token::Value name_token = peek(); | 2154 Token::Value name_token = peek(); |
2155 | 2155 |
| 2156 int function_token_position = scanner()->peek_location().beg_pos; |
2156 IdentifierT name = impl()->EmptyIdentifier(); | 2157 IdentifierT name = impl()->EmptyIdentifier(); |
2157 ExpressionT name_expression; | 2158 ExpressionT name_expression; |
2158 if (name_token == Token::STATIC) { | 2159 if (name_token == Token::STATIC) { |
2159 Consume(Token::STATIC); | 2160 Consume(Token::STATIC); |
| 2161 function_token_position = scanner()->peek_location().beg_pos; |
2160 if (peek() == Token::LPAREN) { | 2162 if (peek() == Token::LPAREN) { |
2161 kind = PropertyKind::kMethodProperty; | 2163 kind = PropertyKind::kMethodProperty; |
2162 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2164 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2163 name_expression = factory()->NewStringLiteral(name, position()); | 2165 name_expression = factory()->NewStringLiteral(name, position()); |
2164 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || | 2166 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || |
2165 peek() == Token::RBRACE) { | 2167 peek() == Token::RBRACE) { |
2166 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2168 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
2167 name_expression = factory()->NewStringLiteral(name, position()); | 2169 name_expression = factory()->NewStringLiteral(name, position()); |
2168 } else { | 2170 } else { |
2169 *is_static = true; | 2171 *is_static = true; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 : FunctionKind::kConciseMethod; | 2224 : FunctionKind::kConciseMethod; |
2223 | 2225 |
2224 if (!*is_static && impl()->IsConstructor(name)) { | 2226 if (!*is_static && impl()->IsConstructor(name)) { |
2225 *has_seen_constructor = true; | 2227 *has_seen_constructor = true; |
2226 kind = has_extends ? FunctionKind::kSubclassConstructor | 2228 kind = has_extends ? FunctionKind::kSubclassConstructor |
2227 : FunctionKind::kBaseConstructor; | 2229 : FunctionKind::kBaseConstructor; |
2228 } | 2230 } |
2229 | 2231 |
2230 ExpressionT value = impl()->ParseFunctionLiteral( | 2232 ExpressionT value = impl()->ParseFunctionLiteral( |
2231 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2233 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2232 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2234 FLAG_harmony_function_tostring ? function_token_position |
2233 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2235 : kNoSourcePosition, |
| 2236 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2237 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2234 | 2238 |
2235 *property_kind = ClassLiteralProperty::METHOD; | 2239 *property_kind = ClassLiteralProperty::METHOD; |
2236 return factory()->NewClassLiteralProperty(name_expression, value, | 2240 return factory()->NewClassLiteralProperty(name_expression, value, |
2237 *property_kind, *is_static, | 2241 *property_kind, *is_static, |
2238 *is_computed_name); | 2242 *is_computed_name); |
2239 } | 2243 } |
2240 | 2244 |
2241 case PropertyKind::kAccessorProperty: { | 2245 case PropertyKind::kAccessorProperty: { |
2242 DCHECK((is_get || is_set) && !is_generator && !is_async); | 2246 DCHECK((is_get || is_set) && !is_generator && !is_async); |
2243 | 2247 |
2244 if (!*is_computed_name) { | 2248 if (!*is_computed_name) { |
2245 checker->CheckClassMethodName( | 2249 checker->CheckClassMethodName( |
2246 name_token, PropertyKind::kAccessorProperty, false, false, | 2250 name_token, PropertyKind::kAccessorProperty, false, false, |
2247 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2251 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2248 // Make sure the name expression is a string since we need a Name for | 2252 // Make sure the name expression is a string since we need a Name for |
2249 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2253 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2250 // this statically we can skip the extra runtime check. | 2254 // this statically we can skip the extra runtime check. |
2251 name_expression = | 2255 name_expression = |
2252 factory()->NewStringLiteral(name, name_expression->position()); | 2256 factory()->NewStringLiteral(name, name_expression->position()); |
2253 } | 2257 } |
2254 | 2258 |
2255 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2259 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
2256 : FunctionKind::kSetterFunction; | 2260 : FunctionKind::kSetterFunction; |
2257 | 2261 |
2258 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2262 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2259 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2263 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2260 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2264 FLAG_harmony_function_tostring ? function_token_position |
2261 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2265 : kNoSourcePosition, |
| 2266 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2267 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
2262 | 2268 |
2263 if (!*is_computed_name) { | 2269 if (!*is_computed_name) { |
2264 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2270 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2265 } | 2271 } |
2266 | 2272 |
2267 *property_kind = | 2273 *property_kind = |
2268 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; | 2274 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
2269 return factory()->NewClassLiteralProperty(name_expression, value, | 2275 return factory()->NewClassLiteralProperty(name_expression, value, |
2270 *property_kind, *is_static, | 2276 *property_kind, *is_static, |
2271 *is_computed_name); | 2277 *is_computed_name); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2431 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2437 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2432 MessageTemplate::kInvalidDestructuringTarget); | 2438 MessageTemplate::kInvalidDestructuringTarget); |
2433 | 2439 |
2434 FunctionKind kind = is_generator | 2440 FunctionKind kind = is_generator |
2435 ? FunctionKind::kConciseGeneratorMethod | 2441 ? FunctionKind::kConciseGeneratorMethod |
2436 : is_async ? FunctionKind::kAsyncConciseMethod | 2442 : is_async ? FunctionKind::kAsyncConciseMethod |
2437 : FunctionKind::kConciseMethod; | 2443 : FunctionKind::kConciseMethod; |
2438 | 2444 |
2439 ExpressionT value = impl()->ParseFunctionLiteral( | 2445 ExpressionT value = impl()->ParseFunctionLiteral( |
2440 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2446 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2441 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2447 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, |
2442 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2448 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2449 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2443 | 2450 |
2444 return factory()->NewObjectLiteralProperty( | 2451 return factory()->NewObjectLiteralProperty( |
2445 name_expression, value, ObjectLiteralProperty::COMPUTED, | 2452 name_expression, value, ObjectLiteralProperty::COMPUTED, |
2446 *is_computed_name); | 2453 *is_computed_name); |
2447 } | 2454 } |
2448 | 2455 |
2449 case PropertyKind::kAccessorProperty: { | 2456 case PropertyKind::kAccessorProperty: { |
2450 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && | 2457 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && |
2451 !is_async); | 2458 !is_async); |
2452 | 2459 |
2453 classifier()->RecordPatternError( | 2460 classifier()->RecordPatternError( |
2454 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2461 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2455 MessageTemplate::kInvalidDestructuringTarget); | 2462 MessageTemplate::kInvalidDestructuringTarget); |
2456 | 2463 |
2457 if (!*is_computed_name) { | 2464 if (!*is_computed_name) { |
2458 // Make sure the name expression is a string since we need a Name for | 2465 // Make sure the name expression is a string since we need a Name for |
2459 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2466 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
2460 // this statically we can skip the extra runtime check. | 2467 // this statically we can skip the extra runtime check. |
2461 name_expression = | 2468 name_expression = |
2462 factory()->NewStringLiteral(name, name_expression->position()); | 2469 factory()->NewStringLiteral(name, name_expression->position()); |
2463 } | 2470 } |
2464 | 2471 |
2465 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2472 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
2466 : FunctionKind::kSetterFunction; | 2473 : FunctionKind::kSetterFunction; |
2467 | 2474 |
2468 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2475 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
2469 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2476 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2470 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2477 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, |
2471 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2478 FunctionLiteral::kAccessorOrMethod, language_mode(), |
| 2479 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2472 | 2480 |
2473 if (!*is_computed_name) { | 2481 if (!*is_computed_name) { |
2474 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2482 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
2475 } | 2483 } |
2476 | 2484 |
2477 return factory()->NewObjectLiteralProperty( | 2485 return factory()->NewObjectLiteralProperty( |
2478 name_expression, value, is_get ? ObjectLiteralProperty::GETTER | 2486 name_expression, value, is_get ? ObjectLiteralProperty::GETTER |
2479 : ObjectLiteralProperty::SETTER, | 2487 : ObjectLiteralProperty::SETTER, |
2480 *is_computed_name); | 2488 *is_computed_name); |
2481 } | 2489 } |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3295 } | 3303 } |
3296 | 3304 |
3297 FunctionKind function_kind = Check(Token::MUL) | 3305 FunctionKind function_kind = Check(Token::MUL) |
3298 ? FunctionKind::kGeneratorFunction | 3306 ? FunctionKind::kGeneratorFunction |
3299 : FunctionKind::kNormalFunction; | 3307 : FunctionKind::kNormalFunction; |
3300 IdentifierT name = impl()->EmptyIdentifier(); | 3308 IdentifierT name = impl()->EmptyIdentifier(); |
3301 bool is_strict_reserved_name = false; | 3309 bool is_strict_reserved_name = false; |
3302 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3310 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3303 FunctionLiteral::FunctionType function_type = | 3311 FunctionLiteral::FunctionType function_type = |
3304 FunctionLiteral::kAnonymousExpression; | 3312 FunctionLiteral::kAnonymousExpression; |
3305 if (peek_any_identifier()) { | 3313 if (impl()->IgnoreFunctionName()) { |
| 3314 // Consume and discard the next token, which is always the identifier |
| 3315 // "anonymous". |
| 3316 Consume(Token::IDENTIFIER); |
| 3317 } else if (peek_any_identifier()) { |
3306 name = ParseIdentifierOrStrictReservedWord( | 3318 name = ParseIdentifierOrStrictReservedWord( |
3307 function_kind, &is_strict_reserved_name, CHECK_OK); | 3319 function_kind, &is_strict_reserved_name, CHECK_OK); |
3308 function_name_location = scanner()->location(); | 3320 function_name_location = scanner()->location(); |
3309 function_type = FunctionLiteral::kNamedExpression; | 3321 function_type = FunctionLiteral::kNamedExpression; |
3310 } | 3322 } |
3311 result = impl()->ParseFunctionLiteral( | 3323 result = impl()->ParseFunctionLiteral( |
3312 name, function_name_location, | 3324 name, function_name_location, |
3313 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3325 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
3314 : kFunctionNameValidityUnknown, | 3326 : kFunctionNameValidityUnknown, |
3315 function_kind, function_token_position, function_type, language_mode(), | 3327 function_kind, function_token_position, function_type, language_mode(), |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4194 // | 4206 // |
4195 // async [no LineTerminator here] function BindingIdentifier[Await] | 4207 // async [no LineTerminator here] function BindingIdentifier[Await] |
4196 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 4208 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
4197 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 4209 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
4198 int pos = position(); | 4210 int pos = position(); |
4199 Expect(Token::FUNCTION, CHECK_OK); | 4211 Expect(Token::FUNCTION, CHECK_OK); |
4200 bool is_strict_reserved = false; | 4212 bool is_strict_reserved = false; |
4201 IdentifierT name = impl()->EmptyIdentifier(); | 4213 IdentifierT name = impl()->EmptyIdentifier(); |
4202 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | 4214 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
4203 | 4215 |
4204 if (peek_any_identifier()) { | 4216 if (impl()->IgnoreFunctionName()) { |
| 4217 // Consume and discard the next token, which is always the identifier |
| 4218 // "anonymous". |
| 4219 Consume(Token::IDENTIFIER); |
| 4220 } else if (peek_any_identifier()) { |
4205 type = FunctionLiteral::kNamedExpression; | 4221 type = FunctionLiteral::kNamedExpression; |
4206 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, | 4222 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, |
4207 &is_strict_reserved, CHECK_OK); | 4223 &is_strict_reserved, CHECK_OK); |
4208 } | 4224 } |
4209 return impl()->ParseFunctionLiteral( | 4225 return impl()->ParseFunctionLiteral( |
4210 name, scanner()->location(), | 4226 name, scanner()->location(), |
4211 is_strict_reserved ? kFunctionNameIsStrictReserved | 4227 is_strict_reserved ? kFunctionNameIsStrictReserved |
4212 : kFunctionNameValidityUnknown, | 4228 : kFunctionNameValidityUnknown, |
4213 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); | 4229 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); |
4214 } | 4230 } |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5495 has_seen_constructor_ = true; | 5511 has_seen_constructor_ = true; |
5496 return; | 5512 return; |
5497 } | 5513 } |
5498 } | 5514 } |
5499 | 5515 |
5500 | 5516 |
5501 } // namespace internal | 5517 } // namespace internal |
5502 } // namespace v8 | 5518 } // namespace v8 |
5503 | 5519 |
5504 #endif // V8_PARSING_PARSER_BASE_H | 5520 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |