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

Side by Side Diff: src/preparser.h

Issue 1173003002: Rebase for "parse destructuring assignment" patch (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 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 (is_strong(language_mode())) { 2131 if (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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2156 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2221 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2157 scope->set_start_position(beg_pos); 2222 scope->set_start_position(beg_pos);
2158 ExpressionClassifier args_classifier; 2223 ExpressionClassifier args_classifier;
2159 bool has_rest = false; 2224 bool has_rest = false;
2160 result = this->ParseArrowFunctionLiteral(scope, has_rest, 2225 result = this->ParseArrowFunctionLiteral(scope, has_rest,
2161 args_classifier, CHECK_OK); 2226 args_classifier, CHECK_OK);
2162 } else { 2227 } else {
2163 // Heuristically try to detect immediately called functions before 2228 // Heuristically try to detect immediately called functions before
2164 // seeing the call parentheses. 2229 // seeing the call parentheses.
2165 parenthesized_function_ = (peek() == Token::FUNCTION); 2230 parenthesized_function_ = (peek() == Token::FUNCTION);
2166 result = this->ParseExpression(true, classifier, CHECK_OK); 2231 ExpressionClassifier expr_classifier;
2232 result = this->ParseExpression(true, &expr_classifier, CHECK_OK);
2167 Expect(Token::RPAREN, CHECK_OK); 2233 Expect(Token::RPAREN, CHECK_OK);
2234 if (peek() == Token::ARROW || parenthesized_function_) {
2235 classifier->Accumulate(
2236 expr_classifier,
2237 ExpressionClassifier::ArrowFormalParametersProduction |
2238 ExpressionClassifier::FormalParametersProductions);
2239 } else {
2240 lhs_part = expr_classifier.AssignmentTarget();
2241 }
2168 } 2242 }
2169 break; 2243 break;
2170 2244
2171 case Token::CLASS: { 2245 case Token::CLASS: {
2172 BindingPatternUnexpectedToken(classifier); 2246 BindingPatternUnexpectedToken(classifier);
2173 Consume(Token::CLASS); 2247 Consume(Token::CLASS);
2174 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 2248 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2175 ReportMessage(MessageTemplate::kSloppyLexical); 2249 ReportMessage(MessageTemplate::kSloppyLexical);
2176 *ok = false; 2250 *ok = false;
2177 break; 2251 break;
(...skipping 15 matching lines...) Expand all
2193 2267
2194 case Token::TEMPLATE_SPAN: 2268 case Token::TEMPLATE_SPAN:
2195 case Token::TEMPLATE_TAIL: 2269 case Token::TEMPLATE_TAIL:
2196 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos, 2270 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), beg_pos,
2197 classifier, CHECK_OK); 2271 classifier, CHECK_OK);
2198 break; 2272 break;
2199 2273
2200 case Token::MOD: 2274 case Token::MOD:
2201 if (allow_natives() || extension_ != NULL) { 2275 if (allow_natives() || extension_ != NULL) {
2202 result = this->ParseV8Intrinsic(CHECK_OK); 2276 result = this->ParseV8Intrinsic(CHECK_OK);
2277 lhs_part = ExpressionClassifier::TARGET_CALL;
2203 break; 2278 break;
2204 } 2279 }
2205 // If we're not allowing special syntax we fall-through to the 2280 // If we're not allowing special syntax we fall-through to the
2206 // default case. 2281 // default case.
2207 2282
2208 default: { 2283 default: {
2209 Next(); 2284 Next();
2210 ReportUnexpectedToken(token); 2285 ReportUnexpectedToken(token);
2211 *ok = false; 2286 *ok = false;
2212 } 2287 }
2213 } 2288 }
2214 2289
2290 if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) {
2291 classifier->AppendAssignmentTarget(lhs_part);
2292 }
2293
2215 return result; 2294 return result;
2216 } 2295 }
2217 2296
2218 2297
2219 template <class Traits> 2298 template <class Traits>
2220 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 2299 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2221 bool accept_IN, bool* ok) { 2300 bool accept_IN, bool* ok) {
2222 ExpressionClassifier classifier; 2301 ExpressionClassifier classifier;
2223 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); 2302 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
2224 ValidateExpression(&classifier, CHECK_OK); 2303 ValidateExpression(&classifier, CHECK_OK);
2225 return result; 2304 return result;
2226 } 2305 }
2227 2306
2228 2307
2229 // Precedence = 1 2308 // Precedence = 1
2230 template <class Traits> 2309 template <class Traits>
2231 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 2310 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
2232 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 2311 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
2233 // Expression :: 2312 // Expression ::
2234 // AssignmentExpression 2313 // AssignmentExpression
2235 // Expression ',' AssignmentExpression 2314 // Expression ',' AssignmentExpression
2236 2315
2237 ExpressionClassifier binding_classifier; 2316 ExpressionClassifier expr_classifier;
2238 ExpressionT result = 2317 ExpressionT result =
2239 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 2318 this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
2240 classifier->Accumulate(binding_classifier, 2319 classifier->AccumulateValidSimpleAssignmentTarget(expr_classifier);
2241 ExpressionClassifier::AllProductions); 2320 classifier->Accumulate(expr_classifier,
2321 expr_classifier.is_destructuring_assignment()
2322 ? ExpressionClassifier::PatternProductions
2323 : ExpressionClassifier::AllProductions);
2242 while (peek() == Token::COMMA) { 2324 while (peek() == Token::COMMA) {
2243 Expect(Token::COMMA, CHECK_OK); 2325 Expect(Token::COMMA, CHECK_OK);
2244 int pos = position(); 2326 int pos = position();
2245 ExpressionT right = this->ParseAssignmentExpression( 2327 classifier->ReportInvalidSimpleAssignmentTarget();
2246 accept_IN, &binding_classifier, CHECK_OK); 2328 ExpressionClassifier expr_classifier;
2247 classifier->Accumulate(binding_classifier, 2329 ExpressionT right =
2248 ExpressionClassifier::AllProductions); 2330 this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
2331 classifier->Accumulate(expr_classifier,
2332 expr_classifier.is_destructuring_assignment()
2333 ? ExpressionClassifier::PatternProductions
2334 : ExpressionClassifier::AllProductions);
2335
2336
2249 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 2337 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
2250 } 2338 }
2251 return result; 2339 return result;
2252 } 2340 }
2253 2341
2254 2342
2255 template <class Traits> 2343 template <class Traits>
2256 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 2344 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
2257 ExpressionClassifier* classifier, bool* ok) { 2345 ExpressionClassifier* classifier, bool* ok) {
2258 // ArrayLiteral :: 2346 // ArrayLiteral ::
2259 // '[' Expression? (',' Expression?)* ']' 2347 // '[' Expression? (',' Expression?)* ']'
2260 2348
2261 int pos = peek_position(); 2349 int pos = peek_position();
2262 typename Traits::Type::ExpressionList values = 2350 typename Traits::Type::ExpressionList values =
2263 this->NewExpressionList(4, zone_); 2351 this->NewExpressionList(4, zone_);
2264 Expect(Token::LBRACK, CHECK_OK); 2352 Expect(Token::LBRACK, CHECK_OK);
2265 while (peek() != Token::RBRACK) { 2353 while (peek() != Token::RBRACK) {
2266 bool seen_spread = false; 2354 bool seen_spread = false;
2267 ExpressionT elem = this->EmptyExpression(); 2355 ExpressionT elem = this->EmptyExpression();
2356 ExpressionClassifier element_classifier;
2357 bool accumulate_element = true;
2358 int start_pos = peek_position();
2268 if (peek() == Token::COMMA) { 2359 if (peek() == Token::COMMA) {
2269 if (is_strong(language_mode())) { 2360 if (is_strong(language_mode())) {
2270 ReportMessageAt(scanner()->peek_location(), 2361 ReportMessageAt(scanner()->peek_location(),
2271 MessageTemplate::kStrongEllision); 2362 MessageTemplate::kStrongEllision);
2272 *ok = false; 2363 *ok = false;
2273 return this->EmptyExpression(); 2364 return this->EmptyExpression();
2274 } 2365 }
2275 elem = this->GetLiteralTheHole(peek_position(), factory()); 2366 elem = this->GetLiteralTheHole(peek_position(), factory());
2367 accumulate_element = false;
2276 } else if (peek() == Token::ELLIPSIS) { 2368 } else if (peek() == Token::ELLIPSIS) {
2277 if (!allow_harmony_spread_arrays()) { 2369 if (!allow_harmony_spread_arrays()) {
2278 ExpressionUnexpectedToken(classifier); 2370 ExpressionUnexpectedToken(classifier);
2279 } 2371 }
2280 int start_pos = peek_position();
2281 Consume(Token::ELLIPSIS); 2372 Consume(Token::ELLIPSIS);
2282 ExpressionT argument = 2373 ExpressionT argument =
2283 this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2374 this->ParseAssignmentElement(true, &element_classifier, CHECK_OK);
2284 elem = factory()->NewSpread(argument, start_pos); 2375 elem = factory()->NewSpread(argument, start_pos);
2285 seen_spread = true; 2376 seen_spread = true;
2377
2378 // AssignmentRestElements may not have initializers
2379 if (element_classifier.IsAssigned()) {
2380 Scanner::Location location(start_pos, scanner()->location().end_pos);
2381 classifier->RecordAssignmentPatternError(
2382 location, MessageTemplate::kInitializedAssignmentRestElement);
2383 }
2286 } else { 2384 } else {
2287 elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK); 2385 elem = this->ParseAssignmentElement(true, &element_classifier, CHECK_OK);
2288 } 2386 }
2387 if (accumulate_element) {
2388 if (!element_classifier.IsValidSimpleAssignmentTarget() &&
2389 !element_classifier.IsValidPattern()) {
2390 Scanner::Location location(start_pos, scanner()->location().end_pos);
2391 classifier->RecordAssignmentPatternError(
2392 location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
2393 }
2394 classifier->Accumulate(element_classifier);
2395 }
2396
2289 values->Add(elem, zone_); 2397 values->Add(elem, zone_);
2290 if (peek() != Token::RBRACK) { 2398 if (peek() != Token::RBRACK) {
2291 if (seen_spread) { 2399 if (seen_spread) {
2292 BindingPatternUnexpectedToken(classifier); 2400 PatternUnexpectedToken(classifier);
2293 } 2401 }
2294 Expect(Token::COMMA, CHECK_OK); 2402 Expect(Token::COMMA, CHECK_OK);
2295 } 2403 }
2296 } 2404 }
2297 Expect(Token::RBRACK, CHECK_OK); 2405 Expect(Token::RBRACK, CHECK_OK);
2298 2406
2299 // Update the scope information before the pre-parsing bailout. 2407 // Update the scope information before the pre-parsing bailout.
2300 int literal_index = function_state_->NextMaterializedLiteralIndex(); 2408 int literal_index = function_state_->NextMaterializedLiteralIndex();
2301 2409
2302 return factory()->NewArrayLiteral(values, literal_index, 2410 return factory()->NewArrayLiteral(values, literal_index,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2371 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 2479 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2372 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 2480 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
2373 ExpressionClassifier* classifier, bool* ok) { 2481 ExpressionClassifier* classifier, bool* ok) {
2374 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); 2482 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
2375 ExpressionT value = this->EmptyExpression(); 2483 ExpressionT value = this->EmptyExpression();
2376 IdentifierT name = this->EmptyIdentifier(); 2484 IdentifierT name = this->EmptyIdentifier();
2377 bool is_get = false; 2485 bool is_get = false;
2378 bool is_set = false; 2486 bool is_set = false;
2379 bool name_is_static = false; 2487 bool name_is_static = false;
2380 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL); 2488 bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
2381 2489 // Classify destructuring assignment target for ObjectAssignmentPattern
2490 ExpressionClassifier property_classifier;
2382 Token::Value name_token = peek(); 2491 Token::Value name_token = peek();
2383 int next_beg_pos = scanner()->peek_location().beg_pos; 2492 int next_beg_pos = scanner()->peek_location().beg_pos;
2384 int next_end_pos = scanner()->peek_location().end_pos; 2493 int next_end_pos = scanner()->peek_location().end_pos;
2494 int value_start = next_beg_pos;
2495 int value_end = next_end_pos;
2385 ExpressionT name_expression = ParsePropertyName( 2496 ExpressionT name_expression = ParsePropertyName(
2386 &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier, 2497 &name, &is_get, &is_set, &name_is_static, is_computed_name,
2387 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2498 &property_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2388 2499
2389 if (fni_ != nullptr && !*is_computed_name) { 2500 if (fni_ != nullptr && !*is_computed_name) {
2390 this->PushLiteralName(fni_, name); 2501 this->PushLiteralName(fni_, name);
2391 } 2502 }
2392 2503
2393 if (!in_class && !is_generator && peek() == Token::COLON) { 2504 if (!in_class && !is_generator && peek() == Token::COLON) {
2394 // PropertyDefinition : PropertyName ':' AssignmentExpression 2505 // PropertyDefinition : PropertyName ':' AssignmentExpression
2395 if (!*is_computed_name) { 2506 if (!*is_computed_name) {
2396 checker->CheckProperty(name_token, kValueProperty, is_static, 2507 checker->CheckProperty(name_token, kValueProperty, is_static,
2397 is_generator, 2508 is_generator,
2398 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2509 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2399 } 2510 }
2400 Consume(Token::COLON); 2511 Consume(Token::COLON);
2401 value = this->ParseAssignmentExpression( 2512 property_classifier = ExpressionClassifier();
2402 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2513 value_start = peek_position();
2403 2514 value = this->ParseAssignmentElement(
2515 true, &property_classifier,
2516 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2517 value_end = scanner()->location().end_pos;
2404 } else if (is_generator || 2518 } else if (is_generator ||
2405 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { 2519 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
2406 // Concise Method 2520 // Concise Method
2521 property_classifier.ReportInvalidSimpleAssignmentTarget();
2407 if (!*is_computed_name) { 2522 if (!*is_computed_name) {
2408 checker->CheckProperty(name_token, kMethodProperty, is_static, 2523 checker->CheckProperty(name_token, kMethodProperty, is_static,
2409 is_generator, 2524 is_generator,
2410 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2525 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2411 } 2526 }
2412 2527
2413 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod 2528 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
2414 : FunctionKind::kConciseMethod; 2529 : FunctionKind::kConciseMethod;
2415 2530
2416 if (in_class && !is_static && this->IsConstructor(name)) { 2531 if (in_class && !is_static && this->IsConstructor(name)) {
(...skipping 10 matching lines...) Expand all
2427 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 2542 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
2428 FunctionLiteral::NORMAL_ARITY, 2543 FunctionLiteral::NORMAL_ARITY,
2429 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2544 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2430 2545
2431 return factory()->NewObjectLiteralProperty(name_expression, value, 2546 return factory()->NewObjectLiteralProperty(name_expression, value,
2432 ObjectLiteralProperty::COMPUTED, 2547 ObjectLiteralProperty::COMPUTED,
2433 is_static, *is_computed_name); 2548 is_static, *is_computed_name);
2434 2549
2435 } else if (in_class && name_is_static && !is_static) { 2550 } else if (in_class && name_is_static && !is_static) {
2436 // static MethodDefinition 2551 // static MethodDefinition
2552 property_classifier.ReportInvalidSimpleAssignmentTarget();
2437 return ParsePropertyDefinition(checker, true, has_extends, true, 2553 return ParsePropertyDefinition(checker, true, has_extends, true,
2438 is_computed_name, nullptr, classifier, ok); 2554 is_computed_name, nullptr, classifier, ok);
2439 } else if (is_get || is_set) { 2555 } else if (is_get || is_set) {
2440 // Accessor 2556 // Accessor
2557 property_classifier.ReportInvalidSimpleAssignmentTarget();
2441 name = this->EmptyIdentifier(); 2558 name = this->EmptyIdentifier();
2442 bool dont_care = false; 2559 bool dont_care = false;
2443 name_token = peek(); 2560 name_token = peek();
2444 2561
2445 name_expression = ParsePropertyName( 2562 name_expression = ParsePropertyName(
2446 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier, 2563 &name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
2447 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2564 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2448 2565
2449 if (!*is_computed_name) { 2566 if (!*is_computed_name) {
2450 checker->CheckProperty(name_token, kAccessorProperty, is_static, 2567 checker->CheckProperty(name_token, kAccessorProperty, is_static,
(...skipping 11 matching lines...) Expand all
2462 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2579 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2463 2580
2464 // Make sure the name expression is a string since we need a Name for 2581 // Make sure the name expression is a string since we need a Name for
2465 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this 2582 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2466 // statically we can skip the extra runtime check. 2583 // statically we can skip the extra runtime check.
2467 if (!*is_computed_name) { 2584 if (!*is_computed_name) {
2468 name_expression = 2585 name_expression =
2469 factory()->NewStringLiteral(name, name_expression->position()); 2586 factory()->NewStringLiteral(name, name_expression->position());
2470 } 2587 }
2471 2588
2589 value_end = scanner()->location().end_pos;
2590 Scanner::Location location(value_start, value_end);
2591 classifier->RecordAssignmentPatternError(
2592 location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
2593
2472 return factory()->NewObjectLiteralProperty( 2594 return factory()->NewObjectLiteralProperty(
2473 name_expression, value, 2595 name_expression, value,
2474 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, 2596 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2475 is_static, *is_computed_name); 2597 is_static, *is_computed_name);
2476 2598
2477 } else if (!in_class && allow_harmony_object_literals_ && 2599 } else if (!in_class && allow_harmony_object_literals_ &&
2478 Token::IsIdentifier(name_token, language_mode(), 2600 Token::IsIdentifier(name_token, language_mode(),
2479 this->is_generator())) { 2601 this->is_generator())) {
2480 DCHECK(!*is_computed_name); 2602 DCHECK(!*is_computed_name);
2481 DCHECK(!is_static); 2603 DCHECK(!is_static);
(...skipping 15 matching lines...) Expand all
2497 return factory()->NewObjectLiteralProperty( 2619 return factory()->NewObjectLiteralProperty(
2498 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); 2620 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false);
2499 2621
2500 } else { 2622 } else {
2501 Token::Value next = Next(); 2623 Token::Value next = Next();
2502 ReportUnexpectedToken(next); 2624 ReportUnexpectedToken(next);
2503 *ok = false; 2625 *ok = false;
2504 return this->EmptyObjectLiteralProperty(); 2626 return this->EmptyObjectLiteralProperty();
2505 } 2627 }
2506 2628
2629 if (!property_classifier.IsValidSimpleAssignmentTarget() &&
2630 !property_classifier.IsPatternAssignmentElement()) {
2631 Scanner::Location location(value_start, value_end);
2632 classifier->RecordAssignmentPatternError(
2633 location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
2634 }
2635 classifier->Accumulate(property_classifier);
2636
2507 return factory()->NewObjectLiteralProperty(name_expression, value, is_static, 2637 return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
2508 *is_computed_name); 2638 *is_computed_name);
2509 } 2639 }
2510 2640
2511 2641
2512 template <class Traits> 2642 template <class Traits>
2513 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 2643 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
2514 ExpressionClassifier* classifier, bool* ok) { 2644 ExpressionClassifier* classifier, bool* ok) {
2515 // ObjectLiteral :: 2645 // ObjectLiteral ::
2516 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2646 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 // the parser and preparser 2769 // the parser and preparser
2640 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); 2770 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count);
2641 } 2771 }
2642 2772
2643 return result; 2773 return result;
2644 } 2774 }
2645 2775
2646 // Precedence = 2 2776 // Precedence = 2
2647 template <class Traits> 2777 template <class Traits>
2648 typename ParserBase<Traits>::ExpressionT 2778 typename ParserBase<Traits>::ExpressionT
2649 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, 2779 ParserBase<Traits>::ParseAssignmentExpression(unsigned flags,
2780 bool* needs_destructuring,
2650 ExpressionClassifier* classifier, 2781 ExpressionClassifier* classifier,
2651 bool* ok) { 2782 bool* ok) {
2652 // AssignmentExpression :: 2783 // AssignmentExpression ::
2653 // ConditionalExpression 2784 // ConditionalExpression
2654 // ArrowFunction 2785 // ArrowFunction
2655 // YieldExpression 2786 // YieldExpression
2656 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2787 // LeftHandSideExpression AssignmentOperator AssignmentExpression
2788 bool accept_IN = flags & ACCEPT_IN;
2789 bool is_assignment_element = flags & ASSIGNMENT_ELEMENT;
2657 2790
2658 Scanner::Location lhs_location = scanner()->peek_location(); 2791 Scanner::Location lhs_location = scanner()->peek_location();
2659 2792
2660 if (peek() == Token::YIELD && is_generator()) { 2793 if (peek() == Token::YIELD && is_generator()) {
2661 return this->ParseYieldExpression(classifier, ok); 2794 return this->ParseYieldExpression(classifier, ok);
2662 } 2795 }
2663 2796
2797 bool maybe_assignment_pattern =
2798 allow_harmony_destructuring() &&
2799 classifier->is_valid_assignment_pattern() &&
2800 (peek() == Token::LBRACK || peek() == Token::LBRACE);
2801
2664 if (fni_ != NULL) fni_->Enter(); 2802 if (fni_ != NULL) fni_->Enter();
2665 ParserBase<Traits>::Checkpoint checkpoint(this); 2803 ParserBase<Traits>::Checkpoint checkpoint(this);
2666 ExpressionClassifier arrow_formals_classifier; 2804 ExpressionClassifier arrow_formals_classifier;
2667 if (peek() != Token::LPAREN) { 2805 if (peek() != Token::LPAREN) {
2668 // The expression we are going to read is not a parenthesized arrow function 2806 // The expression we are going to read is not a parenthesized arrow function
2669 // formal parameter list. 2807 // formal parameter list.
2670 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); 2808 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
2671 } 2809 }
2810
2672 ExpressionT expression = this->ParseConditionalExpression( 2811 ExpressionT expression = this->ParseConditionalExpression(
2673 accept_IN, &arrow_formals_classifier, CHECK_OK); 2812 accept_IN, &arrow_formals_classifier, CHECK_OK);
2813
2814 if (!arrow_formals_classifier.is_valid_assignment_pattern()) {
2815 if (maybe_assignment_pattern && peek() == Token::ASSIGN) {
2816 // ObjectAssignmentPattern or ArrayAssignmentPattern contains an error
2817 ReportClassifierError(
2818 arrow_formals_classifier.assignment_pattern_error());
2819 *ok = false;
2820 return this->EmptyExpression();
2821 }
2822 }
2823
2674 classifier->Accumulate(arrow_formals_classifier); 2824 classifier->Accumulate(arrow_formals_classifier);
2675 2825
2676 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { 2826 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2677 checkpoint.Restore(); 2827 checkpoint.Restore();
2678 BindingPatternUnexpectedToken(classifier); 2828 BindingPatternUnexpectedToken(classifier);
2829 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY);
2679 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2830 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2680 CHECK_OK); 2831 CHECK_OK);
2681 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos); 2832 Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
2682 bool has_rest = false; 2833 bool has_rest = false;
2683 Scope* scope = 2834 Scope* scope =
2684 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction); 2835 this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
2685 scope->set_start_position(lhs_location.beg_pos); 2836 scope->set_start_position(lhs_location.beg_pos);
2686 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2837 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2687 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest, 2838 this->ParseArrowFunctionFormalParameters(scope, expression, loc, &has_rest,
2688 &duplicate_loc, CHECK_OK); 2839 &duplicate_loc, CHECK_OK);
2689 if (duplicate_loc.IsValid()) { 2840 if (duplicate_loc.IsValid()) {
2690 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2841 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2691 duplicate_loc); 2842 duplicate_loc);
2692 } 2843 }
2693 expression = this->ParseArrowFunctionLiteral( 2844 expression = this->ParseArrowFunctionLiteral(
2694 scope, has_rest, arrow_formals_classifier, CHECK_OK); 2845 scope, has_rest, arrow_formals_classifier, CHECK_OK);
2695 return expression; 2846 return expression;
2696 } 2847 }
2697 2848
2698 // "expression" was not itself an arrow function parameter list, but it might 2849 // "expression" was not itself an arrow function parameter list, but it might
2699 // form part of one. Propagate speculative formal parameter error locations. 2850 // form part of one. Propagate speculative formal parameter error locations.
2700 classifier->Accumulate(arrow_formals_classifier, 2851 classifier->Accumulate(arrow_formals_classifier,
2701 ExpressionClassifier::FormalParametersProductions); 2852 ExpressionClassifier::FormalParametersProductions);
2702 2853
2854 bool valid_destructuring_assignment_target =
2855 arrow_formals_classifier.IsValidSimpleAssignmentTarget();
2856 if (valid_destructuring_assignment_target) {
2857 classifier->AccumulateValidSimpleAssignmentTarget(arrow_formals_classifier);
2858 } else if (!maybe_assignment_pattern ||
2859 !arrow_formals_classifier.is_valid_assignment_pattern()) {
2860 // Potentially a bad DestructuringAssignmentTarget
2861 classifier->RecordAssignmentPatternError(
2862 Scanner::Location(lhs_location.beg_pos, scanner()->location().end_pos),
2863 MessageTemplate::kInvalidDestructuringAssignmentTarget);
2864 }
2865
2866 if (maybe_assignment_pattern) {
2867 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PATTERN);
2868 if ((maybe_assignment_pattern = peek() == Token::ASSIGN)) {
2869 *needs_destructuring = true;
2870 }
2871 }
2872
2703 if (!Token::IsAssignmentOp(peek())) { 2873 if (!Token::IsAssignmentOp(peek())) {
2704 if (fni_ != NULL) fni_->Leave(); 2874 if (fni_ != NULL) fni_->Leave();
2705 // Parsed conditional expression only (no assignment). 2875 // Parsed conditional expression only (no assignment).
2706 return expression; 2876 return expression;
2707 } 2877 }
2708 2878
2709 if (!allow_harmony_destructuring()) { 2879 if (!allow_harmony_destructuring()) {
2710 BindingPatternUnexpectedToken(classifier); 2880 BindingPatternUnexpectedToken(classifier);
2711 } 2881 }
2712 2882
2713 expression = this->CheckAndRewriteReferenceExpression( 2883 if (!maybe_assignment_pattern) {
2714 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment, 2884 expression = this->CheckAndRewriteReferenceExpression(
2715 CHECK_OK); 2885 expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
2886 CHECK_OK);
2887 }
2888
2716 expression = this->MarkExpressionAsAssigned(expression); 2889 expression = this->MarkExpressionAsAssigned(expression);
2717 2890
2718 Token::Value op = Next(); // Get assignment operator. 2891 Token::Value op = Next(); // Get assignment operator.
2719 if (op != Token::ASSIGN) { 2892 if (op != Token::ASSIGN) {
2720 classifier->RecordBindingPatternError(scanner()->location(), 2893 classifier->RecordBindingPatternError(scanner()->location(),
2721 MessageTemplate::kUnexpectedToken, 2894 MessageTemplate::kUnexpectedToken,
2722 Token::String(op)); 2895 Token::String(op));
2896 } else {
2897 classifier->set_assigned();
2723 } 2898 }
2724 int pos = position(); 2899 int pos = position();
2725 2900
2726 ExpressionClassifier rhs_classifier; 2901 ExpressionClassifier rhs_classifier;
2727 ExpressionT right = 2902 unsigned rhs_flags = flags | ASSIGNMENT_RHS;
2728 this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); 2903 if (is_assignment_element) {
2904 // Parse an assignment element's initializer as a regular
2905 // AssignmentExpression
2906 rhs_flags &= ~(ASSIGNMENT_RHS | ASSIGNMENT_ELEMENT);
2907 }
2908 ExpressionT right = this->ParseAssignmentExpression(
2909 rhs_flags, needs_destructuring, &rhs_classifier, CHECK_OK);
2729 classifier->AccumulateReclassifyingAsPattern(rhs_classifier); 2910 classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
2730 2911
2731 // TODO(1231235): We try to estimate the set of properties set by 2912 // TODO(1231235): We try to estimate the set of properties set by
2732 // constructors. We define a new property whenever there is an 2913 // constructors. We define a new property whenever there is an
2733 // assignment to a property of 'this'. We should probably only add 2914 // assignment to a property of 'this'. We should probably only add
2734 // properties if we haven't seen them before. Otherwise we'll 2915 // properties if we haven't seen them before. Otherwise we'll
2735 // probably overestimate the number of properties. 2916 // probably overestimate the number of properties.
2736 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 2917 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2737 function_state_->AddProperty(); 2918 function_state_->AddProperty();
2738 } 2919 }
2739 2920
2740 this->CheckAssigningFunctionLiteralToProperty(expression, right); 2921 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2741 2922
2742 if (fni_ != NULL) { 2923 if (fni_ != NULL) {
2743 // Check if the right hand side is a call to avoid inferring a 2924 // Check if the right hand side is a call to avoid inferring a
2744 // name if we're dealing with "a = function(){...}();"-like 2925 // name if we're dealing with "a = function(){...}();"-like
2745 // expression. 2926 // expression.
2746 if ((op == Token::INIT_VAR 2927 if ((op == Token::INIT_VAR
2747 || op == Token::INIT_CONST_LEGACY 2928 || op == Token::INIT_CONST_LEGACY
2748 || op == Token::ASSIGN) 2929 || op == Token::ASSIGN)
2749 && (!right->IsCall() && !right->IsCallNew())) { 2930 && (!right->IsCall() && !right->IsCallNew())) {
2750 fni_->Infer(); 2931 fni_->Infer();
2751 } else { 2932 } else {
2752 fni_->RemoveLastFunction(); 2933 fni_->RemoveLastFunction();
2753 } 2934 }
2754 fni_->Leave(); 2935 fni_->Leave();
2755 } 2936 }
2756 2937
2757 return factory()->NewAssignment(op, expression, right, pos); 2938 ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
2939 return this->CheckDestructuringAssignment(
2940 result, classifier, *needs_destructuring, flags, CHECK_OK);
2758 } 2941 }
2759 2942
2760 template <class Traits> 2943 template <class Traits>
2761 typename ParserBase<Traits>::ExpressionT 2944 typename ParserBase<Traits>::ExpressionT
2762 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, 2945 ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
2763 bool* ok) { 2946 bool* ok) {
2764 // YieldExpression :: 2947 // YieldExpression ::
2765 // 'yield' ([no line terminator] '*'? AssignmentExpression)? 2948 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2766 int pos = peek_position(); 2949 int pos = peek_position();
2767 Expect(Token::YIELD, CHECK_OK); 2950 Expect(Token::YIELD, CHECK_OK);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2811 // ConditionalExpression :: 2994 // ConditionalExpression ::
2812 // LogicalOrExpression 2995 // LogicalOrExpression
2813 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 2996 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2814 2997
2815 int pos = peek_position(); 2998 int pos = peek_position();
2816 // We start using the binary expression parser for prec >= 4 only! 2999 // We start using the binary expression parser for prec >= 4 only!
2817 ExpressionT expression = 3000 ExpressionT expression =
2818 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); 3001 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2819 if (peek() != Token::CONDITIONAL) return expression; 3002 if (peek() != Token::CONDITIONAL) return expression;
2820 BindingPatternUnexpectedToken(classifier); 3003 BindingPatternUnexpectedToken(classifier);
3004 classifier->ReportInvalidSimpleAssignmentTarget();
2821 Consume(Token::CONDITIONAL); 3005 Consume(Token::CONDITIONAL);
2822 // In parsing the first assignment expression in conditional 3006 // In parsing the first assignment expression in conditional
2823 // expressions we always accept the 'in' keyword; see ECMA-262, 3007 // expressions we always accept the 'in' keyword; see ECMA-262,
2824 // section 11.12, page 58. 3008 // section 11.12, page 58.
2825 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); 3009 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
2826 Expect(Token::COLON, CHECK_OK); 3010 Expect(Token::COLON, CHECK_OK);
2827 ExpressionT right = 3011 ExpressionT right =
2828 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); 3012 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2829 return factory()->NewConditional(expression, left, right, pos); 3013 return factory()->NewConditional(expression, left, right, pos);
2830 } 3014 }
2831 3015
2832 3016
2833 // Precedence >= 4 3017 // Precedence >= 4
2834 template <class Traits> 3018 template <class Traits>
2835 typename ParserBase<Traits>::ExpressionT 3019 typename ParserBase<Traits>::ExpressionT
2836 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, 3020 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
2837 ExpressionClassifier* classifier, 3021 ExpressionClassifier* classifier,
2838 bool* ok) { 3022 bool* ok) {
2839 DCHECK(prec >= 4); 3023 DCHECK(prec >= 4);
2840 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK); 3024 ExpressionT x = this->ParseUnaryExpression(classifier, CHECK_OK);
2841 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 3025 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2842 // prec1 >= 4 3026 // prec1 >= 4
2843 while (Precedence(peek(), accept_IN) == prec1) { 3027 while (Precedence(peek(), accept_IN) == prec1) {
2844 BindingPatternUnexpectedToken(classifier); 3028 BindingPatternUnexpectedToken(classifier);
3029 classifier->ReportInvalidSimpleAssignmentTarget();
2845 Token::Value op = Next(); 3030 Token::Value op = Next();
2846 Scanner::Location op_location = scanner()->location(); 3031 Scanner::Location op_location = scanner()->location();
2847 int pos = position(); 3032 int pos = position();
2848 ExpressionT y = 3033 ExpressionT y =
2849 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); 3034 ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
2850 3035
2851 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 3036 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2852 factory())) { 3037 factory())) {
2853 continue; 3038 continue;
2854 } 3039 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2897 // '++' UnaryExpression 3082 // '++' UnaryExpression
2898 // '--' UnaryExpression 3083 // '--' UnaryExpression
2899 // '+' UnaryExpression 3084 // '+' UnaryExpression
2900 // '-' UnaryExpression 3085 // '-' UnaryExpression
2901 // '~' UnaryExpression 3086 // '~' UnaryExpression
2902 // '!' UnaryExpression 3087 // '!' UnaryExpression
2903 3088
2904 Token::Value op = peek(); 3089 Token::Value op = peek();
2905 if (Token::IsUnaryOp(op)) { 3090 if (Token::IsUnaryOp(op)) {
2906 BindingPatternUnexpectedToken(classifier); 3091 BindingPatternUnexpectedToken(classifier);
2907 3092 classifier->ReportInvalidSimpleAssignmentTarget();
2908 op = Next(); 3093 op = Next();
2909 int pos = position(); 3094 int pos = position();
2910 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); 3095 ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
2911 3096
2912 if (op == Token::DELETE && is_strict(language_mode())) { 3097 if (op == Token::DELETE && is_strict(language_mode())) {
2913 if (is_strong(language_mode())) { 3098 if (is_strong(language_mode())) {
2914 ReportMessage(MessageTemplate::kStrongDelete); 3099 ReportMessage(MessageTemplate::kStrongDelete);
2915 *ok = false; 3100 *ok = false;
2916 return this->EmptyExpression(); 3101 return this->EmptyExpression();
2917 } else if (this->IsIdentifier(expression)) { 3102 } else if (this->IsIdentifier(expression)) {
2918 // "delete identifier" is a syntax error in strict mode. 3103 // "delete identifier" is a syntax error in strict mode.
2919 ReportMessage(MessageTemplate::kStrictDelete); 3104 ReportMessage(MessageTemplate::kStrictDelete);
2920 *ok = false; 3105 *ok = false;
2921 return this->EmptyExpression(); 3106 return this->EmptyExpression();
2922 } 3107 }
2923 } 3108 }
2924 3109
2925 // Allow Traits do rewrite the expression. 3110 // Allow Traits do rewrite the expression.
2926 return this->BuildUnaryExpression(expression, op, pos, factory()); 3111 return this->BuildUnaryExpression(expression, op, pos, factory());
2927 } else if (Token::IsCountOp(op)) { 3112 } else if (Token::IsCountOp(op)) {
2928 BindingPatternUnexpectedToken(classifier); 3113 BindingPatternUnexpectedToken(classifier);
3114 classifier->ReportInvalidSimpleAssignmentTarget();
2929 op = Next(); 3115 op = Next();
2930 Scanner::Location lhs_location = scanner()->peek_location(); 3116 Scanner::Location lhs_location = scanner()->peek_location();
2931 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK); 3117 ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
2932 expression = this->CheckAndRewriteReferenceExpression( 3118 expression = this->CheckAndRewriteReferenceExpression(
2933 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp, 3119 expression, lhs_location, MessageTemplate::kInvalidLhsInPrefixOp,
2934 CHECK_OK); 3120 CHECK_OK);
2935 this->MarkExpressionAsAssigned(expression); 3121 this->MarkExpressionAsAssigned(expression);
2936 3122
2937 return factory()->NewCountOperation(op, 3123 return factory()->NewCountOperation(op,
2938 true /* prefix */, 3124 true /* prefix */,
(...skipping 12 matching lines...) Expand all
2951 bool* ok) { 3137 bool* ok) {
2952 // PostfixExpression :: 3138 // PostfixExpression ::
2953 // LeftHandSideExpression ('++' | '--')? 3139 // LeftHandSideExpression ('++' | '--')?
2954 3140
2955 Scanner::Location lhs_location = scanner()->peek_location(); 3141 Scanner::Location lhs_location = scanner()->peek_location();
2956 ExpressionT expression = 3142 ExpressionT expression =
2957 this->ParseLeftHandSideExpression(classifier, CHECK_OK); 3143 this->ParseLeftHandSideExpression(classifier, CHECK_OK);
2958 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 3144 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2959 Token::IsCountOp(peek())) { 3145 Token::IsCountOp(peek())) {
2960 BindingPatternUnexpectedToken(classifier); 3146 BindingPatternUnexpectedToken(classifier);
2961 3147 classifier->ReportInvalidSimpleAssignmentTarget();
2962 expression = this->CheckAndRewriteReferenceExpression( 3148 expression = this->CheckAndRewriteReferenceExpression(
2963 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp, 3149 expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp,
2964 CHECK_OK); 3150 CHECK_OK);
2965 expression = this->MarkExpressionAsAssigned(expression); 3151 expression = this->MarkExpressionAsAssigned(expression);
2966 3152
2967 Token::Value next = Next(); 3153 Token::Value next = Next();
2968 expression = 3154 expression =
2969 factory()->NewCountOperation(next, 3155 factory()->NewCountOperation(next,
2970 false /* postfix */, 3156 false /* postfix */,
2971 expression, 3157 expression,
(...skipping 10 matching lines...) Expand all
2982 // LeftHandSideExpression :: 3168 // LeftHandSideExpression ::
2983 // (NewExpression | MemberExpression) ... 3169 // (NewExpression | MemberExpression) ...
2984 3170
2985 ExpressionT result = 3171 ExpressionT result =
2986 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); 3172 this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
2987 3173
2988 while (true) { 3174 while (true) {
2989 switch (peek()) { 3175 switch (peek()) {
2990 case Token::LBRACK: { 3176 case Token::LBRACK: {
2991 BindingPatternUnexpectedToken(classifier); 3177 BindingPatternUnexpectedToken(classifier);
3178 classifier->AppendAssignmentTarget(
3179 ExpressionClassifier::TARGET_PROPERTY);
2992 Consume(Token::LBRACK); 3180 Consume(Token::LBRACK);
2993 int pos = position(); 3181 int pos = position();
2994 ExpressionT index = ParseExpression(true, classifier, CHECK_OK); 3182 ExpressionT index = ParseExpression(true, CHECK_OK);
2995 result = factory()->NewProperty(result, index, pos); 3183 result = factory()->NewProperty(result, index, pos);
2996 Expect(Token::RBRACK, CHECK_OK); 3184 Expect(Token::RBRACK, CHECK_OK);
2997 break; 3185 break;
2998 } 3186 }
2999 3187
3000 case Token::LPAREN: { 3188 case Token::LPAREN: {
3001 BindingPatternUnexpectedToken(classifier); 3189 BindingPatternUnexpectedToken(classifier);
3002 3190 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3003 if (is_strong(language_mode()) && this->IsIdentifier(result) && 3191 if (is_strong(language_mode()) && this->IsIdentifier(result) &&
3004 this->IsEval(this->AsIdentifier(result))) { 3192 this->IsEval(this->AsIdentifier(result))) {
3005 ReportMessage(MessageTemplate::kStrongDirectEval); 3193 ReportMessage(MessageTemplate::kStrongDirectEval);
3006 *ok = false; 3194 *ok = false;
3007 return this->EmptyExpression(); 3195 return this->EmptyExpression();
3008 } 3196 }
3009 int pos; 3197 int pos;
3010 if (scanner()->current_token() == Token::IDENTIFIER) { 3198 if (scanner()->current_token() == Token::IDENTIFIER) {
3011 // For call of an identifier we want to report position of 3199 // For call of an identifier we want to report position of
3012 // the identifier as position of the call in the stack trace. 3200 // the identifier as position of the call in the stack trace.
(...skipping 30 matching lines...) Expand all
3043 result = Traits::SpreadCall(result, args, pos); 3231 result = Traits::SpreadCall(result, args, pos);
3044 } else { 3232 } else {
3045 result = factory()->NewCall(result, args, pos); 3233 result = factory()->NewCall(result, args, pos);
3046 } 3234 }
3047 if (fni_ != NULL) fni_->RemoveLastFunction(); 3235 if (fni_ != NULL) fni_->RemoveLastFunction();
3048 break; 3236 break;
3049 } 3237 }
3050 3238
3051 case Token::PERIOD: { 3239 case Token::PERIOD: {
3052 BindingPatternUnexpectedToken(classifier); 3240 BindingPatternUnexpectedToken(classifier);
3241 classifier->AppendAssignmentTarget(
3242 ExpressionClassifier::TARGET_PROPERTY);
3053 Consume(Token::PERIOD); 3243 Consume(Token::PERIOD);
3054 int pos = position(); 3244 int pos = position();
3055 IdentifierT name = ParseIdentifierName(CHECK_OK); 3245 IdentifierT name = ParseIdentifierName(CHECK_OK);
3056 result = factory()->NewProperty( 3246 result = factory()->NewProperty(
3057 result, factory()->NewStringLiteral(name, pos), pos); 3247 result, factory()->NewStringLiteral(name, pos), pos);
3058 if (fni_ != NULL) this->PushLiteralName(fni_, name); 3248 if (fni_ != NULL) this->PushLiteralName(fni_, name);
3059 break; 3249 break;
3060 } 3250 }
3061 3251
3062 default: 3252 default:
(...skipping 22 matching lines...) Expand all
3085 // Examples of new expression: 3275 // Examples of new expression:
3086 // new foo.bar().baz means (new (foo.bar)()).baz 3276 // new foo.bar().baz means (new (foo.bar)()).baz
3087 // new foo()() means (new foo())() 3277 // new foo()() means (new foo())()
3088 // new new foo()() means (new (new foo())()) 3278 // new new foo()() means (new (new foo())())
3089 // new new foo means new (new foo) 3279 // new new foo means new (new foo)
3090 // new new foo() means new (new foo()) 3280 // new new foo() means new (new foo())
3091 // new new foo().bar().baz means (new (new foo()).bar()).baz 3281 // new new foo().bar().baz means (new (new foo()).bar()).baz
3092 3282
3093 if (peek() == Token::NEW) { 3283 if (peek() == Token::NEW) {
3094 BindingPatternUnexpectedToken(classifier); 3284 BindingPatternUnexpectedToken(classifier);
3285 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3095 Consume(Token::NEW); 3286 Consume(Token::NEW);
3096 int new_pos = position(); 3287 int new_pos = position();
3097 ExpressionT result = this->EmptyExpression(); 3288 ExpressionT result = this->EmptyExpression();
3098 if (peek() == Token::SUPER) { 3289 if (peek() == Token::SUPER) {
3099 const bool is_new = true; 3290 const bool is_new = true;
3100 result = ParseSuperExpression(is_new, classifier, CHECK_OK); 3291 result = ParseSuperExpression(is_new, classifier, CHECK_OK);
3101 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { 3292 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
3102 return ParseNewTargetExpression(CHECK_OK); 3293 return ParseNewTargetExpression(CHECK_OK);
3103 } else { 3294 } else {
3104 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); 3295 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3138 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* 3329 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3139 3330
3140 // The '[' Expression ']' and '.' Identifier parts are parsed by 3331 // The '[' Expression ']' and '.' Identifier parts are parsed by
3141 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 3332 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3142 // caller. 3333 // caller.
3143 3334
3144 // Parse the initial primary or function expression. 3335 // Parse the initial primary or function expression.
3145 ExpressionT result = this->EmptyExpression(); 3336 ExpressionT result = this->EmptyExpression();
3146 if (peek() == Token::FUNCTION) { 3337 if (peek() == Token::FUNCTION) {
3147 BindingPatternUnexpectedToken(classifier); 3338 BindingPatternUnexpectedToken(classifier);
3148 3339 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY);
3149 Consume(Token::FUNCTION); 3340 Consume(Token::FUNCTION);
3150 int function_token_position = position(); 3341 int function_token_position = position();
3151 bool is_generator = Check(Token::MUL); 3342 bool is_generator = Check(Token::MUL);
3152 IdentifierT name = this->EmptyIdentifier(); 3343 IdentifierT name = this->EmptyIdentifier();
3153 bool is_strict_reserved_name = false; 3344 bool is_strict_reserved_name = false;
3154 Scanner::Location function_name_location = Scanner::Location::invalid(); 3345 Scanner::Location function_name_location = Scanner::Location::invalid();
3155 FunctionLiteral::FunctionType function_type = 3346 FunctionLiteral::FunctionType function_type =
3156 FunctionLiteral::ANONYMOUS_EXPRESSION; 3347 FunctionLiteral::ANONYMOUS_EXPRESSION;
3157 if (peek_any_identifier()) { 3348 if (peek_any_identifier()) {
3158 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 3349 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3326 while (scope->is_eval_scope() || scope->is_arrow_scope()) { 3517 while (scope->is_eval_scope() || scope->is_arrow_scope()) {
3327 scope = scope->outer_scope(); 3518 scope = scope->outer_scope();
3328 DCHECK_NOT_NULL(scope); 3519 DCHECK_NOT_NULL(scope);
3329 scope = scope->DeclarationScope(); 3520 scope = scope->DeclarationScope();
3330 } 3521 }
3331 3522
3332 FunctionKind kind = scope->function_kind(); 3523 FunctionKind kind = scope->function_kind();
3333 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || 3524 if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3334 i::IsConstructor(kind)) { 3525 i::IsConstructor(kind)) {
3335 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { 3526 if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
3527 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PROPERTY);
3336 scope->RecordSuperPropertyUsage(); 3528 scope->RecordSuperPropertyUsage();
3337 return this->SuperPropertyReference(scope_, factory(), pos); 3529 return this->SuperPropertyReference(scope_, factory(), pos);
3338 } 3530 }
3339 // new super() is never allowed. 3531 // new super() is never allowed.
3340 // super() is only allowed in derived constructor 3532 // super() is only allowed in derived constructor
3341 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { 3533 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
3534 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3342 if (is_strong(language_mode())) { 3535 if (is_strong(language_mode())) {
3343 // Super calls in strong mode are parsed separately. 3536 // Super calls in strong mode are parsed separately.
3344 ReportMessageAt(scanner()->location(), 3537 ReportMessageAt(scanner()->location(),
3345 MessageTemplate::kStrongConstructorSuper); 3538 MessageTemplate::kStrongConstructorSuper);
3346 *ok = false; 3539 *ok = false;
3347 return this->EmptyExpression(); 3540 return this->EmptyExpression();
3348 } 3541 }
3349 // TODO(rossberg): This might not be the correct FunctionState for the 3542 // TODO(rossberg): This might not be the correct FunctionState for the
3350 // method here. 3543 // method here.
3351 function_state_->set_super_location(scanner()->location()); 3544 function_state_->set_super_location(scanner()->location());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3387 template <class Traits> 3580 template <class Traits>
3388 typename ParserBase<Traits>::ExpressionT 3581 typename ParserBase<Traits>::ExpressionT
3389 ParserBase<Traits>::ParseMemberExpressionContinuation( 3582 ParserBase<Traits>::ParseMemberExpressionContinuation(
3390 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { 3583 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
3391 // Parses this part of MemberExpression: 3584 // Parses this part of MemberExpression:
3392 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* 3585 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3393 while (true) { 3586 while (true) {
3394 switch (peek()) { 3587 switch (peek()) {
3395 case Token::LBRACK: { 3588 case Token::LBRACK: {
3396 BindingPatternUnexpectedToken(classifier); 3589 BindingPatternUnexpectedToken(classifier);
3397 3590 classifier->AppendAssignmentTarget(
3591 ExpressionClassifier::TARGET_PROPERTY);
3398 Consume(Token::LBRACK); 3592 Consume(Token::LBRACK);
3399 int pos = position(); 3593 int pos = position();
3400 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); 3594 // Ignore pattern errors within expression
3595 ExpressionClassifier prop_classifier;
3596 ExpressionT index =
3597 this->ParseExpression(true, &prop_classifier, CHECK_OK);
3401 expression = factory()->NewProperty(expression, index, pos); 3598 expression = factory()->NewProperty(expression, index, pos);
3402 if (fni_ != NULL) { 3599 if (fni_ != NULL) {
3403 this->PushPropertyName(fni_, index); 3600 this->PushPropertyName(fni_, index);
3404 } 3601 }
3405 Expect(Token::RBRACK, CHECK_OK); 3602 Expect(Token::RBRACK, CHECK_OK);
3406 break; 3603 break;
3407 } 3604 }
3408 case Token::PERIOD: { 3605 case Token::PERIOD: {
3409 BindingPatternUnexpectedToken(classifier); 3606 BindingPatternUnexpectedToken(classifier);
3607 classifier->AppendAssignmentTarget(
3608 ExpressionClassifier::TARGET_PROPERTY);
3410 3609
3411 Consume(Token::PERIOD); 3610 Consume(Token::PERIOD);
3412 int pos = position(); 3611 int pos = position();
3413 IdentifierT name = ParseIdentifierName(CHECK_OK); 3612 IdentifierT name = ParseIdentifierName(CHECK_OK);
3414 expression = factory()->NewProperty( 3613 expression = factory()->NewProperty(
3415 expression, factory()->NewStringLiteral(name, pos), pos); 3614 expression, factory()->NewStringLiteral(name, pos), pos);
3416 if (fni_ != NULL) { 3615 if (fni_ != NULL) {
3417 this->PushLiteralName(fni_, name); 3616 this->PushLiteralName(fni_, name);
3418 } 3617 }
3419 break; 3618 break;
3420 } 3619 }
3421 case Token::TEMPLATE_SPAN: 3620 case Token::TEMPLATE_SPAN:
3422 case Token::TEMPLATE_TAIL: { 3621 case Token::TEMPLATE_TAIL: {
3423 BindingPatternUnexpectedToken(classifier); 3622 BindingPatternUnexpectedToken(classifier);
3623 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
3424 int pos; 3624 int pos;
3425 if (scanner()->current_token() == Token::IDENTIFIER) { 3625 if (scanner()->current_token() == Token::IDENTIFIER) {
3426 pos = position(); 3626 pos = position();
3427 } else { 3627 } else {
3428 pos = peek_position(); 3628 pos = peek_position();
3429 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 3629 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
3430 // If the tag function looks like an IIFE, set_parenthesized() to 3630 // If the tag function looks like an IIFE, set_parenthesized() to
3431 // force eager compilation. 3631 // force eager compilation.
3432 expression->AsFunctionLiteral()->set_should_eager_compile(); 3632 expression->AsFunctionLiteral()->set_should_eager_compile();
3433 } 3633 }
3434 } 3634 }
3635 // Ignore classifying tagged template
3636 ExpressionClassifier call_classifier;
3435 expression = 3637 expression =
3436 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); 3638 ParseTemplateLiteral(expression, pos, &call_classifier, CHECK_OK);
3437 break; 3639 break;
3438 } 3640 }
3439 default: 3641 default:
3440 return expression; 3642 return expression;
3441 } 3643 }
3442 } 3644 }
3443 DCHECK(false); 3645 DCHECK(false);
3444 return this->EmptyExpression(); 3646 return this->EmptyExpression();
3445 } 3647 }
3446 3648
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3810 *ok = false; 4012 *ok = false;
3811 return; 4013 return;
3812 } 4014 }
3813 has_seen_constructor_ = true; 4015 has_seen_constructor_ = true;
3814 return; 4016 return;
3815 } 4017 }
3816 } 4018 }
3817 } } // v8::internal 4019 } } // v8::internal
3818 4020
3819 #endif // V8_PREPARSER_H 4021 #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