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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 1625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 } else if (Check(Token::ELLIPSIS)) { | 1636 } else if (Check(Token::ELLIPSIS)) { |
1637 // (...x)=>x. The continuation that looks for the => is in | 1637 // (...x)=>x. The continuation that looks for the => is in |
1638 // ParseAssignmentExpression. | 1638 // ParseAssignmentExpression. |
1639 int ellipsis_pos = position(); | 1639 int ellipsis_pos = position(); |
1640 int expr_pos = peek_position(); | 1640 int expr_pos = peek_position(); |
1641 classifier->RecordExpressionError(scanner()->location(), | 1641 classifier->RecordExpressionError(scanner()->location(), |
1642 MessageTemplate::kUnexpectedToken, | 1642 MessageTemplate::kUnexpectedToken, |
1643 Token::String(Token::ELLIPSIS)); | 1643 Token::String(Token::ELLIPSIS)); |
1644 classifier->RecordNonSimpleParameter(); | 1644 classifier->RecordNonSimpleParameter(); |
1645 ExpressionClassifier binding_classifier(this); | 1645 ExpressionClassifier binding_classifier(this); |
| 1646 // TODO(adamk): The grammar for this is |
| 1647 // BindingIdentifier | BindingPattern, so |
| 1648 // ParseAssignmentExpression is overkill. |
1646 ExpressionT expr = | 1649 ExpressionT expr = |
1647 ParseAssignmentExpression(true, &binding_classifier, CHECK_OK); | 1650 ParseAssignmentExpression(true, &binding_classifier, CHECK_OK); |
1648 classifier->Accumulate(&binding_classifier, | 1651 // This already couldn't be an expression or a pattern, so the |
1649 ExpressionClassifier::AllProductions); | 1652 // only remaining possibility is an arrow formal parameter list. |
| 1653 classifier->Accumulate( |
| 1654 &binding_classifier, |
| 1655 ExpressionClassifier::ArrowFormalParametersProduction); |
1650 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { | 1656 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) { |
1651 classifier->RecordArrowFormalParametersError( | 1657 classifier->RecordArrowFormalParametersError( |
1652 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), | 1658 Scanner::Location(ellipsis_pos, scanner()->location().end_pos), |
1653 MessageTemplate::kInvalidRestParameter); | 1659 MessageTemplate::kInvalidRestParameter); |
1654 } | 1660 } |
1655 if (peek() == Token::COMMA) { | 1661 if (peek() == Token::COMMA) { |
1656 impl()->ReportMessageAt(scanner()->peek_location(), | 1662 impl()->ReportMessageAt(scanner()->peek_location(), |
1657 MessageTemplate::kParamAfterRest); | 1663 MessageTemplate::kParamAfterRest); |
1658 *ok = false; | 1664 *ok = false; |
1659 return impl()->EmptyExpression(); | 1665 return impl()->EmptyExpression(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 } | 1732 } |
1727 | 1733 |
1728 template <typename Impl> | 1734 template <typename Impl> |
1729 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( | 1735 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( |
1730 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1736 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1731 // Expression :: | 1737 // Expression :: |
1732 // AssignmentExpression | 1738 // AssignmentExpression |
1733 // Expression ',' AssignmentExpression | 1739 // Expression ',' AssignmentExpression |
1734 | 1740 |
1735 ExpressionT result; | 1741 ExpressionT result; |
| 1742 |
| 1743 // No need to accumulate binding pattern-related errors, since |
| 1744 // an Expression can't be a binding pattern anyway. |
| 1745 static const unsigned kExpressionProductions = |
| 1746 ExpressionClassifier::AllProductions & |
| 1747 ~(ExpressionClassifier::BindingPatternProduction | |
| 1748 ExpressionClassifier::LetPatternProduction); |
1736 { | 1749 { |
1737 ExpressionClassifier binding_classifier(this); | 1750 ExpressionClassifier binding_classifier(this); |
1738 result = | 1751 result = |
1739 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1752 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
1740 classifier->Accumulate(&binding_classifier, | 1753 classifier->Accumulate(&binding_classifier, kExpressionProductions); |
1741 ExpressionClassifier::AllProductions); | |
1742 } | 1754 } |
1743 bool is_simple_parameter_list = impl()->IsIdentifier(result); | 1755 bool is_simple_parameter_list = impl()->IsIdentifier(result); |
1744 bool seen_rest = false; | 1756 bool seen_rest = false; |
1745 while (peek() == Token::COMMA) { | 1757 while (peek() == Token::COMMA) { |
1746 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1758 CheckNoTailCallExpressions(classifier, CHECK_OK); |
1747 if (seen_rest) { | 1759 if (seen_rest) { |
1748 // At this point the production can't possibly be valid, but we don't know | 1760 // At this point the production can't possibly be valid, but we don't know |
1749 // which error to signal. | 1761 // which error to signal. |
1750 classifier->RecordArrowFormalParametersError( | 1762 classifier->RecordArrowFormalParametersError( |
1751 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1763 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
1752 } | 1764 } |
1753 Consume(Token::COMMA); | 1765 Consume(Token::COMMA); |
1754 bool is_rest = false; | 1766 bool is_rest = false; |
1755 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && | 1767 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && |
1756 PeekAhead() == Token::ARROW) { | 1768 PeekAhead() == Token::ARROW) { |
1757 // a trailing comma is allowed at the end of an arrow parameter list | 1769 // a trailing comma is allowed at the end of an arrow parameter list |
1758 break; | 1770 break; |
1759 } else if (peek() == Token::ELLIPSIS) { | 1771 } else if (peek() == Token::ELLIPSIS) { |
1760 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1772 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
1761 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1773 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
1762 // valid expression or binding pattern. | 1774 // valid expression or binding pattern. |
1763 ExpressionUnexpectedToken(classifier); | 1775 ExpressionUnexpectedToken(classifier); |
1764 BindingPatternUnexpectedToken(classifier); | 1776 BindingPatternUnexpectedToken(classifier); |
1765 Consume(Token::ELLIPSIS); | 1777 Consume(Token::ELLIPSIS); |
| 1778 // TODO(adamk): If is_rest is true we don't need to parse an assignment |
| 1779 // expression, the grammar is BindingIdentifier | BindingPattern. |
1766 seen_rest = is_rest = true; | 1780 seen_rest = is_rest = true; |
1767 } | 1781 } |
1768 int pos = position(), expr_pos = peek_position(); | 1782 int pos = position(), expr_pos = peek_position(); |
1769 ExpressionClassifier binding_classifier(this); | 1783 ExpressionClassifier binding_classifier(this); |
1770 ExpressionT right = | 1784 ExpressionT right = |
1771 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); | 1785 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); |
1772 classifier->Accumulate(&binding_classifier, | 1786 classifier->Accumulate(&binding_classifier, kExpressionProductions); |
1773 ExpressionClassifier::AllProductions); | |
1774 if (is_rest) { | 1787 if (is_rest) { |
1775 if (!impl()->IsIdentifier(right) && !IsValidPattern(right)) { | 1788 if (!impl()->IsIdentifier(right) && !IsValidPattern(right)) { |
1776 classifier->RecordArrowFormalParametersError( | 1789 classifier->RecordArrowFormalParametersError( |
1777 Scanner::Location(pos, scanner()->location().end_pos), | 1790 Scanner::Location(pos, scanner()->location().end_pos), |
1778 MessageTemplate::kInvalidRestParameter); | 1791 MessageTemplate::kInvalidRestParameter); |
1779 } | 1792 } |
1780 right = factory()->NewSpread(right, pos, expr_pos); | 1793 right = factory()->NewSpread(right, pos, expr_pos); |
1781 } | 1794 } |
1782 is_simple_parameter_list = | 1795 is_simple_parameter_list = |
1783 is_simple_parameter_list && impl()->IsIdentifier(right); | 1796 is_simple_parameter_list && impl()->IsIdentifier(right); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 *name = impl()->GetNumberAsSymbol(); | 1910 *name = impl()->GetNumberAsSymbol(); |
1898 break; | 1911 break; |
1899 | 1912 |
1900 case Token::LBRACK: { | 1913 case Token::LBRACK: { |
1901 *is_computed_name = true; | 1914 *is_computed_name = true; |
1902 Consume(Token::LBRACK); | 1915 Consume(Token::LBRACK); |
1903 ExpressionClassifier computed_name_classifier(this); | 1916 ExpressionClassifier computed_name_classifier(this); |
1904 ExpressionT expression = | 1917 ExpressionT expression = |
1905 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); | 1918 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); |
1906 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); | 1919 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); |
1907 classifier->Accumulate(&computed_name_classifier, | 1920 classifier->AccumulateFormalParameterContainmentErrors( |
1908 ExpressionClassifier::ExpressionProductions); | 1921 &computed_name_classifier); |
1909 Expect(Token::RBRACK, CHECK_OK); | 1922 Expect(Token::RBRACK, CHECK_OK); |
1910 return expression; | 1923 return expression; |
1911 } | 1924 } |
1912 | 1925 |
1913 default: | 1926 default: |
1914 *name = ParseIdentifierName(CHECK_OK); | 1927 *name = ParseIdentifierName(CHECK_OK); |
1915 scanner()->IsGetOrSet(is_get, is_set); | 1928 scanner()->IsGetOrSet(is_get, is_set); |
1916 break; | 1929 break; |
1917 } | 1930 } |
1918 | 1931 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2012 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | 2025 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); |
2013 | 2026 |
2014 ExpressionT value; | 2027 ExpressionT value; |
2015 if (peek() == Token::ASSIGN) { | 2028 if (peek() == Token::ASSIGN) { |
2016 Consume(Token::ASSIGN); | 2029 Consume(Token::ASSIGN); |
2017 ExpressionClassifier rhs_classifier(this); | 2030 ExpressionClassifier rhs_classifier(this); |
2018 ExpressionT rhs = ParseAssignmentExpression( | 2031 ExpressionT rhs = ParseAssignmentExpression( |
2019 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2032 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2020 impl()->RewriteNonPattern(&rhs_classifier, | 2033 impl()->RewriteNonPattern(&rhs_classifier, |
2021 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2034 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2022 classifier->Accumulate(&rhs_classifier, | 2035 classifier->AccumulateFormalParameterContainmentErrors(&rhs_classifier); |
2023 ExpressionClassifier::ExpressionProductions); | |
2024 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 2036 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
2025 kNoSourcePosition); | 2037 kNoSourcePosition); |
2026 classifier->RecordObjectLiteralError( | 2038 classifier->RecordObjectLiteralError( |
2027 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2039 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
2028 MessageTemplate::kInvalidCoverInitializedName); | 2040 MessageTemplate::kInvalidCoverInitializedName); |
2029 | 2041 |
2030 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); | 2042 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); |
2031 } else { | 2043 } else { |
2032 value = lhs; | 2044 value = lhs; |
2033 } | 2045 } |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2380 if (fni_ != nullptr) fni_->Infer(); | 2392 if (fni_ != nullptr) fni_->Infer(); |
2381 | 2393 |
2382 return expression; | 2394 return expression; |
2383 } | 2395 } |
2384 | 2396 |
2385 // "expression" was not itself an arrow function parameter list, but it might | 2397 // "expression" was not itself an arrow function parameter list, but it might |
2386 // form part of one. Propagate speculative formal parameter error locations | 2398 // form part of one. Propagate speculative formal parameter error locations |
2387 // (including those for binding patterns, since formal parameters can | 2399 // (including those for binding patterns, since formal parameters can |
2388 // themselves contain binding patterns). | 2400 // themselves contain binding patterns). |
2389 // Do not merge pending non-pattern expressions yet! | 2401 // Do not merge pending non-pattern expressions yet! |
2390 unsigned productions = | 2402 unsigned productions = ExpressionClassifier::AllProductions & |
2391 ExpressionClassifier::FormalParametersProductions | | 2403 ~ExpressionClassifier::ArrowFormalParametersProduction; |
2392 ExpressionClassifier::AsyncArrowFormalParametersProduction | | |
2393 ExpressionClassifier::FormalParameterInitializerProduction; | |
2394 | 2404 |
2395 // Parenthesized identifiers and property references are allowed as part | 2405 // Parenthesized identifiers and property references are allowed as part |
2396 // of a larger binding pattern, even though parenthesized patterns | 2406 // of a larger assignment pattern, even though parenthesized patterns |
2397 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate | 2407 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate |
2398 // assignment pattern errors if the parsed expression is more complex. | 2408 // assignment pattern errors if the parsed expression is more complex. |
2399 if (IsValidReferenceExpression(expression)) { | 2409 if (IsValidReferenceExpression(expression)) { |
2400 productions |= ExpressionClassifier::PatternProductions & | 2410 productions &= ~ExpressionClassifier::AssignmentPatternProduction; |
2401 ~ExpressionClassifier::AssignmentPatternProduction; | |
2402 } else { | |
2403 productions |= ExpressionClassifier::PatternProductions; | |
2404 } | 2411 } |
2405 | 2412 |
2406 const bool is_destructuring_assignment = | 2413 const bool is_destructuring_assignment = |
2407 IsValidPattern(expression) && peek() == Token::ASSIGN; | 2414 IsValidPattern(expression) && peek() == Token::ASSIGN; |
2408 if (!is_destructuring_assignment) { | 2415 if (is_destructuring_assignment) { |
2409 // This may be an expression or a pattern, so we must continue to | 2416 // This is definitely not an expression so don't accumulate |
2410 // accumulate expression-related errors. | 2417 // expression-related errors. |
2411 productions |= ExpressionClassifier::ExpressionProductions | | 2418 productions &= ~(ExpressionClassifier::ExpressionProduction | |
2412 ExpressionClassifier::ObjectLiteralProduction; | 2419 ExpressionClassifier::ObjectLiteralProduction | |
| 2420 ExpressionClassifier::TailCallExpressionProduction); |
2413 } | 2421 } |
2414 | 2422 |
2415 classifier->Accumulate(&arrow_formals_classifier, productions, false); | 2423 classifier->Accumulate(&arrow_formals_classifier, productions, false); |
2416 | 2424 |
2417 if (!Token::IsAssignmentOp(peek())) { | 2425 if (!Token::IsAssignmentOp(peek())) { |
2418 // Parsed conditional expression only (no assignment). | 2426 // Parsed conditional expression only (no assignment). |
2419 // Now pending non-pattern expressions must be merged. | 2427 // Now pending non-pattern expressions must be merged. |
2420 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2428 classifier->MergeNonPatterns(&arrow_formals_classifier); |
2421 return expression; | 2429 return expression; |
2422 } | 2430 } |
(...skipping 20 matching lines...) Expand all Loading... |
2443 Token::String(op)); | 2451 Token::String(op)); |
2444 } | 2452 } |
2445 int pos = position(); | 2453 int pos = position(); |
2446 | 2454 |
2447 ExpressionClassifier rhs_classifier(this); | 2455 ExpressionClassifier rhs_classifier(this); |
2448 | 2456 |
2449 ExpressionT right = | 2457 ExpressionT right = |
2450 ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); | 2458 ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK); |
2451 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); | 2459 CheckNoTailCallExpressions(&rhs_classifier, CHECK_OK); |
2452 impl()->RewriteNonPattern(&rhs_classifier, CHECK_OK); | 2460 impl()->RewriteNonPattern(&rhs_classifier, CHECK_OK); |
2453 classifier->Accumulate( | 2461 classifier->AccumulateFormalParameterContainmentErrors(&rhs_classifier); |
2454 &rhs_classifier, | |
2455 ExpressionClassifier::ExpressionProductions | | |
2456 ExpressionClassifier::ObjectLiteralProduction | | |
2457 ExpressionClassifier::AsyncArrowFormalParametersProduction); | |
2458 | 2462 |
2459 // TODO(1231235): We try to estimate the set of properties set by | 2463 // TODO(1231235): We try to estimate the set of properties set by |
2460 // constructors. We define a new property whenever there is an | 2464 // constructors. We define a new property whenever there is an |
2461 // assignment to a property of 'this'. We should probably only add | 2465 // assignment to a property of 'this'. We should probably only add |
2462 // properties if we haven't seen them before. Otherwise we'll | 2466 // properties if we haven't seen them before. Otherwise we'll |
2463 // probably overestimate the number of properties. | 2467 // probably overestimate the number of properties. |
2464 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { | 2468 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { |
2465 function_state_->AddProperty(); | 2469 function_state_->AddProperty(); |
2466 } | 2470 } |
2467 | 2471 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2882 *ok = false; | 2886 *ok = false; |
2883 return impl()->EmptyExpression(); | 2887 return impl()->EmptyExpression(); |
2884 } | 2888 } |
2885 if (args->length()) { | 2889 if (args->length()) { |
2886 // async ( Arguments ) => ... | 2890 // async ( Arguments ) => ... |
2887 return impl()->ExpressionListToExpression(args); | 2891 return impl()->ExpressionListToExpression(args); |
2888 } | 2892 } |
2889 // async () => ... | 2893 // async () => ... |
2890 return factory()->NewEmptyParentheses(pos); | 2894 return factory()->NewEmptyParentheses(pos); |
2891 } else { | 2895 } else { |
2892 classifier->Accumulate(&async_classifier, | 2896 classifier->AccumulateFormalParameterContainmentErrors( |
2893 ExpressionClassifier::AllProductions); | 2897 &async_classifier); |
2894 } | 2898 } |
2895 } else { | 2899 } else { |
2896 args = ParseArguments(&spread_pos, false, classifier, CHECK_OK); | 2900 args = ParseArguments(&spread_pos, false, classifier, CHECK_OK); |
2897 } | 2901 } |
2898 | 2902 |
2899 ArrowFormalParametersUnexpectedToken(classifier); | 2903 ArrowFormalParametersUnexpectedToken(classifier); |
2900 | 2904 |
2901 // Keep track of eval() calls since they disable all local variable | 2905 // Keep track of eval() calls since they disable all local variable |
2902 // optimizations. | 2906 // optimizations. |
2903 // The calls that need special treatment are the | 2907 // The calls that need special treatment are the |
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3706 has_seen_constructor_ = true; | 3710 has_seen_constructor_ = true; |
3707 return; | 3711 return; |
3708 } | 3712 } |
3709 } | 3713 } |
3710 | 3714 |
3711 | 3715 |
3712 } // namespace internal | 3716 } // namespace internal |
3713 } // namespace v8 | 3717 } // namespace v8 |
3714 | 3718 |
3715 #endif // V8_PARSING_PARSER_BASE_H | 3719 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |