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