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