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

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

Issue 1522693002: [es6] strict eval/arguments and strong undefined in AssignmentPattern (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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 | test/cctest/test-parsing.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/hashmap.h" 10 #include "src/hashmap.h"
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 // Checks if the expression is a valid reference expression (e.g., on the 805 // Checks if the expression is a valid reference expression (e.g., on the
806 // left-hand side of assignments). Although ruled out by ECMA as early errors, 806 // left-hand side of assignments). Although ruled out by ECMA as early errors,
807 // we allow calls for web compatibility and rewrite them to a runtime throw. 807 // we allow calls for web compatibility and rewrite them to a runtime throw.
808 ExpressionT CheckAndRewriteReferenceExpression( 808 ExpressionT CheckAndRewriteReferenceExpression(
809 ExpressionT expression, int beg_pos, int end_pos, 809 ExpressionT expression, int beg_pos, int end_pos,
810 MessageTemplate::Template message, bool* ok); 810 MessageTemplate::Template message, bool* ok);
811 ExpressionT ClassifyAndRewriteReferenceExpression( 811 ExpressionT ClassifyAndRewriteReferenceExpression(
812 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, 812 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
813 int end_pos, MessageTemplate::Template message, 813 int end_pos, MessageTemplate::Template message,
814 ParseErrorType type = kSyntaxError); 814 ParseErrorType type = kSyntaxError);
815 void ClassifyReferenceExpression(ExpressionClassifier* classifier,
816 ExpressionT expression, int beg_pos,
817 int end_pos);
815 ExpressionT CheckAndRewriteReferenceExpression( 818 ExpressionT CheckAndRewriteReferenceExpression(
816 ExpressionT expression, int beg_pos, int end_pos, 819 ExpressionT expression, int beg_pos, int end_pos,
817 MessageTemplate::Template message, ParseErrorType type, bool* ok); 820 MessageTemplate::Template message, ParseErrorType type, bool* ok);
818 821
819 bool IsValidReferenceExpression(ExpressionT expression); 822 bool IsValidReferenceExpression(ExpressionT expression);
820 823
821 bool IsAssignableIdentifier(ExpressionT expression) { 824 bool IsAssignableIdentifier(ExpressionT expression) {
822 if (!Traits::IsIdentifier(expression)) return false; 825 if (!Traits::IsIdentifier(expression)) return false;
823 if (is_strict(language_mode()) && 826 if (is_strict(language_mode()) &&
824 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) { 827 Traits::IsEvalOrArguments(Traits::AsIdentifier(expression))) {
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 MessageTemplate::kStrongEllision); 1513 MessageTemplate::kStrongEllision);
1511 *ok = false; 1514 *ok = false;
1512 return this->EmptyExpression(); 1515 return this->EmptyExpression();
1513 } 1516 }
1514 elem = this->GetLiteralTheHole(peek_position(), factory()); 1517 elem = this->GetLiteralTheHole(peek_position(), factory());
1515 } else if (peek() == Token::ELLIPSIS) { 1518 } else if (peek() == Token::ELLIPSIS) {
1516 int start_pos = peek_position(); 1519 int start_pos = peek_position();
1517 Consume(Token::ELLIPSIS); 1520 Consume(Token::ELLIPSIS);
1518 ExpressionT argument = 1521 ExpressionT argument =
1519 this->ParseAssignmentExpression(true, classifier, CHECK_OK); 1522 this->ParseAssignmentExpression(true, classifier, CHECK_OK);
1523 ClassifyReferenceExpression(classifier, argument, start_pos,
1524 scanner()->location().end_pos);
1520 elem = factory()->NewSpread(argument, start_pos); 1525 elem = factory()->NewSpread(argument, start_pos);
1521 1526
1522 if (first_spread_index < 0) { 1527 if (first_spread_index < 0) {
1523 first_spread_index = values->length(); 1528 first_spread_index = values->length();
1524 } 1529 }
1525 1530
1526 CheckDestructuringElement(argument, classifier, start_pos, 1531 CheckDestructuringElement(argument, classifier, start_pos,
adamk 2015/12/12 01:03:35 I think CheckDestructuringElement is doing the wor
caitp (gmail) 2015/12/12 01:08:14 Yes, there is some redundant stuff here --- as men
adamk 2015/12/12 01:10:44 Would much prefer less duplication to message clar
1527 scanner()->location().end_pos); 1532 scanner()->location().end_pos);
1528 1533
1529 if (peek() == Token::COMMA) { 1534 if (peek() == Token::COMMA) {
1530 classifier->RecordPatternError( 1535 classifier->RecordPatternError(
1531 Scanner::Location(start_pos, scanner()->location().end_pos), 1536 Scanner::Location(start_pos, scanner()->location().end_pos),
1532 MessageTemplate::kElementAfterRest); 1537 MessageTemplate::kElementAfterRest);
1533 } 1538 }
1534 } else { 1539 } else {
1535 elem = this->ParseAssignmentExpression(true, kIsPatternElement, 1540 elem = this->ParseAssignmentExpression(true, kIsPatternElement,
1536 classifier, CHECK_OK); 1541 classifier, CHECK_OK);
1542 ClassifyReferenceExpression(classifier, elem, pos,
1543 scanner()->location().end_pos);
1537 if (!this->IsValidReferenceExpression(elem) && 1544 if (!this->IsValidReferenceExpression(elem) &&
1538 !classifier->is_valid_assignment_pattern()) { 1545 !classifier->is_valid_assignment_pattern()) {
1539 classifier->RecordPatternError( 1546 classifier->RecordPatternError(
1540 Scanner::Location(pos, scanner()->location().end_pos), 1547 Scanner::Location(pos, scanner()->location().end_pos),
1541 MessageTemplate::kInvalidDestructuringTarget); 1548 MessageTemplate::kInvalidDestructuringTarget);
1542 } 1549 }
1543 } 1550 }
1544 values->Add(elem, zone_); 1551 values->Add(elem, zone_);
1545 if (peek() != Token::RBRACK) { 1552 if (peek() != Token::RBRACK) {
1546 Expect(Token::COMMA, CHECK_OK); 1553 Expect(Token::COMMA, CHECK_OK);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 // PropertyName ':' AssignmentExpression 1670 // PropertyName ':' AssignmentExpression
1664 if (!*is_computed_name) { 1671 if (!*is_computed_name) {
1665 checker->CheckProperty(name_token, kValueProperty, false, false, 1672 checker->CheckProperty(name_token, kValueProperty, false, false,
1666 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1673 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1667 } 1674 }
1668 Consume(Token::COLON); 1675 Consume(Token::COLON);
1669 int pos = peek_position(); 1676 int pos = peek_position();
1670 value = this->ParseAssignmentExpression( 1677 value = this->ParseAssignmentExpression(
1671 true, kIsPatternElement, classifier, 1678 true, kIsPatternElement, classifier,
1672 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1679 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1673 1680 ClassifyReferenceExpression(classifier, value, pos,
1681 scanner()->location().end_pos);
1674 if (!this->IsValidReferenceExpression(value) && 1682 if (!this->IsValidReferenceExpression(value) &&
1675 !classifier->is_valid_assignment_pattern()) { 1683 !classifier->is_valid_assignment_pattern()) {
1676 classifier->RecordPatternError( 1684 classifier->RecordPatternError(
1677 Scanner::Location(pos, scanner()->location().end_pos), 1685 Scanner::Location(pos, scanner()->location().end_pos),
1678 MessageTemplate::kInvalidDestructuringTarget); 1686 MessageTemplate::kInvalidDestructuringTarget);
1679 } 1687 }
1680 1688
1681 return factory()->NewObjectLiteralProperty(name_expression, value, false, 1689 return factory()->NewObjectLiteralProperty(name_expression, value, false,
1682 *is_computed_name); 1690 *is_computed_name);
1683 } 1691 }
(...skipping 20 matching lines...) Expand all
1704 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 1712 classifier->RecordDuplicateFormalParameterError(scanner()->location());
1705 } 1713 }
1706 if (name_token == Token::LET) { 1714 if (name_token == Token::LET) {
1707 classifier->RecordLetPatternError( 1715 classifier->RecordLetPatternError(
1708 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 1716 scanner()->location(), MessageTemplate::kLetInLexicalBinding);
1709 } 1717 }
1710 1718
1711 ExpressionT lhs = this->ExpressionFromIdentifier( 1719 ExpressionT lhs = this->ExpressionFromIdentifier(
1712 name, next_beg_pos, next_end_pos, scope_, factory()); 1720 name, next_beg_pos, next_end_pos, scope_, factory());
1713 1721
1722 ClassifyReferenceExpression(classifier, lhs, next_beg_pos, next_end_pos);
1723
1714 if (peek() == Token::ASSIGN) { 1724 if (peek() == Token::ASSIGN) {
1715 Consume(Token::ASSIGN); 1725 Consume(Token::ASSIGN);
1716 ExpressionClassifier rhs_classifier; 1726 ExpressionClassifier rhs_classifier;
1717 ExpressionT rhs = this->ParseAssignmentExpression( 1727 ExpressionT rhs = this->ParseAssignmentExpression(
1718 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1728 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
1719 classifier->Accumulate(rhs_classifier, 1729 classifier->Accumulate(rhs_classifier,
1720 ExpressionClassifier::ExpressionProductions); 1730 ExpressionClassifier::ExpressionProductions);
1721 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, 1731 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
1722 RelocInfo::kNoPosition); 1732 RelocInfo::kNoPosition);
1723 classifier->RecordCoverInitializedNameError( 1733 classifier->RecordCoverInitializedNameError(
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
2043 ExpressionClassifier::FormalParametersProductions | 2053 ExpressionClassifier::FormalParametersProductions |
2044 ExpressionClassifier::CoverInitializedNameProduction); 2054 ExpressionClassifier::CoverInitializedNameProduction);
2045 2055
2046 bool maybe_pattern = 2056 bool maybe_pattern =
2047 expression->IsObjectLiteral() || expression->IsArrayLiteral(); 2057 expression->IsObjectLiteral() || expression->IsArrayLiteral();
2048 // bool binding_pattern = 2058 // bool binding_pattern =
2049 // allow_harmony_destructuring_bind() && maybe_pattern && !is_rhs; 2059 // allow_harmony_destructuring_bind() && maybe_pattern && !is_rhs;
2050 2060
2051 if (!Token::IsAssignmentOp(peek())) { 2061 if (!Token::IsAssignmentOp(peek())) {
2052 // Parsed conditional expression only (no assignment). 2062 // Parsed conditional expression only (no assignment).
2063 if (is_pattern_element && !maybe_pattern) {
2064 ClassifyReferenceExpression(classifier, expression, lhs_beg_pos,
2065 scanner()->location().end_pos);
2066 }
2053 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && 2067 if (is_pattern_element && !this->IsValidReferenceExpression(expression) &&
2054 !maybe_pattern) { 2068 !maybe_pattern) {
2055 classifier->RecordPatternError( 2069 classifier->RecordPatternError(
2056 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), 2070 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
2057 MessageTemplate::kInvalidDestructuringTarget); 2071 MessageTemplate::kInvalidDestructuringTarget);
2058 } else if (is_rhs && maybe_pattern) { 2072 } else if (is_rhs && maybe_pattern) {
2059 ValidateExpression(classifier, CHECK_OK); 2073 ValidateExpression(classifier, CHECK_OK);
2060 } 2074 }
2061 2075
2062 return expression; 2076 return expression;
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after
3231 ExpressionClassifier classifier; 3245 ExpressionClassifier classifier;
3232 ExpressionT result = ClassifyAndRewriteReferenceExpression( 3246 ExpressionT result = ClassifyAndRewriteReferenceExpression(
3233 &classifier, expression, beg_pos, end_pos, message, type); 3247 &classifier, expression, beg_pos, end_pos, message, type);
3234 ValidateExpression(&classifier, ok); 3248 ValidateExpression(&classifier, ok);
3235 if (!*ok) return this->EmptyExpression(); 3249 if (!*ok) return this->EmptyExpression();
3236 return result; 3250 return result;
3237 } 3251 }
3238 3252
3239 3253
3240 template <typename Traits> 3254 template <typename Traits>
3255 void ParserBase<Traits>::ClassifyReferenceExpression(
adamk 2015/12/12 01:03:35 Indeed, this code is very close to the existing Ch
3256 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
3257 int end_pos) {
3258 if (!this->IsIdentifier(expression)) return;
3259 IdentifierT ref = this->AsIdentifier(expression);
3260 if (is_strict(language_mode()) && this->IsEvalOrArguments(ref)) {
3261 classifier->RecordAssignmentPatternError(
3262 Scanner::Location(beg_pos, end_pos),
3263 MessageTemplate::kStrictEvalArguments);
3264 } else if (is_strong(language_mode()) && this->IsUndefined(ref)) {
3265 classifier->RecordAssignmentPatternError(
3266 Scanner::Location(beg_pos, end_pos), MessageTemplate::kStrongUndefined);
3267 }
3268 }
3269
3270
3271 template <typename Traits>
3241 typename ParserBase<Traits>::ExpressionT 3272 typename ParserBase<Traits>::ExpressionT
3242 ParserBase<Traits>::ClassifyAndRewriteReferenceExpression( 3273 ParserBase<Traits>::ClassifyAndRewriteReferenceExpression(
3243 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos, 3274 ExpressionClassifier* classifier, ExpressionT expression, int beg_pos,
3244 int end_pos, MessageTemplate::Template message, ParseErrorType type) { 3275 int end_pos, MessageTemplate::Template message, ParseErrorType type) {
3245 Scanner::Location location(beg_pos, end_pos); 3276 Scanner::Location location(beg_pos, end_pos);
3246 if (this->IsIdentifier(expression)) { 3277 if (this->IsIdentifier(expression)) {
3247 if (is_strict(language_mode()) && 3278 if (is_strict(language_mode()) &&
3248 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 3279 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
3249 classifier->RecordExpressionError( 3280 classifier->RecordExpressionError(
3250 location, MessageTemplate::kStrictEvalArguments, kSyntaxError); 3281 location, MessageTemplate::kStrictEvalArguments, kSyntaxError);
3282 classifier->RecordAssignmentPatternError(
3283 location, MessageTemplate::kStrictEvalArguments);
3251 return expression; 3284 return expression;
3252 } 3285 }
3253 if (is_strong(language_mode()) && 3286 if (is_strong(language_mode()) &&
3254 this->IsUndefined(this->AsIdentifier(expression))) { 3287 this->IsUndefined(this->AsIdentifier(expression))) {
3255 classifier->RecordExpressionError( 3288 classifier->RecordExpressionError(
3256 location, MessageTemplate::kStrongUndefined, kSyntaxError); 3289 location, MessageTemplate::kStrongUndefined, kSyntaxError);
3290 classifier->RecordAssignmentPatternError(
3291 location, MessageTemplate::kStrongUndefined);
3257 return expression; 3292 return expression;
3258 } 3293 }
3259 } 3294 }
3260 if (expression->IsValidReferenceExpression()) { 3295 if (expression->IsValidReferenceExpression()) {
3261 return expression; 3296 return expression;
3262 } else if (expression->IsCall()) { 3297 } else if (expression->IsCall()) {
3263 // If it is a call, make it a runtime error for legacy web compatibility. 3298 // If it is a call, make it a runtime error for legacy web compatibility.
3264 // Rewrite `expr' to `expr[throw ReferenceError]'. 3299 // Rewrite `expr' to `expr[throw ReferenceError]'.
3265 int pos = location.beg_pos; 3300 int pos = location.beg_pos;
3266 ExpressionT error = this->NewThrowReferenceError(message, pos); 3301 ExpressionT error = this->NewThrowReferenceError(message, pos);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 return; 3384 return;
3350 } 3385 }
3351 has_seen_constructor_ = true; 3386 has_seen_constructor_ = true;
3352 return; 3387 return;
3353 } 3388 }
3354 } 3389 }
3355 } // namespace internal 3390 } // namespace internal
3356 } // namespace v8 3391 } // namespace v8
3357 3392
3358 #endif // V8_PARSING_PARSER_BASE_H 3393 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « no previous file | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698