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

Side by Side Diff: src/preparser.h

Issue 1168643005: [es6] parse destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase + Bunch of tests + Nits fixed Created 5 years, 6 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') | test/cctest/test-parsing.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 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 void ReportMessageAt(Scanner::Location location, 497 void ReportMessageAt(Scanner::Location location,
498 MessageTemplate::Template message, 498 MessageTemplate::Template message,
499 ParseErrorType error_type = kSyntaxError) { 499 ParseErrorType error_type = kSyntaxError) {
500 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0), 500 Traits::ReportMessageAt(location, message, reinterpret_cast<const char*>(0),
501 error_type); 501 error_type);
502 } 502 }
503 503
504 void ReportUnexpectedToken(Token::Value token); 504 void ReportUnexpectedToken(Token::Value token);
505 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token); 505 void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token);
506 506
507 ExpressionT CheckDestructuringAssignment(ExpressionT expr,
508 ExpressionClassifier* classifier,
509 bool needs_destructuring,
510 unsigned flags, bool* ok) {
511 // Don't rewrite AssignmentElement or RHS
512 // An AssignmentElement's optional initializer is parsed as a separate
513 // assignment expression.
514 const bool rewrite =
515 !(flags & (ASSIGNMENT_RHS | ASSIGNMENT_ELEMENT)) && needs_destructuring;
516 if (classifier->is_destructuring_assignment()) {
517 if (!classifier->is_valid_assignment_pattern()) {
518 this->ReportClassifierError(classifier->assignment_pattern_error());
519 *ok = false;
520 return this->EmptyExpression();
521 }
522 } else if (flags & ~ASSIGNMENT_ELEMENT) {
523 // If not a destructuring assignment, expect an expression
524 ValidateExpression(classifier, ok);
525 if (!*ok) return this->EmptyExpression();
526 }
527 if (rewrite) return Traits::RewriteDestructuringAssignment(expr, ok);
528 return expr;
529 }
507 530
508 void ReportClassifierError(const ExpressionClassifier::Error& error) { 531 void ReportClassifierError(const ExpressionClassifier::Error& error) {
509 Traits::ReportMessageAt(error.location, error.message, error.arg, 532 Traits::ReportMessageAt(error.location, error.message, error.arg,
510 kSyntaxError); 533 kSyntaxError);
511 } 534 }
512 535
513 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) { 536 void ValidateExpression(const ExpressionClassifier* classifier, bool* ok) {
514 if (!classifier->is_valid_expression()) { 537 if (!classifier->is_valid_expression()) {
515 ReportClassifierError(classifier->expression_error()); 538 ReportClassifierError(classifier->expression_error());
516 *ok = false; 539 *ok = false;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 MessageTemplate::kUnexpectedToken, 595 MessageTemplate::kUnexpectedToken,
573 Token::String(peek())); 596 Token::String(peek()));
574 } 597 }
575 598
576 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) { 599 void BindingPatternUnexpectedToken(ExpressionClassifier* classifier) {
577 classifier->RecordBindingPatternError(scanner()->peek_location(), 600 classifier->RecordBindingPatternError(scanner()->peek_location(),
578 MessageTemplate::kUnexpectedToken, 601 MessageTemplate::kUnexpectedToken,
579 Token::String(peek())); 602 Token::String(peek()));
580 } 603 }
581 604
605 void AssignmentPatternUnexpectedToken(ExpressionClassifier* classifier) {
606 classifier->RecordAssignmentPatternError(scanner()->peek_location(),
607 MessageTemplate::kUnexpectedToken,
608 Token::String(peek()));
609 }
610
611 void PatternUnexpectedToken(ExpressionClassifier* classifier) {
612 BindingPatternUnexpectedToken(classifier);
613 AssignmentPatternUnexpectedToken(classifier);
614 }
615
582 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) { 616 void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
583 classifier->RecordArrowFormalParametersError( 617 classifier->RecordArrowFormalParametersError(
584 scanner()->peek_location(), MessageTemplate::kUnexpectedToken, 618 scanner()->peek_location(), MessageTemplate::kUnexpectedToken,
585 Token::String(peek())); 619 Token::String(peek()));
586 } 620 }
587 621
588 // Recursive descent functions: 622 // Recursive descent functions:
589 623
590 // Parses an identifier that is valid for the current scope, in particular it 624 // Parses an identifier that is valid for the current scope, in particular it
591 // fails on strict mode future reserved keywords in a strict scope. If 625 // fails on strict mode future reserved keywords in a strict scope. If
(...skipping 26 matching lines...) Expand all
618 bool* is_static, bool* is_computed_name, 652 bool* is_static, bool* is_computed_name,
619 ExpressionClassifier* classifier, bool* ok); 653 ExpressionClassifier* classifier, bool* ok);
620 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 654 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
621 ObjectLiteralPropertyT ParsePropertyDefinition( 655 ObjectLiteralPropertyT ParsePropertyDefinition(
622 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 656 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
623 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 657 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
624 ExpressionClassifier* classifier, bool* ok); 658 ExpressionClassifier* classifier, bool* ok);
625 typename Traits::Type::ExpressionList ParseArguments( 659 typename Traits::Type::ExpressionList ParseArguments(
626 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 660 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
627 bool* ok); 661 bool* ok);
662 enum AssignmentExpressionFlags {
663 ACCEPT_IN = 1 << 0,
664 ASSIGNMENT_RHS = 1 << 1,
665 ASSIGNMENT_ELEMENT = 1 << 2
666 };
667 ExpressionT ParseAssignmentExpression(unsigned flags,
668 bool* needs_destructuring,
669 ExpressionClassifier* classifier,
670 bool* ok);
628 ExpressionT ParseAssignmentExpression(bool accept_IN, 671 ExpressionT ParseAssignmentExpression(bool accept_IN,
629 ExpressionClassifier* classifier, 672 ExpressionClassifier* classifier,
630 bool* ok); 673 bool* ok) {
674 // Overloaded for legacy compat
675 bool destructuring = false;
676 unsigned flags = accept_IN ? ACCEPT_IN : 0;
677 return ParseAssignmentExpression(flags, &destructuring, classifier, ok);
678 }
679 ExpressionT ParseAssignmentElement(bool accept_IN,
680 ExpressionClassifier* classifier,
681 bool* ok) {
682 // Don't automatically rewrite AssignmentExpressions which are meant to be
683 // AssignmentElements
684 bool destructuring = false;
685 unsigned flags = (accept_IN ? ACCEPT_IN : 0) | ASSIGNMENT_ELEMENT;
686 return ParseAssignmentExpression(flags, &destructuring, classifier, ok);
687 }
631 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); 688 ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
632 ExpressionT ParseConditionalExpression(bool accept_IN, 689 ExpressionT ParseConditionalExpression(bool accept_IN,
633 ExpressionClassifier* classifier, 690 ExpressionClassifier* classifier,
634 bool* ok); 691 bool* ok);
635 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, 692 ExpressionT ParseBinaryExpression(int prec, bool accept_IN,
636 ExpressionClassifier* classifier, bool* ok); 693 ExpressionClassifier* classifier, bool* ok);
637 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok); 694 ExpressionT ParseUnaryExpression(ExpressionClassifier* classifier, bool* ok);
638 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier, 695 ExpressionT ParsePostfixExpression(ExpressionClassifier* classifier,
639 bool* ok); 696 bool* ok);
640 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier, 697 ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 1636
1580 inline void MaterializeUnspreadArgumentsLiterals(int count); 1637 inline void MaterializeUnspreadArgumentsLiterals(int count);
1581 1638
1582 inline PreParserExpression SpreadCall(PreParserExpression function, 1639 inline PreParserExpression SpreadCall(PreParserExpression function,
1583 PreParserExpressionList args, int pos); 1640 PreParserExpressionList args, int pos);
1584 1641
1585 inline PreParserExpression SpreadCallNew(PreParserExpression function, 1642 inline PreParserExpression SpreadCallNew(PreParserExpression function,
1586 PreParserExpressionList args, 1643 PreParserExpressionList args,
1587 int pos); 1644 int pos);
1588 1645
1646 inline PreParserExpression RewriteDestructuringAssignment(
1647 PreParserExpression expr, bool* ok) {
1648 return expr;
1649 }
1650
1589 private: 1651 private:
1590 PreParser* pre_parser_; 1652 PreParser* pre_parser_;
1591 }; 1653 };
1592 1654
1593 1655
1594 // Preparsing checks a JavaScript program and emits preparse-data that helps 1656 // Preparsing checks a JavaScript program and emits preparse-data that helps
1595 // a later parsing to be faster. 1657 // a later parsing to be faster.
1596 // See preparse-data-format.h for the data format. 1658 // See preparse-data-format.h for the data format.
1597 1659
1598 // The PreParser checks that the syntax follows the grammar for JavaScript, 1660 // The PreParser checks that the syntax follows the grammar for JavaScript,
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 // ObjectLiteral 2115 // ObjectLiteral
2054 // RegExpLiteral 2116 // RegExpLiteral
2055 // ClassLiteral 2117 // ClassLiteral
2056 // '(' Expression ')' 2118 // '(' Expression ')'
2057 // TemplateLiteral 2119 // TemplateLiteral
2058 2120
2059 int beg_pos = scanner()->peek_location().beg_pos; 2121 int beg_pos = scanner()->peek_location().beg_pos;
2060 int end_pos = scanner()->peek_location().end_pos; 2122 int end_pos = scanner()->peek_location().end_pos;
2061 ExpressionT result = this->EmptyExpression(); 2123 ExpressionT result = this->EmptyExpression();
2062 Token::Value token = peek(); 2124 Token::Value token = peek();
2125 typename ExpressionClassifier::AssignmentTargetType lhs_part =
2126 ExpressionClassifier::TARGET_PRIMARY;
2063 switch (token) { 2127 switch (token) {
2064 case Token::THIS: { 2128 case Token::THIS: {
2065 BindingPatternUnexpectedToken(classifier); 2129 BindingPatternUnexpectedToken(classifier);
2066 Consume(Token::THIS); 2130 Consume(Token::THIS);
2067 if (FLAG_strong_this && is_strong(language_mode())) { 2131 if (FLAG_strong_this && is_strong(language_mode())) {
2068 // Constructors' usages of 'this' in strong mode are parsed separately. 2132 // Constructors' usages of 'this' in strong mode are parsed separately.
2069 // TODO(rossberg): this does not work with arrow functions yet. 2133 // TODO(rossberg): this does not work with arrow functions yet.
2070 if (i::IsConstructor(function_state_->kind())) { 2134 if (i::IsConstructor(function_state_->kind())) {
2071 ReportMessage(MessageTemplate::kStrongConstructorThis); 2135 ReportMessage(MessageTemplate::kStrongConstructorThis);
2072 *ok = false; 2136 *ok = false;
(...skipping 20 matching lines...) Expand all
2093 result = 2157 result =
2094 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); 2158 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory());
2095 break; 2159 break;
2096 2160
2097 case Token::IDENTIFIER: 2161 case Token::IDENTIFIER:
2098 case Token::LET: 2162 case Token::LET:
2099 case Token::STATIC: 2163 case Token::STATIC:
2100 case Token::YIELD: 2164 case Token::YIELD:
2101 case Token::FUTURE_STRICT_RESERVED_WORD: { 2165 case Token::FUTURE_STRICT_RESERVED_WORD: {
2102 // Using eval or arguments in this context is OK even in strict mode. 2166 // Using eval or arguments in this context is OK even in strict mode.
2167 lhs_part = ExpressionClassifier::TARGET_IDENTIFIER;
2103 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); 2168 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
2104 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, 2169 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
2105 factory()); 2170 factory());
2106 break; 2171 break;
2107 } 2172 }
2108 2173
2109 case Token::STRING: { 2174 case Token::STRING: {
2110 classifier->RecordBindingPatternError( 2175 classifier->RecordBindingPatternError(
2111 scanner()->location(), MessageTemplate::kUnexpectedTokenString); 2176 scanner()->location(), MessageTemplate::kUnexpectedTokenString);
2112 Consume(Token::STRING); 2177 Consume(Token::STRING);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2174 *ok = false; 2239 *ok = false;
2175 return this->EmptyExpression(); 2240 return this->EmptyExpression();
2176 } 2241 }
2177 Expect(Token::RPAREN, CHECK_OK); 2242 Expect(Token::RPAREN, CHECK_OK);
2178 result = this->ParseArrowFunctionLiteral(scope, has_rest, 2243 result = this->ParseArrowFunctionLiteral(scope, has_rest,
2179 args_classifier, CHECK_OK); 2244 args_classifier, CHECK_OK);
2180 } else { 2245 } else {
2181 // Heuristically try to detect immediately called functions before 2246 // Heuristically try to detect immediately called functions before
2182 // seeing the call parentheses. 2247 // seeing the call parentheses.
2183 parenthesized_function_ = (peek() == Token::FUNCTION); 2248 parenthesized_function_ = (peek() == Token::FUNCTION);
2249 lhs_part = ExpressionClassifier::TARGET_NONE;
2184 result = this->ParseExpression(true, classifier, CHECK_OK); 2250 result = this->ParseExpression(true, classifier, CHECK_OK);
2185 Expect(Token::RPAREN, CHECK_OK); 2251 Expect(Token::RPAREN, CHECK_OK);
2186 } 2252 }
2187 break; 2253 break;
2188 2254
2189 case Token::CLASS: { 2255 case Token::CLASS: {
2190 BindingPatternUnexpectedToken(classifier); 2256 BindingPatternUnexpectedToken(classifier);
2191 Consume(Token::CLASS); 2257 Consume(Token::CLASS);
2192 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 2258 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2193 ReportMessage(MessageTemplate::kSloppyLexical); 2259 ReportMessage(MessageTemplate::kSloppyLexical);
(...skipping 17 matching lines...) Expand all
2211 2277
2212 case Token::TEMPLATE_SPAN: 2278 case Token::TEMPLATE_SPAN:
2213 case Token::TEMPLATE_TAIL: 2279 case Token::TEMPLATE_TAIL:
2214 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, 2280 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
2215 classifier, CHECK_OK); 2281 classifier, CHECK_OK);
2216 break; 2282 break;
2217 2283
2218 case Token::MOD: 2284 case Token::MOD:
2219 if (allow_natives() || extension_ != NULL) { 2285 if (allow_natives() || extension_ != NULL) {
2220 result = this->ParseV8Intrinsic(CHECK_OK); 2286 result = this->ParseV8Intrinsic(CHECK_OK);
2287 lhs_part = ExpressionClassifier::TARGET_CALL;
2221 break; 2288 break;
2222 } 2289 }
2223 // If we're not allowing special syntax we fall-through to the 2290 // If we're not allowing special syntax we fall-through to the
2224 // default case. 2291 // default case.
2225 2292
2226 default: { 2293 default: {
2227 Next(); 2294 Next();
2228 ReportUnexpectedToken(token); 2295 ReportUnexpectedToken(token);
2229 *ok = false; 2296 *ok = false;
2230 } 2297 }
2231 } 2298 }
2232 2299
2300 if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) {
2301 classifier->AppendAssignmentTarget(lhs_part);
2302 }
2303
2233 return result; 2304 return result;
2234 } 2305 }
2235 2306
2236 2307
2237 template <class Traits> 2308 template <class Traits>
2238 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 2309 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2239 bool accept_IN, bool* ok) { 2310 bool accept_IN, bool* ok) {
2240 ExpressionClassifier classifier; 2311 ExpressionClassifier classifier;
2241 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); 2312 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2242 ValidateExpression(&classifier, CHECK_OK); 2313 ValidateExpression(&classifier, CHECK_OK);
2243 return result; 2314 return result;
2244 } 2315 }
2245 2316
2246 2317
2247 // Precedence = 1 2318 // Precedence = 1
2248 template <class Traits> 2319 template <class Traits>
2249 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 2320 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2250 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 2321 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2251 // Expression :: 2322 // Expression ::
2252 // AssignmentExpression 2323 // AssignmentExpression
2253 // Expression ',' AssignmentExpression 2324 // Expression ',' AssignmentExpression
2254 2325
2255 ExpressionClassifier binding_classifier; 2326 ExpressionClassifier expr_classifier;
2256 ExpressionT result = 2327 ExpressionT result =
2257 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 2328 this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
2258 classifier->Accumulate(binding_classifier, 2329 ExpressionClassifier::AssignmentTargetType lhs_type =
2259 ExpressionClassifier::AllProductions); 2330 expr_classifier.AssignmentTarget();
2331 classifier->Accumulate(expr_classifier,
2332 expr_classifier.is_destructuring_assignment()
2333 ? ExpressionClassifier::PatternProductions
2334 : ExpressionClassifier::AllProductions);
2260 bool seen_rest = false; 2335 bool seen_rest = false;
2261 while (peek() == Token::COMMA) { 2336 while (peek() == Token::COMMA) {
2337 ExpressionClassifier expr_classifier;
2338 lhs_type = ExpressionClassifier::TARGET_PRIMARY;
2262 if (seen_rest) { 2339 if (seen_rest) {
2263 // At this point the production can't possibly be valid, but we don't know 2340 // At this point the production can't possibly be valid, but we don't know
2264 // which error to signal. 2341 // which error to signal.
2265 classifier->RecordArrowFormalParametersError( 2342 classifier->RecordArrowFormalParametersError(
2266 scanner()->peek_location(), MessageTemplate::kParamAfterRest); 2343 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2267 } 2344 }
2268 Consume(Token::COMMA); 2345 Consume(Token::COMMA);
2269 bool is_rest = false; 2346 bool is_rest = false;
2270 if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) { 2347 if (allow_harmony_rest_params() && peek() == Token::ELLIPSIS) {
2271 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only 2348 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2272 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a 2349 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2273 // valid expression or binding pattern. 2350 // valid expression or binding pattern.
2274 ExpressionUnexpectedToken(classifier); 2351 ExpressionUnexpectedToken(classifier);
2275 BindingPatternUnexpectedToken(classifier); 2352 BindingPatternUnexpectedToken(classifier);
2276 Consume(Token::ELLIPSIS); 2353 Consume(Token::ELLIPSIS);
2277 seen_rest = is_rest = true; 2354 seen_rest = is_rest = true;
2278 } 2355 }
2279 int pos = position(); 2356 int pos = position();
2280 ExpressionT right = this->ParseAssignmentExpression( 2357 ExpressionT right =
2281 accept_IN, &binding_classifier, CHECK_OK); 2358 this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
2282 if (is_rest) right = factory()->NewSpread(right, pos); 2359 if (is_rest) right = factory()->NewSpread(right, pos);
2283 classifier->Accumulate(binding_classifier, 2360 classifier->Accumulate(expr_classifier,
2284 ExpressionClassifier::AllProductions); 2361 expr_classifier.is_destructuring_assignment()
2362 ? ExpressionClassifier::PatternProductions
2363 : ExpressionClassifier::AllProductions);
2364
2285 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 2365 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2286 } 2366 }
2367 classifier->AppendAssignmentTarget(lhs_type);
2287 return result; 2368 return result;
2288 } 2369 }
2289 2370
2290 2371
2291 template <class Traits> 2372 template <class Traits>
2292 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 2373 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2293 ExpressionClassifier* classifier, bool* ok) { 2374 ExpressionClassifier* classifier, bool* ok) {
2294 // ArrayLiteral :: 2375 // ArrayLiteral ::
2295 // '[' Expression? (',' Expression?)* ']' 2376 // '[' Expression? (',' Expression?)* ']'
2296 2377
2297 int pos = peek_position(); 2378 int pos = peek_position();
2298 typename Traits::Type::ExpressionList values = 2379 typename Traits::Type::ExpressionList values =
2299 this->NewExpressionList(4, zone_); 2380 this->NewExpressionList(4, zone_);
2300 Expect(Token::LBRACK, CHECK_OK); 2381 Expect(Token::LBRACK, CHECK_OK);
2301 while (peek() != Token::RBRACK) { 2382 while (peek() != Token::RBRACK) {
2302 bool seen_spread = false; 2383 bool seen_spread = false;
2303 ExpressionT elem = this->EmptyExpression(); 2384 ExpressionT elem = this->EmptyExpression();
2385 ExpressionClassifier element_classifier;
2386 bool accumulate_element = true;
2387 int start_pos = peek_position();
2304 if (peek() == Token::COMMA) { 2388 if (peek() == Token::COMMA) {
2305 if (is_strong(language_mode())) { 2389 if (is_strong(language_mode())) {
2306 ReportMessageAt(scanner()->peek_location(), 2390 ReportMessageAt(scanner()->peek_location(),
2307 MessageTemplate::kStrongEllision); 2391 MessageTemplate::kStrongEllision);
2308 *ok = false; 2392 *ok = false;
2309 return this->EmptyExpression(); 2393 return this->EmptyExpression();
2310 } 2394 }
2311 elem = this->GetLiteralTheHole(peek_position(), factory()); 2395 elem = this->GetLiteralTheHole(peek_position(), factory());
2396 accumulate_element = false;
2312 } else if (peek() == Token::ELLIPSIS) { 2397 } else if (peek() == Token::ELLIPSIS) {
2313 if (!allow_harmony_spread_arrays()) { 2398 if (!allow_harmony_spread_arrays()) {
2314 ExpressionUnexpectedToken(classifier); 2399 ExpressionUnexpectedToken(classifier);
2315 } 2400 }
2316 int start_pos = peek_position();
2317 Consume(Token::ELLIPSIS); 2401 Consume(Token::ELLIPSIS);
2318 ExpressionT argument = 2402 ExpressionT argument =
2319 this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2403 this->ParseAssignmentElement(true, &element_classifier, CHECK_OK);
2320 elem = factory()->NewSpread(argument, start_pos); 2404 elem = factory()->NewSpread(argument, start_pos);
2321 seen_spread = true; 2405 seen_spread = true;
2406
2407 // AssignmentRestElements may not have initializers
2408 if (element_classifier.IsAssigned()) {
2409 Scanner::Location location(start_pos, scanner()->location().end_pos);
2410 classifier->RecordAssignmentPatternError(
2411 location, MessageTemplate::kInitializedAssignmentRestElement);
2412 }
2322 } else { 2413 } else {
2323 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2414 elem = this->ParseAssignmentElement(true, &element_classifier, CHECK_OK);
2324 } 2415 }
2416 if (accumulate_element) {
2417 if (!element_classifier.IsValidSimpleAssignmentTarget() &&
2418 !element_classifier.IsValidPattern()) {
2419 Scanner::Location location(start_pos, scanner()->location().end_pos);
2420 classifier->RecordAssignmentPatternError(
2421 location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
2422 }
2423 classifier->Accumulate(element_classifier);
2424 }
2425
2325 values->Add(elem, zone_); 2426 values->Add(elem, zone_);
2326 if (peek() != Token::RBRACK) { 2427 if (peek() != Token::RBRACK) {
2327 if (seen_spread) { 2428 if (seen_spread) {
2328 BindingPatternUnexpectedToken(classifier); 2429 PatternUnexpectedToken(classifier);
2329 } 2430 }
2330 Expect(Token::COMMA, CHECK_OK); 2431 Expect(Token::COMMA, CHECK_OK);
2331 } 2432 }
2332 } 2433 }
2333 Expect(Token::RBRACK, CHECK_OK); 2434 Expect(Token::RBRACK, CHECK_OK);
2334 2435
2335 // Update the scope information before the pre-parsing bailout. 2436 // Update the scope information before the pre-parsing bailout.
2336 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2437 int literal_index = function_state_->NextMaterializedLiteralIndex();
2337 2438
2338 return factory()->NewArrayLiteral(values, literal_index, 2439 return factory()->NewArrayLiteral(values, literal_index,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 2508 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2408 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 2509 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2409 ExpressionClassifier* classifier, bool* ok) { 2510 ExpressionClassifier* classifier, bool* ok) {
2410 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); 2511 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2411 ExpressionT value = this->EmptyExpression(); 2512 ExpressionT value = this->EmptyExpression();
2412 IdentifierT name = this->EmptyIdentifier(); 2513 IdentifierT name = this->EmptyIdentifier();
2413 bool is_get = false; 2514 bool is_get = false;
2414 bool is_set = false; 2515 bool is_set = false;
2415 bool name_is_static = false; 2516 bool name_is_static = false;
2416 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 2517 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
2417 2518 // Classify destructuring assignment target for ObjectAssignmentPattern
2519 ExpressionClassifier property_classifier;
2418 Token::Value name_token = peek(); 2520 Token::Value name_token = peek();
2419 int next_beg_pos = scanner()->peek_location().beg_pos; 2521 int next_beg_pos = scanner()->peek_location().beg_pos;
2420 int next_end_pos = scanner()->peek_location().end_pos; 2522 int next_end_pos = scanner()->peek_location().end_pos;
2523 int value_start = next_beg_pos;
2524 int value_end = next_end_pos;
2421 ExpressionT name_expression = ParsePropertyName( 2525 ExpressionT name_expression = ParsePropertyName(
2422 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, 2526 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2423 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2527 &property_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2424 2528
2425 if (fni_ != nullptr && !*is_computed_name) { 2529 if (fni_ != nullptr && !*is_computed_name) {
2426 this->PushLiteralName(fni_, name); 2530 this->PushLiteralName(fni_, name);
2427 } 2531 }
2428 2532
2429 if (!in_class && !is_generator && peek() == Token::COLON) { 2533 if (!in_class && !is_generator && peek() == Token::COLON) {
2430 // PropertyDefinition : PropertyName ':' AssignmentExpression 2534 // PropertyDefinition : PropertyName ':' AssignmentExpression
2431 if (!*is_computed_name) { 2535 if (!*is_computed_name) {
2432 checker->CheckProperty(name_token, kValueProperty, is_static, 2536 checker->CheckProperty(name_token, kValueProperty, is_static,
2433 is_generator, 2537 is_generator,
2434 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2538 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2435 } 2539 }
2436 Consume(Token::COLON); 2540 Consume(Token::COLON);
2437 value = this->ParseAssignmentExpression( 2541 property_classifier = ExpressionClassifier();
2438 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2542 value_start = peek_position();
2439 2543 value = this->ParseAssignmentElement(
2544 true, &property_classifier,
2545 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2546 value_end = scanner()->location().end_pos;
2440 } else if (is_generator || 2547 } else if (is_generator ||
2441 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 2548 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2442 // Concise Method 2549 // Concise Method
2550 property_classifier.ReportInvalidSimpleAssignmentTarget();
2443 if (!*is_computed_name) { 2551 if (!*is_computed_name) {
2444 checker->CheckProperty(name_token, kMethodProperty, is_static, 2552 checker->CheckProperty(name_token, kMethodProperty, is_static,
2445 is_generator, 2553 is_generator,
2446 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2554 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2447 } 2555 }
2448 2556
2449 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod 2557 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2450 : FunctionKind::kConciseMethod; 2558 : FunctionKind::kConciseMethod;
2451 2559
2452 if (in_class && !is_static && this->IsConstructor(name)) { 2560 if (in_class && !is_static && this->IsConstructor(name)) {
(...skipping 10 matching lines...) Expand all
2463 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 2571 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2464 FunctionLiteral::NORMAL_ARITY, 2572 FunctionLiteral::NORMAL_ARITY,
2465 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2573 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2466 2574
2467 return factory()->NewObjectLiteralProperty(name_expression, value, 2575 return factory()->NewObjectLiteralProperty(name_expression, value,
2468 ObjectLiteralProperty::COMPUTED, 2576 ObjectLiteralProperty::COMPUTED,
2469 is_static, *is_computed_name); 2577 is_static, *is_computed_name);
2470 2578
2471 } else if (in_class && name_is_static && !is_static) { 2579 } else if (in_class && name_is_static && !is_static) {
2472 // static MethodDefinition 2580 // static MethodDefinition
2581 property_classifier.ReportInvalidSimpleAssignmentTarget();
2473 return ParsePropertyDefinition(checker, true, has_extends, true, 2582 return ParsePropertyDefinition(checker, true, has_extends, true,
2474 is_computed_name, nullptr, classifier, ok); 2583 is_computed_name, nullptr, classifier, ok);
2475 } else if (is_get || is_set) { 2584 } else if (is_get || is_set) {
2476 // Accessor 2585 // Accessor
2586 property_classifier.ReportInvalidSimpleAssignmentTarget();
2477 name = this->EmptyIdentifier(); 2587 name = this->EmptyIdentifier();
2478 bool dont_care = false; 2588 bool dont_care = false;
2479 name_token = peek(); 2589 name_token = peek();
2480 2590
2481 name_expression = ParsePropertyName( 2591 name_expression = ParsePropertyName(
2482 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2592 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2483 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2593 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2484 2594
2485 if (!*is_computed_name) { 2595 if (!*is_computed_name) {
2486 checker->CheckProperty(name_token, kAccessorProperty, is_static, 2596 checker->CheckProperty(name_token, kAccessorProperty, is_static,
(...skipping 11 matching lines...) Expand all
2498 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2608 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2499 2609
2500 // Make sure the name expression is a string since we need a Name for 2610 // Make sure the name expression is a string since we need a Name for
2501 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this 2611 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2502 // statically we can skip the extra runtime check. 2612 // statically we can skip the extra runtime check.
2503 if (!*is_computed_name) { 2613 if (!*is_computed_name) {
2504 name_expression = 2614 name_expression =
2505 factory()->NewStringLiteral(name, name_expression->position()); 2615 factory()->NewStringLiteral(name, name_expression->position());
2506 } 2616 }
2507 2617
2618 value_end = scanner()->location().end_pos;
2619 Scanner::Location location(value_start, value_end);
2620 classifier->RecordAssignmentPatternError(
2621 location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
2622
2508 return factory()->NewObjectLiteralProperty( 2623 return factory()->NewObjectLiteralProperty(
2509 name_expression, value, 2624 name_expression, value,
2510 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, 2625 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2511 is_static, *is_computed_name); 2626 is_static, *is_computed_name);
2512 2627
2513 } else if (!in_class && allow_harmony_object_literals_ && 2628 } else if (!in_class && allow_harmony_object_literals_ &&
2514 Token::IsIdentifier(name_token, language_mode(), 2629 Token::IsIdentifier(name_token, language_mode(),
2515 this->is_generator())) { 2630 this->is_generator())) {
2516 DCHECK(!*is_computed_name); 2631 DCHECK(!*is_computed_name);
2517 DCHECK(!is_static); 2632 DCHECK(!is_static);
(...skipping 15 matching lines...) Expand all
2533 return factory()->NewObjectLiteralProperty( 2648 return factory()->NewObjectLiteralProperty(
2534 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); 2649 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false);
2535 2650
2536 } else { 2651 } else {
2537 Token::Value next = Next(); 2652 Token::Value next = Next();
2538 ReportUnexpectedToken(next); 2653 ReportUnexpectedToken(next);
2539 *ok = false; 2654 *ok = false;
2540 return this->EmptyObjectLiteralProperty(); 2655 return this->EmptyObjectLiteralProperty();
2541 } 2656 }
2542 2657
2658 if (!property_classifier.IsValidSimpleAssignmentTarget() &&
2659 !property_classifier.IsPatternAssignmentElement()) {
2660 Scanner::Location location(value_start, value_end);
2661 classifier->RecordAssignmentPatternError(
2662 location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
2663 }
2664 classifier->Accumulate(property_classifier);
2665
2543 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, 2666 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2544 *is_computed_name); 2667 *is_computed_name);
2545 } 2668 }
2546 2669
2547 2670
2548 template <class Traits> 2671 template <class Traits>
2549 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 2672 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2550 ExpressionClassifier* classifier, bool* ok) { 2673 ExpressionClassifier* classifier, bool* ok) {
2551 // ObjectLiteral :: 2674 // ObjectLiteral ::
2552 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2675 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 // the parser and preparser 2798 // the parser and preparser
2676 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); 2799 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2677 } 2800 }
2678 2801
2679 return result; 2802 return result;
2680 } 2803 }
2681 2804
2682 // Precedence = 2 2805 // Precedence = 2
2683 template <class Traits> 2806 template <class Traits>
2684 typename ParserBase<Traits>::ExpressionT 2807 typename ParserBase<Traits>::ExpressionT
2685 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, 2808 ParserBase<Traits>::ParseAssignmentExpression(unsigned flags,
2809 bool* needs_destructuring,
2686 ExpressionClassifier* classifier, 2810 ExpressionClassifier* classifier,
2687 bool* ok) { 2811 bool* ok) {
2688 // AssignmentExpression :: 2812 // AssignmentExpression ::
2689 // ConditionalExpression 2813 // ConditionalExpression
2690 // ArrowFunction 2814 // ArrowFunction
2691 // YieldExpression 2815 // YieldExpression
2692 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2816 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2817 bool accept_IN = flags & ACCEPT_IN;
2818 bool is_assignment_element = flags & ASSIGNMENT_ELEMENT;
2693 2819
2694 Scanner::Location lhs_location = scanner()->peek_location(); 2820 Scanner::Location lhs_location = scanner()->peek_location();
2695 2821
2696 if (peek() == Token::YIELD && is_generator()) { 2822 if (peek() == Token::YIELD && is_generator()) {
2697 return this->ParseYieldExpression(classifier, ok); 2823 return this->ParseYieldExpression(classifier, ok);
2698 } 2824 }
2699 2825
2826 bool maybe_assignment_pattern =
2827 allow_harmony_destructuring() &&
2828 classifier->is_valid_assignment_pattern() &&
2829 (peek() == Token::LBRACK || peek() == Token::LBRACE);
2830
2700 if (fni_ != NULL) fni_->Enter(); 2831 if (fni_ != NULL) fni_->Enter();
2701 ParserBase<Traits>::Checkpoint checkpoint(this); 2832 ParserBase<Traits>::Checkpoint checkpoint(this);
2702 ExpressionClassifier arrow_formals_classifier; 2833 ExpressionClassifier arrow_formals_classifier;
2703 if (peek() != Token::LPAREN) { 2834 if (peek() != Token::LPAREN) {
2704 // The expression we are going to read is not a parenthesized arrow function 2835 // The expression we are going to read is not a parenthesized arrow function
2705 // formal parameter list. 2836 // formal parameter list.
2706 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); 2837 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2707 } 2838 }
2708 ExpressionT expression = this->ParseConditionalExpression( 2839 ExpressionT expression = this->ParseConditionalExpression(
2709 accept_IN, &arrow_formals_classifier, CHECK_OK); 2840 accept_IN, &arrow_formals_classifier, CHECK_OK);
2710 2841
2842 if (!arrow_formals_classifier.is_valid_assignment_pattern()) {
2843 if (maybe_assignment_pattern && peek() == Token::ASSIGN) {
2844 // ObjectAssignmentPattern or ArrayAssignmentPattern contains an error
2845 ReportClassifierError(
2846 arrow_formals_classifier.assignment_pattern_error());
2847 *ok = false;
2848 return this->EmptyExpression();
2849 }
2850 }
2851
2711 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { 2852 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2712 checkpoint.Restore(); 2853 checkpoint.Restore();
2713 BindingPatternUnexpectedToken(classifier); 2854 BindingPatternUnexpectedToken(classifier);
2855 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY);
2714 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2856 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2715 CHECK_OK); 2857 CHECK_OK);
2716 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); 2858 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
2717 Scope* scope = 2859 Scope* scope =
2718 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2860 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2719 scope->set_start_position(lhs_location.beg_pos); 2861 scope->set_start_position(lhs_location.beg_pos);
2720 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2862 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2721 bool has_rest = false; 2863 bool has_rest = false;
2722 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, 2864 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest,
2723 &duplicate_loc, CHECK_OK); 2865 &duplicate_loc, CHECK_OK);
2724 if (duplicate_loc.IsValid()) { 2866 if (duplicate_loc.IsValid()) {
2725 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2867 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2726 duplicate_loc); 2868 duplicate_loc);
2727 } 2869 }
2728 expression = this->ParseArrowFunctionLiteral( 2870 expression = this->ParseArrowFunctionLiteral(
2729 scope, has_rest, arrow_formals_classifier, CHECK_OK); 2871 scope, has_rest, arrow_formals_classifier, CHECK_OK);
2730 return expression; 2872 return expression;
2731 } 2873 }
2732 2874
2733 // "expression" was not itself an arrow function parameter list, but it might 2875 // "expression" was not itself an arrow function parameter list, but it might
2734 // form part of one. Propagate speculative formal parameter error locations. 2876 // form part of one. Propagate speculative formal parameter error locations.
2735 classifier->Accumulate(arrow_formals_classifier, 2877 classifier->Accumulate(arrow_formals_classifier,
2736 ExpressionClassifier::StandardProductions | 2878 ExpressionClassifier::StandardProductions |
2737 ExpressionClassifier::FormalParametersProductions); 2879 ExpressionClassifier::FormalParametersProductions);
2738 2880
2881 bool valid_destructuring_assignment_target =
2882 arrow_formals_classifier.IsValidSimpleAssignmentTarget();
2883 if (valid_destructuring_assignment_target) {
2884 classifier->AccumulateValidSimpleAssignmentTarget(arrow_formals_classifier);
2885 } else if (!maybe_assignment_pattern ||
2886 !arrow_formals_classifier.is_valid_assignment_pattern()) {
2887 // Potentially a bad DestructuringAssignmentTarget
2888 classifier->RecordAssignmentPatternError(
2889 Scanner::Location(lhs_location.beg_pos, scanner()->location().end_pos),
2890 MessageTemplate::kInvalidDestructuringAssignmentTarget);
2891 }
2892
2893 if (maybe_assignment_pattern) {
2894 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PATTERN);
2895 if ((maybe_assignment_pattern = peek() == Token::ASSIGN)) {
2896 *needs_destructuring = true;
2897 }
2898 }
2899
2739 if (!Token::IsAssignmentOp(peek())) { 2900 if (!Token::IsAssignmentOp(peek())) {
2740 if (fni_ != NULL) fni_->Leave(); 2901 if (fni_ != NULL) fni_->Leave();
2741 // Parsed conditional expression only (no assignment). 2902 // Parsed conditional expression only (no assignment).
2742 return expression; 2903 return expression;
2743 } 2904 }
2744 2905
2745 if (!allow_harmony_destructuring()) { 2906 if (!allow_harmony_destructuring()) {
2746 BindingPatternUnexpectedToken(classifier); 2907 BindingPatternUnexpectedToken(classifier);
2747 } 2908 }
2748 2909
2749 expression = this->CheckAndRewriteReferenceExpression( 2910 if (!maybe_assignment_pattern) {
2750 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, 2911 expression = this->CheckAndRewriteReferenceExpression(
2751 CHECK_OK); 2912 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
2913 CHECK_OK);
2914 }
2915
2752 expression = this->MarkExpressionAsAssigned(expression); 2916 expression = this->MarkExpressionAsAssigned(expression);
2753 2917
2754 Token::Value op = Next(); // Get assignment operator. 2918 Token::Value op = Next(); // Get assignment operator.
2755 if (op != Token::ASSIGN) { 2919 if (op == Token::ASSIGN) {
2920 classifier->set_assigned();
2921 } else {
2756 classifier->RecordBindingPatternError(scanner()->location(), 2922 classifier->RecordBindingPatternError(scanner()->location(),
2757 MessageTemplate::kUnexpectedToken, 2923 MessageTemplate::kUnexpectedToken,
2758 Token::String(op)); 2924 Token::String(op));
2759 } 2925 }
2760 int pos = position(); 2926 int pos = position();
2761 2927
2762 ExpressionClassifier rhs_classifier; 2928 ExpressionClassifier rhs_classifier;
2763 ExpressionT right = 2929 unsigned rhs_flags = flags | ASSIGNMENT_RHS;
2764 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); 2930 if (is_assignment_element) {
2931 // Parse an assignment element's initializer as a regular
2932 // AssignmentExpression
2933 rhs_flags &= ~(ASSIGNMENT_RHS | ASSIGNMENT_ELEMENT);
2934 }
2935 ExpressionT right = this->ParseAssignmentExpression(
2936 rhs_flags, needs_destructuring, &rhs_classifier, CHECK_OK);
arv (Not doing code reviews) 2015/06/19 18:49:05 Don't we need to pass in a new boolean here? The o
2765 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); 2937 classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
2766 2938
2767 // TODO(1231235): We try to estimate the set of properties set by 2939 // TODO(1231235): We try to estimate the set of properties set by
2768 // constructors. We define a new property whenever there is an 2940 // constructors. We define a new property whenever there is an
2769 // assignment to a property of 'this'. We should probably only add 2941 // assignment to a property of 'this'. We should probably only add
2770 // properties if we haven't seen them before. Otherwise we'll 2942 // properties if we haven't seen them before. Otherwise we'll
2771 // probably overestimate the number of properties. 2943 // probably overestimate the number of properties.
2772 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 2944 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2773 function_state_->AddProperty(); 2945 function_state_->AddProperty();
2774 } 2946 }
2775 2947
2776 this->CheckAssigningFunctionLiteralToProperty(expression, right); 2948 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2777 2949
2778 if (fni_ != NULL) { 2950 if (fni_ != NULL) {
2779 // Check if the right hand side is a call to avoid inferring a 2951 // Check if the right hand side is a call to avoid inferring a
2780 // name if we're dealing with "a = function(){...}();"-like 2952 // name if we're dealing with "a = function(){...}();"-like
2781 // expression. 2953 // expression.
2782 if ((op == Token::INIT_VAR 2954 if ((op == Token::INIT_VAR
2783 || op == Token::INIT_CONST_LEGACY 2955 || op == Token::INIT_CONST_LEGACY
2784 || op == Token::ASSIGN) 2956 || op == Token::ASSIGN)
2785 && (!right->IsCall() && !right->IsCallNew())) { 2957 && (!right->IsCall() && !right->IsCallNew())) {
2786 fni_->Infer(); 2958 fni_->Infer();
2787 } else { 2959 } else {
2788 fni_->RemoveLastFunction(); 2960 fni_->RemoveLastFunction();
2789 } 2961 }
2790 fni_->Leave(); 2962 fni_->Leave();
2791 } 2963 }
2792 2964
2793 return factory()->NewAssignment(op, expression, right, pos); 2965 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2966 return this->CheckDestructuringAssignment(
2967 result, classifier, *needs_destructuring, flags, CHECK_OK);
2794 } 2968 }
2795 2969
2796 template <class Traits> 2970 template <class Traits>
2797 typename ParserBase<Traits>::ExpressionT 2971 typename ParserBase<Traits>::ExpressionT
2798 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, 2972 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
2799 bool* ok) { 2973 bool* ok) {
2800 // YieldExpression :: 2974 // YieldExpression ::
2801 // 'yield' ([no line terminator] '*'? AssignmentExpression)? 2975 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2802 int pos = peek_position(); 2976 int pos = peek_position();
2803 Expect(Token::YIELD, CHECK_OK); 2977 Expect(Token::YIELD, CHECK_OK);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2847 // ConditionalExpression :: 3021 // ConditionalExpression ::
2848 // LogicalOrExpression 3022 // LogicalOrExpression
2849 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 3023 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2850 3024
2851 int pos = peek_position(); 3025 int pos = peek_position();
2852 // We start using the binary expression parser for prec >= 4 only! 3026 // We start using the binary expression parser for prec >= 4 only!
2853 ExpressionT expression = 3027 ExpressionT expression =
2854 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); 3028 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2855 if (peek() != Token::CONDITIONAL) return expression; 3029 if (peek() != Token::CONDITIONAL) return expression;
2856 BindingPatternUnexpectedToken(classifier); 3030 BindingPatternUnexpectedToken(classifier);
3031 classifier->ReportInvalidSimpleAssignmentTarget();
2857 Consume(Token::CONDITIONAL); 3032 Consume(Token::CONDITIONAL);
2858 // In parsing the first assignment expression in conditional 3033 // In parsing the first assignment expression in conditional
2859 // expressions we always accept the 'in' keyword; see ECMA-262, 3034 // expressions we always accept the 'in' keyword; see ECMA-262,
2860 // section 11.12, page 58. 3035 // section 11.12, page 58.
2861 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); 3036 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
2862 Expect(Token::COLON, CHECK_OK); 3037 Expect(Token::COLON, CHECK_OK);
2863 ExpressionT right = 3038 ExpressionT right =
2864 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); 3039 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2865 return factory()->NewConditional(expression, left, right, pos); 3040 return factory()->NewConditional(expression, left, right, pos);
2866 } 3041 }
2867 3042
2868 3043
2869 // Precedence >= 4 3044 // Precedence >= 4
2870 template <class Traits> 3045 template <class Traits>
2871 typename ParserBase<Traits>::ExpressionT 3046 typename ParserBase<Traits>::ExpressionT
2872 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, 3047 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2873 ExpressionClassifier* classifier, 3048 ExpressionClassifier* classifier,
2874 bool* ok) { 3049 bool* ok) {
2875 DCHECK(prec >= 4); 3050 DCHECK(prec >= 4);
2876 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); 3051 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2877 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 3052 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2878 // prec1 >= 4 3053 // prec1 >= 4
2879 while (Precedence(peek(), accept_IN) == prec1) { 3054 while (Precedence(peek(), accept_IN) == prec1) {
2880 BindingPatternUnexpectedToken(classifier); 3055 BindingPatternUnexpectedToken(classifier);
3056 classifier->ReportInvalidSimpleAssignmentTarget();
2881 Token::Value op = Next(); 3057 Token::Value op = Next();
2882 Scanner::Location op_location = scanner()->location(); 3058 Scanner::Location op_location = scanner()->location();
2883 int pos = position(); 3059 int pos = position();
2884 ExpressionT y = 3060 ExpressionT y =
2885 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); 3061 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
2886 3062
2887 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 3063 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2888 factory())) { 3064 factory())) {
2889 continue; 3065 continue;
2890 } 3066 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2933 // '++' UnaryExpression 3109 // '++' UnaryExpression
2934 // '--' UnaryExpression 3110 // '--' UnaryExpression
2935 // '+' UnaryExpression 3111 // '+' UnaryExpression
2936 // '-' UnaryExpression 3112 // '-' UnaryExpression
2937 // '~' UnaryExpression 3113 // '~' UnaryExpression
2938 // '!' UnaryExpression 3114 // '!' UnaryExpression
2939 3115
2940 Token::Value op = peek(); 3116 Token::Value op = peek();
2941 if (Token::IsUnaryOp(op)) { 3117 if (Token::IsUnaryOp(op)) {
2942 BindingPatternUnexpectedToken(classifier); 3118 BindingPatternUnexpectedToken(classifier);
2943 3119 classifier->ReportInvalidSimpleAssignmentTarget();
2944 op = Next(); 3120 op = Next();
2945 int pos = position(); 3121 int pos = position();
2946 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); 3122 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
2947 3123
2948 if (op == Token::DELETE && is_strict(language_mode())) { 3124 if (op == Token::DELETE && is_strict(language_mode())) {
2949 if (is_strong(language_mode())) { 3125 if (is_strong(language_mode())) {
2950 ReportMessage(MessageTemplate::kStrongDelete); 3126 ReportMessage(MessageTemplate::kStrongDelete);
2951 *ok = false; 3127 *ok = false;
2952 return this->EmptyExpression(); 3128 return this->EmptyExpression();
2953 } else if (this->IsIdentifier(expression)) { 3129 } else if (this->IsIdentifier(expression)) {
2954 // "delete identifier" is a syntax error in strict mode. 3130 // "delete identifier" is a syntax error in strict mode.
2955 ReportMessage(MessageTemplate::kStrictDelete); 3131 ReportMessage(MessageTemplate::kStrictDelete);
2956 *ok = false; 3132 *ok = false;
2957 return this->EmptyExpression(); 3133 return this->EmptyExpression();
2958 } 3134 }
2959 } 3135 }
2960 3136
2961 // Allow Traits do rewrite the expression. 3137 // Allow Traits do rewrite the expression.
2962 return this->BuildUnaryExpression(expression, op, pos, factory()); 3138 return this->BuildUnaryExpression(expression, op, pos, factory());
2963 } else if (Token::IsCountOp(op)) { 3139 } else if (Token::IsCountOp(op)) {
2964 BindingPatternUnexpectedToken(classifier); 3140 BindingPatternUnexpectedToken(classifier);
3141 classifier->ReportInvalidSimpleAssignmentTarget();
2965 op = Next(); 3142 op = Next();
2966 Scanner::Location lhs_location = scanner()->peek_location(); 3143 Scanner::Location lhs_location = scanner()->peek_location();
2967 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); 3144 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
2968 expression = this->CheckAndRewriteReferenceExpression( 3145 expression = this->CheckAndRewriteReferenceExpression(
2969 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, 3146 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp,
2970 CHECK_OK); 3147 CHECK_OK);
2971 this->MarkExpressionAsAssigned(expression); 3148 this->MarkExpressionAsAssigned(expression);
2972 3149
2973 return factory()->NewCountOperation(op, 3150 return factory()->NewCountOperation(op,
2974 true /* prefix */, 3151 true /* prefix */,
(...skipping 12 matching lines...) Expand all
2987 bool* ok) { 3164 bool* ok) {
2988 // PostfixExpression :: 3165 // PostfixExpression ::
2989 // LeftHandSideExpression ('++' | '--')? 3166 // LeftHandSideExpression ('++' | '--')?
2990 3167
2991 Scanner::Location lhs_location = scanner()->peek_location(); 3168 Scanner::Location lhs_location = scanner()->peek_location();
2992 ExpressionT expression = 3169 ExpressionT expression =
2993 this->ParseLeftHandSideExpression(classifier, CHECK_OK); 3170 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2994 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 3171 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2995 Token::IsCountOp(peek())) { 3172 Token::IsCountOp(peek())) {
2996 BindingPatternUnexpectedToken(classifier); 3173 BindingPatternUnexpectedToken(classifier);
2997 3174 classifier->ReportInvalidSimpleAssignmentTarget();
2998 expression = this->CheckAndRewriteReferenceExpression( 3175 expression = this->CheckAndRewriteReferenceExpression(
2999 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, 3176 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp,
3000 CHECK_OK); 3177 CHECK_OK);
3001 expression = this->MarkExpressionAsAssigned(expression); 3178 expression = this->MarkExpressionAsAssigned(expression);
3002 3179
3003 Token::Value next = Next(); 3180 Token::Value next = Next();
3004 expression = 3181 expression =
3005 factory()->NewCountOperation(next, 3182 factory()->NewCountOperation(next,
3006 false /* postfix */, 3183 false /* postfix */,
3007 expression, 3184 expression,
(...skipping 10 matching lines...) Expand all
3018 // LeftHandSideExpression :: 3195 // LeftHandSideExpression ::
3019 // (NewExpression | MemberExpression) ... 3196 // (NewExpression | MemberExpression) ...
3020 3197
3021 ExpressionT result = 3198 ExpressionT result =
3022 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); 3199 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
3023 3200
3024 while (true) { 3201 while (true) {
3025 switch (peek()) { 3202 switch (peek()) {
3026 case Token::LBRACK: { 3203 case Token::LBRACK: {
3027 BindingPatternUnexpectedToken(classifier); 3204 BindingPatternUnexpectedToken(classifier);
3205 classifier->AppendAssignmentTarget(
3206 ExpressionClassifier::TARGET_PROPERTY);
3028 Consume(Token::LBRACK); 3207 Consume(Token::LBRACK);
3029 int pos = position(); 3208 int pos = position();
3030 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); 3209 ExpressionT index = ParseExpression(true, CHECK_OK);
3031 result = factory()->NewProperty(result, index, pos); 3210 result = factory()->NewProperty(result, index, pos);
3032 Expect(Token::RBRACK, CHECK_OK); 3211 Expect(Token::RBRACK, CHECK_OK);
3033 break; 3212 break;
3034 } 3213 }
3035 3214
3036 case Token::LPAREN: { 3215 case Token::LPAREN: {
3037 BindingPatternUnexpectedToken(classifier); 3216 BindingPatternUnexpectedToken(classifier);
3038 3217 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3039 if (is_strong(language_mode()) && this->IsIdentifier(result) && 3218 if (is_strong(language_mode()) && this->IsIdentifier(result) &&
3040 this->IsEval(this->AsIdentifier(result))) { 3219 this->IsEval(this->AsIdentifier(result))) {
3041 ReportMessage(MessageTemplate::kStrongDirectEval); 3220 ReportMessage(MessageTemplate::kStrongDirectEval);
3042 *ok = false; 3221 *ok = false;
3043 return this->EmptyExpression(); 3222 return this->EmptyExpression();
3044 } 3223 }
3045 int pos; 3224 int pos;
3046 if (scanner()->current_token() == Token::IDENTIFIER) { 3225 if (scanner()->current_token() == Token::IDENTIFIER) {
3047 // For call of an identifier we want to report position of 3226 // For call of an identifier we want to report position of
3048 // the identifier as position of the call in the stack trace. 3227 // the identifier as position of the call in the stack trace.
(...skipping 30 matching lines...) Expand all
3079 result = Traits::SpreadCall(result, args, pos); 3258 result = Traits::SpreadCall(result, args, pos);
3080 } else { 3259 } else {
3081 result = factory()->NewCall(result, args, pos); 3260 result = factory()->NewCall(result, args, pos);
3082 } 3261 }
3083 if (fni_ != NULL) fni_->RemoveLastFunction(); 3262 if (fni_ != NULL) fni_->RemoveLastFunction();
3084 break; 3263 break;
3085 } 3264 }
3086 3265
3087 case Token::PERIOD: { 3266 case Token::PERIOD: {
3088 BindingPatternUnexpectedToken(classifier); 3267 BindingPatternUnexpectedToken(classifier);
3268 classifier->AppendAssignmentTarget(
3269 ExpressionClassifier::TARGET_PROPERTY);
3089 Consume(Token::PERIOD); 3270 Consume(Token::PERIOD);
3090 int pos = position(); 3271 int pos = position();
3091 IdentifierT name = ParseIdentifierName(CHECK_OK); 3272 IdentifierT name = ParseIdentifierName(CHECK_OK);
3092 result = factory()->NewProperty( 3273 result = factory()->NewProperty(
3093 result, factory()->NewStringLiteral(name, pos), pos); 3274 result, factory()->NewStringLiteral(name, pos), pos);
3094 if (fni_ != NULL) this->PushLiteralName(fni_, name); 3275 if (fni_ != NULL) this->PushLiteralName(fni_, name);
3095 break; 3276 break;
3096 } 3277 }
3097 3278
3098 case Token::TEMPLATE_SPAN: 3279 case Token::TEMPLATE_SPAN:
(...skipping 29 matching lines...) Expand all
3128 // Examples of new expression: 3309 // Examples of new expression:
3129 // new foo.bar().baz means (new (foo.bar)()).baz 3310 // new foo.bar().baz means (new (foo.bar)()).baz
3130 // new foo()() means (new foo())() 3311 // new foo()() means (new foo())()
3131 // new new foo()() means (new (new foo())()) 3312 // new new foo()() means (new (new foo())())
3132 // new new foo means new (new foo) 3313 // new new foo means new (new foo)
3133 // new new foo() means new (new foo()) 3314 // new new foo() means new (new foo())
3134 // new new foo().bar().baz means (new (new foo()).bar()).baz 3315 // new new foo().bar().baz means (new (new foo()).bar()).baz
3135 3316
3136 if (peek() == Token::NEW) { 3317 if (peek() == Token::NEW) {
3137 BindingPatternUnexpectedToken(classifier); 3318 BindingPatternUnexpectedToken(classifier);
3319 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3138 Consume(Token::NEW); 3320 Consume(Token::NEW);
3139 int new_pos = position(); 3321 int new_pos = position();
3140 ExpressionT result = this->EmptyExpression(); 3322 ExpressionT result = this->EmptyExpression();
3141 if (peek() == Token::SUPER) { 3323 if (peek() == Token::SUPER) {
3142 const bool is_new = true; 3324 const bool is_new = true;
3143 result = ParseSuperExpression(is_new, classifier, CHECK_OK); 3325 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3144 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { 3326 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
3145 return ParseNewTargetExpression(CHECK_OK); 3327 return ParseNewTargetExpression(CHECK_OK);
3146 } else { 3328 } else {
3147 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); 3329 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3181 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* 3363 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3182 3364
3183 // The '[' Expression ']' and '.' Identifier parts are parsed by 3365 // The '[' Expression ']' and '.' Identifier parts are parsed by
3184 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 3366 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3185 // caller. 3367 // caller.
3186 3368
3187 // Parse the initial primary or function expression. 3369 // Parse the initial primary or function expression.
3188 ExpressionT result = this->EmptyExpression(); 3370 ExpressionT result = this->EmptyExpression();
3189 if (peek() == Token::FUNCTION) { 3371 if (peek() == Token::FUNCTION) {
3190 BindingPatternUnexpectedToken(classifier); 3372 BindingPatternUnexpectedToken(classifier);
3191 3373 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY);
3192 Consume(Token::FUNCTION); 3374 Consume(Token::FUNCTION);
3193 int function_token_position = position(); 3375 int function_token_position = position();
3194 bool is_generator = Check(Token::MUL); 3376 bool is_generator = Check(Token::MUL);
3195 IdentifierT name = this->EmptyIdentifier(); 3377 IdentifierT name = this->EmptyIdentifier();
3196 bool is_strict_reserved_name = false; 3378 bool is_strict_reserved_name = false;
3197 Scanner::Location function_name_location = Scanner::Location::invalid(); 3379 Scanner::Location function_name_location = Scanner::Location::invalid();
3198 FunctionLiteral::FunctionType function_type = 3380 FunctionLiteral::FunctionType function_type =
3199 FunctionLiteral::ANONYMOUS_EXPRESSION; 3381 FunctionLiteral::ANONYMOUS_EXPRESSION;
3200 if (peek_any_identifier()) { 3382 if (peek_any_identifier()) {
3201 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 3383 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3369 while (scope->is_eval_scope() || scope->is_arrow_scope()) { 3551 while (scope->is_eval_scope() || scope->is_arrow_scope()) {
3370 scope = scope->outer_scope(); 3552 scope = scope->outer_scope();
3371 DCHECK_NOT_NULL(scope); 3553 DCHECK_NOT_NULL(scope);
3372 scope = scope->DeclarationScope(); 3554 scope = scope->DeclarationScope();
3373 } 3555 }
3374 3556
3375 FunctionKind kind = scope->function_kind(); 3557 FunctionKind kind = scope->function_kind();
3376 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || 3558 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3377 i::IsConstructor(kind)) { 3559 i::IsConstructor(kind)) {
3378 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { 3560 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3561 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PROPERTY);
3379 scope->RecordSuperPropertyUsage(); 3562 scope->RecordSuperPropertyUsage();
3380 return this->SuperPropertyReference(scope_, factory(), pos); 3563 return this->SuperPropertyReference(scope_, factory(), pos);
3381 } 3564 }
3382 // new super() is never allowed. 3565 // new super() is never allowed.
3383 // super() is only allowed in derived constructor 3566 // super() is only allowed in derived constructor
3384 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { 3567 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3568 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3385 if (is_strong(language_mode())) { 3569 if (is_strong(language_mode())) {
3386 // Super calls in strong mode are parsed separately. 3570 // Super calls in strong mode are parsed separately.
3387 ReportMessageAt(scanner()->location(), 3571 ReportMessageAt(scanner()->location(),
3388 MessageTemplate::kStrongConstructorSuper); 3572 MessageTemplate::kStrongConstructorSuper);
3389 *ok = false; 3573 *ok = false;
3390 return this->EmptyExpression(); 3574 return this->EmptyExpression();
3391 } 3575 }
3392 // TODO(rossberg): This might not be the correct FunctionState for the 3576 // TODO(rossberg): This might not be the correct FunctionState for the
3393 // method here. 3577 // method here.
3394 function_state_->set_super_location(scanner()->location()); 3578 function_state_->set_super_location(scanner()->location());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3430 template <class Traits> 3614 template <class Traits>
3431 typename ParserBase<Traits>::ExpressionT 3615 typename ParserBase<Traits>::ExpressionT
3432 ParserBase<Traits>::ParseMemberExpressionContinuation( 3616 ParserBase<Traits>::ParseMemberExpressionContinuation(
3433 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { 3617 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
3434 // Parses this part of MemberExpression: 3618 // Parses this part of MemberExpression:
3435 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* 3619 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3436 while (true) { 3620 while (true) {
3437 switch (peek()) { 3621 switch (peek()) {
3438 case Token::LBRACK: { 3622 case Token::LBRACK: {
3439 BindingPatternUnexpectedToken(classifier); 3623 BindingPatternUnexpectedToken(classifier);
3440 3624 classifier->AppendAssignmentTarget(
3625 ExpressionClassifier::TARGET_PROPERTY);
3441 Consume(Token::LBRACK); 3626 Consume(Token::LBRACK);
3442 int pos = position(); 3627 int pos = position();
3443 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); 3628 // Ignore pattern errors within expression
3629 ExpressionClassifier prop_classifier;
3630 ExpressionT index =
3631 this->ParseExpression(true, &prop_classifier, CHECK_OK);
3444 expression = factory()->NewProperty(expression, index, pos); 3632 expression = factory()->NewProperty(expression, index, pos);
3445 if (fni_ != NULL) { 3633 if (fni_ != NULL) {
3446 this->PushPropertyName(fni_, index); 3634 this->PushPropertyName(fni_, index);
3447 } 3635 }
3448 Expect(Token::RBRACK, CHECK_OK); 3636 Expect(Token::RBRACK, CHECK_OK);
3449 break; 3637 break;
3450 } 3638 }
3451 case Token::PERIOD: { 3639 case Token::PERIOD: {
3452 BindingPatternUnexpectedToken(classifier); 3640 BindingPatternUnexpectedToken(classifier);
3641 classifier->AppendAssignmentTarget(
3642 ExpressionClassifier::TARGET_PROPERTY);
3453 3643
3454 Consume(Token::PERIOD); 3644 Consume(Token::PERIOD);
3455 int pos = position(); 3645 int pos = position();
3456 IdentifierT name = ParseIdentifierName(CHECK_OK); 3646 IdentifierT name = ParseIdentifierName(CHECK_OK);
3457 expression = factory()->NewProperty( 3647 expression = factory()->NewProperty(
3458 expression, factory()->NewStringLiteral(name, pos), pos); 3648 expression, factory()->NewStringLiteral(name, pos), pos);
3459 if (fni_ != NULL) { 3649 if (fni_ != NULL) {
3460 this->PushLiteralName(fni_, name); 3650 this->PushLiteralName(fni_, name);
3461 } 3651 }
3462 break; 3652 break;
3463 } 3653 }
3464 case Token::TEMPLATE_SPAN: 3654 case Token::TEMPLATE_SPAN:
3465 case Token::TEMPLATE_TAIL: { 3655 case Token::TEMPLATE_TAIL: {
3466 BindingPatternUnexpectedToken(classifier); 3656 BindingPatternUnexpectedToken(classifier);
3657 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3467 int pos; 3658 int pos;
3468 if (scanner()->current_token() == Token::IDENTIFIER) { 3659 if (scanner()->current_token() == Token::IDENTIFIER) {
3469 pos = position(); 3660 pos = position();
3470 } else { 3661 } else {
3471 pos = peek_position(); 3662 pos = peek_position();
3472 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 3663 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3473 // If the tag function looks like an IIFE, set_parenthesized() to 3664 // If the tag function looks like an IIFE, set_parenthesized() to
3474 // force eager compilation. 3665 // force eager compilation.
3475 expression->AsFunctionLiteral()->set_should_eager_compile(); 3666 expression->AsFunctionLiteral()->set_should_eager_compile();
3476 } 3667 }
3477 } 3668 }
3669 // Ignore classifying tagged template
3670 ExpressionClassifier call_classifier;
3478 expression = 3671 expression =
3479 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); 3672 ParseTemplateLiteral(expression, pos, &call_classifier, CHECK_OK);
3480 break; 3673 break;
3481 } 3674 }
3482 default: 3675 default:
3483 return expression; 3676 return expression;
3484 } 3677 }
3485 } 3678 }
3486 DCHECK(false); 3679 DCHECK(false);
3487 return this->EmptyExpression(); 3680 return this->EmptyExpression();
3488 } 3681 }
3489 3682
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3864 *ok = false; 4057 *ok = false;
3865 return; 4058 return;
3866 } 4059 }
3867 has_seen_constructor_ = true; 4060 has_seen_constructor_ = true;
3868 return; 4061 return;
3869 } 4062 }
3870 } 4063 }
3871 } } // v8::internal 4064 } } // v8::internal
3872 4065
3873 #endif // V8_PREPARSER_H 4066 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698