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_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 // whether it is strict mode future reserved. | 593 // whether it is strict mode future reserved. |
594 IdentifierT ParseIdentifierOrStrictReservedWord( | 594 IdentifierT ParseIdentifierOrStrictReservedWord( |
595 bool* is_strict_reserved, | 595 bool* is_strict_reserved, |
596 bool* ok); | 596 bool* ok); |
597 IdentifierT ParseIdentifierName(bool* ok); | 597 IdentifierT ParseIdentifierName(bool* ok); |
598 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 598 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
599 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 599 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
600 bool* is_set, | 600 bool* is_set, |
601 bool* ok); | 601 bool* ok); |
602 | 602 |
603 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | |
604 | 603 |
605 ExpressionT ParsePrimaryExpression(bool* ok); | 604 class ExpressionClassifier { |
| 605 public: |
| 606 ExpressionClassifier() |
| 607 : expression_error_(Scanner::Location::invalid()), |
| 608 binding_pattern_error_(Scanner::Location::invalid()), |
| 609 assignment_pattern_error_(Scanner::Location::invalid()) {} |
| 610 |
| 611 bool is_valid_expression() const { |
| 612 return expression_error_ == Scanner::Location::invalid(); |
| 613 } |
| 614 |
| 615 bool is_valid_binding_pattern() const { |
| 616 return binding_pattern_error_ == Scanner::Location::invalid(); |
| 617 } |
| 618 |
| 619 bool is_valid_assignmnent_pattern() const { |
| 620 return assignment_pattern_error_ == Scanner::Location::invalid(); |
| 621 } |
| 622 |
| 623 void RecordExpressionError(const Scanner::Location& loc) { |
| 624 if (!is_valid_expression()) return; |
| 625 expression_error_ = loc; |
| 626 } |
| 627 |
| 628 void RecordBindingPatternError(const Scanner::Location& loc) { |
| 629 if (!is_valid_binding_pattern()) return; |
| 630 binding_pattern_error_ = loc; |
| 631 } |
| 632 |
| 633 void RecordAssignmentPatternError(const Scanner::Location& loc) { |
| 634 if (!is_valid_assignmnent_pattern()) return; |
| 635 assignment_pattern_error_ = loc; |
| 636 } |
| 637 |
| 638 private: |
| 639 Scanner::Location expression_error_; |
| 640 Scanner::Location binding_pattern_error_; |
| 641 Scanner::Location assignment_pattern_error_; |
| 642 }; |
| 643 |
| 644 ExpressionT ParseRegExpLiteral(bool seen_equal, |
| 645 ExpressionClassifier* classifier, bool* ok); |
| 646 |
| 647 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 648 bool* ok); |
606 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 649 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
607 ExpressionT ParseArrayLiteral(bool* ok); | 650 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| 651 bool* ok); |
| 652 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); |
608 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 653 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
609 bool* is_static, bool* is_computed_name, | 654 bool* is_static, bool* is_computed_name, |
610 bool* ok); | 655 ExpressionClassifier* classifier, bool* ok); |
611 ExpressionT ParseObjectLiteral(bool* ok); | 656 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
612 ObjectLiteralPropertyT ParsePropertyDefinition( | 657 ObjectLiteralPropertyT ParsePropertyDefinition( |
613 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 658 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
614 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 659 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 660 ExpressionClassifier* classifier, bool* ok); |
| 661 typename Traits::Type::ExpressionList ParseArguments( |
| 662 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, |
615 bool* ok); | 663 bool* ok); |
616 typename Traits::Type::ExpressionList ParseArguments( | 664 ExpressionT ParseAssignmentExpression(bool accept_IN, |
617 Scanner::Location* first_spread_pos, bool* ok); | 665 ExpressionClassifier* classifier, |
618 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 666 bool* ok); |
619 ExpressionT ParseYieldExpression(bool* ok); | 667 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
620 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 668 ExpressionT ParseConditionalExpression(bool accept_IN, |
621 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 669 ExpressionClassifier* classifier, |
622 ExpressionT ParseUnaryExpression(bool* ok); | 670 bool* ok); |
623 ExpressionT ParsePostfixExpression(bool* ok); | 671 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
624 ExpressionT ParseLeftHandSideExpression(bool* ok); | 672 ExpressionClassifier* classifier, bool* ok); |
625 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 673 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
626 ExpressionT ParseMemberExpression(bool* ok); | 674 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
627 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 675 bool* ok); |
628 bool* ok); | 676 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| 677 bool* ok); |
| 678 ExpressionT ParseMemberWithNewPrefixesExpression( |
| 679 ExpressionClassifier* classifier, bool* ok); |
| 680 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); |
| 681 ExpressionT ParseMemberExpressionContinuation( |
| 682 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); |
629 ExpressionT ParseArrowFunctionLiteral( | 683 ExpressionT ParseArrowFunctionLiteral( |
630 Scope* function_scope, const FormalParameterErrorLocations& error_locs, | 684 Scope* function_scope, const FormalParameterErrorLocations& error_locs, |
631 bool has_rest, bool* ok); | 685 bool has_rest, ExpressionClassifier* classifier, bool* ok); |
632 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 686 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
| 687 ExpressionClassifier* classifier, bool* ok); |
633 void AddTemplateExpression(ExpressionT); | 688 void AddTemplateExpression(ExpressionT); |
634 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 689 ExpressionT ParseSuperExpression(bool is_new, |
635 ExpressionT ParseStrongInitializationExpression(bool* ok); | 690 ExpressionClassifier* classifier, bool* ok); |
636 ExpressionT ParseStrongSuperCallExpression(bool* ok); | 691 ExpressionT ParseStrongInitializationExpression( |
| 692 ExpressionClassifier* classifier, bool* ok); |
| 693 ExpressionT ParseStrongSuperCallExpression(ExpressionClassifier* classifier, |
| 694 bool* ok); |
637 | 695 |
638 void ParseFormalParameter(FormalParameterScopeT* scope, | 696 void ParseFormalParameter(FormalParameterScopeT* scope, |
639 FormalParameterErrorLocations* locs, bool is_rest, | 697 FormalParameterErrorLocations* locs, bool is_rest, |
640 bool* ok); | 698 bool* ok); |
641 int ParseFormalParameterList(FormalParameterScopeT* scope, | 699 int ParseFormalParameterList(FormalParameterScopeT* scope, |
642 FormalParameterErrorLocations* locs, | 700 FormalParameterErrorLocations* locs, |
643 bool* has_rest, bool* ok); | 701 bool* has_rest, bool* ok); |
644 void CheckArityRestrictions( | 702 void CheckArityRestrictions( |
645 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 703 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
646 int formals_start_pos, int formals_end_pos, bool* ok); | 704 int formals_start_pos, int formals_end_pos, bool* ok); |
(...skipping 1335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1982 bool* ok) { | 2040 bool* ok) { |
1983 IdentifierT result = ParseIdentifierName(ok); | 2041 IdentifierT result = ParseIdentifierName(ok); |
1984 if (!*ok) return Traits::EmptyIdentifier(); | 2042 if (!*ok) return Traits::EmptyIdentifier(); |
1985 scanner()->IsGetOrSet(is_get, is_set); | 2043 scanner()->IsGetOrSet(is_get, is_set); |
1986 return result; | 2044 return result; |
1987 } | 2045 } |
1988 | 2046 |
1989 | 2047 |
1990 template <class Traits> | 2048 template <class Traits> |
1991 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( | 2049 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
1992 bool seen_equal, bool* ok) { | 2050 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { |
1993 int pos = peek_position(); | 2051 int pos = peek_position(); |
1994 if (!scanner()->ScanRegExpPattern(seen_equal)) { | 2052 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
1995 Next(); | 2053 Next(); |
1996 ReportMessage("unterminated_regexp"); | 2054 ReportMessage("unterminated_regexp"); |
1997 *ok = false; | 2055 *ok = false; |
1998 return Traits::EmptyExpression(); | 2056 return Traits::EmptyExpression(); |
1999 } | 2057 } |
2000 | 2058 |
2001 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2059 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2002 | 2060 |
(...skipping 16 matching lines...) Expand all Loading... |
2019 #define DUMMY ) // to make indentation work | 2077 #define DUMMY ) // to make indentation work |
2020 #undef DUMMY | 2078 #undef DUMMY |
2021 | 2079 |
2022 // Used in functions where the return type is not ExpressionT. | 2080 // Used in functions where the return type is not ExpressionT. |
2023 #define CHECK_OK_CUSTOM(x) ok); \ | 2081 #define CHECK_OK_CUSTOM(x) ok); \ |
2024 if (!*ok) return this->x(); \ | 2082 if (!*ok) return this->x(); \ |
2025 ((void)0 | 2083 ((void)0 |
2026 #define DUMMY ) // to make indentation work | 2084 #define DUMMY ) // to make indentation work |
2027 #undef DUMMY | 2085 #undef DUMMY |
2028 | 2086 |
| 2087 |
2029 template <class Traits> | 2088 template <class Traits> |
2030 typename ParserBase<Traits>::ExpressionT | 2089 typename ParserBase<Traits>::ExpressionT |
2031 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { | 2090 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 2091 bool* ok) { |
2032 // PrimaryExpression :: | 2092 // PrimaryExpression :: |
2033 // 'this' | 2093 // 'this' |
2034 // 'null' | 2094 // 'null' |
2035 // 'true' | 2095 // 'true' |
2036 // 'false' | 2096 // 'false' |
2037 // Identifier | 2097 // Identifier |
2038 // Number | 2098 // Number |
2039 // String | 2099 // String |
2040 // ArrayLiteral | 2100 // ArrayLiteral |
2041 // ObjectLiteral | 2101 // ObjectLiteral |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2087 break; | 2147 break; |
2088 } | 2148 } |
2089 | 2149 |
2090 case Token::STRING: { | 2150 case Token::STRING: { |
2091 Consume(Token::STRING); | 2151 Consume(Token::STRING); |
2092 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2152 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
2093 break; | 2153 break; |
2094 } | 2154 } |
2095 | 2155 |
2096 case Token::ASSIGN_DIV: | 2156 case Token::ASSIGN_DIV: |
2097 result = this->ParseRegExpLiteral(true, CHECK_OK); | 2157 result = this->ParseRegExpLiteral(true, classifier, CHECK_OK); |
2098 break; | 2158 break; |
2099 | 2159 |
2100 case Token::DIV: | 2160 case Token::DIV: |
2101 result = this->ParseRegExpLiteral(false, CHECK_OK); | 2161 result = this->ParseRegExpLiteral(false, classifier, CHECK_OK); |
2102 break; | 2162 break; |
2103 | 2163 |
2104 case Token::LBRACK: | 2164 case Token::LBRACK: |
2105 result = this->ParseArrayLiteral(CHECK_OK); | 2165 result = this->ParseArrayLiteral(classifier, CHECK_OK); |
2106 break; | 2166 break; |
2107 | 2167 |
2108 case Token::LBRACE: | 2168 case Token::LBRACE: |
2109 result = this->ParseObjectLiteral(CHECK_OK); | 2169 result = this->ParseObjectLiteral(classifier, CHECK_OK); |
2110 break; | 2170 break; |
2111 | 2171 |
2112 case Token::LPAREN: | 2172 case Token::LPAREN: |
2113 Consume(Token::LPAREN); | 2173 Consume(Token::LPAREN); |
2114 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { | 2174 if (allow_harmony_arrow_functions() && Check(Token::RPAREN)) { |
2115 // As a primary expression, the only thing that can follow "()" is "=>". | 2175 // As a primary expression, the only thing that can follow "()" is "=>". |
2116 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2176 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
2117 scope->set_start_position(beg_pos); | 2177 scope->set_start_position(beg_pos); |
2118 FormalParameterErrorLocations error_locs; | 2178 FormalParameterErrorLocations error_locs; |
2119 bool has_rest = false; | 2179 bool has_rest = false; |
2120 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, | 2180 result = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
2121 CHECK_OK); | 2181 classifier, CHECK_OK); |
2122 } else { | 2182 } else { |
2123 // Heuristically try to detect immediately called functions before | 2183 // Heuristically try to detect immediately called functions before |
2124 // seeing the call parentheses. | 2184 // seeing the call parentheses. |
2125 parenthesized_function_ = (peek() == Token::FUNCTION); | 2185 parenthesized_function_ = (peek() == Token::FUNCTION); |
2126 result = this->ParseExpression(true, CHECK_OK); | 2186 result = this->ParseExpression(true, classifier, CHECK_OK); |
2127 result->increase_parenthesization_level(); | 2187 result->increase_parenthesization_level(); |
2128 Expect(Token::RPAREN, CHECK_OK); | 2188 Expect(Token::RPAREN, CHECK_OK); |
2129 } | 2189 } |
2130 break; | 2190 break; |
2131 | 2191 |
2132 case Token::CLASS: { | 2192 case Token::CLASS: { |
2133 Consume(Token::CLASS); | 2193 Consume(Token::CLASS); |
2134 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2194 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2135 ReportMessage("sloppy_lexical"); | 2195 ReportMessage("sloppy_lexical"); |
2136 *ok = false; | 2196 *ok = false; |
(...skipping 10 matching lines...) Expand all Loading... |
2147 } | 2207 } |
2148 result = this->ParseClassLiteral(name, class_name_location, | 2208 result = this->ParseClassLiteral(name, class_name_location, |
2149 is_strict_reserved_name, | 2209 is_strict_reserved_name, |
2150 class_token_position, CHECK_OK); | 2210 class_token_position, CHECK_OK); |
2151 break; | 2211 break; |
2152 } | 2212 } |
2153 | 2213 |
2154 case Token::TEMPLATE_SPAN: | 2214 case Token::TEMPLATE_SPAN: |
2155 case Token::TEMPLATE_TAIL: | 2215 case Token::TEMPLATE_TAIL: |
2156 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 2216 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
2157 CHECK_OK); | 2217 classifier, CHECK_OK); |
2158 break; | 2218 break; |
2159 | 2219 |
2160 case Token::MOD: | 2220 case Token::MOD: |
2161 if (allow_natives() || extension_ != NULL) { | 2221 if (allow_natives() || extension_ != NULL) { |
2162 result = this->ParseV8Intrinsic(CHECK_OK); | 2222 result = this->ParseV8Intrinsic(CHECK_OK); |
2163 break; | 2223 break; |
2164 } | 2224 } |
2165 // If we're not allowing special syntax we fall-through to the | 2225 // If we're not allowing special syntax we fall-through to the |
2166 // default case. | 2226 // default case. |
2167 | 2227 |
2168 default: { | 2228 default: { |
2169 Next(); | 2229 Next(); |
2170 ReportUnexpectedToken(token); | 2230 ReportUnexpectedToken(token); |
2171 *ok = false; | 2231 *ok = false; |
2172 } | 2232 } |
2173 } | 2233 } |
2174 | 2234 |
2175 return result; | 2235 return result; |
2176 } | 2236 } |
2177 | 2237 |
| 2238 |
| 2239 template <class Traits> |
| 2240 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2241 bool accept_IN, bool* ok) { |
| 2242 ExpressionClassifier classifier; |
| 2243 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
| 2244 // TODO(dslomov): report error if not a valid expression. |
| 2245 return result; |
| 2246 } |
| 2247 |
| 2248 |
2178 // Precedence = 1 | 2249 // Precedence = 1 |
2179 template <class Traits> | 2250 template <class Traits> |
2180 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2251 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
2181 bool accept_IN, bool* ok) { | 2252 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
2182 // Expression :: | 2253 // Expression :: |
2183 // AssignmentExpression | 2254 // AssignmentExpression |
2184 // Expression ',' AssignmentExpression | 2255 // Expression ',' AssignmentExpression |
2185 | 2256 |
2186 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2257 ExpressionT result = |
| 2258 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2187 while (peek() == Token::COMMA) { | 2259 while (peek() == Token::COMMA) { |
2188 Expect(Token::COMMA, CHECK_OK); | 2260 Expect(Token::COMMA, CHECK_OK); |
2189 int pos = position(); | 2261 int pos = position(); |
2190 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2262 ExpressionT right = |
| 2263 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2191 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2264 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2192 } | 2265 } |
2193 return result; | 2266 return result; |
2194 } | 2267 } |
2195 | 2268 |
2196 | 2269 |
2197 template <class Traits> | 2270 template <class Traits> |
2198 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2271 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
2199 bool* ok) { | 2272 ExpressionClassifier* classifier, bool* ok) { |
2200 // ArrayLiteral :: | 2273 // ArrayLiteral :: |
2201 // '[' Expression? (',' Expression?)* ']' | 2274 // '[' Expression? (',' Expression?)* ']' |
2202 | 2275 |
2203 int pos = peek_position(); | 2276 int pos = peek_position(); |
2204 typename Traits::Type::ExpressionList values = | 2277 typename Traits::Type::ExpressionList values = |
2205 this->NewExpressionList(4, zone_); | 2278 this->NewExpressionList(4, zone_); |
2206 Expect(Token::LBRACK, CHECK_OK); | 2279 Expect(Token::LBRACK, CHECK_OK); |
2207 while (peek() != Token::RBRACK) { | 2280 while (peek() != Token::RBRACK) { |
2208 ExpressionT elem = this->EmptyExpression(); | 2281 ExpressionT elem = this->EmptyExpression(); |
2209 if (peek() == Token::COMMA) { | 2282 if (peek() == Token::COMMA) { |
2210 if (is_strong(language_mode())) { | 2283 if (is_strong(language_mode())) { |
2211 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); | 2284 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); |
2212 *ok = false; | 2285 *ok = false; |
2213 return this->EmptyExpression(); | 2286 return this->EmptyExpression(); |
2214 } | 2287 } |
2215 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2288 elem = this->GetLiteralTheHole(peek_position(), factory()); |
2216 } else { | 2289 } else { |
2217 elem = this->ParseAssignmentExpression(true, CHECK_OK); | 2290 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
2218 } | 2291 } |
2219 values->Add(elem, zone_); | 2292 values->Add(elem, zone_); |
2220 if (peek() != Token::RBRACK) { | 2293 if (peek() != Token::RBRACK) { |
2221 Expect(Token::COMMA, CHECK_OK); | 2294 Expect(Token::COMMA, CHECK_OK); |
2222 } | 2295 } |
2223 } | 2296 } |
2224 Expect(Token::RBRACK, CHECK_OK); | 2297 Expect(Token::RBRACK, CHECK_OK); |
2225 | 2298 |
2226 // Update the scope information before the pre-parsing bailout. | 2299 // Update the scope information before the pre-parsing bailout. |
2227 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2300 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2228 | 2301 |
2229 return factory()->NewArrayLiteral(values, literal_index, pos); | 2302 return factory()->NewArrayLiteral(values, literal_index, pos); |
2230 } | 2303 } |
2231 | 2304 |
2232 | 2305 |
2233 template <class Traits> | 2306 template <class Traits> |
2234 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 2307 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
2235 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, | 2308 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
2236 bool* is_computed_name, bool* ok) { | 2309 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
2237 Token::Value token = peek(); | 2310 Token::Value token = peek(); |
2238 int pos = peek_position(); | 2311 int pos = peek_position(); |
2239 | 2312 |
2240 // For non computed property names we normalize the name a bit: | 2313 // For non computed property names we normalize the name a bit: |
2241 // | 2314 // |
2242 // "12" -> 12 | 2315 // "12" -> 12 |
2243 // 12.3 -> "12.3" | 2316 // 12.3 -> "12.3" |
2244 // 12.30 -> "12.3" | 2317 // 12.30 -> "12.3" |
2245 // identifier -> "identifier" | 2318 // identifier -> "identifier" |
2246 // | 2319 // |
(...skipping 12 matching lines...) Expand all Loading... |
2259 | 2332 |
2260 case Token::NUMBER: | 2333 case Token::NUMBER: |
2261 Consume(Token::NUMBER); | 2334 Consume(Token::NUMBER); |
2262 *name = this->GetNumberAsSymbol(scanner()); | 2335 *name = this->GetNumberAsSymbol(scanner()); |
2263 break; | 2336 break; |
2264 | 2337 |
2265 case Token::LBRACK: | 2338 case Token::LBRACK: |
2266 if (allow_harmony_computed_property_names_) { | 2339 if (allow_harmony_computed_property_names_) { |
2267 *is_computed_name = true; | 2340 *is_computed_name = true; |
2268 Consume(Token::LBRACK); | 2341 Consume(Token::LBRACK); |
2269 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 2342 ExpressionT expression = |
| 2343 ParseAssignmentExpression(true, classifier, CHECK_OK); |
2270 Expect(Token::RBRACK, CHECK_OK); | 2344 Expect(Token::RBRACK, CHECK_OK); |
2271 return expression; | 2345 return expression; |
2272 } | 2346 } |
2273 | 2347 |
2274 // Fall through. | 2348 // Fall through. |
2275 case Token::STATIC: | 2349 case Token::STATIC: |
2276 *is_static = true; | 2350 *is_static = true; |
2277 | 2351 |
2278 // Fall through. | 2352 // Fall through. |
2279 default: | 2353 default: |
2280 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | 2354 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
2281 break; | 2355 break; |
2282 } | 2356 } |
2283 | 2357 |
2284 uint32_t index; | 2358 uint32_t index; |
2285 return this->IsArrayIndex(*name, &index) | 2359 return this->IsArrayIndex(*name, &index) |
2286 ? factory()->NewNumberLiteral(index, pos) | 2360 ? factory()->NewNumberLiteral(index, pos) |
2287 : factory()->NewStringLiteral(*name, pos); | 2361 : factory()->NewStringLiteral(*name, pos); |
2288 } | 2362 } |
2289 | 2363 |
2290 | 2364 |
2291 template <class Traits> | 2365 template <class Traits> |
2292 typename ParserBase<Traits>::ObjectLiteralPropertyT | 2366 typename ParserBase<Traits>::ObjectLiteralPropertyT |
2293 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, | 2367 ParserBase<Traits>::ParsePropertyDefinition( |
2294 bool in_class, bool has_extends, | 2368 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
2295 bool is_static, | 2369 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
2296 bool* is_computed_name, | 2370 ExpressionClassifier* classifier, bool* ok) { |
2297 bool* has_seen_constructor, | |
2298 bool* ok) { | |
2299 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 2371 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
2300 ExpressionT value = this->EmptyExpression(); | 2372 ExpressionT value = this->EmptyExpression(); |
2301 IdentifierT name = this->EmptyIdentifier(); | 2373 IdentifierT name = this->EmptyIdentifier(); |
2302 bool is_get = false; | 2374 bool is_get = false; |
2303 bool is_set = false; | 2375 bool is_set = false; |
2304 bool name_is_static = false; | 2376 bool name_is_static = false; |
2305 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2377 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
2306 | 2378 |
2307 Token::Value name_token = peek(); | 2379 Token::Value name_token = peek(); |
2308 int next_beg_pos = scanner()->peek_location().beg_pos; | 2380 int next_beg_pos = scanner()->peek_location().beg_pos; |
2309 int next_end_pos = scanner()->peek_location().end_pos; | 2381 int next_end_pos = scanner()->peek_location().end_pos; |
2310 ExpressionT name_expression = ParsePropertyName( | 2382 ExpressionT name_expression = ParsePropertyName( |
2311 &name, &is_get, &is_set, &name_is_static, is_computed_name, | 2383 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
2312 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2384 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2313 | 2385 |
2314 if (fni_ != nullptr && !*is_computed_name) { | 2386 if (fni_ != nullptr && !*is_computed_name) { |
2315 this->PushLiteralName(fni_, name); | 2387 this->PushLiteralName(fni_, name); |
2316 } | 2388 } |
2317 | 2389 |
2318 if (!in_class && !is_generator && peek() == Token::COLON) { | 2390 if (!in_class && !is_generator && peek() == Token::COLON) { |
2319 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2391 // PropertyDefinition : PropertyName ':' AssignmentExpression |
2320 if (!*is_computed_name) { | 2392 if (!*is_computed_name) { |
2321 checker->CheckProperty(name_token, kValueProperty, is_static, | 2393 checker->CheckProperty(name_token, kValueProperty, is_static, |
2322 is_generator, | 2394 is_generator, |
2323 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2395 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2324 } | 2396 } |
2325 Consume(Token::COLON); | 2397 Consume(Token::COLON); |
2326 value = this->ParseAssignmentExpression( | 2398 value = this->ParseAssignmentExpression( |
2327 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2399 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2328 | 2400 |
2329 } else if (is_generator || | 2401 } else if (is_generator || |
2330 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2402 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
2331 // Concise Method | 2403 // Concise Method |
2332 if (!*is_computed_name) { | 2404 if (!*is_computed_name) { |
2333 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2405 checker->CheckProperty(name_token, kMethodProperty, is_static, |
2334 is_generator, | 2406 is_generator, |
2335 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2407 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2336 } | 2408 } |
2337 | 2409 |
(...skipping 15 matching lines...) Expand all Loading... |
2353 FunctionLiteral::NORMAL_ARITY, | 2425 FunctionLiteral::NORMAL_ARITY, |
2354 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2426 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2355 | 2427 |
2356 return factory()->NewObjectLiteralProperty(name_expression, value, | 2428 return factory()->NewObjectLiteralProperty(name_expression, value, |
2357 ObjectLiteralProperty::COMPUTED, | 2429 ObjectLiteralProperty::COMPUTED, |
2358 is_static, *is_computed_name); | 2430 is_static, *is_computed_name); |
2359 | 2431 |
2360 } else if (in_class && name_is_static && !is_static) { | 2432 } else if (in_class && name_is_static && !is_static) { |
2361 // static MethodDefinition | 2433 // static MethodDefinition |
2362 return ParsePropertyDefinition(checker, true, has_extends, true, | 2434 return ParsePropertyDefinition(checker, true, has_extends, true, |
2363 is_computed_name, nullptr, ok); | 2435 is_computed_name, nullptr, classifier, ok); |
2364 } else if (is_get || is_set) { | 2436 } else if (is_get || is_set) { |
2365 // Accessor | 2437 // Accessor |
2366 name = this->EmptyIdentifier(); | 2438 name = this->EmptyIdentifier(); |
2367 bool dont_care = false; | 2439 bool dont_care = false; |
2368 name_token = peek(); | 2440 name_token = peek(); |
2369 | 2441 |
2370 name_expression = ParsePropertyName( | 2442 name_expression = ParsePropertyName( |
2371 &name, &dont_care, &dont_care, &dont_care, is_computed_name, | 2443 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
2372 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2444 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2373 | 2445 |
2374 if (!*is_computed_name) { | 2446 if (!*is_computed_name) { |
2375 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2447 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
2376 is_generator, | 2448 is_generator, |
2377 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2449 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2378 } | 2450 } |
2379 | 2451 |
2380 FunctionKind kind = FunctionKind::kAccessorFunction; | 2452 FunctionKind kind = FunctionKind::kAccessorFunction; |
2381 if (!in_class) kind = WithObjectLiteralBit(kind); | 2453 if (!in_class) kind = WithObjectLiteralBit(kind); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2416 return this->EmptyObjectLiteralProperty(); | 2488 return this->EmptyObjectLiteralProperty(); |
2417 } | 2489 } |
2418 | 2490 |
2419 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, | 2491 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
2420 *is_computed_name); | 2492 *is_computed_name); |
2421 } | 2493 } |
2422 | 2494 |
2423 | 2495 |
2424 template <class Traits> | 2496 template <class Traits> |
2425 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2497 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
2426 bool* ok) { | 2498 ExpressionClassifier* classifier, bool* ok) { |
2427 // ObjectLiteral :: | 2499 // ObjectLiteral :: |
2428 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2500 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2429 | 2501 |
2430 int pos = peek_position(); | 2502 int pos = peek_position(); |
2431 typename Traits::Type::PropertyList properties = | 2503 typename Traits::Type::PropertyList properties = |
2432 this->NewPropertyList(4, zone_); | 2504 this->NewPropertyList(4, zone_); |
2433 int number_of_boilerplate_properties = 0; | 2505 int number_of_boilerplate_properties = 0; |
2434 bool has_function = false; | 2506 bool has_function = false; |
2435 bool has_computed_names = false; | 2507 bool has_computed_names = false; |
2436 ObjectLiteralChecker checker(this); | 2508 ObjectLiteralChecker checker(this); |
2437 | 2509 |
2438 Expect(Token::LBRACE, CHECK_OK); | 2510 Expect(Token::LBRACE, CHECK_OK); |
2439 | 2511 |
2440 while (peek() != Token::RBRACE) { | 2512 while (peek() != Token::RBRACE) { |
2441 if (fni_ != nullptr) fni_->Enter(); | 2513 if (fni_ != nullptr) fni_->Enter(); |
2442 | 2514 |
2443 const bool in_class = false; | 2515 const bool in_class = false; |
2444 const bool is_static = false; | 2516 const bool is_static = false; |
2445 const bool has_extends = false; | 2517 const bool has_extends = false; |
2446 bool is_computed_name = false; | 2518 bool is_computed_name = false; |
2447 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2519 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
2448 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, | 2520 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, |
2449 CHECK_OK); | 2521 classifier, CHECK_OK); |
2450 | 2522 |
2451 if (is_computed_name) { | 2523 if (is_computed_name) { |
2452 has_computed_names = true; | 2524 has_computed_names = true; |
2453 } | 2525 } |
2454 | 2526 |
2455 // Mark top-level object literals that contain function literals and | 2527 // Mark top-level object literals that contain function literals and |
2456 // pretenure the literal so it can be added as a constant function | 2528 // pretenure the literal so it can be added as a constant function |
2457 // property. (Parser only.) | 2529 // property. (Parser only.) |
2458 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2530 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
2459 &has_function); | 2531 &has_function); |
(...skipping 22 matching lines...) Expand all Loading... |
2482 return factory()->NewObjectLiteral(properties, | 2554 return factory()->NewObjectLiteral(properties, |
2483 literal_index, | 2555 literal_index, |
2484 number_of_boilerplate_properties, | 2556 number_of_boilerplate_properties, |
2485 has_function, | 2557 has_function, |
2486 pos); | 2558 pos); |
2487 } | 2559 } |
2488 | 2560 |
2489 | 2561 |
2490 template <class Traits> | 2562 template <class Traits> |
2491 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2563 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
2492 Scanner::Location* first_spread_arg_loc, bool* ok) { | 2564 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, |
| 2565 bool* ok) { |
2493 // Arguments :: | 2566 // Arguments :: |
2494 // '(' (AssignmentExpression)*[','] ')' | 2567 // '(' (AssignmentExpression)*[','] ')' |
2495 | 2568 |
2496 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2569 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2497 typename Traits::Type::ExpressionList result = | 2570 typename Traits::Type::ExpressionList result = |
2498 this->NewExpressionList(4, zone_); | 2571 this->NewExpressionList(4, zone_); |
2499 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2572 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2500 bool done = (peek() == Token::RPAREN); | 2573 bool done = (peek() == Token::RPAREN); |
2501 bool was_unspread = false; | 2574 bool was_unspread = false; |
2502 int unspread_sequences_count = 0; | 2575 int unspread_sequences_count = 0; |
2503 while (!done) { | 2576 while (!done) { |
2504 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); | 2577 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); |
2505 int start_pos = peek_position(); | 2578 int start_pos = peek_position(); |
2506 if (is_spread) Consume(Token::ELLIPSIS); | 2579 if (is_spread) Consume(Token::ELLIPSIS); |
2507 | 2580 |
2508 ExpressionT argument = this->ParseAssignmentExpression( | 2581 ExpressionT argument = this->ParseAssignmentExpression( |
2509 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2582 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
2510 if (is_spread) { | 2583 if (is_spread) { |
2511 if (!spread_arg.IsValid()) { | 2584 if (!spread_arg.IsValid()) { |
2512 spread_arg.beg_pos = start_pos; | 2585 spread_arg.beg_pos = start_pos; |
2513 spread_arg.end_pos = peek_position(); | 2586 spread_arg.end_pos = peek_position(); |
2514 } | 2587 } |
2515 argument = factory()->NewSpread(argument, start_pos); | 2588 argument = factory()->NewSpread(argument, start_pos); |
2516 } | 2589 } |
2517 result->Add(argument, zone_); | 2590 result->Add(argument, zone_); |
2518 | 2591 |
2519 // unspread_sequences_count is the number of sequences of parameters which | 2592 // unspread_sequences_count is the number of sequences of parameters which |
(...skipping 29 matching lines...) Expand all Loading... |
2549 // the parser and preparser | 2622 // the parser and preparser |
2550 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2623 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
2551 } | 2624 } |
2552 | 2625 |
2553 return result; | 2626 return result; |
2554 } | 2627 } |
2555 | 2628 |
2556 // Precedence = 2 | 2629 // Precedence = 2 |
2557 template <class Traits> | 2630 template <class Traits> |
2558 typename ParserBase<Traits>::ExpressionT | 2631 typename ParserBase<Traits>::ExpressionT |
2559 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2632 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| 2633 ExpressionClassifier* classifier, |
| 2634 bool* ok) { |
2560 // AssignmentExpression :: | 2635 // AssignmentExpression :: |
2561 // ConditionalExpression | 2636 // ConditionalExpression |
2562 // ArrowFunction | 2637 // ArrowFunction |
2563 // YieldExpression | 2638 // YieldExpression |
2564 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2639 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2565 | 2640 |
2566 Scanner::Location lhs_location = scanner()->peek_location(); | 2641 Scanner::Location lhs_location = scanner()->peek_location(); |
2567 | 2642 |
2568 if (peek() == Token::YIELD && is_generator()) { | 2643 if (peek() == Token::YIELD && is_generator()) { |
2569 return this->ParseYieldExpression(ok); | 2644 return this->ParseYieldExpression(classifier, ok); |
2570 } | 2645 } |
2571 | 2646 |
2572 if (fni_ != NULL) fni_->Enter(); | 2647 if (fni_ != NULL) fni_->Enter(); |
2573 ParserBase<Traits>::Checkpoint checkpoint(this); | 2648 ParserBase<Traits>::Checkpoint checkpoint(this); |
2574 ExpressionT expression = | 2649 ExpressionT expression = |
2575 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2650 this->ParseConditionalExpression(accept_IN, classifier, CHECK_OK); |
2576 | 2651 |
2577 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2652 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
2578 checkpoint.Restore(); | 2653 checkpoint.Restore(); |
2579 FormalParameterErrorLocations error_locs; | 2654 FormalParameterErrorLocations error_locs; |
2580 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); | 2655 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); |
2581 bool has_rest = false; | 2656 bool has_rest = false; |
2582 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); | 2657 Scope* scope = this->NewScope(scope_, ARROW_SCOPE); |
2583 scope->set_start_position(lhs_location.beg_pos); | 2658 scope->set_start_position(lhs_location.beg_pos); |
2584 this->ParseArrowFunctionFormalParameters(scope, expression, loc, | 2659 this->ParseArrowFunctionFormalParameters(scope, expression, loc, |
2585 &error_locs, &has_rest, CHECK_OK); | 2660 &error_locs, &has_rest, CHECK_OK); |
2586 expression = | 2661 expression = this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, |
2587 this->ParseArrowFunctionLiteral(scope, error_locs, has_rest, CHECK_OK); | 2662 classifier, CHECK_OK); |
2588 return expression; | 2663 return expression; |
2589 } | 2664 } |
2590 | 2665 |
2591 if (!Token::IsAssignmentOp(peek())) { | 2666 if (!Token::IsAssignmentOp(peek())) { |
2592 if (fni_ != NULL) fni_->Leave(); | 2667 if (fni_ != NULL) fni_->Leave(); |
2593 // Parsed conditional expression only (no assignment). | 2668 // Parsed conditional expression only (no assignment). |
2594 return expression; | 2669 return expression; |
2595 } | 2670 } |
2596 | 2671 |
2597 expression = this->CheckAndRewriteReferenceExpression( | 2672 expression = this->CheckAndRewriteReferenceExpression( |
2598 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2673 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
2599 expression = this->MarkExpressionAsAssigned(expression); | 2674 expression = this->MarkExpressionAsAssigned(expression); |
2600 | 2675 |
2601 Token::Value op = Next(); // Get assignment operator. | 2676 Token::Value op = Next(); // Get assignment operator. |
2602 int pos = position(); | 2677 int pos = position(); |
2603 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2678 ExpressionT right = |
| 2679 this->ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2604 | 2680 |
2605 // TODO(1231235): We try to estimate the set of properties set by | 2681 // TODO(1231235): We try to estimate the set of properties set by |
2606 // constructors. We define a new property whenever there is an | 2682 // constructors. We define a new property whenever there is an |
2607 // assignment to a property of 'this'. We should probably only add | 2683 // assignment to a property of 'this'. We should probably only add |
2608 // properties if we haven't seen them before. Otherwise we'll | 2684 // properties if we haven't seen them before. Otherwise we'll |
2609 // probably overestimate the number of properties. | 2685 // probably overestimate the number of properties. |
2610 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2686 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
2611 function_state_->AddProperty(); | 2687 function_state_->AddProperty(); |
2612 } | 2688 } |
2613 | 2689 |
(...skipping 12 matching lines...) Expand all Loading... |
2626 fni_->RemoveLastFunction(); | 2702 fni_->RemoveLastFunction(); |
2627 } | 2703 } |
2628 fni_->Leave(); | 2704 fni_->Leave(); |
2629 } | 2705 } |
2630 | 2706 |
2631 return factory()->NewAssignment(op, expression, right, pos); | 2707 return factory()->NewAssignment(op, expression, right, pos); |
2632 } | 2708 } |
2633 | 2709 |
2634 template <class Traits> | 2710 template <class Traits> |
2635 typename ParserBase<Traits>::ExpressionT | 2711 typename ParserBase<Traits>::ExpressionT |
2636 ParserBase<Traits>::ParseYieldExpression(bool* ok) { | 2712 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| 2713 bool* ok) { |
2637 // YieldExpression :: | 2714 // YieldExpression :: |
2638 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2715 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
2639 int pos = peek_position(); | 2716 int pos = peek_position(); |
2640 Expect(Token::YIELD, CHECK_OK); | 2717 Expect(Token::YIELD, CHECK_OK); |
2641 ExpressionT generator_object = | 2718 ExpressionT generator_object = |
2642 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2719 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
2643 ExpressionT expression = Traits::EmptyExpression(); | 2720 ExpressionT expression = Traits::EmptyExpression(); |
2644 Yield::Kind kind = Yield::kSuspend; | 2721 Yield::Kind kind = Yield::kSuspend; |
2645 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2722 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
2646 if (Check(Token::MUL)) kind = Yield::kDelegating; | 2723 if (Check(Token::MUL)) kind = Yield::kDelegating; |
2647 switch (peek()) { | 2724 switch (peek()) { |
2648 case Token::EOS: | 2725 case Token::EOS: |
2649 case Token::SEMICOLON: | 2726 case Token::SEMICOLON: |
2650 case Token::RBRACE: | 2727 case Token::RBRACE: |
2651 case Token::RBRACK: | 2728 case Token::RBRACK: |
2652 case Token::RPAREN: | 2729 case Token::RPAREN: |
2653 case Token::COLON: | 2730 case Token::COLON: |
2654 case Token::COMMA: | 2731 case Token::COMMA: |
2655 // The above set of tokens is the complete set of tokens that can appear | 2732 // The above set of tokens is the complete set of tokens that can appear |
2656 // after an AssignmentExpression, and none of them can start an | 2733 // after an AssignmentExpression, and none of them can start an |
2657 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2734 // AssignmentExpression. This allows us to avoid looking for an RHS for |
2658 // a Yield::kSuspend operation, given only one look-ahead token. | 2735 // a Yield::kSuspend operation, given only one look-ahead token. |
2659 if (kind == Yield::kSuspend) | 2736 if (kind == Yield::kSuspend) |
2660 break; | 2737 break; |
2661 DCHECK_EQ(Yield::kDelegating, kind); | 2738 DCHECK_EQ(Yield::kDelegating, kind); |
2662 // Delegating yields require an RHS; fall through. | 2739 // Delegating yields require an RHS; fall through. |
2663 default: | 2740 default: |
2664 expression = ParseAssignmentExpression(false, CHECK_OK); | 2741 expression = ParseAssignmentExpression(false, classifier, CHECK_OK); |
2665 break; | 2742 break; |
2666 } | 2743 } |
2667 } | 2744 } |
2668 if (kind == Yield::kDelegating) { | 2745 if (kind == Yield::kDelegating) { |
2669 // var iterator = subject[Symbol.iterator](); | 2746 // var iterator = subject[Symbol.iterator](); |
2670 expression = this->GetIterator(expression, factory()); | 2747 expression = this->GetIterator(expression, factory()); |
2671 } | 2748 } |
2672 typename Traits::Type::YieldExpression yield = | 2749 typename Traits::Type::YieldExpression yield = |
2673 factory()->NewYield(generator_object, expression, kind, pos); | 2750 factory()->NewYield(generator_object, expression, kind, pos); |
2674 if (kind == Yield::kDelegating) { | 2751 if (kind == Yield::kDelegating) { |
2675 yield->set_index(function_state_->NextHandlerIndex()); | 2752 yield->set_index(function_state_->NextHandlerIndex()); |
2676 } | 2753 } |
2677 return yield; | 2754 return yield; |
2678 } | 2755 } |
2679 | 2756 |
2680 | 2757 |
2681 // Precedence = 3 | 2758 // Precedence = 3 |
2682 template <class Traits> | 2759 template <class Traits> |
2683 typename ParserBase<Traits>::ExpressionT | 2760 typename ParserBase<Traits>::ExpressionT |
2684 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2761 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
| 2762 ExpressionClassifier* classifier, |
| 2763 bool* ok) { |
2685 // ConditionalExpression :: | 2764 // ConditionalExpression :: |
2686 // LogicalOrExpression | 2765 // LogicalOrExpression |
2687 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2766 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2688 | 2767 |
2689 int pos = peek_position(); | 2768 int pos = peek_position(); |
2690 // We start using the binary expression parser for prec >= 4 only! | 2769 // We start using the binary expression parser for prec >= 4 only! |
2691 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2770 ExpressionT expression = |
| 2771 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
2692 if (peek() != Token::CONDITIONAL) return expression; | 2772 if (peek() != Token::CONDITIONAL) return expression; |
2693 Consume(Token::CONDITIONAL); | 2773 Consume(Token::CONDITIONAL); |
2694 // In parsing the first assignment expression in conditional | 2774 // In parsing the first assignment expression in conditional |
2695 // expressions we always accept the 'in' keyword; see ECMA-262, | 2775 // expressions we always accept the 'in' keyword; see ECMA-262, |
2696 // section 11.12, page 58. | 2776 // section 11.12, page 58. |
2697 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); | 2777 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
2698 Expect(Token::COLON, CHECK_OK); | 2778 Expect(Token::COLON, CHECK_OK); |
2699 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2779 ExpressionT right = |
| 2780 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2700 return factory()->NewConditional(expression, left, right, pos); | 2781 return factory()->NewConditional(expression, left, right, pos); |
2701 } | 2782 } |
2702 | 2783 |
2703 | 2784 |
2704 // Precedence >= 4 | 2785 // Precedence >= 4 |
2705 template <class Traits> | 2786 template <class Traits> |
2706 typename ParserBase<Traits>::ExpressionT | 2787 typename ParserBase<Traits>::ExpressionT |
2707 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2788 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| 2789 ExpressionClassifier* classifier, |
| 2790 bool* ok) { |
2708 DCHECK(prec >= 4); | 2791 DCHECK(prec >= 4); |
2709 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); | 2792 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); |
2710 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2793 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
2711 // prec1 >= 4 | 2794 // prec1 >= 4 |
2712 while (Precedence(peek(), accept_IN) == prec1) { | 2795 while (Precedence(peek(), accept_IN) == prec1) { |
2713 Token::Value op = Next(); | 2796 Token::Value op = Next(); |
2714 Scanner::Location op_location = scanner()->location(); | 2797 Scanner::Location op_location = scanner()->location(); |
2715 int pos = position(); | 2798 int pos = position(); |
2716 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 2799 ExpressionT y = |
| 2800 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); |
2717 | 2801 |
2718 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2802 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
2719 factory())) { | 2803 factory())) { |
2720 continue; | 2804 continue; |
2721 } | 2805 } |
2722 | 2806 |
2723 // For now we distinguish between comparisons and other binary | 2807 // For now we distinguish between comparisons and other binary |
2724 // operations. (We could combine the two and get rid of this | 2808 // operations. (We could combine the two and get rid of this |
2725 // code and AST node eventually.) | 2809 // code and AST node eventually.) |
2726 if (Token::IsCompareOp(op)) { | 2810 if (Token::IsCompareOp(op)) { |
(...skipping 20 matching lines...) Expand all Loading... |
2747 x = factory()->NewBinaryOperation(op, x, y, pos); | 2831 x = factory()->NewBinaryOperation(op, x, y, pos); |
2748 } | 2832 } |
2749 } | 2833 } |
2750 } | 2834 } |
2751 return x; | 2835 return x; |
2752 } | 2836 } |
2753 | 2837 |
2754 | 2838 |
2755 template <class Traits> | 2839 template <class Traits> |
2756 typename ParserBase<Traits>::ExpressionT | 2840 typename ParserBase<Traits>::ExpressionT |
2757 ParserBase<Traits>::ParseUnaryExpression(bool* ok) { | 2841 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, |
| 2842 bool* ok) { |
2758 // UnaryExpression :: | 2843 // UnaryExpression :: |
2759 // PostfixExpression | 2844 // PostfixExpression |
2760 // 'delete' UnaryExpression | 2845 // 'delete' UnaryExpression |
2761 // 'void' UnaryExpression | 2846 // 'void' UnaryExpression |
2762 // 'typeof' UnaryExpression | 2847 // 'typeof' UnaryExpression |
2763 // '++' UnaryExpression | 2848 // '++' UnaryExpression |
2764 // '--' UnaryExpression | 2849 // '--' UnaryExpression |
2765 // '+' UnaryExpression | 2850 // '+' UnaryExpression |
2766 // '-' UnaryExpression | 2851 // '-' UnaryExpression |
2767 // '~' UnaryExpression | 2852 // '~' UnaryExpression |
2768 // '!' UnaryExpression | 2853 // '!' UnaryExpression |
2769 | 2854 |
2770 Token::Value op = peek(); | 2855 Token::Value op = peek(); |
2771 if (Token::IsUnaryOp(op)) { | 2856 if (Token::IsUnaryOp(op)) { |
2772 op = Next(); | 2857 op = Next(); |
2773 int pos = position(); | 2858 int pos = position(); |
2774 ExpressionT expression = ParseUnaryExpression(CHECK_OK); | 2859 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); |
2775 | 2860 |
2776 if (op == Token::DELETE && is_strict(language_mode())) { | 2861 if (op == Token::DELETE && is_strict(language_mode())) { |
2777 if (is_strong(language_mode())) { | 2862 if (is_strong(language_mode())) { |
2778 ReportMessage("strong_delete"); | 2863 ReportMessage("strong_delete"); |
2779 *ok = false; | 2864 *ok = false; |
2780 return this->EmptyExpression(); | 2865 return this->EmptyExpression(); |
2781 } else if (this->IsIdentifier(expression)) { | 2866 } else if (this->IsIdentifier(expression)) { |
2782 // "delete identifier" is a syntax error in strict mode. | 2867 // "delete identifier" is a syntax error in strict mode. |
2783 ReportMessage("strict_delete"); | 2868 ReportMessage("strict_delete"); |
2784 *ok = false; | 2869 *ok = false; |
2785 return this->EmptyExpression(); | 2870 return this->EmptyExpression(); |
2786 } | 2871 } |
2787 } | 2872 } |
2788 | 2873 |
2789 // Allow Traits do rewrite the expression. | 2874 // Allow Traits do rewrite the expression. |
2790 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2875 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2791 } else if (Token::IsCountOp(op)) { | 2876 } else if (Token::IsCountOp(op)) { |
2792 op = Next(); | 2877 op = Next(); |
2793 Scanner::Location lhs_location = scanner()->peek_location(); | 2878 Scanner::Location lhs_location = scanner()->peek_location(); |
2794 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); | 2879 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); |
2795 expression = this->CheckAndRewriteReferenceExpression( | 2880 expression = this->CheckAndRewriteReferenceExpression( |
2796 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 2881 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
2797 this->MarkExpressionAsAssigned(expression); | 2882 this->MarkExpressionAsAssigned(expression); |
2798 | 2883 |
2799 return factory()->NewCountOperation(op, | 2884 return factory()->NewCountOperation(op, |
2800 true /* prefix */, | 2885 true /* prefix */, |
2801 expression, | 2886 expression, |
2802 position()); | 2887 position()); |
2803 | 2888 |
2804 } else { | 2889 } else { |
2805 return this->ParsePostfixExpression(ok); | 2890 return this->ParsePostfixExpression(classifier, ok); |
2806 } | 2891 } |
2807 } | 2892 } |
2808 | 2893 |
2809 | 2894 |
2810 template <class Traits> | 2895 template <class Traits> |
2811 typename ParserBase<Traits>::ExpressionT | 2896 typename ParserBase<Traits>::ExpressionT |
2812 ParserBase<Traits>::ParsePostfixExpression(bool* ok) { | 2897 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 2898 bool* ok) { |
2813 // PostfixExpression :: | 2899 // PostfixExpression :: |
2814 // LeftHandSideExpression ('++' | '--')? | 2900 // LeftHandSideExpression ('++' | '--')? |
2815 | 2901 |
2816 Scanner::Location lhs_location = scanner()->peek_location(); | 2902 Scanner::Location lhs_location = scanner()->peek_location(); |
2817 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); | 2903 ExpressionT expression = |
| 2904 this->ParseLeftHandSideExpression(classifier, CHECK_OK); |
2818 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2905 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
2819 Token::IsCountOp(peek())) { | 2906 Token::IsCountOp(peek())) { |
2820 expression = this->CheckAndRewriteReferenceExpression( | 2907 expression = this->CheckAndRewriteReferenceExpression( |
2821 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 2908 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); |
2822 expression = this->MarkExpressionAsAssigned(expression); | 2909 expression = this->MarkExpressionAsAssigned(expression); |
2823 | 2910 |
2824 Token::Value next = Next(); | 2911 Token::Value next = Next(); |
2825 expression = | 2912 expression = |
2826 factory()->NewCountOperation(next, | 2913 factory()->NewCountOperation(next, |
2827 false /* postfix */, | 2914 false /* postfix */, |
2828 expression, | 2915 expression, |
2829 position()); | 2916 position()); |
2830 } | 2917 } |
2831 return expression; | 2918 return expression; |
2832 } | 2919 } |
2833 | 2920 |
2834 | 2921 |
2835 template <class Traits> | 2922 template <class Traits> |
2836 typename ParserBase<Traits>::ExpressionT | 2923 typename ParserBase<Traits>::ExpressionT |
2837 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { | 2924 ParserBase<Traits>::ParseLeftHandSideExpression( |
| 2925 ExpressionClassifier* classifier, bool* ok) { |
2838 // LeftHandSideExpression :: | 2926 // LeftHandSideExpression :: |
2839 // (NewExpression | MemberExpression) ... | 2927 // (NewExpression | MemberExpression) ... |
2840 | 2928 |
2841 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2929 ExpressionT result = |
| 2930 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
2842 | 2931 |
2843 while (true) { | 2932 while (true) { |
2844 switch (peek()) { | 2933 switch (peek()) { |
2845 case Token::LBRACK: { | 2934 case Token::LBRACK: { |
2846 Consume(Token::LBRACK); | 2935 Consume(Token::LBRACK); |
2847 int pos = position(); | 2936 int pos = position(); |
2848 ExpressionT index = ParseExpression(true, CHECK_OK); | 2937 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); |
2849 result = factory()->NewProperty(result, index, pos); | 2938 result = factory()->NewProperty(result, index, pos); |
2850 Expect(Token::RBRACK, CHECK_OK); | 2939 Expect(Token::RBRACK, CHECK_OK); |
2851 break; | 2940 break; |
2852 } | 2941 } |
2853 | 2942 |
2854 case Token::LPAREN: { | 2943 case Token::LPAREN: { |
2855 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 2944 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
2856 this->IsEval(this->AsIdentifier(result))) { | 2945 this->IsEval(this->AsIdentifier(result))) { |
2857 ReportMessage("strong_direct_eval"); | 2946 ReportMessage("strong_direct_eval"); |
2858 *ok = false; | 2947 *ok = false; |
(...skipping 13 matching lines...) Expand all Loading... |
2872 pos = peek_position(); | 2961 pos = peek_position(); |
2873 // Also the trailing parenthesis are a hint that the function will | 2962 // Also the trailing parenthesis are a hint that the function will |
2874 // be called immediately. If we happen to have parsed a preceding | 2963 // be called immediately. If we happen to have parsed a preceding |
2875 // function literal eagerly, we can also compile it eagerly. | 2964 // function literal eagerly, we can also compile it eagerly. |
2876 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2965 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
2877 result->AsFunctionLiteral()->set_parenthesized(); | 2966 result->AsFunctionLiteral()->set_parenthesized(); |
2878 } | 2967 } |
2879 } | 2968 } |
2880 Scanner::Location spread_pos; | 2969 Scanner::Location spread_pos; |
2881 typename Traits::Type::ExpressionList args = | 2970 typename Traits::Type::ExpressionList args = |
2882 ParseArguments(&spread_pos, CHECK_OK); | 2971 ParseArguments(&spread_pos, classifier, CHECK_OK); |
2883 | 2972 |
2884 // Keep track of eval() calls since they disable all local variable | 2973 // Keep track of eval() calls since they disable all local variable |
2885 // optimizations. | 2974 // optimizations. |
2886 // The calls that need special treatment are the | 2975 // The calls that need special treatment are the |
2887 // direct eval calls. These calls are all of the form eval(...), with | 2976 // direct eval calls. These calls are all of the form eval(...), with |
2888 // no explicit receiver. | 2977 // no explicit receiver. |
2889 // These calls are marked as potentially direct eval calls. Whether | 2978 // These calls are marked as potentially direct eval calls. Whether |
2890 // they are actually direct calls to eval is determined at run time. | 2979 // they are actually direct calls to eval is determined at run time. |
2891 this->CheckPossibleEvalCall(result, scope_); | 2980 this->CheckPossibleEvalCall(result, scope_); |
2892 | 2981 |
(...skipping 19 matching lines...) Expand all Loading... |
2912 | 3001 |
2913 default: | 3002 default: |
2914 return result; | 3003 return result; |
2915 } | 3004 } |
2916 } | 3005 } |
2917 } | 3006 } |
2918 | 3007 |
2919 | 3008 |
2920 template <class Traits> | 3009 template <class Traits> |
2921 typename ParserBase<Traits>::ExpressionT | 3010 typename ParserBase<Traits>::ExpressionT |
2922 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { | 3011 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
| 3012 ExpressionClassifier* classifier, bool* ok) { |
2923 // NewExpression :: | 3013 // NewExpression :: |
2924 // ('new')+ MemberExpression | 3014 // ('new')+ MemberExpression |
2925 | 3015 |
2926 // The grammar for new expressions is pretty warped. We can have several 'new' | 3016 // The grammar for new expressions is pretty warped. We can have several 'new' |
2927 // keywords following each other, and then a MemberExpression. When we see '(' | 3017 // keywords following each other, and then a MemberExpression. When we see '(' |
2928 // after the MemberExpression, it's associated with the rightmost unassociated | 3018 // after the MemberExpression, it's associated with the rightmost unassociated |
2929 // 'new' to create a NewExpression with arguments. However, a NewExpression | 3019 // 'new' to create a NewExpression with arguments. However, a NewExpression |
2930 // can also occur without arguments. | 3020 // can also occur without arguments. |
2931 | 3021 |
2932 // Examples of new expression: | 3022 // Examples of new expression: |
2933 // new foo.bar().baz means (new (foo.bar)()).baz | 3023 // new foo.bar().baz means (new (foo.bar)()).baz |
2934 // new foo()() means (new foo())() | 3024 // new foo()() means (new foo())() |
2935 // new new foo()() means (new (new foo())()) | 3025 // new new foo()() means (new (new foo())()) |
2936 // new new foo means new (new foo) | 3026 // new new foo means new (new foo) |
2937 // new new foo() means new (new foo()) | 3027 // new new foo() means new (new foo()) |
2938 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3028 // new new foo().bar().baz means (new (new foo()).bar()).baz |
2939 | 3029 |
2940 if (peek() == Token::NEW) { | 3030 if (peek() == Token::NEW) { |
2941 Consume(Token::NEW); | 3031 Consume(Token::NEW); |
2942 int new_pos = position(); | 3032 int new_pos = position(); |
2943 ExpressionT result = this->EmptyExpression(); | 3033 ExpressionT result = this->EmptyExpression(); |
2944 if (peek() == Token::SUPER) { | 3034 if (peek() == Token::SUPER) { |
2945 const bool is_new = true; | 3035 const bool is_new = true; |
2946 result = ParseSuperExpression(is_new, CHECK_OK); | 3036 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
2947 } else { | 3037 } else { |
2948 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 3038 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
2949 } | 3039 } |
2950 if (peek() == Token::LPAREN) { | 3040 if (peek() == Token::LPAREN) { |
2951 // NewExpression with arguments. | 3041 // NewExpression with arguments. |
2952 Scanner::Location spread_pos; | 3042 Scanner::Location spread_pos; |
2953 typename Traits::Type::ExpressionList args = | 3043 typename Traits::Type::ExpressionList args = |
2954 this->ParseArguments(&spread_pos, CHECK_OK); | 3044 this->ParseArguments(&spread_pos, classifier, CHECK_OK); |
2955 | 3045 |
2956 if (spread_pos.IsValid()) { | 3046 if (spread_pos.IsValid()) { |
2957 args = Traits::PrepareSpreadArguments(args); | 3047 args = Traits::PrepareSpreadArguments(args); |
2958 result = Traits::SpreadCallNew(result, args, new_pos); | 3048 result = Traits::SpreadCallNew(result, args, new_pos); |
2959 } else { | 3049 } else { |
2960 result = factory()->NewCallNew(result, args, new_pos); | 3050 result = factory()->NewCallNew(result, args, new_pos); |
2961 } | 3051 } |
2962 // The expression can still continue with . or [ after the arguments. | 3052 // The expression can still continue with . or [ after the arguments. |
2963 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 3053 result = |
| 3054 this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK); |
2964 return result; | 3055 return result; |
2965 } | 3056 } |
2966 // NewExpression without arguments. | 3057 // NewExpression without arguments. |
2967 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 3058 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
2968 new_pos); | 3059 new_pos); |
2969 } | 3060 } |
2970 // No 'new' or 'super' keyword. | 3061 // No 'new' or 'super' keyword. |
2971 return this->ParseMemberExpression(ok); | 3062 return this->ParseMemberExpression(classifier, ok); |
2972 } | 3063 } |
2973 | 3064 |
2974 | 3065 |
2975 template <class Traits> | 3066 template <class Traits> |
2976 typename ParserBase<Traits>::ExpressionT | 3067 typename ParserBase<Traits>::ExpressionT |
2977 ParserBase<Traits>::ParseMemberExpression(bool* ok) { | 3068 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
| 3069 bool* ok) { |
2978 // MemberExpression :: | 3070 // MemberExpression :: |
2979 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3071 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
2980 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3072 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
2981 | 3073 |
2982 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3074 // The '[' Expression ']' and '.' Identifier parts are parsed by |
2983 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3075 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
2984 // caller. | 3076 // caller. |
2985 | 3077 |
2986 // Parse the initial primary or function expression. | 3078 // Parse the initial primary or function expression. |
2987 ExpressionT result = this->EmptyExpression(); | 3079 ExpressionT result = this->EmptyExpression(); |
(...skipping 13 matching lines...) Expand all Loading... |
3001 function_type = FunctionLiteral::NAMED_EXPRESSION; | 3093 function_type = FunctionLiteral::NAMED_EXPRESSION; |
3002 } | 3094 } |
3003 result = this->ParseFunctionLiteral( | 3095 result = this->ParseFunctionLiteral( |
3004 name, function_name_location, is_strict_reserved_name, | 3096 name, function_name_location, is_strict_reserved_name, |
3005 is_generator ? FunctionKind::kGeneratorFunction | 3097 is_generator ? FunctionKind::kGeneratorFunction |
3006 : FunctionKind::kNormalFunction, | 3098 : FunctionKind::kNormalFunction, |
3007 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 3099 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
3008 CHECK_OK); | 3100 CHECK_OK); |
3009 } else if (peek() == Token::SUPER) { | 3101 } else if (peek() == Token::SUPER) { |
3010 const bool is_new = false; | 3102 const bool is_new = false; |
3011 result = ParseSuperExpression(is_new, CHECK_OK); | 3103 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
3012 } else { | 3104 } else { |
3013 result = ParsePrimaryExpression(CHECK_OK); | 3105 result = ParsePrimaryExpression(classifier, CHECK_OK); |
3014 } | 3106 } |
3015 | 3107 |
3016 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 3108 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); |
3017 return result; | 3109 return result; |
3018 } | 3110 } |
3019 | 3111 |
3020 | 3112 |
3021 template <class Traits> | 3113 template <class Traits> |
3022 typename ParserBase<Traits>::ExpressionT | 3114 typename ParserBase<Traits>::ExpressionT |
3023 ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) { | 3115 ParserBase<Traits>::ParseStrongInitializationExpression( |
| 3116 ExpressionClassifier* classifier, bool* ok) { |
3024 // InitializationExpression :: (strong mode) | 3117 // InitializationExpression :: (strong mode) |
3025 // 'this' '.' IdentifierName '=' AssignmentExpression | 3118 // 'this' '.' IdentifierName '=' AssignmentExpression |
3026 // 'this' '[' Expression ']' '=' AssignmentExpression | 3119 // 'this' '[' Expression ']' '=' AssignmentExpression |
3027 | 3120 |
3028 if (fni_ != NULL) fni_->Enter(); | 3121 if (fni_ != NULL) fni_->Enter(); |
3029 | 3122 |
3030 Consume(Token::THIS); | 3123 Consume(Token::THIS); |
3031 int pos = position(); | 3124 int pos = position(); |
3032 function_state_->set_this_location(scanner()->location()); | 3125 function_state_->set_this_location(scanner()->location()); |
3033 scope_->RecordThisUsage(); | 3126 scope_->RecordThisUsage(); |
3034 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | 3127 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); |
3035 | 3128 |
3036 ExpressionT left = this->EmptyExpression(); | 3129 ExpressionT left = this->EmptyExpression(); |
3037 switch (peek()) { | 3130 switch (peek()) { |
3038 case Token::LBRACK: { | 3131 case Token::LBRACK: { |
3039 Consume(Token::LBRACK); | 3132 Consume(Token::LBRACK); |
3040 int pos = position(); | 3133 int pos = position(); |
3041 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 3134 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
3042 left = factory()->NewProperty(this_expr, index, pos); | 3135 left = factory()->NewProperty(this_expr, index, pos); |
3043 if (fni_ != NULL) { | 3136 if (fni_ != NULL) { |
3044 this->PushPropertyName(fni_, index); | 3137 this->PushPropertyName(fni_, index); |
3045 } | 3138 } |
3046 Expect(Token::RBRACK, CHECK_OK); | 3139 Expect(Token::RBRACK, CHECK_OK); |
3047 break; | 3140 break; |
3048 } | 3141 } |
3049 case Token::PERIOD: { | 3142 case Token::PERIOD: { |
3050 Consume(Token::PERIOD); | 3143 Consume(Token::PERIOD); |
3051 int pos = position(); | 3144 int pos = position(); |
(...skipping 13 matching lines...) Expand all Loading... |
3065 | 3158 |
3066 if (peek() != Token::ASSIGN) { | 3159 if (peek() != Token::ASSIGN) { |
3067 ReportMessageAt(function_state_->this_location(), | 3160 ReportMessageAt(function_state_->this_location(), |
3068 "strong_constructor_this"); | 3161 "strong_constructor_this"); |
3069 *ok = false; | 3162 *ok = false; |
3070 return this->EmptyExpression(); | 3163 return this->EmptyExpression(); |
3071 } | 3164 } |
3072 Consume(Token::ASSIGN); | 3165 Consume(Token::ASSIGN); |
3073 left = this->MarkExpressionAsAssigned(left); | 3166 left = this->MarkExpressionAsAssigned(left); |
3074 | 3167 |
3075 ExpressionT right = this->ParseAssignmentExpression(true, CHECK_OK); | 3168 ExpressionT right = |
| 3169 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
3076 this->CheckAssigningFunctionLiteralToProperty(left, right); | 3170 this->CheckAssigningFunctionLiteralToProperty(left, right); |
3077 function_state_->AddProperty(); | 3171 function_state_->AddProperty(); |
3078 if (fni_ != NULL) { | 3172 if (fni_ != NULL) { |
3079 // Check if the right hand side is a call to avoid inferring a | 3173 // Check if the right hand side is a call to avoid inferring a |
3080 // name if we're dealing with "this.a = function(){...}();"-like | 3174 // name if we're dealing with "this.a = function(){...}();"-like |
3081 // expression. | 3175 // expression. |
3082 if (!right->IsCall() && !right->IsCallNew()) { | 3176 if (!right->IsCall() && !right->IsCallNew()) { |
3083 fni_->Infer(); | 3177 fni_->Infer(); |
3084 } else { | 3178 } else { |
3085 fni_->RemoveLastFunction(); | 3179 fni_->RemoveLastFunction(); |
3086 } | 3180 } |
3087 fni_->Leave(); | 3181 fni_->Leave(); |
3088 } | 3182 } |
3089 | 3183 |
3090 if (function_state_->return_location().IsValid()) { | 3184 if (function_state_->return_location().IsValid()) { |
3091 ReportMessageAt(function_state_->return_location(), | 3185 ReportMessageAt(function_state_->return_location(), |
3092 "strong_constructor_return_misplaced"); | 3186 "strong_constructor_return_misplaced"); |
3093 *ok = false; | 3187 *ok = false; |
3094 return this->EmptyExpression(); | 3188 return this->EmptyExpression(); |
3095 } | 3189 } |
3096 | 3190 |
3097 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | 3191 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); |
3098 } | 3192 } |
3099 | 3193 |
3100 | 3194 |
3101 template <class Traits> | 3195 template <class Traits> |
3102 typename ParserBase<Traits>::ExpressionT | 3196 typename ParserBase<Traits>::ExpressionT |
3103 ParserBase<Traits>::ParseStrongSuperCallExpression(bool* ok) { | 3197 ParserBase<Traits>::ParseStrongSuperCallExpression( |
| 3198 ExpressionClassifier* classifier, bool* ok) { |
3104 // SuperCallExpression :: (strong mode) | 3199 // SuperCallExpression :: (strong mode) |
3105 // 'super' '(' ExpressionList ')' | 3200 // 'super' '(' ExpressionList ')' |
3106 | 3201 |
3107 Consume(Token::SUPER); | 3202 Consume(Token::SUPER); |
3108 int pos = position(); | 3203 int pos = position(); |
3109 Scanner::Location super_loc = scanner()->location(); | 3204 Scanner::Location super_loc = scanner()->location(); |
3110 ExpressionT expr = this->SuperReference(scope_, factory()); | 3205 ExpressionT expr = this->SuperReference(scope_, factory()); |
3111 | 3206 |
3112 if (peek() != Token::LPAREN) { | 3207 if (peek() != Token::LPAREN) { |
3113 ReportMessage("strong_constructor_super"); | 3208 ReportMessage("strong_constructor_super"); |
3114 *ok = false; | 3209 *ok = false; |
3115 return this->EmptyExpression(); | 3210 return this->EmptyExpression(); |
3116 } | 3211 } |
3117 | 3212 |
3118 Scanner::Location spread_pos; | 3213 Scanner::Location spread_pos; |
3119 typename Traits::Type::ExpressionList args = | 3214 typename Traits::Type::ExpressionList args = |
3120 ParseArguments(&spread_pos, CHECK_OK); | 3215 ParseArguments(&spread_pos, classifier, CHECK_OK); |
3121 | 3216 |
3122 // TODO(rossberg): This doesn't work with arrow functions yet. | 3217 // TODO(rossberg): This doesn't work with arrow functions yet. |
3123 if (!IsSubclassConstructor(function_state_->kind())) { | 3218 if (!IsSubclassConstructor(function_state_->kind())) { |
3124 ReportMessage("unexpected_super"); | 3219 ReportMessage("unexpected_super"); |
3125 *ok = false; | 3220 *ok = false; |
3126 return this->EmptyExpression(); | 3221 return this->EmptyExpression(); |
3127 } else if (function_state_->super_location().IsValid()) { | 3222 } else if (function_state_->super_location().IsValid()) { |
3128 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | 3223 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); |
3129 *ok = false; | 3224 *ok = false; |
3130 return this->EmptyExpression(); | 3225 return this->EmptyExpression(); |
(...skipping 13 matching lines...) Expand all Loading... |
3144 args = Traits::PrepareSpreadArguments(args); | 3239 args = Traits::PrepareSpreadArguments(args); |
3145 return Traits::SpreadCall(expr, args, pos); | 3240 return Traits::SpreadCall(expr, args, pos); |
3146 } else { | 3241 } else { |
3147 return factory()->NewCall(expr, args, pos); | 3242 return factory()->NewCall(expr, args, pos); |
3148 } | 3243 } |
3149 } | 3244 } |
3150 | 3245 |
3151 | 3246 |
3152 template <class Traits> | 3247 template <class Traits> |
3153 typename ParserBase<Traits>::ExpressionT | 3248 typename ParserBase<Traits>::ExpressionT |
3154 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 3249 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
| 3250 ExpressionClassifier* classifier, |
| 3251 bool* ok) { |
3155 Expect(Token::SUPER, CHECK_OK); | 3252 Expect(Token::SUPER, CHECK_OK); |
3156 | 3253 |
3157 // TODO(wingo): Does this actually work with lazily compiled arrows? | 3254 // TODO(wingo): Does this actually work with lazily compiled arrows? |
3158 FunctionState* function_state = function_state_; | 3255 FunctionState* function_state = function_state_; |
3159 while (IsArrowFunction(function_state->kind())) { | 3256 while (IsArrowFunction(function_state->kind())) { |
3160 function_state = function_state->outer(); | 3257 function_state = function_state->outer(); |
3161 } | 3258 } |
3162 // TODO(arv): Handle eval scopes similarly. | 3259 // TODO(arv): Handle eval scopes similarly. |
3163 | 3260 |
3164 FunctionKind kind = function_state->kind(); | 3261 FunctionKind kind = function_state->kind(); |
(...skipping 18 matching lines...) Expand all Loading... |
3183 } | 3280 } |
3184 | 3281 |
3185 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3282 ReportMessageAt(scanner()->location(), "unexpected_super"); |
3186 *ok = false; | 3283 *ok = false; |
3187 return this->EmptyExpression(); | 3284 return this->EmptyExpression(); |
3188 } | 3285 } |
3189 | 3286 |
3190 | 3287 |
3191 template <class Traits> | 3288 template <class Traits> |
3192 typename ParserBase<Traits>::ExpressionT | 3289 typename ParserBase<Traits>::ExpressionT |
3193 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 3290 ParserBase<Traits>::ParseMemberExpressionContinuation( |
3194 bool* ok) { | 3291 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
3195 // Parses this part of MemberExpression: | 3292 // Parses this part of MemberExpression: |
3196 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3293 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
3197 while (true) { | 3294 while (true) { |
3198 switch (peek()) { | 3295 switch (peek()) { |
3199 case Token::LBRACK: { | 3296 case Token::LBRACK: { |
3200 Consume(Token::LBRACK); | 3297 Consume(Token::LBRACK); |
3201 int pos = position(); | 3298 int pos = position(); |
3202 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 3299 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); |
3203 expression = factory()->NewProperty(expression, index, pos); | 3300 expression = factory()->NewProperty(expression, index, pos); |
3204 if (fni_ != NULL) { | 3301 if (fni_ != NULL) { |
3205 this->PushPropertyName(fni_, index); | 3302 this->PushPropertyName(fni_, index); |
3206 } | 3303 } |
3207 Expect(Token::RBRACK, CHECK_OK); | 3304 Expect(Token::RBRACK, CHECK_OK); |
3208 break; | 3305 break; |
3209 } | 3306 } |
3210 case Token::PERIOD: { | 3307 case Token::PERIOD: { |
3211 Consume(Token::PERIOD); | 3308 Consume(Token::PERIOD); |
3212 int pos = position(); | 3309 int pos = position(); |
(...skipping 11 matching lines...) Expand all Loading... |
3224 if (scanner()->current_token() == Token::IDENTIFIER) { | 3321 if (scanner()->current_token() == Token::IDENTIFIER) { |
3225 pos = position(); | 3322 pos = position(); |
3226 } else { | 3323 } else { |
3227 pos = peek_position(); | 3324 pos = peek_position(); |
3228 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3325 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3229 // If the tag function looks like an IIFE, set_parenthesized() to | 3326 // If the tag function looks like an IIFE, set_parenthesized() to |
3230 // force eager compilation. | 3327 // force eager compilation. |
3231 expression->AsFunctionLiteral()->set_parenthesized(); | 3328 expression->AsFunctionLiteral()->set_parenthesized(); |
3232 } | 3329 } |
3233 } | 3330 } |
3234 expression = ParseTemplateLiteral(expression, pos, CHECK_OK); | 3331 expression = |
| 3332 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); |
3235 break; | 3333 break; |
3236 } | 3334 } |
3237 default: | 3335 default: |
3238 return expression; | 3336 return expression; |
3239 } | 3337 } |
3240 } | 3338 } |
3241 DCHECK(false); | 3339 DCHECK(false); |
3242 return this->EmptyExpression(); | 3340 return this->EmptyExpression(); |
3243 } | 3341 } |
3244 | 3342 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3336 default: | 3434 default: |
3337 break; | 3435 break; |
3338 } | 3436 } |
3339 } | 3437 } |
3340 | 3438 |
3341 | 3439 |
3342 template <class Traits> | 3440 template <class Traits> |
3343 typename ParserBase<Traits>::ExpressionT | 3441 typename ParserBase<Traits>::ExpressionT |
3344 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3442 ParserBase<Traits>::ParseArrowFunctionLiteral( |
3345 Scope* scope, const FormalParameterErrorLocations& error_locs, | 3443 Scope* scope, const FormalParameterErrorLocations& error_locs, |
3346 bool has_rest, bool* ok) { | 3444 bool has_rest, ExpressionClassifier* classifier, bool* ok) { |
3347 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3445 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3348 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3446 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3349 // `=> ...` is never a valid expression, so report as syntax error. | 3447 // `=> ...` is never a valid expression, so report as syntax error. |
3350 // If next token is not `=>`, it's a syntax error anyways. | 3448 // If next token is not `=>`, it's a syntax error anyways. |
3351 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3449 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3352 *ok = false; | 3450 *ok = false; |
3353 return this->EmptyExpression(); | 3451 return this->EmptyExpression(); |
3354 } | 3452 } |
3355 | 3453 |
3356 typename Traits::Type::StatementList body; | 3454 typename Traits::Type::StatementList body; |
(...skipping 25 matching lines...) Expand all Loading... |
3382 Token::INIT_VAR, kArrowFunction, CHECK_OK); | 3480 Token::INIT_VAR, kArrowFunction, CHECK_OK); |
3383 materialized_literal_count = | 3481 materialized_literal_count = |
3384 function_state.materialized_literal_count(); | 3482 function_state.materialized_literal_count(); |
3385 expected_property_count = function_state.expected_property_count(); | 3483 expected_property_count = function_state.expected_property_count(); |
3386 handler_count = function_state.handler_count(); | 3484 handler_count = function_state.handler_count(); |
3387 } | 3485 } |
3388 } else { | 3486 } else { |
3389 // Single-expression body | 3487 // Single-expression body |
3390 int pos = position(); | 3488 int pos = position(); |
3391 parenthesized_function_ = false; | 3489 parenthesized_function_ = false; |
3392 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3490 ExpressionT expression = |
| 3491 ParseAssignmentExpression(true, classifier, CHECK_OK); |
3393 body = this->NewStatementList(1, zone()); | 3492 body = this->NewStatementList(1, zone()); |
3394 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3493 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3395 materialized_literal_count = function_state.materialized_literal_count(); | 3494 materialized_literal_count = function_state.materialized_literal_count(); |
3396 expected_property_count = function_state.expected_property_count(); | 3495 expected_property_count = function_state.expected_property_count(); |
3397 handler_count = function_state.handler_count(); | 3496 handler_count = function_state.handler_count(); |
3398 } | 3497 } |
3399 super_loc = function_state.super_location(); | 3498 super_loc = function_state.super_location(); |
3400 | 3499 |
3401 scope->set_end_position(scanner()->location().end_pos); | 3500 scope->set_end_position(scanner()->location().end_pos); |
3402 | 3501 |
(...skipping 25 matching lines...) Expand all Loading... |
3428 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3527 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
3429 | 3528 |
3430 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3529 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3431 | 3530 |
3432 return function_literal; | 3531 return function_literal; |
3433 } | 3532 } |
3434 | 3533 |
3435 | 3534 |
3436 template <typename Traits> | 3535 template <typename Traits> |
3437 typename ParserBase<Traits>::ExpressionT | 3536 typename ParserBase<Traits>::ExpressionT |
3438 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { | 3537 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, |
| 3538 ExpressionClassifier* classifier, |
| 3539 bool* ok) { |
3439 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3540 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
3440 // text followed by a substitution expression), finalized by a single | 3541 // text followed by a substitution expression), finalized by a single |
3441 // TEMPLATE_TAIL. | 3542 // TEMPLATE_TAIL. |
3442 // | 3543 // |
3443 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 3544 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
3444 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 3545 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
3445 // NoSubstitutionTemplate. | 3546 // NoSubstitutionTemplate. |
3446 // | 3547 // |
3447 // When parsing a TemplateLiteral, we must have scanned either an initial | 3548 // When parsing a TemplateLiteral, we must have scanned either an initial |
3448 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3549 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3480 return Traits::EmptyExpression(); | 3581 return Traits::EmptyExpression(); |
3481 } else if (next == Token::ILLEGAL) { | 3582 } else if (next == Token::ILLEGAL) { |
3482 Traits::ReportMessageAt( | 3583 Traits::ReportMessageAt( |
3483 Scanner::Location(position() + 1, peek_position()), | 3584 Scanner::Location(position() + 1, peek_position()), |
3484 "unexpected_token", "ILLEGAL", kSyntaxError); | 3585 "unexpected_token", "ILLEGAL", kSyntaxError); |
3485 *ok = false; | 3586 *ok = false; |
3486 return Traits::EmptyExpression(); | 3587 return Traits::EmptyExpression(); |
3487 } | 3588 } |
3488 | 3589 |
3489 int expr_pos = peek_position(); | 3590 int expr_pos = peek_position(); |
3490 ExpressionT expression = this->ParseExpression(true, CHECK_OK); | 3591 ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); |
3491 Traits::AddTemplateExpression(&ts, expression); | 3592 Traits::AddTemplateExpression(&ts, expression); |
3492 | 3593 |
3493 if (peek() != Token::RBRACE) { | 3594 if (peek() != Token::RBRACE) { |
3494 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3595 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
3495 "unterminated_template_expr"); | 3596 "unterminated_template_expr"); |
3496 *ok = false; | 3597 *ok = false; |
3497 return Traits::EmptyExpression(); | 3598 return Traits::EmptyExpression(); |
3498 } | 3599 } |
3499 | 3600 |
3500 // If we didn't die parsing that expression, our next token should be a | 3601 // If we didn't die parsing that expression, our next token should be a |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3612 *ok = false; | 3713 *ok = false; |
3613 return; | 3714 return; |
3614 } | 3715 } |
3615 has_seen_constructor_ = true; | 3716 has_seen_constructor_ = true; |
3616 return; | 3717 return; |
3617 } | 3718 } |
3618 } | 3719 } |
3619 } } // v8::internal | 3720 } } // v8::internal |
3620 | 3721 |
3621 #endif // V8_PREPARSER_H | 3722 #endif // V8_PREPARSER_H |
OLD | NEW |