| 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 |