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

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