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/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 | 742 |
743 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 743 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
744 bool* ok); | 744 bool* ok); |
745 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 745 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
746 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 746 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
747 bool* ok); | 747 bool* ok); |
748 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 748 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
749 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 749 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
750 bool* is_computed_name, | 750 bool* is_computed_name, |
751 ExpressionClassifier* classifier, bool* ok); | 751 ExpressionClassifier* classifier, bool* ok); |
| 752 ExpressionT ParsePropertyNameInType(bool* ok); |
752 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 753 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
753 ObjectLiteralPropertyT ParsePropertyDefinition( | 754 ObjectLiteralPropertyT ParsePropertyDefinition( |
754 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 755 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
755 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 756 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
756 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 757 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
757 typename Traits::Type::ExpressionList ParseArguments( | 758 typename Traits::Type::ExpressionList ParseArguments( |
758 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 759 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
759 bool* ok); | 760 bool* ok); |
760 | 761 |
761 ExpressionT ParseAssignmentExpression(bool accept_IN, | 762 ExpressionT ParseAssignmentExpression(bool accept_IN, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 // Parsing optional types. | 838 // Parsing optional types. |
838 typename TypeSystem::Type ParseValidType(bool* ok); | 839 typename TypeSystem::Type ParseValidType(bool* ok); |
839 typename TypeSystem::Type ParseValidTypeOrStringLiteral(bool* ok); | 840 typename TypeSystem::Type ParseValidTypeOrStringLiteral(bool* ok); |
840 typename TypeSystem::Type ParseType(bool* ok); | 841 typename TypeSystem::Type ParseType(bool* ok); |
841 typename TypeSystem::Type ParseUnionOrIntersectionOrPrimaryType(bool* ok); | 842 typename TypeSystem::Type ParseUnionOrIntersectionOrPrimaryType(bool* ok); |
842 typename TypeSystem::Type ParseIntersectionOrPrimaryType(bool* ok); | 843 typename TypeSystem::Type ParseIntersectionOrPrimaryType(bool* ok); |
843 typename TypeSystem::Type ParsePrimaryTypeOrParameterList(bool* ok); | 844 typename TypeSystem::Type ParsePrimaryTypeOrParameterList(bool* ok); |
844 typename TypeSystem::TypeParameters ParseTypeParameters(bool* ok); | 845 typename TypeSystem::TypeParameters ParseTypeParameters(bool* ok); |
845 typename TypeSystem::TypeList ParseTypeArguments(bool* ok); | 846 typename TypeSystem::TypeList ParseTypeArguments(bool* ok); |
846 IdentifierListT ParsePropertyNameList(bool* ok); | 847 IdentifierListT ParsePropertyNameList(bool* ok); |
| 848 typename TypeSystem::TypeMember ParseTypeMember(bool* ok); |
847 | 849 |
848 typename TypeSystem::Type ValidateType(typename TypeSystem::Type type, | 850 typename TypeSystem::Type ValidateType(typename TypeSystem::Type type, |
849 Scanner::Location location, bool* ok) { | 851 Scanner::Location location, bool* ok) { |
850 typename TypeSystem::Type result = type->Uncover(ok); | 852 typename TypeSystem::Type result = type->Uncover(ok); |
851 if (*ok) { | 853 if (*ok) { |
852 if (!result->IsStringLiteralType()) return result; | 854 if (!result->IsStringLiteralType()) return result; |
853 *ok = false; | 855 *ok = false; |
854 } | 856 } |
855 ReportMessageAt(location, MessageTemplate::kInvalidType); | 857 ReportMessageAt(location, MessageTemplate::kInvalidType); |
856 return type; | 858 return type; |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 break; | 1588 break; |
1587 } | 1589 } |
1588 | 1590 |
1589 uint32_t index; | 1591 uint32_t index; |
1590 return this->IsArrayIndex(*name, &index) | 1592 return this->IsArrayIndex(*name, &index) |
1591 ? factory()->NewNumberLiteral(index, pos) | 1593 ? factory()->NewNumberLiteral(index, pos) |
1592 : factory()->NewStringLiteral(*name, pos); | 1594 : factory()->NewStringLiteral(*name, pos); |
1593 } | 1595 } |
1594 | 1596 |
1595 | 1597 |
| 1598 // This is a simplified version of ParsePropertyName |
| 1599 template <class Traits> |
| 1600 typename ParserBase<Traits>::ExpressionT |
| 1601 ParserBase<Traits>::ParsePropertyNameInType(bool* ok) { |
| 1602 Token::Value token = peek(); |
| 1603 int pos = peek_position(); |
| 1604 IdentifierT name = this->EmptyIdentifier(); |
| 1605 |
| 1606 // For non computed property names we normalize the name a bit: |
| 1607 // |
| 1608 // "12" -> 12 |
| 1609 // 12.3 -> "12.3" |
| 1610 // 12.30 -> "12.3" |
| 1611 // identifier -> "identifier" |
| 1612 // |
| 1613 // This is important because we use the property name as a key in a hash |
| 1614 // table when we compute constant properties. |
| 1615 switch (token) { |
| 1616 case Token::STRING: |
| 1617 Consume(Token::STRING); |
| 1618 name = this->GetSymbol(scanner()); |
| 1619 break; |
| 1620 |
| 1621 case Token::SMI: |
| 1622 Consume(Token::SMI); |
| 1623 name = this->GetNumberAsSymbol(scanner()); |
| 1624 break; |
| 1625 |
| 1626 case Token::NUMBER: |
| 1627 Consume(Token::NUMBER); |
| 1628 name = this->GetNumberAsSymbol(scanner()); |
| 1629 break; |
| 1630 |
| 1631 default: |
| 1632 name = ParseIdentifierName(CHECK_OK); |
| 1633 break; |
| 1634 } |
| 1635 |
| 1636 uint32_t index; |
| 1637 return this->IsArrayIndex(name, &index) |
| 1638 ? factory()->NewNumberLiteral(index, pos) |
| 1639 : factory()->NewStringLiteral(name, pos); |
| 1640 } |
| 1641 |
| 1642 |
1596 template <class Traits> | 1643 template <class Traits> |
1597 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1644 typename ParserBase<Traits>::ObjectLiteralPropertyT |
1598 ParserBase<Traits>::ParsePropertyDefinition( | 1645 ParserBase<Traits>::ParsePropertyDefinition( |
1599 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1646 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
1600 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1647 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
1601 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1648 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
1602 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1649 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
1603 ExpressionT value = this->EmptyExpression(); | 1650 ExpressionT value = this->EmptyExpression(); |
1604 bool is_get = false; | 1651 bool is_get = false; |
1605 bool is_set = false; | 1652 bool is_set = false; |
(...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3321 elements->Add(type_element, zone()); | 3368 elements->Add(type_element, zone()); |
3322 valid_type = false; | 3369 valid_type = false; |
3323 spread = true; | 3370 spread = true; |
3324 break; | 3371 break; |
3325 } | 3372 } |
3326 typename TypeSystem::Type type_element = ParseType(CHECK_OK_TYPE); | 3373 typename TypeSystem::Type type_element = ParseType(CHECK_OK_TYPE); |
3327 elements->Add(type_element, zone()); | 3374 elements->Add(type_element, zone()); |
3328 if (!type_element->IsValidType()) valid_type = false; | 3375 if (!type_element->IsValidType()) valid_type = false; |
3329 if (!type_element->IsValidBindingIdentifierOrPattern()) | 3376 if (!type_element->IsValidBindingIdentifierOrPattern()) |
3330 valid_binder = false; | 3377 valid_binder = false; |
3331 if (peek() != Token::RBRACK) { // Braces required here. | 3378 if (peek() != Token::RBRACK) { |
3332 Expect(Token::COMMA, CHECK_OK_TYPE); | 3379 Expect(Token::COMMA, CHECK_OK_TYPE); |
3333 trailing_comma = true; | 3380 trailing_comma = true; |
3334 } | 3381 } |
3335 } while (peek() != Token::RBRACK); | 3382 } while (peek() != Token::RBRACK); |
3336 } | 3383 } |
3337 Consume(Token::RBRACK); | 3384 Consume(Token::RBRACK); |
3338 type = factory()->NewTupleType(elements, valid_type && !trailing_comma, | 3385 type = factory()->NewTupleType(elements, valid_type && !trailing_comma, |
3339 valid_binder, spread, pos); | 3386 valid_binder, spread, pos); |
3340 break; | 3387 break; |
3341 } | 3388 } |
| 3389 case Token::LBRACE: { |
| 3390 Consume(Token::LBRACE); |
| 3391 typename TypeSystem::TypeMembers members = this->EmptyTypeMembers(); |
| 3392 bool valid_type = true, valid_binder = true; |
| 3393 while (peek() != Token::RBRACE) { |
| 3394 typename TypeSystem::TypeMember type_member = |
| 3395 ParseTypeMember(CHECK_OK_TYPE); |
| 3396 members->Add(type_member, zone()); |
| 3397 if (!type_member->IsValidType()) valid_type = false; |
| 3398 if (!type_member->IsValidBindingIdentifierOrPattern()) |
| 3399 valid_binder = false; |
| 3400 if (peek() != Token::RBRACE && !Check(Token::COMMA)) { |
| 3401 ExpectSemicolon(CHECK_OK_TYPE); |
| 3402 valid_binder = false; // Semicolons not allowed in valid binders. |
| 3403 } |
| 3404 } |
| 3405 Consume(Token::RBRACE); |
| 3406 type = factory()->NewObjectType(members, valid_type, valid_binder, pos); |
| 3407 break; |
| 3408 } |
3342 case Token::TYPEOF: { | 3409 case Token::TYPEOF: { |
3343 Consume(Token::TYPEOF); | 3410 Consume(Token::TYPEOF); |
3344 IdentifierT name = ParseIdentifierName(CHECK_OK_TYPE); | 3411 IdentifierT name = ParseIdentifierName(CHECK_OK_TYPE); |
3345 IdentifierListT property_names = this->NullIdentifierList(); | 3412 IdentifierListT property_names = this->NullIdentifierList(); |
3346 if (peek() == Token::PERIOD) { // Braces required here. | 3413 if (peek() == Token::PERIOD) { // Braces required here. |
3347 property_names = ParsePropertyNameList(CHECK_OK_TYPE); | 3414 property_names = ParsePropertyNameList(CHECK_OK_TYPE); |
3348 } | 3415 } |
3349 type = factory()->NewQueryType(name, property_names, pos); | 3416 type = factory()->NewQueryType(name, property_names, pos); |
3350 break; | 3417 break; |
3351 } | 3418 } |
3352 case Token::VOID: { | 3419 case Token::VOID: { |
3353 Consume(Token::VOID); | 3420 Consume(Token::VOID); |
3354 type = factory()->NewPredefinedType(typesystem::PredefinedType::kVoidType, | 3421 type = factory()->NewPredefinedType(typesystem::PredefinedType::kVoidType, |
3355 pos); | 3422 pos); |
3356 break; | 3423 break; |
3357 } | 3424 } |
3358 case Token::THIS: { | 3425 case Token::THIS: { |
3359 Consume(Token::THIS); | 3426 Consume(Token::THIS); |
3360 type = factory()->NewThisType(pos); | 3427 type = factory()->NewThisType(pos); |
3361 break; | 3428 break; |
3362 } | 3429 } |
3363 // TODO(nikolaos): Missing object types. | |
3364 case Token::STRING: { | 3430 case Token::STRING: { |
3365 Consume(Token::STRING); | 3431 Consume(Token::STRING); |
3366 IdentifierT str = this->GetSymbol(scanner()); | 3432 IdentifierT str = this->GetSymbol(scanner()); |
3367 type = factory()->NewStringLiteralType(str, pos); | 3433 type = factory()->NewStringLiteralType(str, pos); |
3368 break; | 3434 break; |
3369 } | 3435 } |
3370 default: | 3436 default: |
3371 ReportUnexpectedToken(Next()); | 3437 ReportUnexpectedToken(Next()); |
3372 *ok = false; | 3438 *ok = false; |
3373 return type; | 3439 return type; |
(...skipping 20 matching lines...) Expand all Loading... |
3394 IdentifierListT property_names = this->EmptyIdentifierList(); | 3460 IdentifierListT property_names = this->EmptyIdentifierList(); |
3395 do { | 3461 do { |
3396 IdentifierT property_name = | 3462 IdentifierT property_name = |
3397 ParseIdentifierName(CHECK_OK_CUSTOM(NullIdentifierList)); | 3463 ParseIdentifierName(CHECK_OK_CUSTOM(NullIdentifierList)); |
3398 property_names->Add(property_name, zone()); | 3464 property_names->Add(property_name, zone()); |
3399 } while (Check(Token::PERIOD)); | 3465 } while (Check(Token::PERIOD)); |
3400 return property_names; | 3466 return property_names; |
3401 } | 3467 } |
3402 | 3468 |
3403 | 3469 |
| 3470 template <typename Traits> |
| 3471 typename ParserBase<Traits>::TypeSystem::TypeMember |
| 3472 ParserBase<Traits>::ParseTypeMember(bool* ok) { |
| 3473 int pos = peek_position(); |
| 3474 bool valid_type = true, valid_binder = false; |
| 3475 // Parse index signature. |
| 3476 if (Check(Token::LBRACK)) { |
| 3477 int property_pos = peek_position(); |
| 3478 IdentifierT property_name = |
| 3479 ParseIdentifierName(CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3480 ExpressionT property = |
| 3481 factory()->NewStringLiteral(property_name, property_pos); |
| 3482 Expect(Token::COLON, CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3483 typesystem::TypeMember::IndexType index_type = |
| 3484 typesystem::TypeMember::kNoIndexType; |
| 3485 if (peek() == Token::IDENTIFIER) { |
| 3486 if (CheckContextualKeyword(CStrVector("number"))) { |
| 3487 index_type = typesystem::TypeMember::kNumberIndexType; |
| 3488 } else if (CheckContextualKeyword(CStrVector("string"))) { |
| 3489 index_type = typesystem::TypeMember::kStringIndexType; |
| 3490 } |
| 3491 } |
| 3492 if (index_type == typesystem::TypeMember::kNoIndexType) { |
| 3493 Scanner::Location next_location = scanner()->peek_location(); |
| 3494 ReportMessageAt(next_location, MessageTemplate::kBadIndexType); |
| 3495 *ok = false; |
| 3496 return this->EmptyTypeMember(); |
| 3497 } |
| 3498 Expect(Token::RBRACK, CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3499 // Parse optional result type |
| 3500 typename TypeSystem::Type type = this->EmptyType(); |
| 3501 if (Check(Token::COLON)) { // Braces required here. |
| 3502 type = ParseValidType(CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3503 } |
| 3504 return factory()->NewTypeMember(property, index_type, type, pos); |
| 3505 } |
| 3506 // Parse property, method, call or constructor signatures. |
| 3507 ExpressionT property = this->EmptyExpression(); |
| 3508 bool has_property = false; |
| 3509 bool optional = false; |
| 3510 bool has_new = Check(Token::NEW); |
| 3511 if (!has_new && peek() != Token::LT && peek() != Token::LPAREN) { |
| 3512 // Parse property name. |
| 3513 property = ParsePropertyNameInType(CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3514 has_property = true; |
| 3515 optional = Check(Token::CONDITIONAL); |
| 3516 valid_binder = !optional; |
| 3517 } |
| 3518 // Parse optional type parameters. |
| 3519 typename TypeSystem::TypeParameters type_parameters = |
| 3520 this->NullTypeParameters(); |
| 3521 if (peek() == Token::LT) { // Braces required here. |
| 3522 type_parameters = ParseTypeParameters(CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3523 valid_binder = false; |
| 3524 } |
| 3525 // Require formal parameters if type parameters are present |
| 3526 // or if no property was specified. |
| 3527 if ((!has_property || !this->IsNullTypeParameters(type_parameters)) && |
| 3528 peek() != Token::LPAREN) { |
| 3529 Expect(Token::LPAREN, CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3530 UNREACHABLE(); |
| 3531 } |
| 3532 // Parse optional formal parameters. |
| 3533 typename TypeSystem::FormalParameters parameters = |
| 3534 this->NullFormalParameters(); |
| 3535 if (peek() == Token::LPAREN) { |
| 3536 typename TypeSystem::Type type_params = |
| 3537 ParsePrimaryTypeOrParameterList(CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3538 parameters = type_params->AsValidParameterList( |
| 3539 zone_, CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3540 valid_binder = false; |
| 3541 } |
| 3542 // Parse optional property or result type or covered binding pattern. |
| 3543 typename TypeSystem::Type type = this->EmptyType(); |
| 3544 if (Check(Token::COLON)) { |
| 3545 type = ParseType(CHECK_OK_CUSTOM(EmptyTypeMember)); |
| 3546 if (!type->IsValidType()) valid_type = false; |
| 3547 if (!type->IsValidBindingIdentifierOrPattern()) valid_binder = false; |
| 3548 } |
| 3549 return factory()->NewTypeMember(property, optional, type_parameters, |
| 3550 parameters, type, valid_type, valid_binder, |
| 3551 pos, has_new); |
| 3552 } |
| 3553 |
| 3554 |
3404 #undef CHECK_OK | 3555 #undef CHECK_OK |
3405 #undef CHECK_OK_CUSTOM | 3556 #undef CHECK_OK_CUSTOM |
3406 #undef CHECK_OK_TYPE | 3557 #undef CHECK_OK_TYPE |
3407 | 3558 |
3408 | 3559 |
3409 template <typename Traits> | 3560 template <typename Traits> |
3410 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 3561 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
3411 Token::Value property, PropertyKind type, bool is_static, bool is_generator, | 3562 Token::Value property, PropertyKind type, bool is_static, bool is_generator, |
3412 bool* ok) { | 3563 bool* ok) { |
3413 DCHECK(!is_static); | 3564 DCHECK(!is_static); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3458 has_seen_constructor_ = true; | 3609 has_seen_constructor_ = true; |
3459 return; | 3610 return; |
3460 } | 3611 } |
3461 } | 3612 } |
3462 | 3613 |
3463 | 3614 |
3464 } // namespace internal | 3615 } // namespace internal |
3465 } // namespace v8 | 3616 } // namespace v8 |
3466 | 3617 |
3467 #endif // V8_PARSING_PARSER_BASE_H | 3618 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |