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/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 ZoneList<typename ExpressionClassifier::Error> reported_errors_; | 547 ZoneList<typename ExpressionClassifier::Error> reported_errors_; |
548 | 548 |
549 // If true, the next (and immediately following) function literal is | 549 // If true, the next (and immediately following) function literal is |
550 // preceded by a parenthesis. | 550 // preceded by a parenthesis. |
551 bool next_function_is_parenthesized_; | 551 bool next_function_is_parenthesized_; |
552 | 552 |
553 // The value of the parents' next_function_is_parenthesized_, as it applies | 553 // The value of the parents' next_function_is_parenthesized_, as it applies |
554 // to this function. Filled in by constructor. | 554 // to this function. Filled in by constructor. |
555 bool this_function_is_parenthesized_; | 555 bool this_function_is_parenthesized_; |
556 | 556 |
557 friend class ParserBaseTraits<Impl>; | 557 friend Impl; |
558 friend class Checkpoint; | 558 friend class Checkpoint; |
559 }; | 559 }; |
560 | 560 |
561 // This scope sets current ReturnExprContext to given value. | 561 // This scope sets current ReturnExprContext to given value. |
562 class ReturnExprScope { | 562 class ReturnExprScope { |
563 public: | 563 public: |
564 explicit ReturnExprScope(FunctionState* function_state, | 564 explicit ReturnExprScope(FunctionState* function_state, |
565 ReturnExprContext return_expr_context) | 565 ReturnExprContext return_expr_context) |
566 : function_state_(function_state), | 566 : function_state_(function_state), |
567 sav_return_expr_context_(function_state->return_expr_context()) { | 567 sav_return_expr_context_(function_state->return_expr_context()) { |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1150 ExpressionT ParseMemberExpressionContinuation( | 1150 ExpressionT ParseMemberExpressionContinuation( |
1151 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 1151 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
1152 bool* ok); | 1152 bool* ok); |
1153 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 1153 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
1154 const FormalParametersT& parameters, | 1154 const FormalParametersT& parameters, |
1155 bool is_async, | 1155 bool is_async, |
1156 const ExpressionClassifier& classifier, | 1156 const ExpressionClassifier& classifier, |
1157 bool* ok); | 1157 bool* ok); |
1158 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, | 1158 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
1159 ExpressionClassifier* classifier, bool* ok); | 1159 ExpressionClassifier* classifier, bool* ok); |
1160 void AddTemplateExpression(ExpressionT); | |
1161 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1160 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
1162 ExpressionT ParseNewTargetExpression(bool* ok); | 1161 ExpressionT ParseNewTargetExpression(bool* ok); |
1163 | 1162 |
1164 void ParseFormalParameter(FormalParametersT* parameters, | 1163 void ParseFormalParameter(FormalParametersT* parameters, |
1165 ExpressionClassifier* classifier, bool* ok); | 1164 ExpressionClassifier* classifier, bool* ok); |
1166 void ParseFormalParameterList(FormalParametersT* parameters, | 1165 void ParseFormalParameterList(FormalParametersT* parameters, |
1167 ExpressionClassifier* classifier, bool* ok); | 1166 ExpressionClassifier* classifier, bool* ok); |
1168 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1167 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
1169 bool has_rest, int formals_start_pos, | 1168 bool has_rest, int formals_start_pos, |
1170 int formals_end_pos, bool* ok); | 1169 int formals_end_pos, bool* ok); |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 case Token::SMI: | 1589 case Token::SMI: |
1591 case Token::NUMBER: | 1590 case Token::NUMBER: |
1592 BindingPatternUnexpectedToken(classifier); | 1591 BindingPatternUnexpectedToken(classifier); |
1593 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1592 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1594 | 1593 |
1595 case Token::ASYNC: | 1594 case Token::ASYNC: |
1596 if (allow_harmony_async_await() && | 1595 if (allow_harmony_async_await() && |
1597 !scanner()->HasAnyLineTerminatorAfterNext() && | 1596 !scanner()->HasAnyLineTerminatorAfterNext() && |
1598 PeekAhead() == Token::FUNCTION) { | 1597 PeekAhead() == Token::FUNCTION) { |
1599 Consume(Token::ASYNC); | 1598 Consume(Token::ASYNC); |
1600 return this->ParseAsyncFunctionExpression(CHECK_OK); | 1599 return impl()->ParseAsyncFunctionExpression(CHECK_OK); |
1601 } | 1600 } |
1602 // CoverCallExpressionAndAsyncArrowHead | 1601 // CoverCallExpressionAndAsyncArrowHead |
1603 *is_async = true; | 1602 *is_async = true; |
1604 /* falls through */ | 1603 /* falls through */ |
1605 case Token::IDENTIFIER: | 1604 case Token::IDENTIFIER: |
1606 case Token::LET: | 1605 case Token::LET: |
1607 case Token::STATIC: | 1606 case Token::STATIC: |
1608 case Token::YIELD: | 1607 case Token::YIELD: |
1609 case Token::AWAIT: | 1608 case Token::AWAIT: |
1610 case Token::ESCAPED_STRICT_RESERVED_WORD: | 1609 case Token::ESCAPED_STRICT_RESERVED_WORD: |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 Consume(Token::CLASS); | 1693 Consume(Token::CLASS); |
1695 int class_token_position = position(); | 1694 int class_token_position = position(); |
1696 IdentifierT name = this->EmptyIdentifier(); | 1695 IdentifierT name = this->EmptyIdentifier(); |
1697 bool is_strict_reserved_name = false; | 1696 bool is_strict_reserved_name = false; |
1698 Scanner::Location class_name_location = Scanner::Location::invalid(); | 1697 Scanner::Location class_name_location = Scanner::Location::invalid(); |
1699 if (peek_any_identifier()) { | 1698 if (peek_any_identifier()) { |
1700 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1699 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
1701 CHECK_OK); | 1700 CHECK_OK); |
1702 class_name_location = scanner()->location(); | 1701 class_name_location = scanner()->location(); |
1703 } | 1702 } |
1704 return this->ParseClassLiteral(classifier, name, class_name_location, | 1703 return impl()->ParseClassLiteral(classifier, name, class_name_location, |
1705 is_strict_reserved_name, | 1704 is_strict_reserved_name, |
1706 class_token_position, ok); | 1705 class_token_position, ok); |
1707 } | 1706 } |
1708 | 1707 |
1709 case Token::TEMPLATE_SPAN: | 1708 case Token::TEMPLATE_SPAN: |
1710 case Token::TEMPLATE_TAIL: | 1709 case Token::TEMPLATE_TAIL: |
1711 BindingPatternUnexpectedToken(classifier); | 1710 BindingPatternUnexpectedToken(classifier); |
1712 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 1711 return this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
1713 classifier, ok); | 1712 classifier, ok); |
1714 | 1713 |
1715 case Token::MOD: | 1714 case Token::MOD: |
1716 if (allow_natives() || extension_ != NULL) { | 1715 if (allow_natives() || extension_ != NULL) { |
1717 BindingPatternUnexpectedToken(classifier); | 1716 BindingPatternUnexpectedToken(classifier); |
1718 return this->ParseV8Intrinsic(ok); | 1717 return impl()->ParseV8Intrinsic(ok); |
1719 } | 1718 } |
1720 break; | 1719 break; |
1721 | 1720 |
1722 case Token::DO: | 1721 case Token::DO: |
1723 if (allow_harmony_do_expressions()) { | 1722 if (allow_harmony_do_expressions()) { |
1724 BindingPatternUnexpectedToken(classifier); | 1723 BindingPatternUnexpectedToken(classifier); |
1725 return Traits::ParseDoExpression(ok); | 1724 return impl()->ParseDoExpression(ok); |
1726 } | 1725 } |
1727 break; | 1726 break; |
1728 | 1727 |
1729 default: | 1728 default: |
1730 break; | 1729 break; |
1731 } | 1730 } |
1732 | 1731 |
1733 ReportUnexpectedToken(Next()); | 1732 ReportUnexpectedToken(Next()); |
1734 *ok = false; | 1733 *ok = false; |
1735 return this->EmptyExpression(); | 1734 return this->EmptyExpression(); |
1736 } | 1735 } |
1737 | 1736 |
1738 template <typename Impl> | 1737 template <typename Impl> |
1739 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1738 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
1740 bool accept_IN, bool* ok) { | 1739 bool accept_IN, bool* ok) { |
1741 ExpressionClassifier classifier(this); | 1740 ExpressionClassifier classifier(this); |
1742 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1741 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
1743 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1742 impl()->RewriteNonPattern(&classifier, CHECK_OK); |
1744 return result; | 1743 return result; |
1745 } | 1744 } |
1746 | 1745 |
1747 template <typename Impl> | 1746 template <typename Impl> |
1748 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1747 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
1749 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1748 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1750 // Expression :: | 1749 // Expression :: |
1751 // AssignmentExpression | 1750 // AssignmentExpression |
1752 // Expression ',' AssignmentExpression | 1751 // Expression ',' AssignmentExpression |
1753 | 1752 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 } | 1864 } |
1866 Expect(Token::RBRACK, CHECK_OK); | 1865 Expect(Token::RBRACK, CHECK_OK); |
1867 | 1866 |
1868 // Update the scope information before the pre-parsing bailout. | 1867 // Update the scope information before the pre-parsing bailout. |
1869 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1868 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
1870 | 1869 |
1871 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, | 1870 ExpressionT result = factory()->NewArrayLiteral(values, first_spread_index, |
1872 literal_index, pos); | 1871 literal_index, pos); |
1873 if (first_spread_index >= 0) { | 1872 if (first_spread_index >= 0) { |
1874 result = factory()->NewRewritableExpression(result); | 1873 result = factory()->NewRewritableExpression(result); |
1875 Traits::QueueNonPatternForRewriting(result, ok); | 1874 impl()->QueueNonPatternForRewriting(result, ok); |
1876 if (!*ok) { | 1875 if (!*ok) { |
1877 // If the non-pattern rewriting mechanism is used in the future for | 1876 // If the non-pattern rewriting mechanism is used in the future for |
1878 // rewriting other things than spreads, this error message will have | 1877 // rewriting other things than spreads, this error message will have |
1879 // to change. Also, this error message will never appear while pre- | 1878 // to change. Also, this error message will never appear while pre- |
1880 // parsing (this is OK, as it is an implementation limitation). | 1879 // parsing (this is OK, as it is an implementation limitation). |
1881 ReportMessage(MessageTemplate::kTooManySpreads); | 1880 ReportMessage(MessageTemplate::kTooManySpreads); |
1882 return this->EmptyExpression(); | 1881 return this->EmptyExpression(); |
1883 } | 1882 } |
1884 } | 1883 } |
1885 return result; | 1884 return result; |
(...skipping 30 matching lines...) Expand all Loading... |
1916 Consume(Token::NUMBER); | 1915 Consume(Token::NUMBER); |
1917 *name = this->GetNumberAsSymbol(scanner()); | 1916 *name = this->GetNumberAsSymbol(scanner()); |
1918 break; | 1917 break; |
1919 | 1918 |
1920 case Token::LBRACK: { | 1919 case Token::LBRACK: { |
1921 *is_computed_name = true; | 1920 *is_computed_name = true; |
1922 Consume(Token::LBRACK); | 1921 Consume(Token::LBRACK); |
1923 ExpressionClassifier computed_name_classifier(this); | 1922 ExpressionClassifier computed_name_classifier(this); |
1924 ExpressionT expression = | 1923 ExpressionT expression = |
1925 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 1924 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); |
1926 Traits::RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1925 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); |
1927 classifier->Accumulate(&computed_name_classifier, | 1926 classifier->Accumulate(&computed_name_classifier, |
1928 ExpressionClassifier::ExpressionProductions); | 1927 ExpressionClassifier::ExpressionProductions); |
1929 Expect(Token::RBRACK, CHECK_OK); | 1928 Expect(Token::RBRACK, CHECK_OK); |
1930 return expression; | 1929 return expression; |
1931 } | 1930 } |
1932 | 1931 |
1933 default: | 1932 default: |
1934 *name = ParseIdentifierName(CHECK_OK); | 1933 *name = ParseIdentifierName(CHECK_OK); |
1935 scanner()->IsGetOrSet(is_get, is_set); | 1934 scanner()->IsGetOrSet(is_get, is_set); |
1936 break; | 1935 break; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2030 ExpressionT lhs = | 2029 ExpressionT lhs = |
2031 this->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); | 2030 this->ExpressionFromIdentifier(*name, next_beg_pos, next_end_pos); |
2032 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 2031 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
2033 | 2032 |
2034 ExpressionT value; | 2033 ExpressionT value; |
2035 if (peek() == Token::ASSIGN) { | 2034 if (peek() == Token::ASSIGN) { |
2036 Consume(Token::ASSIGN); | 2035 Consume(Token::ASSIGN); |
2037 ExpressionClassifier rhs_classifier(this); | 2036 ExpressionClassifier rhs_classifier(this); |
2038 ExpressionT rhs = this->ParseAssignmentExpression( | 2037 ExpressionT rhs = this->ParseAssignmentExpression( |
2039 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2038 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2040 Traits::RewriteNonPattern(&rhs_classifier, | 2039 impl()->RewriteNonPattern(&rhs_classifier, |
2041 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2040 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2042 classifier->Accumulate(&rhs_classifier, | 2041 classifier->Accumulate(&rhs_classifier, |
2043 ExpressionClassifier::ExpressionProductions); | 2042 ExpressionClassifier::ExpressionProductions); |
2044 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2043 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2045 kNoSourcePosition); | 2044 kNoSourcePosition); |
2046 classifier->RecordObjectLiteralError( | 2045 classifier->RecordObjectLiteralError( |
2047 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2046 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2048 MessageTemplate::kInvalidCoverInitializedName); | 2047 MessageTemplate::kInvalidCoverInitializedName); |
2049 | 2048 |
2050 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); | 2049 Traits::SetFunctionNameFromIdentifierRef(rhs, lhs); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2088 : is_async ? FunctionKind::kAsyncConciseMethod | 2087 : is_async ? FunctionKind::kAsyncConciseMethod |
2089 : FunctionKind::kConciseMethod; | 2088 : FunctionKind::kConciseMethod; |
2090 | 2089 |
2091 if (in_class && !IsStaticMethod(method_kind) && | 2090 if (in_class && !IsStaticMethod(method_kind) && |
2092 this->IsConstructor(*name)) { | 2091 this->IsConstructor(*name)) { |
2093 *has_seen_constructor = true; | 2092 *has_seen_constructor = true; |
2094 kind = has_extends ? FunctionKind::kSubclassConstructor | 2093 kind = has_extends ? FunctionKind::kSubclassConstructor |
2095 : FunctionKind::kBaseConstructor; | 2094 : FunctionKind::kBaseConstructor; |
2096 } | 2095 } |
2097 | 2096 |
2098 ExpressionT value = this->ParseFunctionLiteral( | 2097 ExpressionT value = impl()->ParseFunctionLiteral( |
2099 *name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2098 *name, scanner()->location(), kSkipFunctionNameCheck, kind, |
2100 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), | 2099 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), |
2101 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2100 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2102 | 2101 |
2103 return factory()->NewObjectLiteralProperty(name_expression, value, | 2102 return factory()->NewObjectLiteralProperty(name_expression, value, |
2104 ObjectLiteralProperty::COMPUTED, | 2103 ObjectLiteralProperty::COMPUTED, |
2105 is_static, *is_computed_name); | 2104 is_static, *is_computed_name); |
2106 } | 2105 } |
2107 | 2106 |
2108 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { | 2107 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) { |
2109 // ClassElement (static) | 2108 // ClassElement (static) |
2110 // 'static' MethodDefinition | 2109 // 'static' MethodDefinition |
2111 *name = this->EmptyIdentifier(); | 2110 *name = this->EmptyIdentifier(); |
2112 ObjectLiteralPropertyT property = ParsePropertyDefinition( | 2111 ObjectLiteralPropertyT property = ParsePropertyDefinition( |
2113 checker, true, has_extends, MethodKind::kStatic, is_computed_name, | 2112 checker, true, has_extends, MethodKind::kStatic, is_computed_name, |
2114 nullptr, classifier, name, ok); | 2113 nullptr, classifier, name, ok); |
2115 Traits::RewriteNonPattern(classifier, ok); | 2114 impl()->RewriteNonPattern(classifier, ok); |
2116 return property; | 2115 return property; |
2117 } | 2116 } |
2118 | 2117 |
2119 if (is_get || is_set) { | 2118 if (is_get || is_set) { |
2120 // MethodDefinition (Accessors) | 2119 // MethodDefinition (Accessors) |
2121 // get PropertyName '(' ')' '{' FunctionBody '}' | 2120 // get PropertyName '(' ')' '{' FunctionBody '}' |
2122 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' | 2121 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' |
2123 *name = this->EmptyIdentifier(); | 2122 *name = this->EmptyIdentifier(); |
2124 bool dont_care = false; | 2123 bool dont_care = false; |
2125 name_token = peek(); | 2124 name_token = peek(); |
2126 | 2125 |
2127 name_expression = ParsePropertyName( | 2126 name_expression = ParsePropertyName( |
2128 name, &dont_care, &dont_care, is_computed_name, classifier, | 2127 name, &dont_care, &dont_care, is_computed_name, classifier, |
2129 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2128 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2130 | 2129 |
2131 if (!*is_computed_name) { | 2130 if (!*is_computed_name) { |
2132 checker->CheckProperty(name_token, kAccessorProperty, method_kind, | 2131 checker->CheckProperty(name_token, kAccessorProperty, method_kind, |
2133 classifier, | 2132 classifier, |
2134 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2133 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2135 } | 2134 } |
2136 | 2135 |
2137 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( | 2136 typename Traits::Type::FunctionLiteral value = impl()->ParseFunctionLiteral( |
2138 *name, scanner()->location(), kSkipFunctionNameCheck, | 2137 *name, scanner()->location(), kSkipFunctionNameCheck, |
2139 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, | 2138 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction, |
2140 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), | 2139 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(), |
2141 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2140 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2142 | 2141 |
2143 // Make sure the name expression is a string since we need a Name for | 2142 // Make sure the name expression is a string since we need a Name for |
2144 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this | 2143 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this |
2145 // statically we can skip the extra runtime check. | 2144 // statically we can skip the extra runtime check. |
2146 if (!*is_computed_name) { | 2145 if (!*is_computed_name) { |
2147 name_expression = | 2146 name_expression = |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2233 int unspread_sequences_count = 0; | 2232 int unspread_sequences_count = 0; |
2234 while (!done) { | 2233 while (!done) { |
2235 int start_pos = peek_position(); | 2234 int start_pos = peek_position(); |
2236 bool is_spread = Check(Token::ELLIPSIS); | 2235 bool is_spread = Check(Token::ELLIPSIS); |
2237 int expr_pos = peek_position(); | 2236 int expr_pos = peek_position(); |
2238 | 2237 |
2239 ExpressionT argument = this->ParseAssignmentExpression( | 2238 ExpressionT argument = this->ParseAssignmentExpression( |
2240 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2239 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
2241 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); | 2240 CheckNoTailCallExpressions(classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
2242 if (!maybe_arrow) { | 2241 if (!maybe_arrow) { |
2243 Traits::RewriteNonPattern(classifier, | 2242 impl()->RewriteNonPattern(classifier, |
2244 CHECK_OK_CUSTOM(NullExpressionList)); | 2243 CHECK_OK_CUSTOM(NullExpressionList)); |
2245 } | 2244 } |
2246 if (is_spread) { | 2245 if (is_spread) { |
2247 if (!spread_arg.IsValid()) { | 2246 if (!spread_arg.IsValid()) { |
2248 spread_arg.beg_pos = start_pos; | 2247 spread_arg.beg_pos = start_pos; |
2249 spread_arg.end_pos = peek_position(); | 2248 spread_arg.end_pos = peek_position(); |
2250 } | 2249 } |
2251 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 2250 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
2252 } | 2251 } |
2253 result->Add(argument, zone_); | 2252 result->Add(argument, zone_); |
(...skipping 24 matching lines...) Expand all Loading... |
2278 Scanner::Location location = scanner_->location(); | 2277 Scanner::Location location = scanner_->location(); |
2279 if (Token::RPAREN != Next()) { | 2278 if (Token::RPAREN != Next()) { |
2280 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2279 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
2281 *ok = false; | 2280 *ok = false; |
2282 return this->NullExpressionList(); | 2281 return this->NullExpressionList(); |
2283 } | 2282 } |
2284 *first_spread_arg_loc = spread_arg; | 2283 *first_spread_arg_loc = spread_arg; |
2285 | 2284 |
2286 if (!maybe_arrow || peek() != Token::ARROW) { | 2285 if (!maybe_arrow || peek() != Token::ARROW) { |
2287 if (maybe_arrow) { | 2286 if (maybe_arrow) { |
2288 Traits::RewriteNonPattern(classifier, | 2287 impl()->RewriteNonPattern(classifier, |
2289 CHECK_OK_CUSTOM(NullExpressionList)); | 2288 CHECK_OK_CUSTOM(NullExpressionList)); |
2290 } | 2289 } |
2291 if (spread_arg.IsValid()) { | 2290 if (spread_arg.IsValid()) { |
2292 // Unspread parameter sequences are translated into array literals in the | 2291 // Unspread parameter sequences are translated into array literals in the |
2293 // parser. Ensure that the number of materialized literals matches between | 2292 // parser. Ensure that the number of materialized literals matches between |
2294 // the parser and preparser | 2293 // the parser and preparser |
2295 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2294 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2296 } | 2295 } |
2297 } | 2296 } |
2298 | 2297 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 MessageTemplate::kUnexpectedToken, | 2450 MessageTemplate::kUnexpectedToken, |
2452 Token::String(op)); | 2451 Token::String(op)); |
2453 } | 2452 } |
2454 int pos = position(); | 2453 int pos = position(); |
2455 | 2454 |
2456 ExpressionClassifier rhs_classifier(this); | 2455 ExpressionClassifier rhs_classifier(this); |
2457 | 2456 |
2458 ExpressionT right = | 2457 ExpressionT right = |
2459 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2458 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
2460 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); | 2459 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); |
2461 Traits::RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2460 impl()->RewriteNonPattern(&rhs_classifier, CHECK_OK); |
2462 classifier->Accumulate( | 2461 classifier->Accumulate( |
2463 &rhs_classifier, | 2462 &rhs_classifier, |
2464 ExpressionClassifier::ExpressionProductions | | 2463 ExpressionClassifier::ExpressionProductions | |
2465 ExpressionClassifier::ObjectLiteralProduction | | 2464 ExpressionClassifier::ObjectLiteralProduction | |
2466 ExpressionClassifier::AsyncArrowFormalParametersProduction); | 2465 ExpressionClassifier::AsyncArrowFormalParametersProduction); |
2467 | 2466 |
2468 // TODO(1231235): We try to estimate the set of properties set by | 2467 // TODO(1231235): We try to estimate the set of properties set by |
2469 // constructors. We define a new property whenever there is an | 2468 // constructors. We define a new property whenever there is an |
2470 // assignment to a property of 'this'. We should probably only add | 2469 // assignment to a property of 'this'. We should probably only add |
2471 // properties if we haven't seen them before. Otherwise we'll | 2470 // properties if we haven't seen them before. Otherwise we'll |
(...skipping 15 matching lines...) Expand all Loading... |
2487 fni_->RemoveLastFunction(); | 2486 fni_->RemoveLastFunction(); |
2488 } | 2487 } |
2489 } | 2488 } |
2490 | 2489 |
2491 if (op == Token::ASSIGN) { | 2490 if (op == Token::ASSIGN) { |
2492 Traits::SetFunctionNameFromIdentifierRef(right, expression); | 2491 Traits::SetFunctionNameFromIdentifierRef(right, expression); |
2493 } | 2492 } |
2494 | 2493 |
2495 if (op == Token::ASSIGN_EXP) { | 2494 if (op == Token::ASSIGN_EXP) { |
2496 DCHECK(!is_destructuring_assignment); | 2495 DCHECK(!is_destructuring_assignment); |
2497 return Traits::RewriteAssignExponentiation(expression, right, pos); | 2496 return impl()->RewriteAssignExponentiation(expression, right, pos); |
2498 } | 2497 } |
2499 | 2498 |
2500 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); | 2499 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); |
2501 | 2500 |
2502 if (is_destructuring_assignment) { | 2501 if (is_destructuring_assignment) { |
2503 result = factory()->NewRewritableExpression(result); | 2502 result = factory()->NewRewritableExpression(result); |
2504 Traits::QueueDestructuringAssignmentForRewriting(result); | 2503 impl()->QueueDestructuringAssignmentForRewriting(result); |
2505 } | 2504 } |
2506 | 2505 |
2507 return result; | 2506 return result; |
2508 } | 2507 } |
2509 | 2508 |
2510 template <typename Impl> | 2509 template <typename Impl> |
2511 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( | 2510 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
2512 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2511 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2513 // YieldExpression :: | 2512 // YieldExpression :: |
2514 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2513 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
(...skipping 19 matching lines...) Expand all Loading... |
2534 case Token::COLON: | 2533 case Token::COLON: |
2535 case Token::COMMA: | 2534 case Token::COMMA: |
2536 // The above set of tokens is the complete set of tokens that can appear | 2535 // The above set of tokens is the complete set of tokens that can appear |
2537 // after an AssignmentExpression, and none of them can start an | 2536 // after an AssignmentExpression, and none of them can start an |
2538 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2537 // AssignmentExpression. This allows us to avoid looking for an RHS for |
2539 // a regular yield, given only one look-ahead token. | 2538 // a regular yield, given only one look-ahead token. |
2540 if (!delegating) break; | 2539 if (!delegating) break; |
2541 // Delegating yields require an RHS; fall through. | 2540 // Delegating yields require an RHS; fall through. |
2542 default: | 2541 default: |
2543 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2542 expression = ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2544 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2543 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2545 break; | 2544 break; |
2546 } | 2545 } |
2547 } | 2546 } |
2548 | 2547 |
2549 if (delegating) { | 2548 if (delegating) { |
2550 return Traits::RewriteYieldStar(generator_object, expression, pos); | 2549 return impl()->RewriteYieldStar(generator_object, expression, pos); |
2551 } | 2550 } |
2552 | 2551 |
2553 expression = Traits::BuildIteratorResult(expression, false); | 2552 expression = Traits::BuildIteratorResult(expression, false); |
2554 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2553 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2555 // TODO(verwaest): Come up with a better solution. | 2554 // TODO(verwaest): Come up with a better solution. |
2556 typename Traits::Type::YieldExpression yield = factory()->NewYield( | 2555 typename Traits::Type::YieldExpression yield = factory()->NewYield( |
2557 generator_object, expression, pos, Yield::kOnExceptionThrow); | 2556 generator_object, expression, pos, Yield::kOnExceptionThrow); |
2558 return yield; | 2557 return yield; |
2559 } | 2558 } |
2560 | 2559 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 // ConditionalExpression :: | 2628 // ConditionalExpression :: |
2630 // LogicalOrExpression | 2629 // LogicalOrExpression |
2631 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2630 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2632 | 2631 |
2633 int pos = peek_position(); | 2632 int pos = peek_position(); |
2634 // We start using the binary expression parser for prec >= 4 only! | 2633 // We start using the binary expression parser for prec >= 4 only! |
2635 ExpressionT expression = | 2634 ExpressionT expression = |
2636 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 2635 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
2637 if (peek() != Token::CONDITIONAL) return expression; | 2636 if (peek() != Token::CONDITIONAL) return expression; |
2638 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2637 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2639 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2638 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2640 BindingPatternUnexpectedToken(classifier); | 2639 BindingPatternUnexpectedToken(classifier); |
2641 ArrowFormalParametersUnexpectedToken(classifier); | 2640 ArrowFormalParametersUnexpectedToken(classifier); |
2642 Consume(Token::CONDITIONAL); | 2641 Consume(Token::CONDITIONAL); |
2643 // In parsing the first assignment expression in conditional | 2642 // In parsing the first assignment expression in conditional |
2644 // expressions we always accept the 'in' keyword; see ECMA-262, | 2643 // expressions we always accept the 'in' keyword; see ECMA-262, |
2645 // section 11.12, page 58. | 2644 // section 11.12, page 58. |
2646 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2645 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
2647 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2646 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2648 Expect(Token::COLON, CHECK_OK); | 2647 Expect(Token::COLON, CHECK_OK); |
2649 ExpressionT right = | 2648 ExpressionT right = |
2650 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2649 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2651 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2650 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2652 return factory()->NewConditional(expression, left, right, pos); | 2651 return factory()->NewConditional(expression, left, right, pos); |
2653 } | 2652 } |
2654 | 2653 |
2655 | 2654 |
2656 // Precedence >= 4 | 2655 // Precedence >= 4 |
2657 template <typename Impl> | 2656 template <typename Impl> |
2658 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( | 2657 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( |
2659 int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 2658 int prec, bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2660 DCHECK(prec >= 4); | 2659 DCHECK(prec >= 4); |
2661 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); | 2660 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2662 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2661 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2663 // prec1 >= 4 | 2662 // prec1 >= 4 |
2664 while (Precedence(peek(), accept_IN) == prec1) { | 2663 while (Precedence(peek(), accept_IN) == prec1) { |
2665 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2664 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2666 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2665 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2667 BindingPatternUnexpectedToken(classifier); | 2666 BindingPatternUnexpectedToken(classifier); |
2668 ArrowFormalParametersUnexpectedToken(classifier); | 2667 ArrowFormalParametersUnexpectedToken(classifier); |
2669 Token::Value op = Next(); | 2668 Token::Value op = Next(); |
2670 int pos = position(); | 2669 int pos = position(); |
2671 | 2670 |
2672 const bool is_right_associative = op == Token::EXP; | 2671 const bool is_right_associative = op == Token::EXP; |
2673 const int next_prec = is_right_associative ? prec1 : prec1 + 1; | 2672 const int next_prec = is_right_associative ? prec1 : prec1 + 1; |
2674 ExpressionT y = | 2673 ExpressionT y = |
2675 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); | 2674 ParseBinaryExpression(next_prec, accept_IN, classifier, CHECK_OK); |
2676 if (op != Token::OR && op != Token::AND) { | 2675 if (op != Token::OR && op != Token::AND) { |
2677 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2676 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2678 } | 2677 } |
2679 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2678 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2680 | 2679 |
2681 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2680 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2682 factory())) { | 2681 factory())) { |
2683 continue; | 2682 continue; |
2684 } | 2683 } |
2685 | 2684 |
2686 // For now we distinguish between comparisons and other binary | 2685 // For now we distinguish between comparisons and other binary |
2687 // operations. (We could combine the two and get rid of this | 2686 // operations. (We could combine the two and get rid of this |
2688 // code and AST node eventually.) | 2687 // code and AST node eventually.) |
2689 if (Token::IsCompareOp(op)) { | 2688 if (Token::IsCompareOp(op)) { |
2690 // We have a comparison. | 2689 // We have a comparison. |
2691 Token::Value cmp = op; | 2690 Token::Value cmp = op; |
2692 switch (op) { | 2691 switch (op) { |
2693 case Token::NE: cmp = Token::EQ; break; | 2692 case Token::NE: cmp = Token::EQ; break; |
2694 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 2693 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
2695 default: break; | 2694 default: break; |
2696 } | 2695 } |
2697 x = factory()->NewCompareOperation(cmp, x, y, pos); | 2696 x = factory()->NewCompareOperation(cmp, x, y, pos); |
2698 if (cmp != op) { | 2697 if (cmp != op) { |
2699 // The comparison was negated - add a NOT. | 2698 // The comparison was negated - add a NOT. |
2700 x = factory()->NewUnaryOperation(Token::NOT, x, pos); | 2699 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
2701 } | 2700 } |
2702 } else if (op == Token::EXP) { | 2701 } else if (op == Token::EXP) { |
2703 x = Traits::RewriteExponentiation(x, y, pos); | 2702 x = impl()->RewriteExponentiation(x, y, pos); |
2704 } else { | 2703 } else { |
2705 // We have a "normal" binary operation. | 2704 // We have a "normal" binary operation. |
2706 x = factory()->NewBinaryOperation(op, x, y, pos); | 2705 x = factory()->NewBinaryOperation(op, x, y, pos); |
2707 } | 2706 } |
2708 } | 2707 } |
2709 } | 2708 } |
2710 return x; | 2709 return x; |
2711 } | 2710 } |
2712 | 2711 |
2713 template <typename Impl> | 2712 template <typename Impl> |
(...skipping 14 matching lines...) Expand all Loading... |
2728 | 2727 |
2729 Token::Value op = peek(); | 2728 Token::Value op = peek(); |
2730 if (Token::IsUnaryOp(op)) { | 2729 if (Token::IsUnaryOp(op)) { |
2731 BindingPatternUnexpectedToken(classifier); | 2730 BindingPatternUnexpectedToken(classifier); |
2732 ArrowFormalParametersUnexpectedToken(classifier); | 2731 ArrowFormalParametersUnexpectedToken(classifier); |
2733 | 2732 |
2734 op = Next(); | 2733 op = Next(); |
2735 int pos = position(); | 2734 int pos = position(); |
2736 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); | 2735 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2737 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2736 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2738 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2737 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2739 | 2738 |
2740 if (op == Token::DELETE && is_strict(language_mode())) { | 2739 if (op == Token::DELETE && is_strict(language_mode())) { |
2741 if (this->IsIdentifier(expression)) { | 2740 if (this->IsIdentifier(expression)) { |
2742 // "delete identifier" is a syntax error in strict mode. | 2741 // "delete identifier" is a syntax error in strict mode. |
2743 ReportMessage(MessageTemplate::kStrictDelete); | 2742 ReportMessage(MessageTemplate::kStrictDelete); |
2744 *ok = false; | 2743 *ok = false; |
2745 return this->EmptyExpression(); | 2744 return this->EmptyExpression(); |
2746 } | 2745 } |
2747 } | 2746 } |
2748 | 2747 |
2749 if (peek() == Token::EXP) { | 2748 if (peek() == Token::EXP) { |
2750 ReportUnexpectedToken(Next()); | 2749 ReportUnexpectedToken(Next()); |
2751 *ok = false; | 2750 *ok = false; |
2752 return this->EmptyExpression(); | 2751 return this->EmptyExpression(); |
2753 } | 2752 } |
2754 | 2753 |
2755 // Allow Traits do rewrite the expression. | 2754 // Allow Traits do rewrite the expression. |
2756 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2755 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2757 } else if (Token::IsCountOp(op)) { | 2756 } else if (Token::IsCountOp(op)) { |
2758 BindingPatternUnexpectedToken(classifier); | 2757 BindingPatternUnexpectedToken(classifier); |
2759 ArrowFormalParametersUnexpectedToken(classifier); | 2758 ArrowFormalParametersUnexpectedToken(classifier); |
2760 op = Next(); | 2759 op = Next(); |
2761 int beg_pos = peek_position(); | 2760 int beg_pos = peek_position(); |
2762 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); | 2761 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
2763 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2762 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2764 expression = this->CheckAndRewriteReferenceExpression( | 2763 expression = this->CheckAndRewriteReferenceExpression( |
2765 expression, beg_pos, scanner()->location().end_pos, | 2764 expression, beg_pos, scanner()->location().end_pos, |
2766 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); | 2765 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); |
2767 this->MarkExpressionAsAssigned(expression); | 2766 this->MarkExpressionAsAssigned(expression); |
2768 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2767 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2769 | 2768 |
2770 return factory()->NewCountOperation(op, | 2769 return factory()->NewCountOperation(op, |
2771 true /* prefix */, | 2770 true /* prefix */, |
2772 expression, | 2771 expression, |
2773 position()); | 2772 position()); |
2774 | 2773 |
2775 } else if (is_async_function() && peek() == Token::AWAIT) { | 2774 } else if (is_async_function() && peek() == Token::AWAIT) { |
2776 classifier->RecordFormalParameterInitializerError( | 2775 classifier->RecordFormalParameterInitializerError( |
2777 scanner()->peek_location(), | 2776 scanner()->peek_location(), |
2778 MessageTemplate::kAwaitExpressionFormalParameter); | 2777 MessageTemplate::kAwaitExpressionFormalParameter); |
2779 | 2778 |
2780 int await_pos = peek_position(); | 2779 int await_pos = peek_position(); |
2781 Consume(Token::AWAIT); | 2780 Consume(Token::AWAIT); |
2782 | 2781 |
2783 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | 2782 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); |
2784 | 2783 |
2785 return Traits::RewriteAwaitExpression(value, await_pos); | 2784 return impl()->RewriteAwaitExpression(value, await_pos); |
2786 } else { | 2785 } else { |
2787 return this->ParsePostfixExpression(classifier, ok); | 2786 return this->ParsePostfixExpression(classifier, ok); |
2788 } | 2787 } |
2789 } | 2788 } |
2790 | 2789 |
2791 template <typename Impl> | 2790 template <typename Impl> |
2792 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( | 2791 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( |
2793 ExpressionClassifier* classifier, bool* ok) { | 2792 ExpressionClassifier* classifier, bool* ok) { |
2794 // PostfixExpression :: | 2793 // PostfixExpression :: |
2795 // LeftHandSideExpression ('++' | '--')? | 2794 // LeftHandSideExpression ('++' | '--')? |
2796 | 2795 |
2797 int lhs_beg_pos = peek_position(); | 2796 int lhs_beg_pos = peek_position(); |
2798 ExpressionT expression = | 2797 ExpressionT expression = |
2799 this->ParseLeftHandSideExpression(classifier, CHECK_OK); | 2798 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
2800 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2799 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2801 Token::IsCountOp(peek())) { | 2800 Token::IsCountOp(peek())) { |
2802 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2801 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2803 BindingPatternUnexpectedToken(classifier); | 2802 BindingPatternUnexpectedToken(classifier); |
2804 ArrowFormalParametersUnexpectedToken(classifier); | 2803 ArrowFormalParametersUnexpectedToken(classifier); |
2805 | 2804 |
2806 expression = this->CheckAndRewriteReferenceExpression( | 2805 expression = this->CheckAndRewriteReferenceExpression( |
2807 expression, lhs_beg_pos, scanner()->location().end_pos, | 2806 expression, lhs_beg_pos, scanner()->location().end_pos, |
2808 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); | 2807 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); |
2809 expression = this->MarkExpressionAsAssigned(expression); | 2808 expression = this->MarkExpressionAsAssigned(expression); |
2810 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2809 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2811 | 2810 |
2812 Token::Value next = Next(); | 2811 Token::Value next = Next(); |
2813 expression = | 2812 expression = |
2814 factory()->NewCountOperation(next, | 2813 factory()->NewCountOperation(next, |
2815 false /* postfix */, | 2814 false /* postfix */, |
2816 expression, | 2815 expression, |
2817 position()); | 2816 position()); |
2818 } | 2817 } |
2819 return expression; | 2818 return expression; |
2820 } | 2819 } |
(...skipping 10 matching lines...) Expand all Loading... |
2831 } | 2830 } |
2832 | 2831 |
2833 bool is_async = false; | 2832 bool is_async = false; |
2834 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( | 2833 ExpressionT result = this->ParseMemberWithNewPrefixesExpression( |
2835 classifier, &is_async, CHECK_OK); | 2834 classifier, &is_async, CHECK_OK); |
2836 | 2835 |
2837 while (true) { | 2836 while (true) { |
2838 switch (peek()) { | 2837 switch (peek()) { |
2839 case Token::LBRACK: { | 2838 case Token::LBRACK: { |
2840 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2839 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2841 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2840 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2842 BindingPatternUnexpectedToken(classifier); | 2841 BindingPatternUnexpectedToken(classifier); |
2843 ArrowFormalParametersUnexpectedToken(classifier); | 2842 ArrowFormalParametersUnexpectedToken(classifier); |
2844 Consume(Token::LBRACK); | 2843 Consume(Token::LBRACK); |
2845 int pos = position(); | 2844 int pos = position(); |
2846 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); | 2845 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
2847 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2846 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2848 result = factory()->NewProperty(result, index, pos); | 2847 result = factory()->NewProperty(result, index, pos); |
2849 Expect(Token::RBRACK, CHECK_OK); | 2848 Expect(Token::RBRACK, CHECK_OK); |
2850 break; | 2849 break; |
2851 } | 2850 } |
2852 | 2851 |
2853 case Token::LPAREN: { | 2852 case Token::LPAREN: { |
2854 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2853 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2855 int pos; | 2854 int pos; |
2856 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2855 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2857 BindingPatternUnexpectedToken(classifier); | 2856 BindingPatternUnexpectedToken(classifier); |
2858 if (scanner()->current_token() == Token::IDENTIFIER || | 2857 if (scanner()->current_token() == Token::IDENTIFIER || |
2859 scanner()->current_token() == Token::SUPER || | 2858 scanner()->current_token() == Token::SUPER || |
2860 scanner()->current_token() == Token::ASYNC) { | 2859 scanner()->current_token() == Token::ASYNC) { |
2861 // For call of an identifier we want to report position of | 2860 // For call of an identifier we want to report position of |
2862 // the identifier as position of the call in the stack trace. | 2861 // the identifier as position of the call in the stack trace. |
2863 pos = position(); | 2862 pos = position(); |
2864 } else { | 2863 } else { |
2865 // For other kinds of calls we record position of the parenthesis as | 2864 // For other kinds of calls we record position of the parenthesis as |
2866 // position of the call. Note that this is extremely important for | 2865 // position of the call. Note that this is extremely important for |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2912 // The calls that need special treatment are the | 2911 // The calls that need special treatment are the |
2913 // direct eval calls. These calls are all of the form eval(...), with | 2912 // direct eval calls. These calls are all of the form eval(...), with |
2914 // no explicit receiver. | 2913 // no explicit receiver. |
2915 // These calls are marked as potentially direct eval calls. Whether | 2914 // These calls are marked as potentially direct eval calls. Whether |
2916 // they are actually direct calls to eval is determined at run time. | 2915 // they are actually direct calls to eval is determined at run time. |
2917 Call::PossiblyEval is_possibly_eval = | 2916 Call::PossiblyEval is_possibly_eval = |
2918 CheckPossibleEvalCall(result, scope()); | 2917 CheckPossibleEvalCall(result, scope()); |
2919 | 2918 |
2920 bool is_super_call = result->IsSuperCallReference(); | 2919 bool is_super_call = result->IsSuperCallReference(); |
2921 if (spread_pos.IsValid()) { | 2920 if (spread_pos.IsValid()) { |
2922 args = Traits::PrepareSpreadArguments(args); | 2921 args = impl()->PrepareSpreadArguments(args); |
2923 result = Traits::SpreadCall(result, args, pos); | 2922 result = impl()->SpreadCall(result, args, pos); |
2924 } else { | 2923 } else { |
2925 result = factory()->NewCall(result, args, pos, is_possibly_eval); | 2924 result = factory()->NewCall(result, args, pos, is_possibly_eval); |
2926 } | 2925 } |
2927 | 2926 |
2928 // Explicit calls to the super constructor using super() perform an | 2927 // Explicit calls to the super constructor using super() perform an |
2929 // implicit binding assignment to the 'this' variable. | 2928 // implicit binding assignment to the 'this' variable. |
2930 if (is_super_call) { | 2929 if (is_super_call) { |
2931 ExpressionT this_expr = this->ThisExpression(pos); | 2930 ExpressionT this_expr = this->ThisExpression(pos); |
2932 result = | 2931 result = |
2933 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 2932 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
2934 } | 2933 } |
2935 | 2934 |
2936 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2935 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2937 break; | 2936 break; |
2938 } | 2937 } |
2939 | 2938 |
2940 case Token::PERIOD: { | 2939 case Token::PERIOD: { |
2941 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2940 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2942 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2941 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2943 BindingPatternUnexpectedToken(classifier); | 2942 BindingPatternUnexpectedToken(classifier); |
2944 ArrowFormalParametersUnexpectedToken(classifier); | 2943 ArrowFormalParametersUnexpectedToken(classifier); |
2945 Consume(Token::PERIOD); | 2944 Consume(Token::PERIOD); |
2946 int pos = position(); | 2945 int pos = position(); |
2947 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2946 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2948 result = factory()->NewProperty( | 2947 result = factory()->NewProperty( |
2949 result, factory()->NewStringLiteral(name, pos), pos); | 2948 result, factory()->NewStringLiteral(name, pos), pos); |
2950 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2949 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2951 break; | 2950 break; |
2952 } | 2951 } |
2953 | 2952 |
2954 case Token::TEMPLATE_SPAN: | 2953 case Token::TEMPLATE_SPAN: |
2955 case Token::TEMPLATE_TAIL: { | 2954 case Token::TEMPLATE_TAIL: { |
2956 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2955 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2957 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2956 impl()->RewriteNonPattern(classifier, CHECK_OK); |
2958 BindingPatternUnexpectedToken(classifier); | 2957 BindingPatternUnexpectedToken(classifier); |
2959 ArrowFormalParametersUnexpectedToken(classifier); | 2958 ArrowFormalParametersUnexpectedToken(classifier); |
2960 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); | 2959 result = ParseTemplateLiteral(result, position(), classifier, CHECK_OK); |
2961 break; | 2960 break; |
2962 } | 2961 } |
2963 | 2962 |
2964 default: | 2963 default: |
2965 return result; | 2964 return result; |
2966 } | 2965 } |
2967 } | 2966 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2999 ExpressionT result; | 2998 ExpressionT result; |
3000 if (peek() == Token::SUPER) { | 2999 if (peek() == Token::SUPER) { |
3001 const bool is_new = true; | 3000 const bool is_new = true; |
3002 result = ParseSuperExpression(is_new, CHECK_OK); | 3001 result = ParseSuperExpression(is_new, CHECK_OK); |
3003 } else if (peek() == Token::PERIOD) { | 3002 } else if (peek() == Token::PERIOD) { |
3004 return ParseNewTargetExpression(CHECK_OK); | 3003 return ParseNewTargetExpression(CHECK_OK); |
3005 } else { | 3004 } else { |
3006 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async, | 3005 result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async, |
3007 CHECK_OK); | 3006 CHECK_OK); |
3008 } | 3007 } |
3009 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3008 impl()->RewriteNonPattern(classifier, CHECK_OK); |
3010 if (peek() == Token::LPAREN) { | 3009 if (peek() == Token::LPAREN) { |
3011 // NewExpression with arguments. | 3010 // NewExpression with arguments. |
3012 Scanner::Location spread_pos; | 3011 Scanner::Location spread_pos; |
3013 typename Traits::Type::ExpressionList args = | 3012 typename Traits::Type::ExpressionList args = |
3014 this->ParseArguments(&spread_pos, classifier, CHECK_OK); | 3013 this->ParseArguments(&spread_pos, classifier, CHECK_OK); |
3015 | 3014 |
3016 if (spread_pos.IsValid()) { | 3015 if (spread_pos.IsValid()) { |
3017 args = Traits::PrepareSpreadArguments(args); | 3016 args = impl()->PrepareSpreadArguments(args); |
3018 result = Traits::SpreadCallNew(result, args, new_pos); | 3017 result = impl()->SpreadCallNew(result, args, new_pos); |
3019 } else { | 3018 } else { |
3020 result = factory()->NewCallNew(result, args, new_pos); | 3019 result = factory()->NewCallNew(result, args, new_pos); |
3021 } | 3020 } |
3022 // The expression can still continue with . or [ after the arguments. | 3021 // The expression can still continue with . or [ after the arguments. |
3023 result = this->ParseMemberExpressionContinuation(result, is_async, | 3022 result = this->ParseMemberExpressionContinuation(result, is_async, |
3024 classifier, CHECK_OK); | 3023 classifier, CHECK_OK); |
3025 return result; | 3024 return result; |
3026 } | 3025 } |
3027 // NewExpression without arguments. | 3026 // NewExpression without arguments. |
3028 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 3027 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3075 bool is_strict_reserved_name = false; | 3074 bool is_strict_reserved_name = false; |
3076 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3075 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3077 FunctionLiteral::FunctionType function_type = | 3076 FunctionLiteral::FunctionType function_type = |
3078 FunctionLiteral::kAnonymousExpression; | 3077 FunctionLiteral::kAnonymousExpression; |
3079 if (peek_any_identifier()) { | 3078 if (peek_any_identifier()) { |
3080 name = ParseIdentifierOrStrictReservedWord( | 3079 name = ParseIdentifierOrStrictReservedWord( |
3081 function_kind, &is_strict_reserved_name, CHECK_OK); | 3080 function_kind, &is_strict_reserved_name, CHECK_OK); |
3082 function_name_location = scanner()->location(); | 3081 function_name_location = scanner()->location(); |
3083 function_type = FunctionLiteral::kNamedExpression; | 3082 function_type = FunctionLiteral::kNamedExpression; |
3084 } | 3083 } |
3085 result = this->ParseFunctionLiteral( | 3084 result = impl()->ParseFunctionLiteral( |
3086 name, function_name_location, | 3085 name, function_name_location, |
3087 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3086 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
3088 : kFunctionNameValidityUnknown, | 3087 : kFunctionNameValidityUnknown, |
3089 function_kind, function_token_position, function_type, language_mode(), | 3088 function_kind, function_token_position, function_type, language_mode(), |
3090 CHECK_OK); | 3089 CHECK_OK); |
3091 } else if (peek() == Token::SUPER) { | 3090 } else if (peek() == Token::SUPER) { |
3092 const bool is_new = false; | 3091 const bool is_new = false; |
3093 result = ParseSuperExpression(is_new, CHECK_OK); | 3092 result = ParseSuperExpression(is_new, CHECK_OK); |
3094 } else { | 3093 } else { |
3095 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); | 3094 result = ParsePrimaryExpression(classifier, is_async, CHECK_OK); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3162 typename ParserBase<Impl>::ExpressionT | 3161 typename ParserBase<Impl>::ExpressionT |
3163 ParserBase<Impl>::ParseMemberExpressionContinuation( | 3162 ParserBase<Impl>::ParseMemberExpressionContinuation( |
3164 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, | 3163 ExpressionT expression, bool* is_async, ExpressionClassifier* classifier, |
3165 bool* ok) { | 3164 bool* ok) { |
3166 // Parses this part of MemberExpression: | 3165 // Parses this part of MemberExpression: |
3167 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3166 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
3168 while (true) { | 3167 while (true) { |
3169 switch (peek()) { | 3168 switch (peek()) { |
3170 case Token::LBRACK: { | 3169 case Token::LBRACK: { |
3171 *is_async = false; | 3170 *is_async = false; |
3172 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3171 impl()->RewriteNonPattern(classifier, CHECK_OK); |
3173 BindingPatternUnexpectedToken(classifier); | 3172 BindingPatternUnexpectedToken(classifier); |
3174 ArrowFormalParametersUnexpectedToken(classifier); | 3173 ArrowFormalParametersUnexpectedToken(classifier); |
3175 | 3174 |
3176 Consume(Token::LBRACK); | 3175 Consume(Token::LBRACK); |
3177 int pos = position(); | 3176 int pos = position(); |
3178 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3177 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
3179 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3178 impl()->RewriteNonPattern(classifier, CHECK_OK); |
3180 expression = factory()->NewProperty(expression, index, pos); | 3179 expression = factory()->NewProperty(expression, index, pos); |
3181 if (fni_ != NULL) { | 3180 if (fni_ != NULL) { |
3182 this->PushPropertyName(fni_, index); | 3181 this->PushPropertyName(fni_, index); |
3183 } | 3182 } |
3184 Expect(Token::RBRACK, CHECK_OK); | 3183 Expect(Token::RBRACK, CHECK_OK); |
3185 break; | 3184 break; |
3186 } | 3185 } |
3187 case Token::PERIOD: { | 3186 case Token::PERIOD: { |
3188 *is_async = false; | 3187 *is_async = false; |
3189 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3188 impl()->RewriteNonPattern(classifier, CHECK_OK); |
3190 BindingPatternUnexpectedToken(classifier); | 3189 BindingPatternUnexpectedToken(classifier); |
3191 ArrowFormalParametersUnexpectedToken(classifier); | 3190 ArrowFormalParametersUnexpectedToken(classifier); |
3192 | 3191 |
3193 Consume(Token::PERIOD); | 3192 Consume(Token::PERIOD); |
3194 int pos = position(); | 3193 int pos = position(); |
3195 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3194 IdentifierT name = ParseIdentifierName(CHECK_OK); |
3196 expression = factory()->NewProperty( | 3195 expression = factory()->NewProperty( |
3197 expression, factory()->NewStringLiteral(name, pos), pos); | 3196 expression, factory()->NewStringLiteral(name, pos), pos); |
3198 if (fni_ != NULL) { | 3197 if (fni_ != NULL) { |
3199 this->PushLiteralName(fni_, name); | 3198 this->PushLiteralName(fni_, name); |
3200 } | 3199 } |
3201 break; | 3200 break; |
3202 } | 3201 } |
3203 case Token::TEMPLATE_SPAN: | 3202 case Token::TEMPLATE_SPAN: |
3204 case Token::TEMPLATE_TAIL: { | 3203 case Token::TEMPLATE_TAIL: { |
3205 *is_async = false; | 3204 *is_async = false; |
3206 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3205 impl()->RewriteNonPattern(classifier, CHECK_OK); |
3207 BindingPatternUnexpectedToken(classifier); | 3206 BindingPatternUnexpectedToken(classifier); |
3208 ArrowFormalParametersUnexpectedToken(classifier); | 3207 ArrowFormalParametersUnexpectedToken(classifier); |
3209 int pos; | 3208 int pos; |
3210 if (scanner()->current_token() == Token::IDENTIFIER) { | 3209 if (scanner()->current_token() == Token::IDENTIFIER) { |
3211 pos = position(); | 3210 pos = position(); |
3212 } else { | 3211 } else { |
3213 pos = peek_position(); | 3212 pos = peek_position(); |
3214 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3213 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3215 // If the tag function looks like an IIFE, set_parenthesized() to | 3214 // If the tag function looks like an IIFE, set_parenthesized() to |
3216 // force eager compilation. | 3215 // force eager compilation. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3250 parameters->is_simple = false; | 3249 parameters->is_simple = false; |
3251 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void)); | 3250 ValidateFormalParameterInitializer(classifier, CHECK_OK_CUSTOM(Void)); |
3252 classifier->RecordNonSimpleParameter(); | 3251 classifier->RecordNonSimpleParameter(); |
3253 } | 3252 } |
3254 | 3253 |
3255 ExpressionT initializer = Traits::EmptyExpression(); | 3254 ExpressionT initializer = Traits::EmptyExpression(); |
3256 if (!is_rest && Check(Token::ASSIGN)) { | 3255 if (!is_rest && Check(Token::ASSIGN)) { |
3257 ExpressionClassifier init_classifier(this); | 3256 ExpressionClassifier init_classifier(this); |
3258 initializer = ParseAssignmentExpression(true, &init_classifier, | 3257 initializer = ParseAssignmentExpression(true, &init_classifier, |
3259 CHECK_OK_CUSTOM(Void)); | 3258 CHECK_OK_CUSTOM(Void)); |
3260 Traits::RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void)); | 3259 impl()->RewriteNonPattern(&init_classifier, CHECK_OK_CUSTOM(Void)); |
3261 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void)); | 3260 ValidateFormalParameterInitializer(&init_classifier, CHECK_OK_CUSTOM(Void)); |
3262 parameters->is_simple = false; | 3261 parameters->is_simple = false; |
3263 init_classifier.Discard(); | 3262 init_classifier.Discard(); |
3264 classifier->RecordNonSimpleParameter(); | 3263 classifier->RecordNonSimpleParameter(); |
3265 | 3264 |
3266 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); | 3265 Traits::SetFunctionNameFromIdentifierRef(initializer, pattern); |
3267 } | 3266 } |
3268 | 3267 |
3269 Traits::AddFormalParameter(parameters, pattern, initializer, | 3268 Traits::AddFormalParameter(parameters, pattern, initializer, |
3270 scanner()->location().end_pos, is_rest); | 3269 scanner()->location().end_pos, is_rest); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3422 Expect(Token::ARROW, CHECK_OK); | 3421 Expect(Token::ARROW, CHECK_OK); |
3423 | 3422 |
3424 if (peek() == Token::LBRACE) { | 3423 if (peek() == Token::LBRACE) { |
3425 // Multiple statement body | 3424 // Multiple statement body |
3426 Consume(Token::LBRACE); | 3425 Consume(Token::LBRACE); |
3427 DCHECK_EQ(scope(), formal_parameters.scope); | 3426 DCHECK_EQ(scope(), formal_parameters.scope); |
3428 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 3427 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
3429 formal_parameters.scope->AllowsLazyParsing()); | 3428 formal_parameters.scope->AllowsLazyParsing()); |
3430 if (is_lazily_parsed) { | 3429 if (is_lazily_parsed) { |
3431 body = this->NewStatementList(0, zone()); | 3430 body = this->NewStatementList(0, zone()); |
3432 this->SkipLazyFunctionBody(&materialized_literal_count, | 3431 impl()->SkipLazyFunctionBody(&materialized_literal_count, |
3433 &expected_property_count, CHECK_OK); | 3432 &expected_property_count, CHECK_OK); |
3434 if (formal_parameters.materialized_literals_count > 0) { | 3433 if (formal_parameters.materialized_literals_count > 0) { |
3435 materialized_literal_count += | 3434 materialized_literal_count += |
3436 formal_parameters.materialized_literals_count; | 3435 formal_parameters.materialized_literals_count; |
3437 } | 3436 } |
3438 } else { | 3437 } else { |
3439 body = this->ParseEagerFunctionBody( | 3438 body = impl()->ParseEagerFunctionBody( |
3440 this->EmptyIdentifier(), kNoSourcePosition, formal_parameters, | 3439 this->EmptyIdentifier(), kNoSourcePosition, formal_parameters, |
3441 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3440 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
3442 materialized_literal_count = | 3441 materialized_literal_count = |
3443 function_state.materialized_literal_count(); | 3442 function_state.materialized_literal_count(); |
3444 expected_property_count = function_state.expected_property_count(); | 3443 expected_property_count = function_state.expected_property_count(); |
3445 } | 3444 } |
3446 } else { | 3445 } else { |
3447 // Single-expression body | 3446 // Single-expression body |
3448 int pos = position(); | 3447 int pos = position(); |
3449 DCHECK(ReturnExprContext::kInsideValidBlock == | 3448 DCHECK(ReturnExprContext::kInsideValidBlock == |
3450 function_state_->return_expr_context()); | 3449 function_state_->return_expr_context()); |
3451 ReturnExprScope allow_tail_calls( | 3450 ReturnExprScope allow_tail_calls( |
3452 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3451 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
3453 body = this->NewStatementList(1, zone()); | 3452 body = this->NewStatementList(1, zone()); |
3454 this->AddParameterInitializationBlock(formal_parameters, body, is_async, | 3453 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
3455 CHECK_OK); | 3454 CHECK_OK); |
3456 ExpressionClassifier classifier(this); | 3455 ExpressionClassifier classifier(this); |
3457 if (is_async) { | 3456 if (is_async) { |
3458 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, | 3457 impl()->ParseAsyncArrowSingleExpressionBody(body, accept_IN, |
3459 pos, CHECK_OK); | 3458 &classifier, pos, CHECK_OK); |
3460 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 3459 impl()->RewriteNonPattern(&classifier, CHECK_OK); |
3461 } else { | 3460 } else { |
3462 ExpressionT expression = | 3461 ExpressionT expression = |
3463 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 3462 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
3464 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 3463 impl()->RewriteNonPattern(&classifier, CHECK_OK); |
3465 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3464 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3466 if (allow_tailcalls() && !is_sloppy(language_mode())) { | 3465 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
3467 // ES6 14.6.1 Static Semantics: IsInTailPosition | 3466 // ES6 14.6.1 Static Semantics: IsInTailPosition |
3468 this->MarkTailPosition(expression); | 3467 impl()->MarkTailPosition(expression); |
3469 } | 3468 } |
3470 } | 3469 } |
3471 materialized_literal_count = function_state.materialized_literal_count(); | 3470 materialized_literal_count = function_state.materialized_literal_count(); |
3472 expected_property_count = function_state.expected_property_count(); | 3471 expected_property_count = function_state.expected_property_count(); |
3473 this->MarkCollectedTailCallExpressions(); | 3472 impl()->MarkCollectedTailCallExpressions(); |
3474 } | 3473 } |
3475 | 3474 |
3476 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3475 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3477 | 3476 |
3478 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3477 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3479 // which is not the same as "parameters of a strict function"; it only means | 3478 // which is not the same as "parameters of a strict function"; it only means |
3480 // that duplicates are not allowed. Of course, the arrow function may | 3479 // that duplicates are not allowed. Of course, the arrow function may |
3481 // itself be strict as well. | 3480 // itself be strict as well. |
3482 const bool allow_duplicate_parameters = false; | 3481 const bool allow_duplicate_parameters = false; |
3483 this->ValidateFormalParameters(&formals_classifier, language_mode(), | 3482 this->ValidateFormalParameters(&formals_classifier, language_mode(), |
3484 allow_duplicate_parameters, CHECK_OK); | 3483 allow_duplicate_parameters, CHECK_OK); |
3485 | 3484 |
3486 // Validate strict mode. | 3485 // Validate strict mode. |
3487 if (is_strict(language_mode())) { | 3486 if (is_strict(language_mode())) { |
3488 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3487 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3489 scanner()->location().end_pos, CHECK_OK); | 3488 scanner()->location().end_pos, CHECK_OK); |
3490 } | 3489 } |
3491 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3490 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3492 | 3491 |
3493 Traits::RewriteDestructuringAssignments(); | 3492 impl()->RewriteDestructuringAssignments(); |
3494 } | 3493 } |
3495 | 3494 |
3496 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3495 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3497 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3496 this->EmptyIdentifierString(), formal_parameters.scope, body, |
3498 materialized_literal_count, expected_property_count, num_parameters, | 3497 materialized_literal_count, expected_property_count, num_parameters, |
3499 FunctionLiteral::kNoDuplicateParameters, | 3498 FunctionLiteral::kNoDuplicateParameters, |
3500 FunctionLiteral::kAnonymousExpression, | 3499 FunctionLiteral::kAnonymousExpression, |
3501 FunctionLiteral::kShouldLazyCompile, arrow_kind, | 3500 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
3502 formal_parameters.scope->start_position()); | 3501 formal_parameters.scope->start_position()); |
3503 | 3502 |
(...skipping 20 matching lines...) Expand all Loading... |
3524 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3523 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
3525 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); | 3524 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); |
3526 | 3525 |
3527 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate. | 3526 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate. |
3528 // In this case we may simply consume the token and build a template with a | 3527 // In this case we may simply consume the token and build a template with a |
3529 // single TEMPLATE_SPAN and no expressions. | 3528 // single TEMPLATE_SPAN and no expressions. |
3530 if (peek() == Token::TEMPLATE_TAIL) { | 3529 if (peek() == Token::TEMPLATE_TAIL) { |
3531 Consume(Token::TEMPLATE_TAIL); | 3530 Consume(Token::TEMPLATE_TAIL); |
3532 int pos = position(); | 3531 int pos = position(); |
3533 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3532 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3534 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos); | 3533 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); |
3535 Traits::AddTemplateSpan(&ts, true); | 3534 impl()->AddTemplateSpan(&ts, true); |
3536 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3535 return impl()->CloseTemplateLiteral(&ts, start, tag); |
3537 } | 3536 } |
3538 | 3537 |
3539 Consume(Token::TEMPLATE_SPAN); | 3538 Consume(Token::TEMPLATE_SPAN); |
3540 int pos = position(); | 3539 int pos = position(); |
3541 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos); | 3540 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); |
3542 Traits::AddTemplateSpan(&ts, false); | 3541 impl()->AddTemplateSpan(&ts, false); |
3543 Token::Value next; | 3542 Token::Value next; |
3544 | 3543 |
3545 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, | 3544 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, |
3546 // and repeat if the following token is a TEMPLATE_SPAN as well (in this | 3545 // and repeat if the following token is a TEMPLATE_SPAN as well (in this |
3547 // case, representing a TemplateMiddle). | 3546 // case, representing a TemplateMiddle). |
3548 | 3547 |
3549 do { | 3548 do { |
3550 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3549 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3551 next = peek(); | 3550 next = peek(); |
3552 if (next == Token::EOS) { | 3551 if (next == Token::EOS) { |
3553 ReportMessageAt(Scanner::Location(start, peek_position()), | 3552 ReportMessageAt(Scanner::Location(start, peek_position()), |
3554 MessageTemplate::kUnterminatedTemplate); | 3553 MessageTemplate::kUnterminatedTemplate); |
3555 *ok = false; | 3554 *ok = false; |
3556 return Traits::EmptyExpression(); | 3555 return Traits::EmptyExpression(); |
3557 } else if (next == Token::ILLEGAL) { | 3556 } else if (next == Token::ILLEGAL) { |
3558 Traits::ReportMessageAt( | 3557 Traits::ReportMessageAt( |
3559 Scanner::Location(position() + 1, peek_position()), | 3558 Scanner::Location(position() + 1, peek_position()), |
3560 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3559 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3561 *ok = false; | 3560 *ok = false; |
3562 return Traits::EmptyExpression(); | 3561 return Traits::EmptyExpression(); |
3563 } | 3562 } |
3564 | 3563 |
3565 int expr_pos = peek_position(); | 3564 int expr_pos = peek_position(); |
3566 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); | 3565 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
3567 CheckNoTailCallExpressions(classifier, CHECK_OK); | 3566 CheckNoTailCallExpressions(classifier, CHECK_OK); |
3568 Traits::RewriteNonPattern(classifier, CHECK_OK); | 3567 impl()->RewriteNonPattern(classifier, CHECK_OK); |
3569 Traits::AddTemplateExpression(&ts, expression); | 3568 impl()->AddTemplateExpression(&ts, expression); |
3570 | 3569 |
3571 if (peek() != Token::RBRACE) { | 3570 if (peek() != Token::RBRACE) { |
3572 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3571 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3573 MessageTemplate::kUnterminatedTemplateExpr); | 3572 MessageTemplate::kUnterminatedTemplateExpr); |
3574 *ok = false; | 3573 *ok = false; |
3575 return Traits::EmptyExpression(); | 3574 return Traits::EmptyExpression(); |
3576 } | 3575 } |
3577 | 3576 |
3578 // If we didn't die parsing that expression, our next token should be a | 3577 // If we didn't die parsing that expression, our next token should be a |
3579 // TEMPLATE_SPAN or TEMPLATE_TAIL. | 3578 // TEMPLATE_SPAN or TEMPLATE_TAIL. |
3580 next = scanner()->ScanTemplateContinuation(); | 3579 next = scanner()->ScanTemplateContinuation(); |
3581 Next(); | 3580 Next(); |
3582 pos = position(); | 3581 pos = position(); |
3583 | 3582 |
3584 if (next == Token::EOS) { | 3583 if (next == Token::EOS) { |
3585 ReportMessageAt(Scanner::Location(start, pos), | 3584 ReportMessageAt(Scanner::Location(start, pos), |
3586 MessageTemplate::kUnterminatedTemplate); | 3585 MessageTemplate::kUnterminatedTemplate); |
3587 *ok = false; | 3586 *ok = false; |
3588 return Traits::EmptyExpression(); | 3587 return Traits::EmptyExpression(); |
3589 } else if (next == Token::ILLEGAL) { | 3588 } else if (next == Token::ILLEGAL) { |
3590 Traits::ReportMessageAt( | 3589 Traits::ReportMessageAt( |
3591 Scanner::Location(position() + 1, peek_position()), | 3590 Scanner::Location(position() + 1, peek_position()), |
3592 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); | 3591 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); |
3593 *ok = false; | 3592 *ok = false; |
3594 return Traits::EmptyExpression(); | 3593 return Traits::EmptyExpression(); |
3595 } | 3594 } |
3596 | 3595 |
3597 Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); | 3596 impl()->AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL); |
3598 } while (next == Token::TEMPLATE_SPAN); | 3597 } while (next == Token::TEMPLATE_SPAN); |
3599 | 3598 |
3600 DCHECK_EQ(next, Token::TEMPLATE_TAIL); | 3599 DCHECK_EQ(next, Token::TEMPLATE_TAIL); |
3601 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); | 3600 CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK); |
3602 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 3601 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
3603 return Traits::CloseTemplateLiteral(&ts, start, tag); | 3602 return impl()->CloseTemplateLiteral(&ts, start, tag); |
3604 } | 3603 } |
3605 | 3604 |
3606 template <typename Impl> | 3605 template <typename Impl> |
3607 typename ParserBase<Impl>::ExpressionT | 3606 typename ParserBase<Impl>::ExpressionT |
3608 ParserBase<Impl>::CheckAndRewriteReferenceExpression( | 3607 ParserBase<Impl>::CheckAndRewriteReferenceExpression( |
3609 ExpressionT expression, int beg_pos, int end_pos, | 3608 ExpressionT expression, int beg_pos, int end_pos, |
3610 MessageTemplate::Template message, bool* ok) { | 3609 MessageTemplate::Template message, bool* ok) { |
3611 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, | 3610 return this->CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, |
3612 message, kReferenceError, ok); | 3611 message, kReferenceError, ok); |
3613 } | 3612 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3712 has_seen_constructor_ = true; | 3711 has_seen_constructor_ = true; |
3713 return; | 3712 return; |
3714 } | 3713 } |
3715 } | 3714 } |
3716 | 3715 |
3717 | 3716 |
3718 } // namespace internal | 3717 } // namespace internal |
3719 } // namespace v8 | 3718 } // namespace v8 |
3720 | 3719 |
3721 #endif // V8_PARSING_PARSER_BASE_H | 3720 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |