Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: src/parsing/parser-base.h

Issue 2271063002: Centralize and standardize logic for ExpressionClassifier accumulation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698