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

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

Issue 2279363002: Remove duplicated code from comma-separated Expression parsing (Closed)
Patch Set: Remove unused message 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
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 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after
1609 Token::String(Token::LPAREN)); 1609 Token::String(Token::LPAREN));
1610 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier); 1610 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier);
1611 Consume(Token::LPAREN); 1611 Consume(Token::LPAREN);
1612 if (Check(Token::RPAREN)) { 1612 if (Check(Token::RPAREN)) {
1613 // ()=>x. The continuation that looks for the => is in 1613 // ()=>x. The continuation that looks for the => is in
1614 // ParseAssignmentExpression. 1614 // ParseAssignmentExpression.
1615 classifier->RecordExpressionError(scanner()->location(), 1615 classifier->RecordExpressionError(scanner()->location(),
1616 MessageTemplate::kUnexpectedToken, 1616 MessageTemplate::kUnexpectedToken,
1617 Token::String(Token::RPAREN)); 1617 Token::String(Token::RPAREN));
1618 return factory()->NewEmptyParentheses(beg_pos); 1618 return factory()->NewEmptyParentheses(beg_pos);
1619 } else if (Check(Token::ELLIPSIS)) {
1620 // (...x)=>x. The continuation that looks for the => is in
1621 // ParseAssignmentExpression.
1622 int ellipsis_pos = position();
1623 int expr_pos = peek_position();
1624 classifier->RecordExpressionError(scanner()->location(),
1625 MessageTemplate::kUnexpectedToken,
1626 Token::String(Token::ELLIPSIS));
1627 classifier->RecordNonSimpleParameter();
1628 ExpressionClassifier binding_classifier(this);
1629 // TODO(adamk): The grammar for this is
1630 // BindingIdentifier | BindingPattern, so
1631 // ParseAssignmentExpression is overkill.
1632 ExpressionT expr =
1633 ParseAssignmentExpression(true, &binding_classifier, CHECK_OK);
1634 // This already couldn't be an expression or a pattern, so the
1635 // only remaining possibility is an arrow formal parameter list.
1636 classifier->Accumulate(
1637 &binding_classifier,
1638 ExpressionClassifier::ArrowFormalParametersProduction);
1639 if (!impl()->IsIdentifier(expr) && !IsValidPattern(expr)) {
1640 classifier->RecordArrowFormalParametersError(
1641 Scanner::Location(ellipsis_pos, scanner()->location().end_pos),
1642 MessageTemplate::kInvalidRestParameter);
1643 }
1644 if (peek() == Token::COMMA) {
1645 impl()->ReportMessageAt(scanner()->peek_location(),
1646 MessageTemplate::kParamAfterRest);
1647 *ok = false;
1648 return impl()->EmptyExpression();
1649 }
1650 Expect(Token::RPAREN, CHECK_OK);
1651 return factory()->NewSpread(expr, ellipsis_pos, expr_pos);
1652 } 1619 }
1653 // Heuristically try to detect immediately called functions before 1620 // Heuristically try to detect immediately called functions before
1654 // seeing the call parentheses. 1621 // seeing the call parentheses.
1655 function_state_->set_next_function_is_parenthesized(peek() == 1622 function_state_->set_next_function_is_parenthesized(peek() ==
1656 Token::FUNCTION); 1623 Token::FUNCTION);
1657 ExpressionT expr = ParseExpression(true, classifier, CHECK_OK); 1624 ExpressionT expr = ParseExpression(true, classifier, CHECK_OK);
1658 Expect(Token::RPAREN, CHECK_OK); 1625 Expect(Token::RPAREN, CHECK_OK);
1659 return expr; 1626 return expr;
1660 } 1627 }
1661 1628
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 return result; 1681 return result;
1715 } 1682 }
1716 1683
1717 template <typename Impl> 1684 template <typename Impl>
1718 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( 1685 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression(
1719 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 1686 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
1720 // Expression :: 1687 // Expression ::
1721 // AssignmentExpression 1688 // AssignmentExpression
1722 // Expression ',' AssignmentExpression 1689 // Expression ',' AssignmentExpression
1723 1690
1724 ExpressionT result; 1691 ExpressionT result = impl()->EmptyExpression();
1692 while (true) {
adamk 2016/08/26 20:13:04 The other loop construct that might make sense her
1693 CheckNoTailCallExpressions(classifier, CHECK_OK);
1694 int comma_pos = position();
1695 ExpressionClassifier binding_classifier(this);
1696 ExpressionT right;
1697 if (Check(Token::ELLIPSIS)) {
1698 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1699 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1700 // valid expression.
1701 binding_classifier.RecordExpressionError(
1702 scanner()->location(), MessageTemplate::kUnexpectedToken,
1703 Token::String(Token::ELLIPSIS));
1704 int ellipsis_pos = position();
1705 int pattern_pos = peek_position();
1706 ExpressionT pattern =
1707 ParsePrimaryExpression(&binding_classifier, CHECK_OK);
1708 ValidateBindingPattern(&binding_classifier, CHECK_OK);
1709 right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos);
1710 } else {
1711 right =
1712 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
1713 }
1714 // No need to accumulate binding pattern-related errors, since
1715 // an Expression can't be a binding pattern anyway.
1716 classifier->Accumulate(
1717 &binding_classifier,
1718 ExpressionClassifier::AllProductions &
1719 ~(ExpressionClassifier::BindingPatternProduction |
1720 ExpressionClassifier::LetPatternProduction));
1721 if (!impl()->IsIdentifier(right)) classifier->RecordNonSimpleParameter();
1722 if (impl()->IsEmptyExpression(result)) {
adamk 2016/08/26 20:13:04 This IsEmptyExpression() thing could be replaced b
nickie 2016/08/29 17:21:27 I'm in favor of the IsEmptyExpression, which I alr
1723 // First time through the loop.
1724 result = right;
1725 } else {
1726 result =
1727 factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos);
1728 }
1725 1729
1726 // No need to accumulate binding pattern-related errors, since 1730 if (!Check(Token::COMMA)) break;
1727 // an Expression can't be a binding pattern anyway. 1731
1728 static const unsigned kExpressionProductions = 1732 if (right->IsSpread()) {
1729 ExpressionClassifier::AllProductions &
1730 ~(ExpressionClassifier::BindingPatternProduction |
1731 ExpressionClassifier::LetPatternProduction);
1732 {
1733 ExpressionClassifier binding_classifier(this);
1734 result =
1735 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
1736 classifier->Accumulate(&binding_classifier, kExpressionProductions);
1737 }
1738 bool is_simple_parameter_list = impl()->IsIdentifier(result);
1739 bool seen_rest = false;
1740 while (peek() == Token::COMMA) {
1741 CheckNoTailCallExpressions(classifier, CHECK_OK);
1742 if (seen_rest) {
1743 // At this point the production can't possibly be valid, but we don't know
1744 // which error to signal.
1745 classifier->RecordArrowFormalParametersError( 1733 classifier->RecordArrowFormalParametersError(
1746 scanner()->peek_location(), MessageTemplate::kParamAfterRest); 1734 scanner()->location(), MessageTemplate::kParamAfterRest);
1747 } 1735 }
1748 Consume(Token::COMMA); 1736
1749 bool is_rest = false;
1750 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && 1737 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN &&
1751 PeekAhead() == Token::ARROW) { 1738 PeekAhead() == Token::ARROW) {
1752 // a trailing comma is allowed at the end of an arrow parameter list 1739 // a trailing comma is allowed at the end of an arrow parameter list
1753 break; 1740 break;
1754 } else if (peek() == Token::ELLIPSIS) {
1755 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1756 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1757 // valid expression or binding pattern.
1758 ExpressionUnexpectedToken(classifier);
1759 BindingPatternUnexpectedToken(classifier);
1760 Consume(Token::ELLIPSIS);
1761 // TODO(adamk): If is_rest is true we don't need to parse an assignment
1762 // expression, the grammar is BindingIdentifier | BindingPattern.
1763 seen_rest = is_rest = true;
1764 } 1741 }
1765 int pos = position(), expr_pos = peek_position();
1766 ExpressionClassifier binding_classifier(this);
1767 ExpressionT right =
1768 ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
1769 classifier->Accumulate(&binding_classifier, kExpressionProductions);
1770 if (is_rest) {
1771 if (!impl()->IsIdentifier(right) && !IsValidPattern(right)) {
1772 classifier->RecordArrowFormalParametersError(
1773 Scanner::Location(pos, scanner()->location().end_pos),
1774 MessageTemplate::kInvalidRestParameter);
1775 }
1776 right = factory()->NewSpread(right, pos, expr_pos);
1777 }
1778 is_simple_parameter_list =
1779 is_simple_parameter_list && impl()->IsIdentifier(right);
1780 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1781 }
1782 if (!is_simple_parameter_list || seen_rest) {
1783 classifier->RecordNonSimpleParameter();
1784 } 1742 }
1785 1743
1786 return result; 1744 return result;
1787 } 1745 }
1788 1746
1789 template <typename Impl> 1747 template <typename Impl>
1790 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( 1748 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral(
1791 ExpressionClassifier* classifier, bool* ok) { 1749 ExpressionClassifier* classifier, bool* ok) {
1792 // ArrayLiteral :: 1750 // ArrayLiteral ::
1793 // '[' Expression? (',' Expression?)* ']' 1751 // '[' Expression? (',' Expression?)* ']'
(...skipping 1895 matching lines...) Expand 10 before | Expand all | Expand 10 after
3689 has_seen_constructor_ = true; 3647 has_seen_constructor_ = true;
3690 return; 3648 return;
3691 } 3649 }
3692 } 3650 }
3693 3651
3694 3652
3695 } // namespace internal 3653 } // namespace internal
3696 } // namespace v8 3654 } // namespace v8
3697 3655
3698 #endif // V8_PARSING_PARSER_BASE_H 3656 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698