Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/parsing/parser-base.h

Issue 1563923002: [es6] Handle function names in object and class literals (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Handled review comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698