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