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

Side by Side Diff: src/preparser.h

Issue 1065983005: Introduce "expression classifier" to the parser. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698