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 = | |
noordhuis
2015/06/15 22:01:09
Maybe make this `const bool`. The mutable version
caitp (gmail)
2015/06/19 14:23:21
Done.
| |
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 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) { |
2756 classifier->RecordBindingPatternError(scanner()->location(), | 2920 classifier->RecordBindingPatternError(scanner()->location(), |
2757 MessageTemplate::kUnexpectedToken, | 2921 MessageTemplate::kUnexpectedToken, |
2758 Token::String(op)); | 2922 Token::String(op)); |
2923 } else { | |
2924 classifier->set_assigned(); | |
noordhuis
2015/06/15 22:01:09
This is a little easier to comprehend if you swap
caitp (gmail)
2015/06/19 14:23:21
Done.
| |
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); | |
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 default: | 3279 default: |
(...skipping 22 matching lines...) Expand all Loading... | |
3121 // Examples of new expression: | 3302 // Examples of new expression: |
3122 // new foo.bar().baz means (new (foo.bar)()).baz | 3303 // new foo.bar().baz means (new (foo.bar)()).baz |
3123 // new foo()() means (new foo())() | 3304 // new foo()() means (new foo())() |
3124 // new new foo()() means (new (new foo())()) | 3305 // new new foo()() means (new (new foo())()) |
3125 // new new foo means new (new foo) | 3306 // new new foo means new (new foo) |
3126 // new new foo() means new (new foo()) | 3307 // new new foo() means new (new foo()) |
3127 // new new foo().bar().baz means (new (new foo()).bar()).baz | 3308 // new new foo().bar().baz means (new (new foo()).bar()).baz |
3128 | 3309 |
3129 if (peek() == Token::NEW) { | 3310 if (peek() == Token::NEW) { |
3130 BindingPatternUnexpectedToken(classifier); | 3311 BindingPatternUnexpectedToken(classifier); |
3312 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); | |
3131 Consume(Token::NEW); | 3313 Consume(Token::NEW); |
3132 int new_pos = position(); | 3314 int new_pos = position(); |
3133 ExpressionT result = this->EmptyExpression(); | 3315 ExpressionT result = this->EmptyExpression(); |
3134 if (peek() == Token::SUPER) { | 3316 if (peek() == Token::SUPER) { |
3135 const bool is_new = true; | 3317 const bool is_new = true; |
3136 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3318 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
3137 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { | 3319 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) { |
3138 return ParseNewTargetExpression(CHECK_OK); | 3320 return ParseNewTargetExpression(CHECK_OK); |
3139 } else { | 3321 } else { |
3140 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); | 3322 result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3174 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3356 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
3175 | 3357 |
3176 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3358 // The '[' Expression ']' and '.' Identifier parts are parsed by |
3177 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3359 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
3178 // caller. | 3360 // caller. |
3179 | 3361 |
3180 // Parse the initial primary or function expression. | 3362 // Parse the initial primary or function expression. |
3181 ExpressionT result = this->EmptyExpression(); | 3363 ExpressionT result = this->EmptyExpression(); |
3182 if (peek() == Token::FUNCTION) { | 3364 if (peek() == Token::FUNCTION) { |
3183 BindingPatternUnexpectedToken(classifier); | 3365 BindingPatternUnexpectedToken(classifier); |
3184 | 3366 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY); |
3185 Consume(Token::FUNCTION); | 3367 Consume(Token::FUNCTION); |
3186 int function_token_position = position(); | 3368 int function_token_position = position(); |
3187 bool is_generator = Check(Token::MUL); | 3369 bool is_generator = Check(Token::MUL); |
3188 IdentifierT name = this->EmptyIdentifier(); | 3370 IdentifierT name = this->EmptyIdentifier(); |
3189 bool is_strict_reserved_name = false; | 3371 bool is_strict_reserved_name = false; |
3190 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3372 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3191 FunctionLiteral::FunctionType function_type = | 3373 FunctionLiteral::FunctionType function_type = |
3192 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3374 FunctionLiteral::ANONYMOUS_EXPRESSION; |
3193 if (peek_any_identifier()) { | 3375 if (peek_any_identifier()) { |
3194 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3376 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3362 while (scope->is_eval_scope() || scope->is_arrow_scope()) { | 3544 while (scope->is_eval_scope() || scope->is_arrow_scope()) { |
3363 scope = scope->outer_scope(); | 3545 scope = scope->outer_scope(); |
3364 DCHECK_NOT_NULL(scope); | 3546 DCHECK_NOT_NULL(scope); |
3365 scope = scope->DeclarationScope(); | 3547 scope = scope->DeclarationScope(); |
3366 } | 3548 } |
3367 | 3549 |
3368 FunctionKind kind = scope->function_kind(); | 3550 FunctionKind kind = scope->function_kind(); |
3369 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3551 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
3370 i::IsConstructor(kind)) { | 3552 i::IsConstructor(kind)) { |
3371 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3553 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
3554 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PROPERTY); | |
3372 scope->RecordSuperPropertyUsage(); | 3555 scope->RecordSuperPropertyUsage(); |
3373 return this->SuperPropertyReference(scope_, factory(), pos); | 3556 return this->SuperPropertyReference(scope_, factory(), pos); |
3374 } | 3557 } |
3375 // new super() is never allowed. | 3558 // new super() is never allowed. |
3376 // super() is only allowed in derived constructor | 3559 // super() is only allowed in derived constructor |
3377 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3560 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
3561 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); | |
3378 if (is_strong(language_mode())) { | 3562 if (is_strong(language_mode())) { |
3379 // Super calls in strong mode are parsed separately. | 3563 // Super calls in strong mode are parsed separately. |
3380 ReportMessageAt(scanner()->location(), | 3564 ReportMessageAt(scanner()->location(), |
3381 MessageTemplate::kStrongConstructorSuper); | 3565 MessageTemplate::kStrongConstructorSuper); |
3382 *ok = false; | 3566 *ok = false; |
3383 return this->EmptyExpression(); | 3567 return this->EmptyExpression(); |
3384 } | 3568 } |
3385 // TODO(rossberg): This might not be the correct FunctionState for the | 3569 // TODO(rossberg): This might not be the correct FunctionState for the |
3386 // method here. | 3570 // method here. |
3387 function_state_->set_super_location(scanner()->location()); | 3571 function_state_->set_super_location(scanner()->location()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3423 template <class Traits> | 3607 template <class Traits> |
3424 typename ParserBase<Traits>::ExpressionT | 3608 typename ParserBase<Traits>::ExpressionT |
3425 ParserBase<Traits>::ParseMemberExpressionContinuation( | 3609 ParserBase<Traits>::ParseMemberExpressionContinuation( |
3426 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { | 3610 ExpressionT expression, ExpressionClassifier* classifier, bool* ok) { |
3427 // Parses this part of MemberExpression: | 3611 // Parses this part of MemberExpression: |
3428 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* | 3612 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* |
3429 while (true) { | 3613 while (true) { |
3430 switch (peek()) { | 3614 switch (peek()) { |
3431 case Token::LBRACK: { | 3615 case Token::LBRACK: { |
3432 BindingPatternUnexpectedToken(classifier); | 3616 BindingPatternUnexpectedToken(classifier); |
3433 | 3617 classifier->AppendAssignmentTarget( |
3618 ExpressionClassifier::TARGET_PROPERTY); | |
3434 Consume(Token::LBRACK); | 3619 Consume(Token::LBRACK); |
3435 int pos = position(); | 3620 int pos = position(); |
3436 ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); | 3621 // Ignore pattern errors within expression |
3622 ExpressionClassifier prop_classifier; | |
3623 ExpressionT index = | |
3624 this->ParseExpression(true, &prop_classifier, CHECK_OK); | |
3437 expression = factory()->NewProperty(expression, index, pos); | 3625 expression = factory()->NewProperty(expression, index, pos); |
3438 if (fni_ != NULL) { | 3626 if (fni_ != NULL) { |
3439 this->PushPropertyName(fni_, index); | 3627 this->PushPropertyName(fni_, index); |
3440 } | 3628 } |
3441 Expect(Token::RBRACK, CHECK_OK); | 3629 Expect(Token::RBRACK, CHECK_OK); |
3442 break; | 3630 break; |
3443 } | 3631 } |
3444 case Token::PERIOD: { | 3632 case Token::PERIOD: { |
3445 BindingPatternUnexpectedToken(classifier); | 3633 BindingPatternUnexpectedToken(classifier); |
3634 classifier->AppendAssignmentTarget( | |
3635 ExpressionClassifier::TARGET_PROPERTY); | |
3446 | 3636 |
3447 Consume(Token::PERIOD); | 3637 Consume(Token::PERIOD); |
3448 int pos = position(); | 3638 int pos = position(); |
3449 IdentifierT name = ParseIdentifierName(CHECK_OK); | 3639 IdentifierT name = ParseIdentifierName(CHECK_OK); |
3450 expression = factory()->NewProperty( | 3640 expression = factory()->NewProperty( |
3451 expression, factory()->NewStringLiteral(name, pos), pos); | 3641 expression, factory()->NewStringLiteral(name, pos), pos); |
3452 if (fni_ != NULL) { | 3642 if (fni_ != NULL) { |
3453 this->PushLiteralName(fni_, name); | 3643 this->PushLiteralName(fni_, name); |
3454 } | 3644 } |
3455 break; | 3645 break; |
3456 } | 3646 } |
3457 case Token::TEMPLATE_SPAN: | 3647 case Token::TEMPLATE_SPAN: |
3458 case Token::TEMPLATE_TAIL: { | 3648 case Token::TEMPLATE_TAIL: { |
3459 BindingPatternUnexpectedToken(classifier); | 3649 BindingPatternUnexpectedToken(classifier); |
3650 classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL); | |
3460 int pos; | 3651 int pos; |
3461 if (scanner()->current_token() == Token::IDENTIFIER) { | 3652 if (scanner()->current_token() == Token::IDENTIFIER) { |
3462 pos = position(); | 3653 pos = position(); |
3463 } else { | 3654 } else { |
3464 pos = peek_position(); | 3655 pos = peek_position(); |
3465 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3656 if (expression->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3466 // If the tag function looks like an IIFE, set_parenthesized() to | 3657 // If the tag function looks like an IIFE, set_parenthesized() to |
3467 // force eager compilation. | 3658 // force eager compilation. |
3468 expression->AsFunctionLiteral()->set_should_eager_compile(); | 3659 expression->AsFunctionLiteral()->set_should_eager_compile(); |
3469 } | 3660 } |
3470 } | 3661 } |
3662 // Ignore classifying tagged template | |
3663 ExpressionClassifier call_classifier; | |
3471 expression = | 3664 expression = |
3472 ParseTemplateLiteral(expression, pos, classifier, CHECK_OK); | 3665 ParseTemplateLiteral(expression, pos, &call_classifier, CHECK_OK); |
3473 break; | 3666 break; |
3474 } | 3667 } |
3475 default: | 3668 default: |
3476 return expression; | 3669 return expression; |
3477 } | 3670 } |
3478 } | 3671 } |
3479 DCHECK(false); | 3672 DCHECK(false); |
3480 return this->EmptyExpression(); | 3673 return this->EmptyExpression(); |
3481 } | 3674 } |
3482 | 3675 |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3846 *ok = false; | 4039 *ok = false; |
3847 return; | 4040 return; |
3848 } | 4041 } |
3849 has_seen_constructor_ = true; | 4042 has_seen_constructor_ = true; |
3850 return; | 4043 return; |
3851 } | 4044 } |
3852 } | 4045 } |
3853 } } // v8::internal | 4046 } } // v8::internal |
3854 | 4047 |
3855 #endif // V8_PREPARSER_H | 4048 #endif // V8_PREPARSER_H |
OLD | NEW |