OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |