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

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

Issue 1602013007: Fix handling of escaped "let" and "static" tokens (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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 | « no previous file | src/parsing/scanner.cc » ('j') | test/cctest/test-parsing.cc » ('J')
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/hashmap.h" 10 #include "src/hashmap.h"
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, 726 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
727 bool* ok); 727 bool* ok);
728 ExpressionT ParseExpression(bool accept_IN, bool* ok); 728 ExpressionT ParseExpression(bool accept_IN, bool* ok);
729 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, 729 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
730 bool* ok); 730 bool* ok);
731 ExpressionT ParseExpression(bool accept_IN, int flags, 731 ExpressionT ParseExpression(bool accept_IN, int flags,
732 ExpressionClassifier* classifier, bool* ok); 732 ExpressionClassifier* classifier, bool* ok);
733 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); 733 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
734 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, 734 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
735 bool* is_static, bool* is_computed_name, 735 bool* is_static, bool* is_computed_name,
736 bool* is_identifier, bool* is_escaped_keyword,
737 ExpressionClassifier* classifier, bool* ok); 736 ExpressionClassifier* classifier, bool* ok);
738 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 737 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
739 ObjectLiteralPropertyT ParsePropertyDefinition( 738 ObjectLiteralPropertyT ParsePropertyDefinition(
740 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 739 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
741 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 740 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
742 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); 741 ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
743 typename Traits::Type::ExpressionList ParseArguments( 742 typename Traits::Type::ExpressionList ParseArguments(
744 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 743 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
745 bool* ok); 744 bool* ok);
746 745
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 next == Token::LET || next == Token::STATIC || 1108 next == Token::LET || next == Token::STATIC ||
1110 (next == Token::YIELD && !is_generator()))) { 1109 (next == Token::YIELD && !is_generator()))) {
1111 classifier->RecordStrictModeFormalParameterError( 1110 classifier->RecordStrictModeFormalParameterError(
1112 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); 1111 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1113 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && 1112 if (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1114 is_strict(language_mode())) { 1113 is_strict(language_mode())) {
1115 ReportUnexpectedToken(next); 1114 ReportUnexpectedToken(next);
1116 *ok = false; 1115 *ok = false;
1117 return Traits::EmptyIdentifier(); 1116 return Traits::EmptyIdentifier();
1118 } 1117 }
1119 if (next == Token::LET) { 1118 if (next == Token::LET ||
1119 (next == Token::ESCAPED_STRICT_RESERVED_WORD &&
1120 scanner()->is_literal_contextual_keyword(CStrVector("let")))) {
1120 classifier->RecordLetPatternError(scanner()->location(), 1121 classifier->RecordLetPatternError(scanner()->location(),
1121 MessageTemplate::kLetInLexicalBinding); 1122 MessageTemplate::kLetInLexicalBinding);
1122 } 1123 }
1123 return this->GetSymbol(scanner()); 1124 return this->GetSymbol(scanner());
1124 } else { 1125 } else {
1125 this->ReportUnexpectedToken(next); 1126 this->ReportUnexpectedToken(next);
1126 *ok = false; 1127 *ok = false;
1127 return Traits::EmptyIdentifier(); 1128 return Traits::EmptyIdentifier();
1128 } 1129 }
1129 } 1130 }
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1551 int literal_index = function_state_->NextMaterializedLiteralIndex();
1551 1552
1552 return factory()->NewArrayLiteral(values, first_spread_index, literal_index, 1553 return factory()->NewArrayLiteral(values, first_spread_index, literal_index,
1553 is_strong(language_mode()), pos); 1554 is_strong(language_mode()), pos);
1554 } 1555 }
1555 1556
1556 1557
1557 template <class Traits> 1558 template <class Traits>
1558 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( 1559 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
1559 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static, 1560 IdentifierT* name, bool* is_get, bool* is_set, bool* is_static,
1560 bool* is_computed_name, bool* is_identifier, bool* is_escaped_keyword, 1561 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
1561 ExpressionClassifier* classifier, bool* ok) {
1562 Token::Value token = peek(); 1562 Token::Value token = peek();
1563 int pos = peek_position(); 1563 int pos = peek_position();
1564 1564
1565 // For non computed property names we normalize the name a bit: 1565 // For non computed property names we normalize the name a bit:
1566 // 1566 //
1567 // "12" -> 12 1567 // "12" -> 12
1568 // 12.3 -> "12.3" 1568 // 12.3 -> "12.3"
1569 // 12.30 -> "12.3" 1569 // 12.30 -> "12.3"
1570 // identifier -> "identifier" 1570 // identifier -> "identifier"
1571 // 1571 //
(...skipping 22 matching lines...) Expand all
1594 ExpressionT expression = 1594 ExpressionT expression =
1595 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); 1595 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
1596 expression = Traits::RewriteNonPattern( 1596 expression = Traits::RewriteNonPattern(
1597 expression, &computed_name_classifier, CHECK_OK); 1597 expression, &computed_name_classifier, CHECK_OK);
1598 classifier->Accumulate(computed_name_classifier, 1598 classifier->Accumulate(computed_name_classifier,
1599 ExpressionClassifier::ExpressionProductions); 1599 ExpressionClassifier::ExpressionProductions);
1600 Expect(Token::RBRACK, CHECK_OK); 1600 Expect(Token::RBRACK, CHECK_OK);
1601 return expression; 1601 return expression;
1602 } 1602 }
1603 1603
1604 case Token::ESCAPED_KEYWORD:
1605 *is_escaped_keyword = true;
1606 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
1607 break;
1608
1609 case Token::STATIC: 1604 case Token::STATIC:
1610 *is_static = true; 1605 *is_static = true;
1611 1606
1612 // Fall through. 1607 // Fall through.
1613 default: 1608 default:
1614 *is_identifier = true;
1615 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK); 1609 *name = ParseIdentifierNameOrGetOrSet(is_get, is_set, CHECK_OK);
1616 break; 1610 break;
1617 } 1611 }
1618 1612
1619 uint32_t index; 1613 uint32_t index;
1620 return this->IsArrayIndex(*name, &index) 1614 return this->IsArrayIndex(*name, &index)
1621 ? factory()->NewNumberLiteral(index, pos) 1615 ? factory()->NewNumberLiteral(index, pos)
1622 : factory()->NewStringLiteral(*name, pos); 1616 : factory()->NewStringLiteral(*name, pos);
1623 } 1617 }
1624 1618
1625 1619
1626 template <class Traits> 1620 template <class Traits>
1627 typename ParserBase<Traits>::ObjectLiteralPropertyT 1621 typename ParserBase<Traits>::ObjectLiteralPropertyT
1628 ParserBase<Traits>::ParsePropertyDefinition( 1622 ParserBase<Traits>::ParsePropertyDefinition(
1629 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 1623 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
1630 bool is_static, bool* is_computed_name, bool* has_seen_constructor, 1624 bool is_static, bool* is_computed_name, bool* has_seen_constructor,
1631 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) { 1625 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
1632 DCHECK(!in_class || is_static || has_seen_constructor != nullptr); 1626 DCHECK(!in_class || is_static || has_seen_constructor != nullptr);
1633 ExpressionT value = this->EmptyExpression(); 1627 ExpressionT value = this->EmptyExpression();
1634 bool is_get = false; 1628 bool is_get = false;
1635 bool is_set = false; 1629 bool is_set = false;
1636 bool name_is_static = false; 1630 bool name_is_static = false;
1637 bool is_generator = Check(Token::MUL); 1631 bool is_generator = Check(Token::MUL);
1638 1632
1639 Token::Value name_token = peek(); 1633 Token::Value name_token = peek();
1640 int next_beg_pos = scanner()->peek_location().beg_pos; 1634 int next_beg_pos = scanner()->peek_location().beg_pos;
1641 int next_end_pos = scanner()->peek_location().end_pos; 1635 int next_end_pos = scanner()->peek_location().end_pos;
1642 bool is_identifier = false;
1643 bool is_escaped_keyword = false;
1644 ExpressionT name_expression = ParsePropertyName( 1636 ExpressionT name_expression = ParsePropertyName(
1645 name, &is_get, &is_set, &name_is_static, is_computed_name, &is_identifier, 1637 name, &is_get, &is_set, &name_is_static, is_computed_name, classifier,
1646 &is_escaped_keyword, classifier,
1647 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1638 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1648 1639
1649 if (fni_ != nullptr && !*is_computed_name) { 1640 if (fni_ != nullptr && !*is_computed_name) {
1650 this->PushLiteralName(fni_, *name); 1641 this->PushLiteralName(fni_, *name);
1651 } 1642 }
1652 1643
1653 bool escaped_static =
1654 is_escaped_keyword &&
1655 scanner()->is_literal_contextual_keyword(CStrVector("static"));
1656
1657 if (!in_class && !is_generator) { 1644 if (!in_class && !is_generator) {
1658 DCHECK(!is_static); 1645 DCHECK(!is_static);
1659 1646
1660 if (peek() == Token::COLON) { 1647 if (peek() == Token::COLON) {
1661 // PropertyDefinition 1648 // PropertyDefinition
1662 // PropertyName ':' AssignmentExpression 1649 // PropertyName ':' AssignmentExpression
1663 if (!*is_computed_name) { 1650 if (!*is_computed_name) {
1664 checker->CheckProperty(name_token, kValueProperty, false, false, 1651 checker->CheckProperty(name_token, kValueProperty, false, false,
1665 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1652 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1666 } 1653 }
1667 Consume(Token::COLON); 1654 Consume(Token::COLON);
1668 value = this->ParseAssignmentExpression( 1655 value = this->ParseAssignmentExpression(
1669 true, kIsPossiblePatternElement, classifier, 1656 true, kIsPossiblePatternElement, classifier,
1670 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1657 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1671 1658
1672 return factory()->NewObjectLiteralProperty(name_expression, value, false, 1659 return factory()->NewObjectLiteralProperty(name_expression, value, false,
1673 *is_computed_name); 1660 *is_computed_name);
1674 } 1661 }
1675 1662
1676 if ((is_identifier || is_escaped_keyword) && 1663 if (Token::IsIdentifier(name_token, language_mode(),
1664 this->is_generator()) &&
1677 (peek() == Token::COMMA || peek() == Token::RBRACE || 1665 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1678 peek() == Token::ASSIGN)) { 1666 peek() == Token::ASSIGN)) {
1679 // PropertyDefinition 1667 // PropertyDefinition
1680 // IdentifierReference 1668 // IdentifierReference
1681 // CoverInitializedName 1669 // CoverInitializedName
1682 // 1670 //
1683 // CoverInitializedName 1671 // CoverInitializedName
1684 // IdentifierReference Initializer? 1672 // IdentifierReference Initializer?
1685 if (!Token::IsIdentifier(name_token, language_mode(),
1686 this->is_generator())) {
1687 if (!escaped_static) {
1688 ReportUnexpectedTokenAt(scanner()->location(), name_token);
1689 *ok = false;
1690 return this->EmptyObjectLiteralProperty();
1691 }
1692 }
1693 if (classifier->duplicate_finder() != nullptr && 1673 if (classifier->duplicate_finder() != nullptr &&
1694 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1674 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
1695 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 1675 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1696 } 1676 }
1697 if (name_token == Token::LET) { 1677 if (name_token == Token::LET) {
1698 classifier->RecordLetPatternError( 1678 classifier->RecordLetPatternError(
1699 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 1679 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1700 } 1680 }
1701 1681
1702 ExpressionT lhs = this->ExpressionFromIdentifier( 1682 ExpressionT lhs = this->ExpressionFromIdentifier(
(...skipping 17 matching lines...) Expand all
1720 } else { 1700 } else {
1721 value = lhs; 1701 value = lhs;
1722 } 1702 }
1723 1703
1724 return factory()->NewObjectLiteralProperty( 1704 return factory()->NewObjectLiteralProperty(
1725 name_expression, value, ObjectLiteralProperty::COMPUTED, false, 1705 name_expression, value, ObjectLiteralProperty::COMPUTED, false,
1726 false); 1706 false);
1727 } 1707 }
1728 } 1708 }
1729 1709
1730 if (in_class && escaped_static && !is_static) {
1731 ReportUnexpectedTokenAt(scanner()->location(), name_token);
1732 *ok = false;
1733 return this->EmptyObjectLiteralProperty();
1734 }
1735
1736 // Method definitions are never valid in patterns. 1710 // Method definitions are never valid in patterns.
1737 classifier->RecordPatternError( 1711 classifier->RecordPatternError(
1738 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 1712 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
1739 MessageTemplate::kInvalidDestructuringTarget); 1713 MessageTemplate::kInvalidDestructuringTarget);
1740 1714
1741 if (is_generator || peek() == Token::LPAREN) { 1715 if (is_generator || peek() == Token::LPAREN) {
1742 // MethodDefinition 1716 // MethodDefinition
1743 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 1717 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1744 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 1718 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1745 if (!*is_computed_name) { 1719 if (!*is_computed_name) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 1758
1785 if (is_get || is_set) { 1759 if (is_get || is_set) {
1786 // MethodDefinition (Accessors) 1760 // MethodDefinition (Accessors)
1787 // get PropertyName '(' ')' '{' FunctionBody '}' 1761 // get PropertyName '(' ')' '{' FunctionBody '}'
1788 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}' 1762 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
1789 *name = this->EmptyIdentifier(); 1763 *name = this->EmptyIdentifier();
1790 bool dont_care = false; 1764 bool dont_care = false;
1791 name_token = peek(); 1765 name_token = peek();
1792 1766
1793 name_expression = ParsePropertyName( 1767 name_expression = ParsePropertyName(
1794 name, &dont_care, &dont_care, &dont_care, is_computed_name, &dont_care, 1768 name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
1795 &dont_care, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1769 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1796 1770
1797 if (!*is_computed_name) { 1771 if (!*is_computed_name) {
1798 checker->CheckProperty(name_token, kAccessorProperty, is_static, 1772 checker->CheckProperty(name_token, kAccessorProperty, is_static,
1799 is_generator, 1773 is_generator,
1800 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1774 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1801 } 1775 }
1802 1776
1803 FunctionKind kind = FunctionKind::kAccessorFunction; 1777 FunctionKind kind = FunctionKind::kAccessorFunction;
1804 if (!in_class) kind = WithObjectLiteralBit(kind); 1778 if (!in_class) kind = WithObjectLiteralBit(kind);
1805 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral( 1779 typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
(...skipping 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after
3374 return; 3348 return;
3375 } 3349 }
3376 has_seen_constructor_ = true; 3350 has_seen_constructor_ = true;
3377 return; 3351 return;
3378 } 3352 }
3379 } 3353 }
3380 } // namespace internal 3354 } // namespace internal
3381 } // namespace v8 3355 } // namespace v8
3382 3356
3383 #endif // V8_PARSING_PARSER_BASE_H 3357 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « no previous file | src/parsing/scanner.cc » ('j') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698