Chromium Code Reviews| 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 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 | 454 |
| 455 bool peek_any_identifier() { | 455 bool peek_any_identifier() { |
| 456 Token::Value next = peek(); | 456 Token::Value next = peek(); |
| 457 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 457 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || |
| 458 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 458 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
| 459 next == Token::STATIC || next == Token::YIELD; | 459 next == Token::STATIC || next == Token::YIELD; |
| 460 } | 460 } |
| 461 | 461 |
| 462 bool CheckContextualKeyword(Vector<const char> keyword) { | 462 bool CheckContextualKeyword(Vector<const char> keyword) { |
| 463 if (PeekContextualKeyword(keyword)) { | 463 if (PeekContextualKeyword(keyword)) { |
| 464 Consume(Token::IDENTIFIER); | 464 Next(); |
| 465 return true; | 465 return true; |
| 466 } | 466 } |
| 467 return false; | 467 return false; |
| 468 } | 468 } |
| 469 | 469 |
| 470 bool PeekContextualKeyword(Vector<const char> keyword) { | 470 bool PeekContextualKeyword(Vector<const char> keyword) { |
| 471 return peek() == Token::IDENTIFIER && | 471 return (peek() == Token::IDENTIFIER || |
| 472 peek() == Token::FUTURE_RESERVED_WORD || | |
| 473 peek() == Token::FUTURE_STRICT_RESERVED_WORD) && | |
| 472 scanner()->is_next_contextual_keyword(keyword); | 474 scanner()->is_next_contextual_keyword(keyword); |
| 473 } | 475 } |
| 474 | 476 |
| 475 void ExpectMetaProperty(Vector<const char> property_name, | 477 void ExpectMetaProperty(Vector<const char> property_name, |
| 476 const char* full_name, int pos, bool* ok); | 478 const char* full_name, int pos, bool* ok); |
| 477 | 479 |
| 478 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 480 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 479 Expect(Token::IDENTIFIER, ok); | 481 Token::Value next = Next(); |
| 480 if (!*ok) return; | 482 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
| 481 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 483 next != Token::FUTURE_STRICT_RESERVED_WORD) { |
| 484 ReportUnexpectedToken(next); | |
| 485 *ok = false; | |
| 486 } else if (!scanner()->is_literal_contextual_keyword(keyword)) { | |
| 482 ReportUnexpectedToken(scanner()->current_token()); | 487 ReportUnexpectedToken(scanner()->current_token()); |
| 483 *ok = false; | 488 *ok = false; |
| 484 } | 489 } |
| 485 } | 490 } |
| 486 | 491 |
| 487 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { | 492 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) { |
| 488 if (Check(Token::IN)) { | 493 if (Check(Token::IN)) { |
| 489 *visit_mode = ForEachStatement::ENUMERATE; | 494 *visit_mode = ForEachStatement::ENUMERATE; |
| 490 return true; | 495 return true; |
| 491 } else if (CheckContextualKeyword(CStrVector("of"))) { | 496 } else if (CheckContextualKeyword(CStrVector("of"))) { |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 } | 847 } |
| 843 } | 848 } |
| 844 | 849 |
| 845 // Parsing optional types. | 850 // Parsing optional types. |
| 846 typename TypeSystem::Type ParseValidType(bool* ok); | 851 typename TypeSystem::Type ParseValidType(bool* ok); |
| 847 typename TypeSystem::Type ParseValidTypeOrStringLiteral(bool* ok); | 852 typename TypeSystem::Type ParseValidTypeOrStringLiteral(bool* ok); |
| 848 typename TypeSystem::Type ParseType(bool* ok); | 853 typename TypeSystem::Type ParseType(bool* ok); |
| 849 typename TypeSystem::Type ParseUnionOrIntersectionOrPrimaryType(bool* ok); | 854 typename TypeSystem::Type ParseUnionOrIntersectionOrPrimaryType(bool* ok); |
| 850 typename TypeSystem::Type ParseIntersectionOrPrimaryType(bool* ok); | 855 typename TypeSystem::Type ParseIntersectionOrPrimaryType(bool* ok); |
| 851 typename TypeSystem::Type ParsePrimaryTypeOrParameterList(bool* ok); | 856 typename TypeSystem::Type ParsePrimaryTypeOrParameterList(bool* ok); |
| 857 typename TypeSystem::Type ParseTypeReference(bool* ok); | |
| 852 typename TypeSystem::TypeParameters ParseTypeParameters(bool* ok); | 858 typename TypeSystem::TypeParameters ParseTypeParameters(bool* ok); |
| 853 typename TypeSystem::TypeList ParseTypeArguments(bool* ok); | 859 typename TypeSystem::TypeList ParseTypeArguments(bool* ok); |
| 854 IdentifierListT ParsePropertyNameList(bool* ok); | 860 IdentifierListT ParsePropertyNameList(bool* ok); |
| 855 typename TypeSystem::TypeMember ParseTypeMember(bool* ok); | 861 typename TypeSystem::TypeMember ParseTypeMember(bool* ok); |
| 856 StatementT ParseTypeAliasDeclaration(int pos, bool* ok); | 862 StatementT ParseTypeAliasDeclaration(int pos, bool* ok); |
| 857 | 863 |
| 858 typename TypeSystem::Type ValidateType(typename TypeSystem::Type type, | 864 typename TypeSystem::Type ValidateType(typename TypeSystem::Type type, |
| 859 Scanner::Location location, bool* ok) { | 865 Scanner::Location location, bool* ok) { |
| 860 typename TypeSystem::Type result = type->Uncover(ok); | 866 typename TypeSystem::Type result = type->Uncover(ok); |
| 861 if (*ok) { | 867 if (*ok) { |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 } | 1654 } |
| 1649 | 1655 |
| 1650 | 1656 |
| 1651 template <class Traits> | 1657 template <class Traits> |
| 1652 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1658 typename ParserBase<Traits>::ObjectLiteralPropertyT |
| 1653 ParserBase<Traits>::ParsePropertyDefinition( | 1659 ParserBase<Traits>::ParsePropertyDefinition( |
| 1654 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1660 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 1655 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1661 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 1656 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1662 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
| 1657 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1663 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
| 1664 | |
| 1665 // Parse index member declarations in typed mode. | |
| 1666 // We implicitly disallow computed property names, in this case, | |
| 1667 // i.e., class C { [42](x) {} } does not work in typed mode. | |
|
rossberg
2016/04/18 11:03:08
Interesting. That's probably going to be a problem
nickie
2016/04/19 14:55:30
I suppose index member declarations can be disting
| |
| 1668 if (in_class && !is_static && scope_->typed() && Check(Token::LBRACK)) { | |
| 1669 int property_pos = peek_position(); | |
| 1670 IdentifierT property_name = | |
| 1671 ParseIdentifierName(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1672 ExpressionT property = | |
| 1673 factory()->NewStringLiteral(property_name, property_pos); | |
| 1674 Expect(Token::COLON, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1675 typesystem::TypeMember::IndexType index_type = | |
| 1676 typesystem::TypeMember::kNoIndexType; | |
| 1677 if (peek() == Token::IDENTIFIER) { | |
| 1678 if (CheckContextualKeyword(CStrVector("number"))) { | |
| 1679 index_type = typesystem::TypeMember::kNumberIndexType; | |
| 1680 } else if (CheckContextualKeyword(CStrVector("string"))) { | |
| 1681 index_type = typesystem::TypeMember::kStringIndexType; | |
| 1682 } | |
| 1683 } | |
| 1684 if (index_type == typesystem::TypeMember::kNoIndexType) { | |
| 1685 Scanner::Location next_location = scanner()->peek_location(); | |
| 1686 ReportMessageAt(next_location, MessageTemplate::kBadIndexType); | |
| 1687 *ok = false; | |
| 1688 return this->EmptyObjectLiteralProperty(); | |
| 1689 } | |
| 1690 Expect(Token::RBRACK, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1691 // Parse optional result type | |
| 1692 typename TypeSystem::Type type = this->EmptyType(); | |
| 1693 if (Check(Token::COLON)) { // Braces required here. | |
| 1694 type = ParseValidType(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1695 } | |
| 1696 USE(property); // TODO(nikolaos): really use these! | |
| 1697 USE(index_type); | |
| 1698 USE(type); | |
| 1699 return this->EmptyObjectLiteralProperty(); | |
| 1700 } | |
| 1701 | |
| 1658 ExpressionT value = this->EmptyExpression(); | 1702 ExpressionT value = this->EmptyExpression(); |
| 1659 bool is_get = false; | 1703 bool is_get = false; |
| 1660 bool is_set = false; | 1704 bool is_set = false; |
| 1661 bool is_generator = Check(Token::MUL); | 1705 bool is_generator = Check(Token::MUL); |
| 1662 | 1706 |
| 1663 Token::Value name_token = peek(); | 1707 Token::Value name_token = peek(); |
| 1664 int next_beg_pos = scanner()->peek_location().beg_pos; | 1708 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 1665 int next_end_pos = scanner()->peek_location().end_pos; | 1709 int next_end_pos = scanner()->peek_location().end_pos; |
| 1666 ExpressionT name_expression = | 1710 ExpressionT name_expression = |
| 1667 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, | 1711 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier, |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1826 name_expression = | 1870 name_expression = |
| 1827 factory()->NewStringLiteral(*name, name_expression->position()); | 1871 factory()->NewStringLiteral(*name, name_expression->position()); |
| 1828 } | 1872 } |
| 1829 | 1873 |
| 1830 return factory()->NewObjectLiteralProperty( | 1874 return factory()->NewObjectLiteralProperty( |
| 1831 name_expression, value, | 1875 name_expression, value, |
| 1832 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 1876 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
| 1833 is_static, *is_computed_name); | 1877 is_static, *is_computed_name); |
| 1834 } | 1878 } |
| 1835 | 1879 |
| 1880 // Allow member variable declarations in typed mode. | |
| 1881 if (in_class && scope_->typed()) { | |
| 1882 // Parse optional type annotation. | |
| 1883 typename TypeSystem::Type type = this->EmptyType(); | |
| 1884 if (Check(Token::COLON)) { // Braces required here. | |
| 1885 type = ParseValidType(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1886 } | |
| 1887 USE(type); // TODO(nikolaos): really use it! | |
| 1888 // Parse optional initializer. | |
| 1889 if (Check(Token::ASSIGN)) { | |
| 1890 ExpressionClassifier rhs_classifier(this); | |
| 1891 ExpressionT rhs = this->ParseAssignmentExpression( | |
| 1892 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1893 Traits::RewriteNonPattern(&rhs_classifier, | |
| 1894 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
| 1895 classifier->Accumulate(&rhs_classifier, | |
| 1896 ExpressionClassifier::ExpressionProductions); | |
| 1897 USE(rhs); // TODO(nikolaos): really use it! | |
| 1898 } | |
| 1899 return this->EmptyObjectLiteralProperty(); | |
| 1900 } | |
| 1901 | |
| 1836 Token::Value next = Next(); | 1902 Token::Value next = Next(); |
| 1837 ReportUnexpectedToken(next); | 1903 ReportUnexpectedToken(next); |
| 1838 *ok = false; | 1904 *ok = false; |
| 1839 return this->EmptyObjectLiteralProperty(); | 1905 return this->EmptyObjectLiteralProperty(); |
| 1840 } | 1906 } |
| 1841 | 1907 |
| 1842 | 1908 |
| 1843 template <class Traits> | 1909 template <class Traits> |
| 1844 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 1910 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| 1845 ExpressionClassifier* classifier, bool* ok) { | 1911 ExpressionClassifier* classifier, bool* ok) { |
| (...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3379 typesystem::PredefinedType::kBooleanType, pos); | 3445 typesystem::PredefinedType::kBooleanType, pos); |
| 3380 } else if (CheckContextualKeyword(CStrVector("number"))) { | 3446 } else if (CheckContextualKeyword(CStrVector("number"))) { |
| 3381 type = factory()->NewPredefinedType( | 3447 type = factory()->NewPredefinedType( |
| 3382 typesystem::PredefinedType::kNumberType, pos); | 3448 typesystem::PredefinedType::kNumberType, pos); |
| 3383 } else if (CheckContextualKeyword(CStrVector("string"))) { | 3449 } else if (CheckContextualKeyword(CStrVector("string"))) { |
| 3384 type = factory()->NewPredefinedType( | 3450 type = factory()->NewPredefinedType( |
| 3385 typesystem::PredefinedType::kStringType, pos); | 3451 typesystem::PredefinedType::kStringType, pos); |
| 3386 } else if (CheckContextualKeyword(CStrVector("symbol"))) { | 3452 } else if (CheckContextualKeyword(CStrVector("symbol"))) { |
| 3387 type = factory()->NewPredefinedType( | 3453 type = factory()->NewPredefinedType( |
| 3388 typesystem::PredefinedType::kSymbolType, pos); | 3454 typesystem::PredefinedType::kSymbolType, pos); |
| 3389 } else { | 3455 } else { // Braces required here. |
| 3390 IdentifierT name = ParseIdentifierName(CHECK_OK_TYPE); | 3456 type = ParseTypeReference(CHECK_OK_TYPE); |
| 3391 typename TypeSystem::TypeList type_arguments = this->NullTypeList(); | |
| 3392 if (peek() == Token::LT) { // Braces required here. | |
| 3393 type_arguments = ParseTypeArguments(CHECK_OK_TYPE); | |
| 3394 } | |
| 3395 type = factory()->NewTypeReference(name, type_arguments, pos); | |
| 3396 } | 3457 } |
| 3397 break; | 3458 break; |
| 3398 } | 3459 } |
| 3399 case Token::LBRACK: { | 3460 case Token::LBRACK: { |
| 3400 Consume(Token::LBRACK); | 3461 Consume(Token::LBRACK); |
| 3401 typename TypeSystem::TypeList elements = this->EmptyTypeList(); | 3462 typename TypeSystem::TypeList elements = this->EmptyTypeList(); |
| 3402 bool valid_type = false, valid_binder = true, spread = false; | 3463 bool valid_type = false, valid_binder = true, spread = false; |
| 3403 bool trailing_comma = false; | 3464 bool trailing_comma = false; |
| 3404 if (peek() != Token::RBRACK) { | 3465 if (peek() != Token::RBRACK) { |
| 3405 valid_type = true; | 3466 valid_type = true; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3497 Expect(Token::RBRACK, CHECK_OK_TYPE); | 3558 Expect(Token::RBRACK, CHECK_OK_TYPE); |
| 3498 type = factory()->NewArrayType(type, pos); | 3559 type = factory()->NewArrayType(type, pos); |
| 3499 } | 3560 } |
| 3500 } | 3561 } |
| 3501 | 3562 |
| 3502 return type; | 3563 return type; |
| 3503 } | 3564 } |
| 3504 | 3565 |
| 3505 | 3566 |
| 3506 template <typename Traits> | 3567 template <typename Traits> |
| 3568 typename ParserBase<Traits>::TypeSystem::Type | |
| 3569 ParserBase<Traits>::ParseTypeReference(bool* ok) { | |
| 3570 int pos = peek_position(); | |
| 3571 IdentifierT name = ParseIdentifierName(CHECK_OK_TYPE); | |
| 3572 typename TypeSystem::TypeList type_arguments = this->NullTypeList(); | |
| 3573 if (peek() == Token::LT) { // Braces required here. | |
| 3574 type_arguments = ParseTypeArguments(CHECK_OK_TYPE); | |
| 3575 } | |
| 3576 return factory()->NewTypeReference(name, type_arguments, pos); | |
| 3577 } | |
| 3578 | |
| 3579 | |
| 3580 template <typename Traits> | |
| 3507 typename ParserBase<Traits>::IdentifierListT | 3581 typename ParserBase<Traits>::IdentifierListT |
| 3508 ParserBase<Traits>::ParsePropertyNameList(bool* ok) { | 3582 ParserBase<Traits>::ParsePropertyNameList(bool* ok) { |
| 3509 Expect(Token::PERIOD, CHECK_OK_CUSTOM(NullIdentifierList)); | 3583 Expect(Token::PERIOD, CHECK_OK_CUSTOM(NullIdentifierList)); |
| 3510 IdentifierListT property_names = this->EmptyIdentifierList(); | 3584 IdentifierListT property_names = this->EmptyIdentifierList(); |
| 3511 do { | 3585 do { |
| 3512 IdentifierT property_name = | 3586 IdentifierT property_name = |
| 3513 ParseIdentifierName(CHECK_OK_CUSTOM(NullIdentifierList)); | 3587 ParseIdentifierName(CHECK_OK_CUSTOM(NullIdentifierList)); |
| 3514 property_names->Add(property_name, zone()); | 3588 property_names->Add(property_name, zone()); |
| 3515 } while (Check(Token::PERIOD)); | 3589 } while (Check(Token::PERIOD)); |
| 3516 return property_names; | 3590 return property_names; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3686 has_seen_constructor_ = true; | 3760 has_seen_constructor_ = true; |
| 3687 return; | 3761 return; |
| 3688 } | 3762 } |
| 3689 } | 3763 } |
| 3690 | 3764 |
| 3691 | 3765 |
| 3692 } // namespace internal | 3766 } // namespace internal |
| 3693 } // namespace v8 | 3767 } // namespace v8 |
| 3694 | 3768 |
| 3695 #endif // V8_PARSING_PARSER_BASE_H | 3769 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |