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 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | 726 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
727 bool* ok); | 727 bool* ok); |
728 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 728 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
729 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, | 729 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
730 bool* ok); | 730 bool* ok); |
731 ExpressionT ParseExpression(bool accept_IN, int flags, | 731 ExpressionT ParseExpression(bool accept_IN, int flags, |
732 ExpressionClassifier* classifier, bool* ok); | 732 ExpressionClassifier* classifier, bool* ok); |
733 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | 733 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
734 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 734 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
735 bool* is_static, bool* is_computed_name, | 735 bool* is_static, bool* is_computed_name, |
736 bool* is_identifier, bool* is_escaped_keyword, | |
737 ExpressionClassifier* classifier, bool* ok); | 736 ExpressionClassifier* classifier, bool* ok); |
738 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 737 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
739 ObjectLiteralPropertyT ParsePropertyDefinition( | 738 ObjectLiteralPropertyT ParsePropertyDefinition( |
740 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 739 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
741 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 740 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
742 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); | 741 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
743 typename Traits::Type::ExpressionList ParseArguments( | 742 typename Traits::Type::ExpressionList ParseArguments( |
744 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 743 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
745 bool* ok); | 744 bool* ok); |
746 | 745 |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 next == Token::LET || next == Token::STATIC || | 1108 next == Token::LET || next == Token::STATIC || |
1110 (next == Token::YIELD && !is_generator()))) { | 1109 (next == Token::YIELD && !is_generator()))) { |
1111 classifier->RecordStrictModeFormalParameterError( | 1110 classifier->RecordStrictModeFormalParameterError( |
1112 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); | 1111 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
1113 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && | 1112 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
1114 is_strict(language_mode())) { | 1113 is_strict(language_mode())) { |
1115 ReportUnexpectedToken(next); | 1114 ReportUnexpectedToken(next); |
1116 *ok = false; | 1115 *ok = false; |
1117 return Traits::EmptyIdentifier(); | 1116 return Traits::EmptyIdentifier(); |
1118 } | 1117 } |
1119 if (next == Token::LET) { | 1118 if (next == Token::LET || |
| 1119 (next == Token::ESCAPED_STRICT_RESERVED_WORD && |
| 1120 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { |
1120 classifier->RecordLetPatternError(scanner()->location(), | 1121 classifier->RecordLetPatternError(scanner()->location(), |
1121 MessageTemplate::kLetInLexicalBinding); | 1122 MessageTemplate::kLetInLexicalBinding); |
1122 } | 1123 } |
1123 return this->GetSymbol(scanner()); | 1124 return this->GetSymbol(scanner()); |
1124 } else { | 1125 } else { |
1125 this->ReportUnexpectedToken(next); | 1126 this->ReportUnexpectedToken(next); |
1126 *ok = false; | 1127 *ok = false; |
1127 return Traits::EmptyIdentifier(); | 1128 return Traits::EmptyIdentifier(); |
1128 } | 1129 } |
1129 } | 1130 } |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1551 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1551 | 1552 |
1552 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, | 1553 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, |
1553 is_strong(language_mode()), pos); | 1554 is_strong(language_mode()), pos); |
1554 } | 1555 } |
1555 | 1556 |
1556 | 1557 |
1557 template <class Traits> | 1558 template <class Traits> |
1558 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 1559 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
1559 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, | 1560 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
1560 bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword, | 1561 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
1561 ExpressionClassifier* classifier, bool* ok) { | |
1562 Token::Value token = peek(); | 1562 Token::Value token = peek(); |
1563 int pos = peek_position(); | 1563 int pos = peek_position(); |
1564 | 1564 |
1565 // For non computed property names we normalize the name a bit: | 1565 // For non computed property names we normalize the name a bit: |
1566 // | 1566 // |
1567 // "12" -> 12 | 1567 // "12" -> 12 |
1568 // 12.3 -> "12.3" | 1568 // 12.3 -> "12.3" |
1569 // 12.30 -> "12.3" | 1569 // 12.30 -> "12.3" |
1570 // identifier -> "identifier" | 1570 // identifier -> "identifier" |
1571 // | 1571 // |
(...skipping 22 matching lines...) Expand all Loading... |
1594 ExpressionT expression = | 1594 ExpressionT expression = |
1595 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 1595 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); |
1596 expression = Traits::RewriteNonPattern( | 1596 expression = Traits::RewriteNonPattern( |
1597 expression, &computed_name_classifier, CHECK_OK); | 1597 expression, &computed_name_classifier, CHECK_OK); |
1598 classifier->Accumulate(computed_name_classifier, | 1598 classifier->Accumulate(computed_name_classifier, |
1599 ExpressionClassifier::ExpressionProductions); | 1599 ExpressionClassifier::ExpressionProductions); |
1600 Expect(Token::RBRACK, CHECK_OK); | 1600 Expect(Token::RBRACK, CHECK_OK); |
1601 return expression; | 1601 return expression; |
1602 } | 1602 } |
1603 | 1603 |
1604 case Token::ESCAPED_KEYWORD: | |
1605 *is_escaped_keyword = true; | |
1606 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | |
1607 break; | |
1608 | |
1609 case Token::STATIC: | 1604 case Token::STATIC: |
1610 *is_static = true; | 1605 *is_static = true; |
1611 | 1606 |
1612 // Fall through. | 1607 // Fall through. |
1613 default: | 1608 default: |
1614 *is_identifier = true; | |
1615 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | 1609 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
1616 break; | 1610 break; |
1617 } | 1611 } |
1618 | 1612 |
1619 uint32_t index; | 1613 uint32_t index; |
1620 return this->IsArrayIndex(*name, &index) | 1614 return this->IsArrayIndex(*name, &index) |
1621 ? factory()->NewNumberLiteral(index, pos) | 1615 ? factory()->NewNumberLiteral(index, pos) |
1622 : factory()->NewStringLiteral(*name, pos); | 1616 : factory()->NewStringLiteral(*name, pos); |
1623 } | 1617 } |
1624 | 1618 |
1625 | 1619 |
1626 template <class Traits> | 1620 template <class Traits> |
1627 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1621 typename ParserBase<Traits>::ObjectLiteralPropertyT |
1628 ParserBase<Traits>::ParsePropertyDefinition( | 1622 ParserBase<Traits>::ParsePropertyDefinition( |
1629 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1623 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
1630 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1624 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
1631 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { | 1625 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
1632 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1626 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
1633 ExpressionT value = this->EmptyExpression(); | 1627 ExpressionT value = this->EmptyExpression(); |
1634 bool is_get = false; | 1628 bool is_get = false; |
1635 bool is_set = false; | 1629 bool is_set = false; |
1636 bool name_is_static = false; | 1630 bool name_is_static = false; |
1637 bool is_generator = Check(Token::MUL); | 1631 bool is_generator = Check(Token::MUL); |
1638 | 1632 |
1639 Token::Value name_token = peek(); | 1633 Token::Value name_token = peek(); |
1640 int next_beg_pos = scanner()->peek_location().beg_pos; | 1634 int next_beg_pos = scanner()->peek_location().beg_pos; |
1641 int next_end_pos = scanner()->peek_location().end_pos; | 1635 int next_end_pos = scanner()->peek_location().end_pos; |
1642 bool is_identifier = false; | |
1643 bool is_escaped_keyword = false; | |
1644 ExpressionT name_expression = ParsePropertyName( | 1636 ExpressionT name_expression = ParsePropertyName( |
1645 name, &is_get, &is_set, &name_is_static, is_computed_name, &is_identifier, | 1637 name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
1646 &is_escaped_keyword, classifier, | |
1647 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1638 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1648 | 1639 |
1649 if (fni_ != nullptr && !*is_computed_name) { | 1640 if (fni_ != nullptr && !*is_computed_name) { |
1650 this->PushLiteralName(fni_, *name); | 1641 this->PushLiteralName(fni_, *name); |
1651 } | 1642 } |
1652 | 1643 |
1653 bool escaped_static = | |
1654 is_escaped_keyword && | |
1655 scanner()->is_literal_contextual_keyword(CStrVector("static")); | |
1656 | |
1657 if (!in_class && !is_generator) { | 1644 if (!in_class && !is_generator) { |
1658 DCHECK(!is_static); | 1645 DCHECK(!is_static); |
1659 | 1646 |
1660 if (peek() == Token::COLON) { | 1647 if (peek() == Token::COLON) { |
1661 // PropertyDefinition | 1648 // PropertyDefinition |
1662 // PropertyName ':' AssignmentExpression | 1649 // PropertyName ':' AssignmentExpression |
1663 if (!*is_computed_name) { | 1650 if (!*is_computed_name) { |
1664 checker->CheckProperty(name_token, kValueProperty, false, false, | 1651 checker->CheckProperty(name_token, kValueProperty, false, false, |
1665 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1652 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1666 } | 1653 } |
1667 Consume(Token::COLON); | 1654 Consume(Token::COLON); |
1668 value = this->ParseAssignmentExpression( | 1655 value = this->ParseAssignmentExpression( |
1669 true, kIsPossiblePatternElement, classifier, | 1656 true, kIsPossiblePatternElement, classifier, |
1670 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1657 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1671 | 1658 |
1672 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1659 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
1673 *is_computed_name); | 1660 *is_computed_name); |
1674 } | 1661 } |
1675 | 1662 |
1676 if ((is_identifier || is_escaped_keyword) && | 1663 if (Token::IsIdentifier(name_token, language_mode(), |
| 1664 this->is_generator()) && |
1677 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1665 (peek() == Token::COMMA || peek() == Token::RBRACE || |
1678 peek() == Token::ASSIGN)) { | 1666 peek() == Token::ASSIGN)) { |
1679 // PropertyDefinition | 1667 // PropertyDefinition |
1680 // IdentifierReference | 1668 // IdentifierReference |
1681 // CoverInitializedName | 1669 // CoverInitializedName |
1682 // | 1670 // |
1683 // CoverInitializedName | 1671 // CoverInitializedName |
1684 // IdentifierReference Initializer? | 1672 // IdentifierReference Initializer? |
1685 if (!Token::IsIdentifier(name_token, language_mode(), | |
1686 this->is_generator())) { | |
1687 if (!escaped_static) { | |
1688 ReportUnexpectedTokenAt(scanner()->location(), name_token); | |
1689 *ok = false; | |
1690 return this->EmptyObjectLiteralProperty(); | |
1691 } | |
1692 } | |
1693 if (classifier->duplicate_finder() != nullptr && | 1673 if (classifier->duplicate_finder() != nullptr && |
1694 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1674 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
1695 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1675 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
1696 } | 1676 } |
1697 if (name_token == Token::LET) { | 1677 if (name_token == Token::LET) { |
1698 classifier->RecordLetPatternError( | 1678 classifier->RecordLetPatternError( |
1699 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1679 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
1700 } | 1680 } |
1701 | 1681 |
1702 ExpressionT lhs = this->ExpressionFromIdentifier( | 1682 ExpressionT lhs = this->ExpressionFromIdentifier( |
(...skipping 17 matching lines...) Expand all Loading... |
1720 } else { | 1700 } else { |
1721 value = lhs; | 1701 value = lhs; |
1722 } | 1702 } |
1723 | 1703 |
1724 return factory()->NewObjectLiteralProperty( | 1704 return factory()->NewObjectLiteralProperty( |
1725 name_expression, value, ObjectLiteralProperty::COMPUTED, false, | 1705 name_expression, value, ObjectLiteralProperty::COMPUTED, false, |
1726 false); | 1706 false); |
1727 } | 1707 } |
1728 } | 1708 } |
1729 | 1709 |
1730 if (in_class && escaped_static && !is_static) { | |
1731 ReportUnexpectedTokenAt(scanner()->location(), name_token); | |
1732 *ok = false; | |
1733 return this->EmptyObjectLiteralProperty(); | |
1734 } | |
1735 | |
1736 // Method definitions are never valid in patterns. | 1710 // Method definitions are never valid in patterns. |
1737 classifier->RecordPatternError( | 1711 classifier->RecordPatternError( |
1738 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 1712 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
1739 MessageTemplate::kInvalidDestructuringTarget); | 1713 MessageTemplate::kInvalidDestructuringTarget); |
1740 | 1714 |
1741 if (is_generator || peek() == Token::LPAREN) { | 1715 if (is_generator || peek() == Token::LPAREN) { |
1742 // MethodDefinition | 1716 // MethodDefinition |
1743 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1717 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1744 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1718 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1745 if (!*is_computed_name) { | 1719 if (!*is_computed_name) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 | 1758 |
1785 if (is_get || is_set) { | 1759 if (is_get || is_set) { |
1786 // MethodDefinition (Accessors) | 1760 // MethodDefinition (Accessors) |
1787 // get PropertyName '(' ')' '{' FunctionBody '}' | 1761 // get PropertyName '(' ')' '{' FunctionBody '}' |
1788 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 1762 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
1789 *name = this->EmptyIdentifier(); | 1763 *name = this->EmptyIdentifier(); |
1790 bool dont_care = false; | 1764 bool dont_care = false; |
1791 name_token = peek(); | 1765 name_token = peek(); |
1792 | 1766 |
1793 name_expression = ParsePropertyName( | 1767 name_expression = ParsePropertyName( |
1794 name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care, | 1768 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
1795 &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1769 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1796 | 1770 |
1797 if (!*is_computed_name) { | 1771 if (!*is_computed_name) { |
1798 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 1772 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
1799 is_generator, | 1773 is_generator, |
1800 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1774 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1801 } | 1775 } |
1802 | 1776 |
1803 FunctionKind kind = FunctionKind::kAccessorFunction; | 1777 FunctionKind kind = FunctionKind::kAccessorFunction; |
1804 if (!in_class) kind = WithObjectLiteralBit(kind); | 1778 if (!in_class) kind = WithObjectLiteralBit(kind); |
1805 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 1779 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
(...skipping 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3374 return; | 3348 return; |
3375 } | 3349 } |
3376 has_seen_constructor_ = true; | 3350 has_seen_constructor_ = true; |
3377 return; | 3351 return; |
3378 } | 3352 } |
3379 } | 3353 } |
3380 } // namespace internal | 3354 } // namespace internal |
3381 } // namespace v8 | 3355 } // namespace v8 |
3382 | 3356 |
3383 #endif // V8_PARSING_PARSER_BASE_H | 3357 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |