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