| 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 |