Chromium Code Reviews| 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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 // whether it is strict mode future reserved. | 567 // whether it is strict mode future reserved. |
| 568 IdentifierT ParseIdentifierOrStrictReservedWord( | 568 IdentifierT ParseIdentifierOrStrictReservedWord( |
| 569 bool* is_strict_reserved, | 569 bool* is_strict_reserved, |
| 570 bool* ok); | 570 bool* ok); |
| 571 IdentifierT ParseIdentifierName(bool* ok); | 571 IdentifierT ParseIdentifierName(bool* ok); |
| 572 // Parses an identifier and determines whether or not it is 'get' or 'set'. | 572 // Parses an identifier and determines whether or not it is 'get' or 'set'. |
| 573 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, | 573 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 574 bool* is_set, | 574 bool* is_set, |
| 575 bool* ok); | 575 bool* ok); |
| 576 | 576 |
| 577 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); | |
| 578 | 577 |
| 579 ExpressionT ParsePrimaryExpression(bool* ok); | 578 class ExpressionClassifier { |
|
rossberg
2015/04/22 09:30:47
Don't we also want is_valid_arrow_parameter_list,
Dmitry Lomov (no reviews)
2015/04/22 09:36:55
Sounds good, but I'd prefer to do that in a separa
| |
| 579 public: | |
| 580 ExpressionClassifier() | |
| 581 : expression_error_(Scanner::Location::invalid()), | |
| 582 binding_pattern_error_(Scanner::Location::invalid()), | |
| 583 assignment_pattern_error_(Scanner::Location::invalid()) {} | |
| 584 | |
| 585 bool is_valid_expression() const { | |
| 586 return expression_error_ == Scanner::Location::invalid(); | |
| 587 } | |
| 588 | |
| 589 bool is_valid_binding_pattern() const { | |
| 590 return binding_pattern_error_ == Scanner::Location::invalid(); | |
| 591 } | |
| 592 | |
| 593 bool is_valid_assignmnent_pattern() const { | |
| 594 return assignment_pattern_error_ == Scanner::Location::invalid(); | |
| 595 } | |
| 596 | |
| 597 void RecordExpressionError(const Scanner::Location& loc) { | |
| 598 if (!is_valid_expression()) return; | |
| 599 expression_error_ = loc; | |
| 600 } | |
| 601 | |
| 602 void RecordBindingPatternError(const Scanner::Location& loc) { | |
| 603 if (!is_valid_binding_pattern()) return; | |
| 604 binding_pattern_error_ = loc; | |
| 605 } | |
| 606 | |
| 607 void RecordAssignmentPatternError(const Scanner::Location& loc) { | |
| 608 if (!is_valid_assignmnent_pattern()) return; | |
| 609 assignment_pattern_error_ = loc; | |
| 610 } | |
| 611 | |
| 612 private: | |
| 613 Scanner::Location expression_error_; | |
| 614 Scanner::Location binding_pattern_error_; | |
| 615 Scanner::Location assignment_pattern_error_; | |
| 616 }; | |
| 617 | |
| 618 ExpressionT ParseRegExpLiteral(bool seen_equal, | |
| 619 ExpressionClassifier* classifier, bool* ok); | |
| 620 | |
| 621 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, | |
| 622 bool* ok); | |
| 580 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 623 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 581 ExpressionT ParseArrayLiteral(bool* ok); | 624 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, |
| 625 bool* ok); | |
| 626 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); | |
| 582 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 627 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 583 bool* is_static, bool* is_computed_name, | 628 bool* is_static, bool* is_computed_name, |
| 584 bool* ok); | 629 ExpressionClassifier* classifier, bool* ok); |
| 585 ExpressionT ParseObjectLiteral(bool* ok); | 630 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); |
| 586 ObjectLiteralPropertyT ParsePropertyDefinition( | 631 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 587 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 632 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 588 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 633 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 634 ExpressionClassifier* classifier, bool* ok); | |
| 635 typename Traits::Type::ExpressionList ParseArguments( | |
| 636 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, | |
| 589 bool* ok); | 637 bool* ok); |
| 590 typename Traits::Type::ExpressionList ParseArguments( | 638 ExpressionT ParseAssignmentExpression(bool accept_IN, |
| 591 Scanner::Location* first_spread_pos, bool* ok); | 639 ExpressionClassifier* classifier, |
| 592 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 640 bool* ok); |
| 593 ExpressionT ParseYieldExpression(bool* ok); | 641 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); |
| 594 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 642 ExpressionT ParseConditionalExpression(bool accept_IN, |
| 595 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 643 ExpressionClassifier* classifier, |
| 596 ExpressionT ParseUnaryExpression(bool* ok); | 644 bool* ok); |
| 597 ExpressionT ParsePostfixExpression(bool* ok); | 645 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, |
| 598 ExpressionT ParseLeftHandSideExpression(bool* ok); | 646 ExpressionClassifier* classifier, bool* ok); |
| 599 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 647 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); |
| 600 ExpressionT ParseMemberExpression(bool* ok); | 648 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, |
| 601 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 649 bool* ok); |
| 602 bool* ok); | 650 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, |
| 651 bool* ok); | |
| 652 ExpressionT ParseMemberWithNewPrefixesExpression( | |
| 653 ExpressionClassifier* classifier, bool* ok); | |
| 654 ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok); | |
| 655 ExpressionT ParseMemberExpressionContinuation( | |
| 656 ExpressionT expression, ExpressionClassifier* classifier, bool* ok); | |
| 603 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 657 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 658 ExpressionClassifier* classifier, | |
| 604 bool* ok); | 659 bool* ok); |
| 605 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 660 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, |
| 661 ExpressionClassifier* classifier, bool* ok); | |
| 606 void AddTemplateExpression(ExpressionT); | 662 void AddTemplateExpression(ExpressionT); |
| 607 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 663 ExpressionT ParseSuperExpression(bool is_new, |
| 664 ExpressionClassifier* classifier, bool* ok); | |
| 608 | 665 |
| 609 // Checks if the expression is a valid reference expression (e.g., on the | 666 // Checks if the expression is a valid reference expression (e.g., on the |
| 610 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 667 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 611 // we allow calls for web compatibility and rewrite them to a runtime throw. | 668 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 612 ExpressionT CheckAndRewriteReferenceExpression( | 669 ExpressionT CheckAndRewriteReferenceExpression( |
| 613 ExpressionT expression, | 670 ExpressionT expression, |
| 614 Scanner::Location location, const char* message, bool* ok); | 671 Scanner::Location location, const char* message, bool* ok); |
| 615 | 672 |
| 616 // Used to validate property names in object literals and class literals | 673 // Used to validate property names in object literals and class literals |
| 617 enum PropertyKind { | 674 enum PropertyKind { |
| (...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1923 bool* ok) { | 1980 bool* ok) { |
| 1924 IdentifierT result = ParseIdentifierName(ok); | 1981 IdentifierT result = ParseIdentifierName(ok); |
| 1925 if (!*ok) return Traits::EmptyIdentifier(); | 1982 if (!*ok) return Traits::EmptyIdentifier(); |
| 1926 scanner()->IsGetOrSet(is_get, is_set); | 1983 scanner()->IsGetOrSet(is_get, is_set); |
| 1927 return result; | 1984 return result; |
| 1928 } | 1985 } |
| 1929 | 1986 |
| 1930 | 1987 |
| 1931 template <class Traits> | 1988 template <class Traits> |
| 1932 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( | 1989 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( |
| 1933 bool seen_equal, bool* ok) { | 1990 bool seen_equal, ExpressionClassifier* classifier, bool* ok) { |
| 1934 int pos = peek_position(); | 1991 int pos = peek_position(); |
| 1935 if (!scanner()->ScanRegExpPattern(seen_equal)) { | 1992 if (!scanner()->ScanRegExpPattern(seen_equal)) { |
| 1936 Next(); | 1993 Next(); |
| 1937 ReportMessage("unterminated_regexp"); | 1994 ReportMessage("unterminated_regexp"); |
| 1938 *ok = false; | 1995 *ok = false; |
| 1939 return Traits::EmptyExpression(); | 1996 return Traits::EmptyExpression(); |
| 1940 } | 1997 } |
| 1941 | 1998 |
| 1942 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1999 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 1943 | 2000 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1960 #define DUMMY ) // to make indentation work | 2017 #define DUMMY ) // to make indentation work |
| 1961 #undef DUMMY | 2018 #undef DUMMY |
| 1962 | 2019 |
| 1963 // Used in functions where the return type is not ExpressionT. | 2020 // Used in functions where the return type is not ExpressionT. |
| 1964 #define CHECK_OK_CUSTOM(x) ok); \ | 2021 #define CHECK_OK_CUSTOM(x) ok); \ |
| 1965 if (!*ok) return this->x(); \ | 2022 if (!*ok) return this->x(); \ |
| 1966 ((void)0 | 2023 ((void)0 |
| 1967 #define DUMMY ) // to make indentation work | 2024 #define DUMMY ) // to make indentation work |
| 1968 #undef DUMMY | 2025 #undef DUMMY |
| 1969 | 2026 |
| 2027 | |
| 2028 #define CHECK_CLASSIFIER_OK classifier, ok); \ | |
|
rossberg
2015/04/22 09:30:47
Don't think this macro is worth it. It saves a sin
Dmitry Lomov (no reviews)
2015/04/22 09:36:55
Yes, I think we should merge ok into a classifier
| |
| 2029 if (!*ok) return this->EmptyExpression(); \ | |
| 2030 ((void)0 | |
| 2031 #define DUMMY ) // to make indentation work | |
| 2032 #undef DUMMY | |
| 2033 | |
| 1970 template <class Traits> | 2034 template <class Traits> |
| 1971 typename ParserBase<Traits>::ExpressionT | 2035 typename ParserBase<Traits>::ExpressionT |
| 1972 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { | 2036 ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, |
| 2037 bool* ok) { | |
| 1973 // PrimaryExpression :: | 2038 // PrimaryExpression :: |
| 1974 // 'this' | 2039 // 'this' |
| 1975 // 'null' | 2040 // 'null' |
| 1976 // 'true' | 2041 // 'true' |
| 1977 // 'false' | 2042 // 'false' |
| 1978 // Identifier | 2043 // Identifier |
| 1979 // Number | 2044 // Number |
| 1980 // String | 2045 // String |
| 1981 // ArrayLiteral | 2046 // ArrayLiteral |
| 1982 // ObjectLiteral | 2047 // ObjectLiteral |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2019 break; | 2084 break; |
| 2020 } | 2085 } |
| 2021 | 2086 |
| 2022 case Token::STRING: { | 2087 case Token::STRING: { |
| 2023 Consume(Token::STRING); | 2088 Consume(Token::STRING); |
| 2024 result = this->ExpressionFromString(beg_pos, scanner(), factory()); | 2089 result = this->ExpressionFromString(beg_pos, scanner(), factory()); |
| 2025 break; | 2090 break; |
| 2026 } | 2091 } |
| 2027 | 2092 |
| 2028 case Token::ASSIGN_DIV: | 2093 case Token::ASSIGN_DIV: |
| 2029 result = this->ParseRegExpLiteral(true, CHECK_OK); | 2094 result = this->ParseRegExpLiteral(true, CHECK_CLASSIFIER_OK); |
| 2030 break; | 2095 break; |
| 2031 | 2096 |
| 2032 case Token::DIV: | 2097 case Token::DIV: |
| 2033 result = this->ParseRegExpLiteral(false, CHECK_OK); | 2098 result = this->ParseRegExpLiteral(false, CHECK_CLASSIFIER_OK); |
| 2034 break; | 2099 break; |
| 2035 | 2100 |
| 2036 case Token::LBRACK: | 2101 case Token::LBRACK: |
| 2037 result = this->ParseArrayLiteral(CHECK_OK); | 2102 result = this->ParseArrayLiteral(CHECK_CLASSIFIER_OK); |
| 2038 break; | 2103 break; |
| 2039 | 2104 |
| 2040 case Token::LBRACE: | 2105 case Token::LBRACE: |
| 2041 result = this->ParseObjectLiteral(CHECK_OK); | 2106 result = this->ParseObjectLiteral(CHECK_CLASSIFIER_OK); |
| 2042 break; | 2107 break; |
| 2043 | 2108 |
| 2044 case Token::LPAREN: | 2109 case Token::LPAREN: |
| 2045 Consume(Token::LPAREN); | 2110 Consume(Token::LPAREN); |
| 2046 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { | 2111 if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) { |
| 2047 // Arrow functions are the only expression type constructions | 2112 // Arrow functions are the only expression type constructions |
| 2048 // for which an empty parameter list "()" is valid input. | 2113 // for which an empty parameter list "()" is valid input. |
| 2049 Consume(Token::RPAREN); | 2114 Consume(Token::RPAREN); |
| 2050 result = this->ParseArrowFunctionLiteral( | 2115 result = this->ParseArrowFunctionLiteral( |
| 2051 beg_pos, this->EmptyArrowParamList(), CHECK_OK); | 2116 beg_pos, this->EmptyArrowParamList(), CHECK_CLASSIFIER_OK); |
| 2052 } else { | 2117 } else { |
| 2053 // Heuristically try to detect immediately called functions before | 2118 // Heuristically try to detect immediately called functions before |
| 2054 // seeing the call parentheses. | 2119 // seeing the call parentheses. |
| 2055 parenthesized_function_ = (peek() == Token::FUNCTION); | 2120 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 2056 result = this->ParseExpression(true, CHECK_OK); | 2121 result = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
| 2057 result->increase_parenthesization_level(); | 2122 result->increase_parenthesization_level(); |
| 2058 Expect(Token::RPAREN, CHECK_OK); | 2123 Expect(Token::RPAREN, CHECK_OK); |
| 2059 } | 2124 } |
| 2060 break; | 2125 break; |
| 2061 | 2126 |
| 2062 case Token::CLASS: { | 2127 case Token::CLASS: { |
| 2063 Consume(Token::CLASS); | 2128 Consume(Token::CLASS); |
| 2064 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2129 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 2065 ReportMessage("sloppy_lexical", NULL); | 2130 ReportMessage("sloppy_lexical", NULL); |
| 2066 *ok = false; | 2131 *ok = false; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2077 } | 2142 } |
| 2078 result = this->ParseClassLiteral(name, class_name_location, | 2143 result = this->ParseClassLiteral(name, class_name_location, |
| 2079 is_strict_reserved_name, | 2144 is_strict_reserved_name, |
| 2080 class_token_position, CHECK_OK); | 2145 class_token_position, CHECK_OK); |
| 2081 break; | 2146 break; |
| 2082 } | 2147 } |
| 2083 | 2148 |
| 2084 case Token::TEMPLATE_SPAN: | 2149 case Token::TEMPLATE_SPAN: |
| 2085 case Token::TEMPLATE_TAIL: | 2150 case Token::TEMPLATE_TAIL: |
| 2086 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, | 2151 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, |
| 2087 CHECK_OK); | 2152 CHECK_CLASSIFIER_OK); |
| 2088 break; | 2153 break; |
| 2089 | 2154 |
| 2090 case Token::MOD: | 2155 case Token::MOD: |
| 2091 if (allow_natives() || extension_ != NULL) { | 2156 if (allow_natives() || extension_ != NULL) { |
| 2092 result = this->ParseV8Intrinsic(CHECK_OK); | 2157 result = this->ParseV8Intrinsic(CHECK_OK); |
| 2093 break; | 2158 break; |
| 2094 } | 2159 } |
| 2095 // If we're not allowing special syntax we fall-through to the | 2160 // If we're not allowing special syntax we fall-through to the |
| 2096 // default case. | 2161 // default case. |
| 2097 | 2162 |
| 2098 default: { | 2163 default: { |
| 2099 Next(); | 2164 Next(); |
| 2100 ReportUnexpectedToken(token); | 2165 ReportUnexpectedToken(token); |
| 2101 *ok = false; | 2166 *ok = false; |
| 2102 } | 2167 } |
| 2103 } | 2168 } |
| 2104 | 2169 |
| 2105 return result; | 2170 return result; |
| 2106 } | 2171 } |
| 2107 | 2172 |
| 2173 | |
| 2174 template <class Traits> | |
| 2175 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | |
| 2176 bool accept_IN, bool* ok) { | |
| 2177 ExpressionClassifier classifier; | |
| 2178 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | |
| 2179 // TODO(dslomov): report error if not a valid expression. | |
| 2180 return result; | |
| 2181 } | |
| 2182 | |
| 2183 | |
| 2108 // Precedence = 1 | 2184 // Precedence = 1 |
| 2109 template <class Traits> | 2185 template <class Traits> |
| 2110 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 2186 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 2111 bool accept_IN, bool* ok) { | 2187 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
| 2112 // Expression :: | 2188 // Expression :: |
| 2113 // AssignmentExpression | 2189 // AssignmentExpression |
| 2114 // Expression ',' AssignmentExpression | 2190 // Expression ',' AssignmentExpression |
| 2115 | 2191 |
| 2116 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2192 ExpressionT result = |
| 2193 this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); | |
| 2117 while (peek() == Token::COMMA) { | 2194 while (peek() == Token::COMMA) { |
| 2118 Expect(Token::COMMA, CHECK_OK); | 2195 Expect(Token::COMMA, CHECK_OK); |
| 2119 int pos = position(); | 2196 int pos = position(); |
| 2120 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2197 ExpressionT right = |
| 2198 this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); | |
| 2121 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 2199 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2122 } | 2200 } |
| 2123 return result; | 2201 return result; |
| 2124 } | 2202 } |
| 2125 | 2203 |
| 2126 | 2204 |
| 2127 template <class Traits> | 2205 template <class Traits> |
| 2128 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( | 2206 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( |
| 2129 bool* ok) { | 2207 ExpressionClassifier* classifier, bool* ok) { |
| 2130 // ArrayLiteral :: | 2208 // ArrayLiteral :: |
| 2131 // '[' Expression? (',' Expression?)* ']' | 2209 // '[' Expression? (',' Expression?)* ']' |
| 2132 | 2210 |
| 2133 int pos = peek_position(); | 2211 int pos = peek_position(); |
| 2134 typename Traits::Type::ExpressionList values = | 2212 typename Traits::Type::ExpressionList values = |
| 2135 this->NewExpressionList(4, zone_); | 2213 this->NewExpressionList(4, zone_); |
| 2136 Expect(Token::LBRACK, CHECK_OK); | 2214 Expect(Token::LBRACK, CHECK_OK); |
| 2137 while (peek() != Token::RBRACK) { | 2215 while (peek() != Token::RBRACK) { |
| 2138 ExpressionT elem = this->EmptyExpression(); | 2216 ExpressionT elem = this->EmptyExpression(); |
| 2139 if (peek() == Token::COMMA) { | 2217 if (peek() == Token::COMMA) { |
| 2140 if (is_strong(language_mode())) { | 2218 if (is_strong(language_mode())) { |
| 2141 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); | 2219 ReportMessageAt(scanner()->peek_location(), "strong_ellision"); |
| 2142 *ok = false; | 2220 *ok = false; |
| 2143 return this->EmptyExpression(); | 2221 return this->EmptyExpression(); |
| 2144 } | 2222 } |
| 2145 elem = this->GetLiteralTheHole(peek_position(), factory()); | 2223 elem = this->GetLiteralTheHole(peek_position(), factory()); |
| 2146 } else { | 2224 } else { |
| 2147 elem = this->ParseAssignmentExpression(true, CHECK_OK); | 2225 elem = this->ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
| 2148 } | 2226 } |
| 2149 values->Add(elem, zone_); | 2227 values->Add(elem, zone_); |
| 2150 if (peek() != Token::RBRACK) { | 2228 if (peek() != Token::RBRACK) { |
| 2151 Expect(Token::COMMA, CHECK_OK); | 2229 Expect(Token::COMMA, CHECK_OK); |
| 2152 } | 2230 } |
| 2153 } | 2231 } |
| 2154 Expect(Token::RBRACK, CHECK_OK); | 2232 Expect(Token::RBRACK, CHECK_OK); |
| 2155 | 2233 |
| 2156 // Update the scope information before the pre-parsing bailout. | 2234 // Update the scope information before the pre-parsing bailout. |
| 2157 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2235 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| 2158 | 2236 |
| 2159 return factory()->NewArrayLiteral(values, literal_index, pos); | 2237 return factory()->NewArrayLiteral(values, literal_index, pos); |
| 2160 } | 2238 } |
| 2161 | 2239 |
| 2162 | 2240 |
| 2163 template <class Traits> | 2241 template <class Traits> |
| 2164 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( | 2242 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( |
| 2165 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, | 2243 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, |
| 2166 bool* is_computed_name, bool* ok) { | 2244 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) { |
| 2167 Token::Value token = peek(); | 2245 Token::Value token = peek(); |
| 2168 int pos = peek_position(); | 2246 int pos = peek_position(); |
| 2169 | 2247 |
| 2170 // For non computed property names we normalize the name a bit: | 2248 // For non computed property names we normalize the name a bit: |
| 2171 // | 2249 // |
| 2172 // "12" -> 12 | 2250 // "12" -> 12 |
| 2173 // 12.3 -> "12.3" | 2251 // 12.3 -> "12.3" |
| 2174 // 12.30 -> "12.3" | 2252 // 12.30 -> "12.3" |
| 2175 // identifier -> "identifier" | 2253 // identifier -> "identifier" |
| 2176 // | 2254 // |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2189 | 2267 |
| 2190 case Token::NUMBER: | 2268 case Token::NUMBER: |
| 2191 Consume(Token::NUMBER); | 2269 Consume(Token::NUMBER); |
| 2192 *name = this->GetNumberAsSymbol(scanner()); | 2270 *name = this->GetNumberAsSymbol(scanner()); |
| 2193 break; | 2271 break; |
| 2194 | 2272 |
| 2195 case Token::LBRACK: | 2273 case Token::LBRACK: |
| 2196 if (allow_harmony_computed_property_names_) { | 2274 if (allow_harmony_computed_property_names_) { |
| 2197 *is_computed_name = true; | 2275 *is_computed_name = true; |
| 2198 Consume(Token::LBRACK); | 2276 Consume(Token::LBRACK); |
| 2199 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 2277 ExpressionT expression = |
| 2278 ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); | |
| 2200 Expect(Token::RBRACK, CHECK_OK); | 2279 Expect(Token::RBRACK, CHECK_OK); |
| 2201 return expression; | 2280 return expression; |
| 2202 } | 2281 } |
| 2203 | 2282 |
| 2204 // Fall through. | 2283 // Fall through. |
| 2205 case Token::STATIC: | 2284 case Token::STATIC: |
| 2206 *is_static = true; | 2285 *is_static = true; |
| 2207 | 2286 |
| 2208 // Fall through. | 2287 // Fall through. |
| 2209 default: | 2288 default: |
| 2210 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); | 2289 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); |
| 2211 break; | 2290 break; |
| 2212 } | 2291 } |
| 2213 | 2292 |
| 2214 uint32_t index; | 2293 uint32_t index; |
| 2215 return this->IsArrayIndex(*name, &index) | 2294 return this->IsArrayIndex(*name, &index) |
| 2216 ? factory()->NewNumberLiteral(index, pos) | 2295 ? factory()->NewNumberLiteral(index, pos) |
| 2217 : factory()->NewStringLiteral(*name, pos); | 2296 : factory()->NewStringLiteral(*name, pos); |
| 2218 } | 2297 } |
| 2219 | 2298 |
| 2220 | 2299 |
| 2221 template <class Traits> | 2300 template <class Traits> |
| 2222 typename ParserBase<Traits>::ObjectLiteralPropertyT | 2301 typename ParserBase<Traits>::ObjectLiteralPropertyT |
| 2223 ParserBase<Traits>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, | 2302 ParserBase<Traits>::ParsePropertyDefinition( |
| 2224 bool in_class, bool has_extends, | 2303 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 2225 bool is_static, | 2304 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 2226 bool* is_computed_name, | 2305 ExpressionClassifier* classifier, bool* ok) { |
| 2227 bool* has_seen_constructor, | |
| 2228 bool* ok) { | |
| 2229 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); | 2306 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); |
| 2230 ExpressionT value = this->EmptyExpression(); | 2307 ExpressionT value = this->EmptyExpression(); |
| 2231 IdentifierT name = this->EmptyIdentifier(); | 2308 IdentifierT name = this->EmptyIdentifier(); |
| 2232 bool is_get = false; | 2309 bool is_get = false; |
| 2233 bool is_set = false; | 2310 bool is_set = false; |
| 2234 bool name_is_static = false; | 2311 bool name_is_static = false; |
| 2235 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); | 2312 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); |
| 2236 | 2313 |
| 2237 Token::Value name_token = peek(); | 2314 Token::Value name_token = peek(); |
| 2238 int next_beg_pos = scanner()->peek_location().beg_pos; | 2315 int next_beg_pos = scanner()->peek_location().beg_pos; |
| 2239 int next_end_pos = scanner()->peek_location().end_pos; | 2316 int next_end_pos = scanner()->peek_location().end_pos; |
| 2240 ExpressionT name_expression = ParsePropertyName( | 2317 ExpressionT name_expression = ParsePropertyName( |
| 2241 &name, &is_get, &is_set, &name_is_static, is_computed_name, | 2318 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, |
| 2242 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2319 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2243 | 2320 |
| 2244 if (fni_ != nullptr && !*is_computed_name) { | 2321 if (fni_ != nullptr && !*is_computed_name) { |
| 2245 this->PushLiteralName(fni_, name); | 2322 this->PushLiteralName(fni_, name); |
| 2246 } | 2323 } |
| 2247 | 2324 |
| 2248 if (!in_class && !is_generator && peek() == Token::COLON) { | 2325 if (!in_class && !is_generator && peek() == Token::COLON) { |
| 2249 // PropertyDefinition : PropertyName ':' AssignmentExpression | 2326 // PropertyDefinition : PropertyName ':' AssignmentExpression |
| 2250 if (!*is_computed_name) { | 2327 if (!*is_computed_name) { |
| 2251 checker->CheckProperty(name_token, kValueProperty, is_static, | 2328 checker->CheckProperty(name_token, kValueProperty, is_static, |
| 2252 is_generator, | 2329 is_generator, |
| 2253 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2330 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2254 } | 2331 } |
| 2255 Consume(Token::COLON); | 2332 Consume(Token::COLON); |
| 2256 value = this->ParseAssignmentExpression( | 2333 value = this->ParseAssignmentExpression( |
| 2257 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2334 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2258 | 2335 |
| 2259 } else if (is_generator || | 2336 } else if (is_generator || |
| 2260 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 2337 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
| 2261 // Concise Method | 2338 // Concise Method |
| 2262 if (!*is_computed_name) { | 2339 if (!*is_computed_name) { |
| 2263 checker->CheckProperty(name_token, kMethodProperty, is_static, | 2340 checker->CheckProperty(name_token, kMethodProperty, is_static, |
| 2264 is_generator, | 2341 is_generator, |
| 2265 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2342 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2266 } | 2343 } |
| 2267 | 2344 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2283 FunctionLiteral::NORMAL_ARITY, | 2360 FunctionLiteral::NORMAL_ARITY, |
| 2284 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2361 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2285 | 2362 |
| 2286 return factory()->NewObjectLiteralProperty(name_expression, value, | 2363 return factory()->NewObjectLiteralProperty(name_expression, value, |
| 2287 ObjectLiteralProperty::COMPUTED, | 2364 ObjectLiteralProperty::COMPUTED, |
| 2288 is_static, *is_computed_name); | 2365 is_static, *is_computed_name); |
| 2289 | 2366 |
| 2290 } else if (in_class && name_is_static && !is_static) { | 2367 } else if (in_class && name_is_static && !is_static) { |
| 2291 // static MethodDefinition | 2368 // static MethodDefinition |
| 2292 return ParsePropertyDefinition(checker, true, has_extends, true, | 2369 return ParsePropertyDefinition(checker, true, has_extends, true, |
| 2293 is_computed_name, nullptr, ok); | 2370 is_computed_name, nullptr, classifier, ok); |
| 2294 } else if (is_get || is_set) { | 2371 } else if (is_get || is_set) { |
| 2295 // Accessor | 2372 // Accessor |
| 2296 name = this->EmptyIdentifier(); | 2373 name = this->EmptyIdentifier(); |
| 2297 bool dont_care = false; | 2374 bool dont_care = false; |
| 2298 name_token = peek(); | 2375 name_token = peek(); |
| 2299 | 2376 |
| 2300 name_expression = ParsePropertyName( | 2377 name_expression = ParsePropertyName( |
| 2301 &name, &dont_care, &dont_care, &dont_care, is_computed_name, | 2378 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, |
| 2302 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2379 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2303 | 2380 |
| 2304 if (!*is_computed_name) { | 2381 if (!*is_computed_name) { |
| 2305 checker->CheckProperty(name_token, kAccessorProperty, is_static, | 2382 checker->CheckProperty(name_token, kAccessorProperty, is_static, |
| 2306 is_generator, | 2383 is_generator, |
| 2307 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2384 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2308 } | 2385 } |
| 2309 | 2386 |
| 2310 FunctionKind kind = FunctionKind::kAccessorFunction; | 2387 FunctionKind kind = FunctionKind::kAccessorFunction; |
| 2311 if (!in_class) kind = WithObjectLiteralBit(kind); | 2388 if (!in_class) kind = WithObjectLiteralBit(kind); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2346 return this->EmptyObjectLiteralProperty(); | 2423 return this->EmptyObjectLiteralProperty(); |
| 2347 } | 2424 } |
| 2348 | 2425 |
| 2349 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, | 2426 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, |
| 2350 *is_computed_name); | 2427 *is_computed_name); |
| 2351 } | 2428 } |
| 2352 | 2429 |
| 2353 | 2430 |
| 2354 template <class Traits> | 2431 template <class Traits> |
| 2355 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( | 2432 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( |
| 2356 bool* ok) { | 2433 ExpressionClassifier* classifier, bool* ok) { |
| 2357 // ObjectLiteral :: | 2434 // ObjectLiteral :: |
| 2358 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2435 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
| 2359 | 2436 |
| 2360 int pos = peek_position(); | 2437 int pos = peek_position(); |
| 2361 typename Traits::Type::PropertyList properties = | 2438 typename Traits::Type::PropertyList properties = |
| 2362 this->NewPropertyList(4, zone_); | 2439 this->NewPropertyList(4, zone_); |
| 2363 int number_of_boilerplate_properties = 0; | 2440 int number_of_boilerplate_properties = 0; |
| 2364 bool has_function = false; | 2441 bool has_function = false; |
| 2365 bool has_computed_names = false; | 2442 bool has_computed_names = false; |
| 2366 ObjectLiteralChecker checker(this); | 2443 ObjectLiteralChecker checker(this); |
| 2367 | 2444 |
| 2368 Expect(Token::LBRACE, CHECK_OK); | 2445 Expect(Token::LBRACE, CHECK_OK); |
| 2369 | 2446 |
| 2370 while (peek() != Token::RBRACE) { | 2447 while (peek() != Token::RBRACE) { |
| 2371 if (fni_ != nullptr) fni_->Enter(); | 2448 if (fni_ != nullptr) fni_->Enter(); |
| 2372 | 2449 |
| 2373 const bool in_class = false; | 2450 const bool in_class = false; |
| 2374 const bool is_static = false; | 2451 const bool is_static = false; |
| 2375 const bool has_extends = false; | 2452 const bool has_extends = false; |
| 2376 bool is_computed_name = false; | 2453 bool is_computed_name = false; |
| 2377 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( | 2454 ObjectLiteralPropertyT property = this->ParsePropertyDefinition( |
| 2378 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, | 2455 &checker, in_class, has_extends, is_static, &is_computed_name, NULL, |
| 2379 CHECK_OK); | 2456 CHECK_CLASSIFIER_OK); |
| 2380 | 2457 |
| 2381 if (is_computed_name) { | 2458 if (is_computed_name) { |
| 2382 has_computed_names = true; | 2459 has_computed_names = true; |
| 2383 } | 2460 } |
| 2384 | 2461 |
| 2385 // Mark top-level object literals that contain function literals and | 2462 // Mark top-level object literals that contain function literals and |
| 2386 // pretenure the literal so it can be added as a constant function | 2463 // pretenure the literal so it can be added as a constant function |
| 2387 // property. (Parser only.) | 2464 // property. (Parser only.) |
| 2388 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, | 2465 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, property, |
| 2389 &has_function); | 2466 &has_function); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2412 return factory()->NewObjectLiteral(properties, | 2489 return factory()->NewObjectLiteral(properties, |
| 2413 literal_index, | 2490 literal_index, |
| 2414 number_of_boilerplate_properties, | 2491 number_of_boilerplate_properties, |
| 2415 has_function, | 2492 has_function, |
| 2416 pos); | 2493 pos); |
| 2417 } | 2494 } |
| 2418 | 2495 |
| 2419 | 2496 |
| 2420 template <class Traits> | 2497 template <class Traits> |
| 2421 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2498 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| 2422 Scanner::Location* first_spread_arg_loc, bool* ok) { | 2499 Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier, |
| 2500 bool* ok) { | |
| 2423 // Arguments :: | 2501 // Arguments :: |
| 2424 // '(' (AssignmentExpression)*[','] ')' | 2502 // '(' (AssignmentExpression)*[','] ')' |
| 2425 | 2503 |
| 2426 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2504 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2427 typename Traits::Type::ExpressionList result = | 2505 typename Traits::Type::ExpressionList result = |
| 2428 this->NewExpressionList(4, zone_); | 2506 this->NewExpressionList(4, zone_); |
| 2429 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2507 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2430 bool done = (peek() == Token::RPAREN); | 2508 bool done = (peek() == Token::RPAREN); |
| 2431 bool was_unspread = false; | 2509 bool was_unspread = false; |
| 2432 int unspread_sequences_count = 0; | 2510 int unspread_sequences_count = 0; |
| 2433 while (!done) { | 2511 while (!done) { |
| 2434 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); | 2512 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); |
| 2435 int start_pos = peek_position(); | 2513 int start_pos = peek_position(); |
| 2436 if (is_spread) Consume(Token::ELLIPSIS); | 2514 if (is_spread) Consume(Token::ELLIPSIS); |
| 2437 | 2515 |
| 2438 ExpressionT argument = this->ParseAssignmentExpression( | 2516 ExpressionT argument = this->ParseAssignmentExpression( |
| 2439 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2517 true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2440 if (is_spread) { | 2518 if (is_spread) { |
| 2441 if (!spread_arg.IsValid()) { | 2519 if (!spread_arg.IsValid()) { |
| 2442 spread_arg.beg_pos = start_pos; | 2520 spread_arg.beg_pos = start_pos; |
| 2443 spread_arg.end_pos = peek_position(); | 2521 spread_arg.end_pos = peek_position(); |
| 2444 } | 2522 } |
| 2445 argument = factory()->NewSpread(argument, start_pos); | 2523 argument = factory()->NewSpread(argument, start_pos); |
| 2446 } | 2524 } |
| 2447 result->Add(argument, zone_); | 2525 result->Add(argument, zone_); |
| 2448 | 2526 |
| 2449 // unspread_sequences_count is the number of sequences of parameters which | 2527 // unspread_sequences_count is the number of sequences of parameters which |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2479 // the parser and preparser | 2557 // the parser and preparser |
| 2480 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2558 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2481 } | 2559 } |
| 2482 | 2560 |
| 2483 return result; | 2561 return result; |
| 2484 } | 2562 } |
| 2485 | 2563 |
| 2486 // Precedence = 2 | 2564 // Precedence = 2 |
| 2487 template <class Traits> | 2565 template <class Traits> |
| 2488 typename ParserBase<Traits>::ExpressionT | 2566 typename ParserBase<Traits>::ExpressionT |
| 2489 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2567 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| 2568 ExpressionClassifier* classifier, | |
| 2569 bool* ok) { | |
| 2490 // AssignmentExpression :: | 2570 // AssignmentExpression :: |
| 2491 // ConditionalExpression | 2571 // ConditionalExpression |
| 2492 // ArrowFunction | 2572 // ArrowFunction |
| 2493 // YieldExpression | 2573 // YieldExpression |
| 2494 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2574 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2495 | 2575 |
| 2496 Scanner::Location lhs_location = scanner()->peek_location(); | 2576 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2497 | 2577 |
| 2498 if (peek() == Token::YIELD && is_generator()) { | 2578 if (peek() == Token::YIELD && is_generator()) { |
| 2499 return this->ParseYieldExpression(ok); | 2579 return this->ParseYieldExpression(classifier, ok); |
| 2500 } | 2580 } |
| 2501 | 2581 |
| 2502 if (fni_ != NULL) fni_->Enter(); | 2582 if (fni_ != NULL) fni_->Enter(); |
| 2503 ParserBase<Traits>::Checkpoint checkpoint(this); | 2583 ParserBase<Traits>::Checkpoint checkpoint(this); |
| 2504 ExpressionT expression = | 2584 ExpressionT expression = |
| 2505 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2585 this->ParseConditionalExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| 2506 | 2586 |
| 2507 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { | 2587 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { |
| 2508 checkpoint.Restore(); | 2588 checkpoint.Restore(); |
| 2509 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | 2589 expression = this->ParseArrowFunctionLiteral( |
| 2510 expression, CHECK_OK); | 2590 lhs_location.beg_pos, expression, CHECK_CLASSIFIER_OK); |
| 2511 return expression; | 2591 return expression; |
| 2512 } | 2592 } |
| 2513 | 2593 |
| 2514 if (!Token::IsAssignmentOp(peek())) { | 2594 if (!Token::IsAssignmentOp(peek())) { |
| 2515 if (fni_ != NULL) fni_->Leave(); | 2595 if (fni_ != NULL) fni_->Leave(); |
| 2516 // Parsed conditional expression only (no assignment). | 2596 // Parsed conditional expression only (no assignment). |
| 2517 return expression; | 2597 return expression; |
| 2518 } | 2598 } |
| 2519 | 2599 |
| 2520 expression = this->CheckAndRewriteReferenceExpression( | 2600 expression = this->CheckAndRewriteReferenceExpression( |
| 2521 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2601 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
| 2522 expression = this->MarkExpressionAsAssigned(expression); | 2602 expression = this->MarkExpressionAsAssigned(expression); |
| 2523 | 2603 |
| 2524 Token::Value op = Next(); // Get assignment operator. | 2604 Token::Value op = Next(); // Get assignment operator. |
| 2525 int pos = position(); | 2605 int pos = position(); |
| 2526 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 2606 ExpressionT right = |
| 2607 this->ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); | |
| 2527 | 2608 |
| 2528 // TODO(1231235): We try to estimate the set of properties set by | 2609 // TODO(1231235): We try to estimate the set of properties set by |
| 2529 // constructors. We define a new property whenever there is an | 2610 // constructors. We define a new property whenever there is an |
| 2530 // assignment to a property of 'this'. We should probably only add | 2611 // assignment to a property of 'this'. We should probably only add |
| 2531 // properties if we haven't seen them before. Otherwise we'll | 2612 // properties if we haven't seen them before. Otherwise we'll |
| 2532 // probably overestimate the number of properties. | 2613 // probably overestimate the number of properties. |
| 2533 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { | 2614 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { |
| 2534 function_state_->AddProperty(); | 2615 function_state_->AddProperty(); |
| 2535 } | 2616 } |
| 2536 | 2617 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2549 fni_->RemoveLastFunction(); | 2630 fni_->RemoveLastFunction(); |
| 2550 } | 2631 } |
| 2551 fni_->Leave(); | 2632 fni_->Leave(); |
| 2552 } | 2633 } |
| 2553 | 2634 |
| 2554 return factory()->NewAssignment(op, expression, right, pos); | 2635 return factory()->NewAssignment(op, expression, right, pos); |
| 2555 } | 2636 } |
| 2556 | 2637 |
| 2557 template <class Traits> | 2638 template <class Traits> |
| 2558 typename ParserBase<Traits>::ExpressionT | 2639 typename ParserBase<Traits>::ExpressionT |
| 2559 ParserBase<Traits>::ParseYieldExpression(bool* ok) { | 2640 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, |
| 2641 bool* ok) { | |
| 2560 // YieldExpression :: | 2642 // YieldExpression :: |
| 2561 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2643 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
| 2562 int pos = peek_position(); | 2644 int pos = peek_position(); |
| 2563 Expect(Token::YIELD, CHECK_OK); | 2645 Expect(Token::YIELD, CHECK_OK); |
| 2564 ExpressionT generator_object = | 2646 ExpressionT generator_object = |
| 2565 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 2647 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
| 2566 ExpressionT expression = Traits::EmptyExpression(); | 2648 ExpressionT expression = Traits::EmptyExpression(); |
| 2567 Yield::Kind kind = Yield::kSuspend; | 2649 Yield::Kind kind = Yield::kSuspend; |
| 2568 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2650 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2569 if (Check(Token::MUL)) kind = Yield::kDelegating; | 2651 if (Check(Token::MUL)) kind = Yield::kDelegating; |
| 2570 switch (peek()) { | 2652 switch (peek()) { |
| 2571 case Token::EOS: | 2653 case Token::EOS: |
| 2572 case Token::SEMICOLON: | 2654 case Token::SEMICOLON: |
| 2573 case Token::RBRACE: | 2655 case Token::RBRACE: |
| 2574 case Token::RBRACK: | 2656 case Token::RBRACK: |
| 2575 case Token::RPAREN: | 2657 case Token::RPAREN: |
| 2576 case Token::COLON: | 2658 case Token::COLON: |
| 2577 case Token::COMMA: | 2659 case Token::COMMA: |
| 2578 // The above set of tokens is the complete set of tokens that can appear | 2660 // The above set of tokens is the complete set of tokens that can appear |
| 2579 // after an AssignmentExpression, and none of them can start an | 2661 // after an AssignmentExpression, and none of them can start an |
| 2580 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2662 // AssignmentExpression. This allows us to avoid looking for an RHS for |
| 2581 // a Yield::kSuspend operation, given only one look-ahead token. | 2663 // a Yield::kSuspend operation, given only one look-ahead token. |
| 2582 if (kind == Yield::kSuspend) | 2664 if (kind == Yield::kSuspend) |
| 2583 break; | 2665 break; |
| 2584 DCHECK_EQ(Yield::kDelegating, kind); | 2666 DCHECK_EQ(Yield::kDelegating, kind); |
| 2585 // Delegating yields require an RHS; fall through. | 2667 // Delegating yields require an RHS; fall through. |
| 2586 default: | 2668 default: |
| 2587 expression = ParseAssignmentExpression(false, CHECK_OK); | 2669 expression = ParseAssignmentExpression(false, CHECK_CLASSIFIER_OK); |
| 2588 break; | 2670 break; |
| 2589 } | 2671 } |
| 2590 } | 2672 } |
| 2591 if (kind == Yield::kDelegating) { | 2673 if (kind == Yield::kDelegating) { |
| 2592 // var iterator = subject[Symbol.iterator](); | 2674 // var iterator = subject[Symbol.iterator](); |
| 2593 expression = this->GetIterator(expression, factory()); | 2675 expression = this->GetIterator(expression, factory()); |
| 2594 } | 2676 } |
| 2595 typename Traits::Type::YieldExpression yield = | 2677 typename Traits::Type::YieldExpression yield = |
| 2596 factory()->NewYield(generator_object, expression, kind, pos); | 2678 factory()->NewYield(generator_object, expression, kind, pos); |
| 2597 if (kind == Yield::kDelegating) { | 2679 if (kind == Yield::kDelegating) { |
| 2598 yield->set_index(function_state_->NextHandlerIndex()); | 2680 yield->set_index(function_state_->NextHandlerIndex()); |
| 2599 } | 2681 } |
| 2600 return yield; | 2682 return yield; |
| 2601 } | 2683 } |
| 2602 | 2684 |
| 2603 | 2685 |
| 2604 // Precedence = 3 | 2686 // Precedence = 3 |
| 2605 template <class Traits> | 2687 template <class Traits> |
| 2606 typename ParserBase<Traits>::ExpressionT | 2688 typename ParserBase<Traits>::ExpressionT |
| 2607 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2689 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
| 2690 ExpressionClassifier* classifier, | |
| 2691 bool* ok) { | |
| 2608 // ConditionalExpression :: | 2692 // ConditionalExpression :: |
| 2609 // LogicalOrExpression | 2693 // LogicalOrExpression |
| 2610 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2694 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2611 | 2695 |
| 2612 int pos = peek_position(); | 2696 int pos = peek_position(); |
| 2613 // We start using the binary expression parser for prec >= 4 only! | 2697 // We start using the binary expression parser for prec >= 4 only! |
| 2614 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2698 ExpressionT expression = |
| 2699 this->ParseBinaryExpression(4, accept_IN, CHECK_CLASSIFIER_OK); | |
| 2615 if (peek() != Token::CONDITIONAL) return expression; | 2700 if (peek() != Token::CONDITIONAL) return expression; |
| 2616 Consume(Token::CONDITIONAL); | 2701 Consume(Token::CONDITIONAL); |
| 2617 // In parsing the first assignment expression in conditional | 2702 // In parsing the first assignment expression in conditional |
| 2618 // expressions we always accept the 'in' keyword; see ECMA-262, | 2703 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2619 // section 11.12, page 58. | 2704 // section 11.12, page 58. |
| 2620 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); | 2705 ExpressionT left = ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); |
| 2621 Expect(Token::COLON, CHECK_OK); | 2706 Expect(Token::COLON, CHECK_OK); |
| 2622 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2707 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_CLASSIFIER_OK); |
| 2623 return factory()->NewConditional(expression, left, right, pos); | 2708 return factory()->NewConditional(expression, left, right, pos); |
| 2624 } | 2709 } |
| 2625 | 2710 |
| 2626 | 2711 |
| 2627 // Precedence >= 4 | 2712 // Precedence >= 4 |
| 2628 template <class Traits> | 2713 template <class Traits> |
| 2629 typename ParserBase<Traits>::ExpressionT | 2714 typename ParserBase<Traits>::ExpressionT |
| 2630 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2715 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, |
| 2716 ExpressionClassifier* classifier, | |
| 2717 bool* ok) { | |
| 2631 DCHECK(prec >= 4); | 2718 DCHECK(prec >= 4); |
| 2632 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); | 2719 ExpressionT x = this->ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
| 2633 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2720 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 2634 // prec1 >= 4 | 2721 // prec1 >= 4 |
| 2635 while (Precedence(peek(), accept_IN) == prec1) { | 2722 while (Precedence(peek(), accept_IN) == prec1) { |
| 2636 Token::Value op = Next(); | 2723 Token::Value op = Next(); |
| 2637 Scanner::Location op_location = scanner()->location(); | 2724 Scanner::Location op_location = scanner()->location(); |
| 2638 int pos = position(); | 2725 int pos = position(); |
| 2639 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 2726 ExpressionT y = |
| 2727 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_CLASSIFIER_OK); | |
| 2640 | 2728 |
| 2641 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, | 2729 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, |
| 2642 factory())) { | 2730 factory())) { |
| 2643 continue; | 2731 continue; |
| 2644 } | 2732 } |
| 2645 | 2733 |
| 2646 // For now we distinguish between comparisons and other binary | 2734 // For now we distinguish between comparisons and other binary |
| 2647 // operations. (We could combine the two and get rid of this | 2735 // operations. (We could combine the two and get rid of this |
| 2648 // code and AST node eventually.) | 2736 // code and AST node eventually.) |
| 2649 if (Token::IsCompareOp(op)) { | 2737 if (Token::IsCompareOp(op)) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 2670 x = factory()->NewBinaryOperation(op, x, y, pos); | 2758 x = factory()->NewBinaryOperation(op, x, y, pos); |
| 2671 } | 2759 } |
| 2672 } | 2760 } |
| 2673 } | 2761 } |
| 2674 return x; | 2762 return x; |
| 2675 } | 2763 } |
| 2676 | 2764 |
| 2677 | 2765 |
| 2678 template <class Traits> | 2766 template <class Traits> |
| 2679 typename ParserBase<Traits>::ExpressionT | 2767 typename ParserBase<Traits>::ExpressionT |
| 2680 ParserBase<Traits>::ParseUnaryExpression(bool* ok) { | 2768 ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, |
| 2769 bool* ok) { | |
| 2681 // UnaryExpression :: | 2770 // UnaryExpression :: |
| 2682 // PostfixExpression | 2771 // PostfixExpression |
| 2683 // 'delete' UnaryExpression | 2772 // 'delete' UnaryExpression |
| 2684 // 'void' UnaryExpression | 2773 // 'void' UnaryExpression |
| 2685 // 'typeof' UnaryExpression | 2774 // 'typeof' UnaryExpression |
| 2686 // '++' UnaryExpression | 2775 // '++' UnaryExpression |
| 2687 // '--' UnaryExpression | 2776 // '--' UnaryExpression |
| 2688 // '+' UnaryExpression | 2777 // '+' UnaryExpression |
| 2689 // '-' UnaryExpression | 2778 // '-' UnaryExpression |
| 2690 // '~' UnaryExpression | 2779 // '~' UnaryExpression |
| 2691 // '!' UnaryExpression | 2780 // '!' UnaryExpression |
| 2692 | 2781 |
| 2693 Token::Value op = peek(); | 2782 Token::Value op = peek(); |
| 2694 if (Token::IsUnaryOp(op)) { | 2783 if (Token::IsUnaryOp(op)) { |
| 2695 op = Next(); | 2784 op = Next(); |
| 2696 int pos = position(); | 2785 int pos = position(); |
| 2697 ExpressionT expression = ParseUnaryExpression(CHECK_OK); | 2786 ExpressionT expression = ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
| 2698 | 2787 |
| 2699 if (op == Token::DELETE && is_strict(language_mode())) { | 2788 if (op == Token::DELETE && is_strict(language_mode())) { |
| 2700 if (is_strong(language_mode())) { | 2789 if (is_strong(language_mode())) { |
| 2701 ReportMessage("strong_delete"); | 2790 ReportMessage("strong_delete"); |
| 2702 *ok = false; | 2791 *ok = false; |
| 2703 return this->EmptyExpression(); | 2792 return this->EmptyExpression(); |
| 2704 } else if (this->IsIdentifier(expression)) { | 2793 } else if (this->IsIdentifier(expression)) { |
| 2705 // "delete identifier" is a syntax error in strict mode. | 2794 // "delete identifier" is a syntax error in strict mode. |
| 2706 ReportMessage("strict_delete"); | 2795 ReportMessage("strict_delete"); |
| 2707 *ok = false; | 2796 *ok = false; |
| 2708 return this->EmptyExpression(); | 2797 return this->EmptyExpression(); |
| 2709 } | 2798 } |
| 2710 } | 2799 } |
| 2711 | 2800 |
| 2712 // Allow Traits do rewrite the expression. | 2801 // Allow Traits do rewrite the expression. |
| 2713 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2802 return this->BuildUnaryExpression(expression, op, pos, factory()); |
| 2714 } else if (Token::IsCountOp(op)) { | 2803 } else if (Token::IsCountOp(op)) { |
| 2715 op = Next(); | 2804 op = Next(); |
| 2716 Scanner::Location lhs_location = scanner()->peek_location(); | 2805 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2717 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); | 2806 ExpressionT expression = this->ParseUnaryExpression(CHECK_CLASSIFIER_OK); |
| 2718 expression = this->CheckAndRewriteReferenceExpression( | 2807 expression = this->CheckAndRewriteReferenceExpression( |
| 2719 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); | 2808 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); |
| 2720 this->MarkExpressionAsAssigned(expression); | 2809 this->MarkExpressionAsAssigned(expression); |
| 2721 | 2810 |
| 2722 return factory()->NewCountOperation(op, | 2811 return factory()->NewCountOperation(op, |
| 2723 true /* prefix */, | 2812 true /* prefix */, |
| 2724 expression, | 2813 expression, |
| 2725 position()); | 2814 position()); |
| 2726 | 2815 |
| 2727 } else { | 2816 } else { |
| 2728 return this->ParsePostfixExpression(ok); | 2817 return this->ParsePostfixExpression(classifier, ok); |
| 2729 } | 2818 } |
| 2730 } | 2819 } |
| 2731 | 2820 |
| 2732 | 2821 |
| 2733 template <class Traits> | 2822 template <class Traits> |
| 2734 typename ParserBase<Traits>::ExpressionT | 2823 typename ParserBase<Traits>::ExpressionT |
| 2735 ParserBase<Traits>::ParsePostfixExpression(bool* ok) { | 2824 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
| 2825 bool* ok) { | |
| 2736 // PostfixExpression :: | 2826 // PostfixExpression :: |
| 2737 // LeftHandSideExpression ('++' | '--')? | 2827 // LeftHandSideExpression ('++' | '--')? |
| 2738 | 2828 |
| 2739 Scanner::Location lhs_location = scanner()->peek_location(); | 2829 Scanner::Location lhs_location = scanner()->peek_location(); |
| 2740 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); | 2830 ExpressionT expression = |
| 2831 this->ParseLeftHandSideExpression(CHECK_CLASSIFIER_OK); | |
| 2741 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2832 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 2742 Token::IsCountOp(peek())) { | 2833 Token::IsCountOp(peek())) { |
| 2743 expression = this->CheckAndRewriteReferenceExpression( | 2834 expression = this->CheckAndRewriteReferenceExpression( |
| 2744 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); | 2835 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); |
| 2745 expression = this->MarkExpressionAsAssigned(expression); | 2836 expression = this->MarkExpressionAsAssigned(expression); |
| 2746 | 2837 |
| 2747 Token::Value next = Next(); | 2838 Token::Value next = Next(); |
| 2748 expression = | 2839 expression = |
| 2749 factory()->NewCountOperation(next, | 2840 factory()->NewCountOperation(next, |
| 2750 false /* postfix */, | 2841 false /* postfix */, |
| 2751 expression, | 2842 expression, |
| 2752 position()); | 2843 position()); |
| 2753 } | 2844 } |
| 2754 return expression; | 2845 return expression; |
| 2755 } | 2846 } |
| 2756 | 2847 |
| 2757 | 2848 |
| 2758 template <class Traits> | 2849 template <class Traits> |
| 2759 typename ParserBase<Traits>::ExpressionT | 2850 typename ParserBase<Traits>::ExpressionT |
| 2760 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { | 2851 ParserBase<Traits>::ParseLeftHandSideExpression( |
| 2852 ExpressionClassifier* classifier, bool* ok) { | |
| 2761 // LeftHandSideExpression :: | 2853 // LeftHandSideExpression :: |
| 2762 // (NewExpression | MemberExpression) ... | 2854 // (NewExpression | MemberExpression) ... |
| 2763 | 2855 |
| 2764 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2856 ExpressionT result = |
| 2857 this->ParseMemberWithNewPrefixesExpression(CHECK_CLASSIFIER_OK); | |
| 2765 | 2858 |
| 2766 while (true) { | 2859 while (true) { |
| 2767 switch (peek()) { | 2860 switch (peek()) { |
| 2768 case Token::LBRACK: { | 2861 case Token::LBRACK: { |
| 2769 Consume(Token::LBRACK); | 2862 Consume(Token::LBRACK); |
| 2770 int pos = position(); | 2863 int pos = position(); |
| 2771 ExpressionT index = ParseExpression(true, CHECK_OK); | 2864 ExpressionT index = ParseExpression(true, CHECK_CLASSIFIER_OK); |
| 2772 result = factory()->NewProperty(result, index, pos); | 2865 result = factory()->NewProperty(result, index, pos); |
| 2773 Expect(Token::RBRACK, CHECK_OK); | 2866 Expect(Token::RBRACK, CHECK_OK); |
| 2774 break; | 2867 break; |
| 2775 } | 2868 } |
| 2776 | 2869 |
| 2777 case Token::LPAREN: { | 2870 case Token::LPAREN: { |
| 2778 if (is_strong(language_mode()) && this->IsIdentifier(result) && | 2871 if (is_strong(language_mode()) && this->IsIdentifier(result) && |
| 2779 this->IsEval(this->AsIdentifier(result))) { | 2872 this->IsEval(this->AsIdentifier(result))) { |
| 2780 ReportMessage("strong_direct_eval"); | 2873 ReportMessage("strong_direct_eval"); |
| 2781 *ok = false; | 2874 *ok = false; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2795 pos = peek_position(); | 2888 pos = peek_position(); |
| 2796 // Also the trailing parenthesis are a hint that the function will | 2889 // Also the trailing parenthesis are a hint that the function will |
| 2797 // be called immediately. If we happen to have parsed a preceding | 2890 // be called immediately. If we happen to have parsed a preceding |
| 2798 // function literal eagerly, we can also compile it eagerly. | 2891 // function literal eagerly, we can also compile it eagerly. |
| 2799 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2892 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2800 result->AsFunctionLiteral()->set_parenthesized(); | 2893 result->AsFunctionLiteral()->set_parenthesized(); |
| 2801 } | 2894 } |
| 2802 } | 2895 } |
| 2803 Scanner::Location spread_pos; | 2896 Scanner::Location spread_pos; |
| 2804 typename Traits::Type::ExpressionList args = | 2897 typename Traits::Type::ExpressionList args = |
| 2805 ParseArguments(&spread_pos, CHECK_OK); | 2898 ParseArguments(&spread_pos, CHECK_CLASSIFIER_OK); |
| 2806 | 2899 |
| 2807 // Keep track of eval() calls since they disable all local variable | 2900 // Keep track of eval() calls since they disable all local variable |
| 2808 // optimizations. | 2901 // optimizations. |
| 2809 // The calls that need special treatment are the | 2902 // The calls that need special treatment are the |
| 2810 // direct eval calls. These calls are all of the form eval(...), with | 2903 // direct eval calls. These calls are all of the form eval(...), with |
| 2811 // no explicit receiver. | 2904 // no explicit receiver. |
| 2812 // These calls are marked as potentially direct eval calls. Whether | 2905 // These calls are marked as potentially direct eval calls. Whether |
| 2813 // they are actually direct calls to eval is determined at run time. | 2906 // they are actually direct calls to eval is determined at run time. |
| 2814 this->CheckPossibleEvalCall(result, scope_); | 2907 this->CheckPossibleEvalCall(result, scope_); |
| 2815 | 2908 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2835 | 2928 |
| 2836 default: | 2929 default: |
| 2837 return result; | 2930 return result; |
| 2838 } | 2931 } |
| 2839 } | 2932 } |
| 2840 } | 2933 } |
| 2841 | 2934 |
| 2842 | 2935 |
| 2843 template <class Traits> | 2936 template <class Traits> |
| 2844 typename ParserBase<Traits>::ExpressionT | 2937 typename ParserBase<Traits>::ExpressionT |
| 2845 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { | 2938 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( |
| 2939 ExpressionClassifier* classifier, bool* ok) { | |
| 2846 // NewExpression :: | 2940 // NewExpression :: |
| 2847 // ('new')+ MemberExpression | 2941 // ('new')+ MemberExpression |
| 2848 | 2942 |
| 2849 // The grammar for new expressions is pretty warped. We can have several 'new' | 2943 // The grammar for new expressions is pretty warped. We can have several 'new' |
| 2850 // keywords following each other, and then a MemberExpression. When we see '(' | 2944 // keywords following each other, and then a MemberExpression. When we see '(' |
| 2851 // after the MemberExpression, it's associated with the rightmost unassociated | 2945 // after the MemberExpression, it's associated with the rightmost unassociated |
| 2852 // 'new' to create a NewExpression with arguments. However, a NewExpression | 2946 // 'new' to create a NewExpression with arguments. However, a NewExpression |
| 2853 // can also occur without arguments. | 2947 // can also occur without arguments. |
| 2854 | 2948 |
| 2855 // Examples of new expression: | 2949 // Examples of new expression: |
| 2856 // new foo.bar().baz means (new (foo.bar)()).baz | 2950 // new foo.bar().baz means (new (foo.bar)()).baz |
| 2857 // new foo()() means (new foo())() | 2951 // new foo()() means (new foo())() |
| 2858 // new new foo()() means (new (new foo())()) | 2952 // new new foo()() means (new (new foo())()) |
| 2859 // new new foo means new (new foo) | 2953 // new new foo means new (new foo) |
| 2860 // new new foo() means new (new foo()) | 2954 // new new foo() means new (new foo()) |
| 2861 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2955 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 2862 | 2956 |
| 2863 if (peek() == Token::NEW) { | 2957 if (peek() == Token::NEW) { |
| 2864 Consume(Token::NEW); | 2958 Consume(Token::NEW); |
| 2865 int new_pos = position(); | 2959 int new_pos = position(); |
| 2866 ExpressionT result = this->EmptyExpression(); | 2960 ExpressionT result = this->EmptyExpression(); |
| 2867 if (peek() == Token::SUPER) { | 2961 if (peek() == Token::SUPER) { |
| 2868 const bool is_new = true; | 2962 const bool is_new = true; |
| 2869 result = ParseSuperExpression(is_new, CHECK_OK); | 2963 result = ParseSuperExpression(is_new, CHECK_CLASSIFIER_OK); |
| 2870 } else { | 2964 } else { |
| 2871 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2965 result = this->ParseMemberWithNewPrefixesExpression(CHECK_CLASSIFIER_OK); |
| 2872 } | 2966 } |
| 2873 if (peek() == Token::LPAREN) { | 2967 if (peek() == Token::LPAREN) { |
| 2874 // NewExpression with arguments. | 2968 // NewExpression with arguments. |
| 2875 Scanner::Location spread_pos; | 2969 Scanner::Location spread_pos; |
| 2876 typename Traits::Type::ExpressionList args = | 2970 typename Traits::Type::ExpressionList args = |
| 2877 this->ParseArguments(&spread_pos, CHECK_OK); | 2971 this->ParseArguments(&spread_pos, CHECK_CLASSIFIER_OK); |
| 2878 | 2972 |
| 2879 if (spread_pos.IsValid()) { | 2973 if (spread_pos.IsValid()) { |
| 2880 args = Traits::PrepareSpreadArguments(args); | 2974 args = Traits::PrepareSpreadArguments(args); |
| 2881 result = Traits::SpreadCallNew(result, args, new_pos); | 2975 result = Traits::SpreadCallNew(result, args, new_pos); |
| 2882 } else { | 2976 } else { |
| 2883 result = factory()->NewCallNew(result, args, new_pos); | 2977 result = factory()->NewCallNew(result, args, new_pos); |
| 2884 } | 2978 } |
| 2885 // The expression can still continue with . or [ after the arguments. | 2979 // The expression can still continue with . or [ after the arguments. |
| 2886 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2980 result = |
| 2981 this->ParseMemberExpressionContinuation(result, CHECK_CLASSIFIER_OK); | |
| 2887 return result; | 2982 return result; |
| 2888 } | 2983 } |
| 2889 // NewExpression without arguments. | 2984 // NewExpression without arguments. |
| 2890 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2985 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
| 2891 new_pos); | 2986 new_pos); |
| 2892 } | 2987 } |
| 2893 // No 'new' or 'super' keyword. | 2988 // No 'new' or 'super' keyword. |
| 2894 return this->ParseMemberExpression(ok); | 2989 return this->ParseMemberExpression(classifier, ok); |
| 2895 } | 2990 } |
| 2896 | 2991 |
| 2897 | 2992 |
| 2898 template <class Traits> | 2993 template <class Traits> |
| 2899 typename ParserBase<Traits>::ExpressionT | 2994 typename ParserBase<Traits>::ExpressionT |
| 2900 ParserBase<Traits>::ParseMemberExpression(bool* ok) { | 2995 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
| 2996 bool* ok) { | |
| 2901 // MemberExpression :: | 2997 // MemberExpression :: |
| 2902 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 2998 // (PrimaryExpression | FunctionLiteral | ClassLiteral) |
| 2903 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 2999 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
| 2904 | 3000 |
| 2905 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3001 // The '[' Expression ']' and '.' Identifier parts are parsed by |
| 2906 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3002 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
| 2907 // caller. | 3003 // caller. |
| 2908 | 3004 |
| 2909 // Parse the initial primary or function expression. | 3005 // Parse the initial primary or function expression. |
| 2910 ExpressionT result = this->EmptyExpression(); | 3006 ExpressionT result = this->EmptyExpression(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2924 function_type = FunctionLiteral::NAMED_EXPRESSION; | 3020 function_type = FunctionLiteral::NAMED_EXPRESSION; |
| 2925 } | 3021 } |
| 2926 result = this->ParseFunctionLiteral( | 3022 result = this->ParseFunctionLiteral( |
| 2927 name, function_name_location, is_strict_reserved_name, | 3023 name, function_name_location, is_strict_reserved_name, |
| 2928 is_generator ? FunctionKind::kGeneratorFunction | 3024 is_generator ? FunctionKind::kGeneratorFunction |
| 2929 : FunctionKind::kNormalFunction, | 3025 : FunctionKind::kNormalFunction, |
| 2930 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 3026 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
| 2931 CHECK_OK); | 3027 CHECK_OK); |
| 2932 } else if (peek() == Token::SUPER) { | 3028 } else if (peek() == Token::SUPER) { |
| 2933 const bool is_new = false; | 3029 const bool is_new = false; |
| 2934 result = ParseSuperExpression(is_new, CHECK_OK); | 3030 result = ParseSuperExpression(is_new, CHECK_CLASSIFIER_OK); |
| 2935 } else { | 3031 } else { |
| 2936 result = ParsePrimaryExpression(CHECK_OK); | 3032 result = ParsePrimaryExpression(CHECK_CLASSIFIER_OK); |
| 2937 } | 3033 } |
| 2938 | 3034 |
| 2939 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 3035 result = ParseMemberExpressionContinuation(result, CHECK_CLASSIFIER_OK); |
| 2940 return result; | 3036 return result; |
| 2941 } | 3037 } |
| 2942 | 3038 |
| 2943 | 3039 |
| 2944 template <class Traits> | 3040 template <class Traits> |
| 2945 typename ParserBase<Traits>::ExpressionT | 3041 typename ParserBase<Traits>::ExpressionT |
| 2946 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 3042 ParserBase<Traits>::ParseSuperExpression(bool is_new, |
| 3043 ExpressionClassifier* classifier, | |
| 3044 bool* ok) { | |
| 2947 Expect(Token::SUPER, CHECK_OK); | 3045 Expect(Token::SUPER, CHECK_OK); |
| 2948 | 3046 |
| 2949 FunctionState* function_state = function_state_; | 3047 FunctionState* function_state = function_state_; |
| 2950 while (IsArrowFunction(function_state->kind())) { | 3048 while (IsArrowFunction(function_state->kind())) { |
| 2951 function_state = function_state->outer(); | 3049 function_state = function_state->outer(); |
| 2952 } | 3050 } |
| 2953 // TODO(arv): Handle eval scopes similarly. | 3051 // TODO(arv): Handle eval scopes similarly. |
| 2954 | 3052 |
| 2955 FunctionKind kind = function_state->kind(); | 3053 FunctionKind kind = function_state->kind(); |
| 2956 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3054 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2980 } | 3078 } |
| 2981 | 3079 |
| 2982 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3080 ReportMessageAt(scanner()->location(), "unexpected_super"); |
| 2983 *ok = false; | 3081 *ok = false; |
| 2984 return this->EmptyExpression(); | 3082 return this->EmptyExpression(); |
| 2985 } | 3083 } |
| 2986 | 3084 |
| 2987 | 3085 |
| 2988 template <class Traits> | 3086 template <class Traits> |
| 2989 typename ParserBase<Traits>::ExpressionT | 3087 typename ParserBase<Traits>::ExpressionT |
| 2990 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 3088 ParserBase<Traits>::ParseMemberExpressionContinuation( |
| 2991 bool* ok) { | 3089 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
| 2992 // Parses this part of MemberExpression: | 3090 // Parses this part of MemberExpression: |
| 2993 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3091 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
| 2994 while (true) { | 3092 while (true) { |
| 2995 switch (peek()) { | 3093 switch (peek()) { |
| 2996 case Token::LBRACK: { | 3094 case Token::LBRACK: { |
| 2997 Consume(Token::LBRACK); | 3095 Consume(Token::LBRACK); |
| 2998 int pos = position(); | 3096 int pos = position(); |
| 2999 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 3097 ExpressionT index = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
| 3000 expression = factory()->NewProperty(expression, index, pos); | 3098 expression = factory()->NewProperty(expression, index, pos); |
| 3001 if (fni_ != NULL) { | 3099 if (fni_ != NULL) { |
| 3002 this->PushPropertyName(fni_, index); | 3100 this->PushPropertyName(fni_, index); |
| 3003 } | 3101 } |
| 3004 Expect(Token::RBRACK, CHECK_OK); | 3102 Expect(Token::RBRACK, CHECK_OK); |
| 3005 break; | 3103 break; |
| 3006 } | 3104 } |
| 3007 case Token::PERIOD: { | 3105 case Token::PERIOD: { |
| 3008 Consume(Token::PERIOD); | 3106 Consume(Token::PERIOD); |
| 3009 int pos = position(); | 3107 int pos = position(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3021 if (scanner()->current_token() == Token::IDENTIFIER) { | 3119 if (scanner()->current_token() == Token::IDENTIFIER) { |
| 3022 pos = position(); | 3120 pos = position(); |
| 3023 } else { | 3121 } else { |
| 3024 pos = peek_position(); | 3122 pos = peek_position(); |
| 3025 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3123 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3026 // If the tag function looks like an IIFE, set_parenthesized() to | 3124 // If the tag function looks like an IIFE, set_parenthesized() to |
| 3027 // force eager compilation. | 3125 // force eager compilation. |
| 3028 expression->AsFunctionLiteral()->set_parenthesized(); | 3126 expression->AsFunctionLiteral()->set_parenthesized(); |
| 3029 } | 3127 } |
| 3030 } | 3128 } |
| 3031 expression = ParseTemplateLiteral(expression, pos, CHECK_OK); | 3129 expression = ParseTemplateLiteral(expression, pos, CHECK_CLASSIFIER_OK); |
| 3032 break; | 3130 break; |
| 3033 } | 3131 } |
| 3034 default: | 3132 default: |
| 3035 return expression; | 3133 return expression; |
| 3036 } | 3134 } |
| 3037 } | 3135 } |
| 3038 DCHECK(false); | 3136 DCHECK(false); |
| 3039 return this->EmptyExpression(); | 3137 return this->EmptyExpression(); |
| 3040 } | 3138 } |
| 3041 | 3139 |
| 3042 | 3140 |
| 3043 template <class Traits> | 3141 template <class Traits> |
| 3044 typename ParserBase<Traits>::ExpressionT | 3142 typename ParserBase<Traits>::ExpressionT |
| 3045 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | 3143 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, |
| 3046 ExpressionT params_ast, | 3144 ExpressionT params_ast, |
| 3145 ExpressionClassifier* classifier, | |
| 3047 bool* ok) { | 3146 bool* ok) { |
| 3048 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3147 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 3049 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3148 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 3050 // `=> ...` is never a valid expression, so report as syntax error. | 3149 // `=> ...` is never a valid expression, so report as syntax error. |
| 3051 // If next token is not `=>`, it's a syntax error anyways. | 3150 // If next token is not `=>`, it's a syntax error anyways. |
| 3052 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3151 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 3053 *ok = false; | 3152 *ok = false; |
| 3054 return this->EmptyExpression(); | 3153 return this->EmptyExpression(); |
| 3055 } | 3154 } |
| 3056 | 3155 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3108 Token::INIT_VAR, kArrowFunction, CHECK_OK); | 3207 Token::INIT_VAR, kArrowFunction, CHECK_OK); |
| 3109 materialized_literal_count = | 3208 materialized_literal_count = |
| 3110 function_state.materialized_literal_count(); | 3209 function_state.materialized_literal_count(); |
| 3111 expected_property_count = function_state.expected_property_count(); | 3210 expected_property_count = function_state.expected_property_count(); |
| 3112 handler_count = function_state.handler_count(); | 3211 handler_count = function_state.handler_count(); |
| 3113 } | 3212 } |
| 3114 } else { | 3213 } else { |
| 3115 // Single-expression body | 3214 // Single-expression body |
| 3116 int pos = position(); | 3215 int pos = position(); |
| 3117 parenthesized_function_ = false; | 3216 parenthesized_function_ = false; |
| 3118 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3217 ExpressionT expression = |
| 3218 ParseAssignmentExpression(true, CHECK_CLASSIFIER_OK); | |
| 3119 body = this->NewStatementList(1, zone()); | 3219 body = this->NewStatementList(1, zone()); |
| 3120 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3220 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3121 materialized_literal_count = function_state.materialized_literal_count(); | 3221 materialized_literal_count = function_state.materialized_literal_count(); |
| 3122 expected_property_count = function_state.expected_property_count(); | 3222 expected_property_count = function_state.expected_property_count(); |
| 3123 handler_count = function_state.handler_count(); | 3223 handler_count = function_state.handler_count(); |
| 3124 } | 3224 } |
| 3125 super_loc = function_state.super_call_location(); | 3225 super_loc = function_state.super_call_location(); |
| 3126 | 3226 |
| 3127 scope->set_start_position(start_pos); | 3227 scope->set_start_position(start_pos); |
| 3128 scope->set_end_position(scanner()->location().end_pos); | 3228 scope->set_end_position(scanner()->location().end_pos); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 3157 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); | 3257 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); |
| 3158 | 3258 |
| 3159 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3259 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
| 3160 | 3260 |
| 3161 return function_literal; | 3261 return function_literal; |
| 3162 } | 3262 } |
| 3163 | 3263 |
| 3164 | 3264 |
| 3165 template <typename Traits> | 3265 template <typename Traits> |
| 3166 typename ParserBase<Traits>::ExpressionT | 3266 typename ParserBase<Traits>::ExpressionT |
| 3167 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { | 3267 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, |
| 3268 ExpressionClassifier* classifier, | |
| 3269 bool* ok) { | |
| 3168 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3270 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
| 3169 // text followed by a substitution expression), finalized by a single | 3271 // text followed by a substitution expression), finalized by a single |
| 3170 // TEMPLATE_TAIL. | 3272 // TEMPLATE_TAIL. |
| 3171 // | 3273 // |
| 3172 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 3274 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
| 3173 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or | 3275 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or |
| 3174 // NoSubstitutionTemplate. | 3276 // NoSubstitutionTemplate. |
| 3175 // | 3277 // |
| 3176 // When parsing a TemplateLiteral, we must have scanned either an initial | 3278 // When parsing a TemplateLiteral, we must have scanned either an initial |
| 3177 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. | 3279 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3209 return Traits::EmptyExpression(); | 3311 return Traits::EmptyExpression(); |
| 3210 } else if (next == Token::ILLEGAL) { | 3312 } else if (next == Token::ILLEGAL) { |
| 3211 Traits::ReportMessageAt( | 3313 Traits::ReportMessageAt( |
| 3212 Scanner::Location(position() + 1, peek_position()), | 3314 Scanner::Location(position() + 1, peek_position()), |
| 3213 "unexpected_token", "ILLEGAL", kSyntaxError); | 3315 "unexpected_token", "ILLEGAL", kSyntaxError); |
| 3214 *ok = false; | 3316 *ok = false; |
| 3215 return Traits::EmptyExpression(); | 3317 return Traits::EmptyExpression(); |
| 3216 } | 3318 } |
| 3217 | 3319 |
| 3218 int expr_pos = peek_position(); | 3320 int expr_pos = peek_position(); |
| 3219 ExpressionT expression = this->ParseExpression(true, CHECK_OK); | 3321 ExpressionT expression = this->ParseExpression(true, CHECK_CLASSIFIER_OK); |
| 3220 Traits::AddTemplateExpression(&ts, expression); | 3322 Traits::AddTemplateExpression(&ts, expression); |
| 3221 | 3323 |
| 3222 if (peek() != Token::RBRACE) { | 3324 if (peek() != Token::RBRACE) { |
| 3223 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), | 3325 ReportMessageAt(Scanner::Location(expr_pos, peek_position()), |
| 3224 "unterminated_template_expr"); | 3326 "unterminated_template_expr"); |
| 3225 *ok = false; | 3327 *ok = false; |
| 3226 return Traits::EmptyExpression(); | 3328 return Traits::EmptyExpression(); |
| 3227 } | 3329 } |
| 3228 | 3330 |
| 3229 // If we didn't die parsing that expression, our next token should be a | 3331 // 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... | |
| 3341 *ok = false; | 3443 *ok = false; |
| 3342 return; | 3444 return; |
| 3343 } | 3445 } |
| 3344 has_seen_constructor_ = true; | 3446 has_seen_constructor_ = true; |
| 3345 return; | 3447 return; |
| 3346 } | 3448 } |
| 3347 } | 3449 } |
| 3348 } } // v8::internal | 3450 } } // v8::internal |
| 3349 | 3451 |
| 3350 #endif // V8_PREPARSER_H | 3452 #endif // V8_PREPARSER_H |
| OLD | NEW |