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

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

Issue 2267783002: [parser] Clean up (pre)parser traits (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@nickie-2267663002-crtp
Patch Set: Rebase Created 4 years, 4 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/base/hashmap.h" 10 #include "src/base/hashmap.h"
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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