| 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 |