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 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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, | 736 bool* is_identifier, bool* is_escaped_keyword, |
737 ExpressionClassifier* classifier, bool* ok); | 737 ExpressionClassifier* classifier, bool* ok); |
738 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); | 738 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
739 ObjectLiteralPropertyT ParsePropertyDefinition( | 739 ObjectLiteralPropertyT ParsePropertyDefinition( |
740 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 740 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
741 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 741 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
742 ExpressionClassifier* classifier, bool* ok); | 742 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); |
743 typename Traits::Type::ExpressionList ParseArguments( | 743 typename Traits::Type::ExpressionList ParseArguments( |
744 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | 744 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
745 bool* ok); | 745 bool* ok); |
746 | 746 |
747 enum AssignmentExpressionFlags { | 747 enum AssignmentExpressionFlags { |
748 kIsLeftHandSide = 0, | 748 kIsLeftHandSide = 0, |
749 kIsRightHandSide = 1 << 0, | 749 kIsRightHandSide = 1 << 0, |
750 kIsPatternElement = 1 << 1, | 750 kIsPatternElement = 1 << 1, |
751 kIsPossibleArrowFormals = 1 << 2 | 751 kIsPossibleArrowFormals = 1 << 2 |
752 }; | 752 }; |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1620 ? factory()->NewNumberLiteral(index, pos) | 1620 ? factory()->NewNumberLiteral(index, pos) |
1621 : factory()->NewStringLiteral(*name, pos); | 1621 : factory()->NewStringLiteral(*name, pos); |
1622 } | 1622 } |
1623 | 1623 |
1624 | 1624 |
1625 template <class Traits> | 1625 template <class Traits> |
1626 typename ParserBase<Traits>::ObjectLiteralPropertyT | 1626 typename ParserBase<Traits>::ObjectLiteralPropertyT |
1627 ParserBase<Traits>::ParsePropertyDefinition( | 1627 ParserBase<Traits>::ParsePropertyDefinition( |
1628 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 1628 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
1629 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 1629 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
1630 ExpressionClassifier* classifier, bool* ok) { | 1630 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { |
1631 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 1631 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
1632 ExpressionT value = this->EmptyExpression(); | 1632 ExpressionT value = this->EmptyExpression(); |
1633 IdentifierT name = this->EmptyIdentifier(); | |
1634 bool is_get = false; | 1633 bool is_get = false; |
1635 bool is_set = false; | 1634 bool is_set = false; |
1636 bool name_is_static = false; | 1635 bool name_is_static = false; |
1637 bool is_generator = Check(Token::MUL); | 1636 bool is_generator = Check(Token::MUL); |
1638 | 1637 |
1639 Token::Value name_token = peek(); | 1638 Token::Value name_token = peek(); |
1640 int next_beg_pos = scanner()->peek_location().beg_pos; | 1639 int next_beg_pos = scanner()->peek_location().beg_pos; |
1641 int next_end_pos = scanner()->peek_location().end_pos; | 1640 int next_end_pos = scanner()->peek_location().end_pos; |
1642 bool is_identifier = false; | 1641 bool is_identifier = false; |
1643 bool is_escaped_keyword = false; | 1642 bool is_escaped_keyword = false; |
1644 ExpressionT name_expression = ParsePropertyName( | 1643 ExpressionT name_expression = ParsePropertyName( |
1645 &name, &is_get, &is_set, &name_is_static, is_computed_name, | 1644 name, &is_get, &is_set, &name_is_static, is_computed_name, &is_identifier, |
1646 &is_identifier, &is_escaped_keyword, classifier, | 1645 &is_escaped_keyword, classifier, |
1647 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1646 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1648 | 1647 |
1649 if (fni_ != nullptr && !*is_computed_name) { | 1648 if (fni_ != nullptr && !*is_computed_name) { |
1650 this->PushLiteralName(fni_, name); | 1649 this->PushLiteralName(fni_, *name); |
1651 } | 1650 } |
1652 | 1651 |
1653 bool escaped_static = | 1652 bool escaped_static = |
1654 is_escaped_keyword && | 1653 is_escaped_keyword && |
1655 scanner()->is_literal_contextual_keyword(CStrVector("static")); | 1654 scanner()->is_literal_contextual_keyword(CStrVector("static")); |
1656 | 1655 |
1657 if (!in_class && !is_generator) { | 1656 if (!in_class && !is_generator) { |
1658 DCHECK(!is_static); | 1657 DCHECK(!is_static); |
1659 | 1658 |
1660 if (peek() == Token::COLON) { | 1659 if (peek() == Token::COLON) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1693 if (classifier->duplicate_finder() != nullptr && | 1692 if (classifier->duplicate_finder() != nullptr && |
1694 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1693 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
1695 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1694 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
1696 } | 1695 } |
1697 if (name_token == Token::LET) { | 1696 if (name_token == Token::LET) { |
1698 classifier->RecordLetPatternError( | 1697 classifier->RecordLetPatternError( |
1699 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1698 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
1700 } | 1699 } |
1701 | 1700 |
1702 ExpressionT lhs = this->ExpressionFromIdentifier( | 1701 ExpressionT lhs = this->ExpressionFromIdentifier( |
1703 name, next_beg_pos, next_end_pos, scope_, factory()); | 1702 *name, next_beg_pos, next_end_pos, scope_, factory()); |
1704 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 1703 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
1705 | 1704 |
1706 if (peek() == Token::ASSIGN) { | 1705 if (peek() == Token::ASSIGN) { |
1707 Consume(Token::ASSIGN); | 1706 Consume(Token::ASSIGN); |
1708 ExpressionClassifier rhs_classifier; | 1707 ExpressionClassifier rhs_classifier; |
1709 ExpressionT rhs = this->ParseAssignmentExpression( | 1708 ExpressionT rhs = this->ParseAssignmentExpression( |
1710 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1709 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1711 classifier->Accumulate(rhs_classifier, | 1710 classifier->Accumulate(rhs_classifier, |
1712 ExpressionClassifier::ExpressionProductions); | 1711 ExpressionClassifier::ExpressionProductions); |
1713 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 1712 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
(...skipping 28 matching lines...) Expand all Loading... |
1742 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 1741 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
1743 if (!*is_computed_name) { | 1742 if (!*is_computed_name) { |
1744 checker->CheckProperty(name_token, kMethodProperty, is_static, | 1743 checker->CheckProperty(name_token, kMethodProperty, is_static, |
1745 is_generator, | 1744 is_generator, |
1746 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1745 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1747 } | 1746 } |
1748 | 1747 |
1749 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1748 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
1750 : FunctionKind::kConciseMethod; | 1749 : FunctionKind::kConciseMethod; |
1751 | 1750 |
1752 if (in_class && !is_static && this->IsConstructor(name)) { | 1751 if (in_class && !is_static && this->IsConstructor(*name)) { |
1753 *has_seen_constructor = true; | 1752 *has_seen_constructor = true; |
1754 kind = has_extends ? FunctionKind::kSubclassConstructor | 1753 kind = has_extends ? FunctionKind::kSubclassConstructor |
1755 : FunctionKind::kBaseConstructor; | 1754 : FunctionKind::kBaseConstructor; |
1756 } | 1755 } |
1757 | 1756 |
1758 if (!in_class) kind = WithObjectLiteralBit(kind); | 1757 if (!in_class) kind = WithObjectLiteralBit(kind); |
1759 | 1758 |
1760 value = this->ParseFunctionLiteral( | 1759 value = this->ParseFunctionLiteral( |
1761 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 1760 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
1762 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 1761 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
1763 FunctionLiteral::NORMAL_ARITY, language_mode(), | 1762 FunctionLiteral::NORMAL_ARITY, language_mode(), |
1764 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1763 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1765 | 1764 |
1766 return factory()->NewObjectLiteralProperty(name_expression, value, | 1765 return factory()->NewObjectLiteralProperty(name_expression, value, |
1767 ObjectLiteralProperty::COMPUTED, | 1766 ObjectLiteralProperty::COMPUTED, |
1768 is_static, *is_computed_name); | 1767 is_static, *is_computed_name); |
1769 } | 1768 } |
1770 | 1769 |
1771 if (in_class && name_is_static && !is_static) { | 1770 if (in_class && name_is_static && !is_static) { |
1772 // ClassElement (static) | 1771 // ClassElement (static) |
1773 // 'static' MethodDefinition | 1772 // 'static' MethodDefinition |
| 1773 *name = this->EmptyIdentifier(); |
1774 return ParsePropertyDefinition(checker, true, has_extends, true, | 1774 return ParsePropertyDefinition(checker, true, has_extends, true, |
1775 is_computed_name, nullptr, classifier, ok); | 1775 is_computed_name, nullptr, classifier, name, |
| 1776 ok); |
1776 } | 1777 } |
1777 | 1778 |
1778 if (is_get || is_set) { | 1779 if (is_get || is_set) { |
1779 // MethodDefinition (Accessors) | 1780 // MethodDefinition (Accessors) |
1780 // get PropertyName '(' ')' '{' FunctionBody '}' | 1781 // get PropertyName '(' ')' '{' FunctionBody '}' |
1781 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 1782 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
1782 name = this->EmptyIdentifier(); | 1783 *name = this->EmptyIdentifier(); |
1783 bool dont_care = false; | 1784 bool dont_care = false; |
1784 name_token = peek(); | 1785 name_token = peek(); |
1785 | 1786 |
1786 name_expression = ParsePropertyName( | 1787 name_expression = ParsePropertyName( |
1787 &name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care, | 1788 name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care, |
1788 &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1789 &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1789 | 1790 |
1790 if (!*is_computed_name) { | 1791 if (!*is_computed_name) { |
1791 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 1792 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
1792 is_generator, | 1793 is_generator, |
1793 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1794 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1794 } | 1795 } |
1795 | 1796 |
1796 FunctionKind kind = FunctionKind::kAccessorFunction; | 1797 FunctionKind kind = FunctionKind::kAccessorFunction; |
1797 if (!in_class) kind = WithObjectLiteralBit(kind); | 1798 if (!in_class) kind = WithObjectLiteralBit(kind); |
1798 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 1799 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( |
1799 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 1800 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
1800 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 1801 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
1801 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, | 1802 is_get ? FunctionLiteral::GETTER_ARITY : FunctionLiteral::SETTER_ARITY, |
1802 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1803 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1803 | 1804 |
1804 // Make sure the name expression is a string since we need a Name for | 1805 // Make sure the name expression is a string since we need a Name for |
1805 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 1806 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
1806 // statically we can skip the extra runtime check. | 1807 // statically we can skip the extra runtime check. |
1807 if (!*is_computed_name) { | 1808 if (!*is_computed_name) { |
1808 name_expression = | 1809 name_expression = |
1809 factory()->NewStringLiteral(name, name_expression->position()); | 1810 factory()->NewStringLiteral(*name, name_expression->position()); |
1810 } | 1811 } |
1811 | 1812 |
1812 return factory()->NewObjectLiteralProperty( | 1813 return factory()->NewObjectLiteralProperty( |
1813 name_expression, value, | 1814 name_expression, value, |
1814 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 1815 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
1815 is_static, *is_computed_name); | 1816 is_static, *is_computed_name); |
1816 } | 1817 } |
1817 | 1818 |
1818 Token::Value next = Next(); | 1819 Token::Value next = Next(); |
1819 ReportUnexpectedToken(next); | 1820 ReportUnexpectedToken(next); |
(...skipping 18 matching lines...) Expand all Loading... |
1838 | 1839 |
1839 Expect(Token::LBRACE, CHECK_OK); | 1840 Expect(Token::LBRACE, CHECK_OK); |
1840 | 1841 |
1841 while (peek() != Token::RBRACE) { | 1842 while (peek() != Token::RBRACE) { |
1842 FuncNameInferrer::State fni_state(fni_); | 1843 FuncNameInferrer::State fni_state(fni_); |
1843 | 1844 |
1844 const bool in_class = false; | 1845 const bool in_class = false; |
1845 const bool is_static = false; | 1846 const bool is_static = false; |
1846 const bool has_extends = false; | 1847 const bool has_extends = false; |
1847 bool is_computed_name = false; | 1848 bool is_computed_name = false; |
| 1849 IdentifierT name = this->EmptyIdentifier(); |
1848 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 1850 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
1849 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, | 1851 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, |
1850 classifier, CHECK_OK); | 1852 classifier, &name, CHECK_OK); |
1851 | 1853 |
1852 if (is_computed_name) { | 1854 if (is_computed_name) { |
1853 has_computed_names = true; | 1855 has_computed_names = true; |
1854 } | 1856 } |
1855 | 1857 |
1856 // Mark top-level object literals that contain function literals and | 1858 // Mark top-level object literals that contain function literals and |
1857 // pretenure the literal so it can be added as a constant function | 1859 // pretenure the literal so it can be added as a constant function |
1858 // property. (Parser only.) | 1860 // property. (Parser only.) |
1859 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 1861 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
1860 &has_function); | 1862 &has_function); |
1861 | 1863 |
1862 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 1864 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
1863 if (!has_computed_names && this->IsBoilerplateProperty(property)) { | 1865 if (!has_computed_names && this->IsBoilerplateProperty(property)) { |
1864 number_of_boilerplate_properties++; | 1866 number_of_boilerplate_properties++; |
1865 } | 1867 } |
1866 properties->Add(property, zone()); | 1868 properties->Add(property, zone()); |
1867 | 1869 |
1868 if (peek() != Token::RBRACE) { | 1870 if (peek() != Token::RBRACE) { |
1869 // Need {} because of the CHECK_OK macro. | 1871 // Need {} because of the CHECK_OK macro. |
1870 Expect(Token::COMMA, CHECK_OK); | 1872 Expect(Token::COMMA, CHECK_OK); |
1871 } | 1873 } |
1872 | 1874 |
1873 if (fni_ != nullptr) fni_->Infer(); | 1875 if (fni_ != nullptr) fni_->Infer(); |
| 1876 |
| 1877 if (allow_harmony_function_name()) { |
| 1878 Traits::SetFunctionNameFromPropertyName(property, name); |
| 1879 } |
1874 } | 1880 } |
1875 Expect(Token::RBRACE, CHECK_OK); | 1881 Expect(Token::RBRACE, CHECK_OK); |
1876 | 1882 |
1877 // Computation of literal_index must happen before pre parse bailout. | 1883 // Computation of literal_index must happen before pre parse bailout. |
1878 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1884 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1879 | 1885 |
1880 return factory()->NewObjectLiteral(properties, | 1886 return factory()->NewObjectLiteral(properties, |
1881 literal_index, | 1887 literal_index, |
1882 number_of_boilerplate_properties, | 1888 number_of_boilerplate_properties, |
1883 has_function, | 1889 has_function, |
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3333 return; | 3339 return; |
3334 } | 3340 } |
3335 has_seen_constructor_ = true; | 3341 has_seen_constructor_ = true; |
3336 return; | 3342 return; |
3337 } | 3343 } |
3338 } | 3344 } |
3339 } // namespace internal | 3345 } // namespace internal |
3340 } // namespace v8 | 3346 } // namespace v8 |
3341 | 3347 |
3342 #endif // V8_PARSING_PARSER_BASE_H | 3348 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |