Chromium Code Reviews| 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/hashmap.h" | 10 #include "src/hashmap.h" |
| (...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1516 int start_pos = peek_position(); | 1516 int start_pos = peek_position(); |
| 1517 Consume(Token::ELLIPSIS); | 1517 Consume(Token::ELLIPSIS); |
| 1518 ExpressionT argument = | 1518 ExpressionT argument = |
| 1519 this->ParseAssignmentExpression(true, classifier, CHECK_OK); | 1519 this->ParseAssignmentExpression(true, classifier, CHECK_OK); |
| 1520 elem = factory()->NewSpread(argument, start_pos); | 1520 elem = factory()->NewSpread(argument, start_pos); |
| 1521 | 1521 |
| 1522 if (first_spread_index < 0) { | 1522 if (first_spread_index < 0) { |
| 1523 first_spread_index = values->length(); | 1523 first_spread_index = values->length(); |
| 1524 } | 1524 } |
| 1525 | 1525 |
| 1526 CheckDestructuringElement(argument, classifier, start_pos, | 1526 if (argument->IsAssignment()) { |
| 1527 scanner()->location().end_pos); | 1527 classifier->RecordPatternError( |
| 1528 Scanner::Location(start_pos, scanner()->location().end_pos), | |
| 1529 MessageTemplate::kInvalidDestructuringTarget); | |
| 1530 } else { | |
| 1531 CheckDestructuringElement(argument, classifier, start_pos, | |
| 1532 scanner()->location().end_pos); | |
| 1533 } | |
| 1528 | 1534 |
| 1529 if (peek() == Token::COMMA) { | 1535 if (peek() == Token::COMMA) { |
| 1530 classifier->RecordPatternError( | 1536 classifier->RecordPatternError( |
| 1531 Scanner::Location(start_pos, scanner()->location().end_pos), | 1537 Scanner::Location(start_pos, scanner()->location().end_pos), |
| 1532 MessageTemplate::kElementAfterRest); | 1538 MessageTemplate::kElementAfterRest); |
| 1533 } | 1539 } |
| 1534 } else { | 1540 } else { |
| 1535 elem = this->ParseAssignmentExpression(true, kIsPatternElement, | 1541 elem = this->ParseAssignmentExpression(true, kIsPatternElement, |
| 1536 classifier, CHECK_OK); | 1542 classifier, CHECK_OK); |
| 1537 if (!this->IsValidReferenceExpression(elem) && | |
| 1538 !classifier->is_valid_assignment_pattern()) { | |
| 1539 classifier->RecordPatternError( | |
| 1540 Scanner::Location(pos, scanner()->location().end_pos), | |
| 1541 MessageTemplate::kInvalidDestructuringTarget); | |
| 1542 } | |
| 1543 } | 1543 } |
| 1544 values->Add(elem, zone_); | 1544 values->Add(elem, zone_); |
| 1545 if (peek() != Token::RBRACK) { | 1545 if (peek() != Token::RBRACK) { |
| 1546 Expect(Token::COMMA, CHECK_OK); | 1546 Expect(Token::COMMA, CHECK_OK); |
| 1547 } | 1547 } |
| 1548 } | 1548 } |
| 1549 Expect(Token::RBRACK, CHECK_OK); | 1549 Expect(Token::RBRACK, CHECK_OK); |
| 1550 | 1550 |
| 1551 // Update the scope information before the pre-parsing bailout. | 1551 // Update the scope information before the pre-parsing bailout. |
| 1552 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 1552 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1659 DCHECK(!is_static); | 1659 DCHECK(!is_static); |
| 1660 | 1660 |
| 1661 if (peek() == Token::COLON) { | 1661 if (peek() == Token::COLON) { |
| 1662 // PropertyDefinition | 1662 // PropertyDefinition |
| 1663 // PropertyName ':' AssignmentExpression | 1663 // PropertyName ':' AssignmentExpression |
| 1664 if (!*is_computed_name) { | 1664 if (!*is_computed_name) { |
| 1665 checker->CheckProperty(name_token, kValueProperty, false, false, | 1665 checker->CheckProperty(name_token, kValueProperty, false, false, |
| 1666 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1666 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1667 } | 1667 } |
| 1668 Consume(Token::COLON); | 1668 Consume(Token::COLON); |
| 1669 int pos = peek_position(); | |
| 1670 value = this->ParseAssignmentExpression( | 1669 value = this->ParseAssignmentExpression( |
| 1671 true, kIsPatternElement, classifier, | 1670 true, kIsPatternElement, classifier, |
| 1672 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1671 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1673 | 1672 |
| 1674 if (!this->IsValidReferenceExpression(value) && | |
| 1675 !classifier->is_valid_assignment_pattern()) { | |
| 1676 classifier->RecordPatternError( | |
| 1677 Scanner::Location(pos, scanner()->location().end_pos), | |
| 1678 MessageTemplate::kInvalidDestructuringTarget); | |
| 1679 } | |
| 1680 | |
| 1681 return factory()->NewObjectLiteralProperty(name_expression, value, false, | 1673 return factory()->NewObjectLiteralProperty(name_expression, value, false, |
| 1682 *is_computed_name); | 1674 *is_computed_name); |
| 1683 } | 1675 } |
| 1684 | 1676 |
| 1685 if ((is_identifier || is_escaped_keyword) && | 1677 if ((is_identifier || is_escaped_keyword) && |
| 1686 (peek() == Token::COMMA || peek() == Token::RBRACE || | 1678 (peek() == Token::COMMA || peek() == Token::RBRACE || |
| 1687 peek() == Token::ASSIGN)) { | 1679 peek() == Token::ASSIGN)) { |
| 1688 // PropertyDefinition | 1680 // PropertyDefinition |
| 1689 // IdentifierReference | 1681 // IdentifierReference |
| 1690 // CoverInitializedName | 1682 // CoverInitializedName |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1703 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 1695 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
| 1704 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 1696 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
| 1705 } | 1697 } |
| 1706 if (name_token == Token::LET) { | 1698 if (name_token == Token::LET) { |
| 1707 classifier->RecordLetPatternError( | 1699 classifier->RecordLetPatternError( |
| 1708 scanner()->location(), MessageTemplate::kLetInLexicalBinding); | 1700 scanner()->location(), MessageTemplate::kLetInLexicalBinding); |
| 1709 } | 1701 } |
| 1710 | 1702 |
| 1711 ExpressionT lhs = this->ExpressionFromIdentifier( | 1703 ExpressionT lhs = this->ExpressionFromIdentifier( |
| 1712 name, next_beg_pos, next_end_pos, scope_, factory()); | 1704 name, next_beg_pos, next_end_pos, scope_, factory()); |
| 1705 CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos); | |
| 1713 | 1706 |
| 1714 if (peek() == Token::ASSIGN) { | 1707 if (peek() == Token::ASSIGN) { |
| 1715 Consume(Token::ASSIGN); | 1708 Consume(Token::ASSIGN); |
| 1716 ExpressionClassifier rhs_classifier; | 1709 ExpressionClassifier rhs_classifier; |
| 1717 ExpressionT rhs = this->ParseAssignmentExpression( | 1710 ExpressionT rhs = this->ParseAssignmentExpression( |
| 1718 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 1711 true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 1719 classifier->Accumulate(rhs_classifier, | 1712 classifier->Accumulate(rhs_classifier, |
| 1720 ExpressionClassifier::ExpressionProductions); | 1713 ExpressionClassifier::ExpressionProductions); |
| 1721 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, | 1714 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, |
| 1722 RelocInfo::kNoPosition); | 1715 RelocInfo::kNoPosition); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2038 // "expression" was not itself an arrow function parameter list, but it might | 2031 // "expression" was not itself an arrow function parameter list, but it might |
| 2039 // form part of one. Propagate speculative formal parameter error locations. | 2032 // form part of one. Propagate speculative formal parameter error locations. |
| 2040 classifier->Accumulate( | 2033 classifier->Accumulate( |
| 2041 arrow_formals_classifier, | 2034 arrow_formals_classifier, |
| 2042 ExpressionClassifier::StandardProductions | | 2035 ExpressionClassifier::StandardProductions | |
| 2043 ExpressionClassifier::FormalParametersProductions | | 2036 ExpressionClassifier::FormalParametersProductions | |
| 2044 ExpressionClassifier::CoverInitializedNameProduction); | 2037 ExpressionClassifier::CoverInitializedNameProduction); |
| 2045 | 2038 |
| 2046 bool maybe_pattern = | 2039 bool maybe_pattern = |
| 2047 expression->IsObjectLiteral() || expression->IsArrayLiteral(); | 2040 expression->IsObjectLiteral() || expression->IsArrayLiteral(); |
| 2048 // bool binding_pattern = | |
| 2049 // allow_harmony_destructuring_bind() && maybe_pattern && !is_rhs; | |
| 2050 | 2041 |
| 2051 if (!Token::IsAssignmentOp(peek())) { | 2042 if (!Token::IsAssignmentOp(peek())) { |
| 2052 // Parsed conditional expression only (no assignment). | 2043 // Parsed conditional expression only (no assignment). |
| 2053 if (is_pattern_element && !this->IsValidReferenceExpression(expression) && | 2044 if (is_pattern_element) { |
| 2054 !maybe_pattern) { | 2045 CheckDestructuringElement(expression, classifier, lhs_beg_pos, |
| 2055 classifier->RecordPatternError( | 2046 scanner()->location().end_pos); |
| 2056 Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), | |
| 2057 MessageTemplate::kInvalidDestructuringTarget); | |
| 2058 } else if (is_rhs && maybe_pattern) { | 2047 } else if (is_rhs && maybe_pattern) { |
| 2059 ValidateExpression(classifier, CHECK_OK); | 2048 ValidateExpression(classifier, CHECK_OK); |
| 2060 } | 2049 } |
| 2061 | 2050 |
| 2062 return expression; | 2051 return expression; |
| 2063 } | 2052 } |
| 2064 | 2053 |
| 2065 if (!(allow_harmony_destructuring_bind() || | 2054 if (!(allow_harmony_destructuring_bind() || |
| 2066 allow_harmony_default_parameters())) { | 2055 allow_harmony_default_parameters())) { |
| 2067 BindingPatternUnexpectedToken(classifier); | 2056 BindingPatternUnexpectedToken(classifier); |
| 2068 } | 2057 } |
| 2069 | 2058 |
| 2070 if (allow_harmony_destructuring_assignment() && maybe_pattern && | 2059 if (allow_harmony_destructuring_assignment() && maybe_pattern && |
| 2071 peek() == Token::ASSIGN) { | 2060 peek() == Token::ASSIGN) { |
| 2072 classifier->ForgiveCoverInitializedNameError(); | 2061 classifier->ForgiveCoverInitializedNameError(); |
| 2073 ValidateAssignmentPattern(classifier, CHECK_OK); | 2062 ValidateAssignmentPattern(classifier, CHECK_OK); |
| 2074 is_destructuring_assignment = true; | 2063 is_destructuring_assignment = true; |
| 2075 } else if (is_arrow_formals) { | 2064 } else if (is_arrow_formals) { |
| 2076 expression = this->ClassifyAndRewriteReferenceExpression( | 2065 expression = this->ClassifyAndRewriteReferenceExpression( |
| 2077 classifier, expression, lhs_beg_pos, scanner()->location().end_pos, | 2066 classifier, expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2078 MessageTemplate::kInvalidLhsInAssignment); | 2067 MessageTemplate::kInvalidLhsInAssignment); |
| 2079 } else { | 2068 } else { |
| 2069 if (is_pattern_element) { | |
| 2070 CheckDestructuringElement(expression, classifier, lhs_beg_pos, | |
| 2071 scanner()->location().end_pos); | |
| 2072 } | |
| 2080 expression = this->CheckAndRewriteReferenceExpression( | 2073 expression = this->CheckAndRewriteReferenceExpression( |
| 2081 expression, lhs_beg_pos, scanner()->location().end_pos, | 2074 expression, lhs_beg_pos, scanner()->location().end_pos, |
| 2082 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2075 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
| 2083 } | 2076 } |
| 2084 | 2077 |
| 2085 expression = this->MarkExpressionAsAssigned(expression); | 2078 expression = this->MarkExpressionAsAssigned(expression); |
| 2086 | 2079 |
| 2087 Token::Value op = Next(); // Get assignment operator. | 2080 Token::Value op = Next(); // Get assignment operator. |
| 2088 if (op != Token::ASSIGN) { | 2081 if (op != Token::ASSIGN) { |
| 2089 classifier->RecordBindingPatternError(scanner()->location(), | 2082 classifier->RecordBindingPatternError(scanner()->location(), |
| (...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3277 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); | 3270 return this->IsAssignableIdentifier(expression) || expression->IsProperty(); |
| 3278 } | 3271 } |
| 3279 | 3272 |
| 3280 | 3273 |
| 3281 template <typename Traits> | 3274 template <typename Traits> |
| 3282 void ParserBase<Traits>::CheckDestructuringElement( | 3275 void ParserBase<Traits>::CheckDestructuringElement( |
| 3283 ExpressionT expression, ExpressionClassifier* classifier, int begin, | 3276 ExpressionT expression, ExpressionClassifier* classifier, int begin, |
| 3284 int end) { | 3277 int end) { |
| 3285 static const MessageTemplate::Template message = | 3278 static const MessageTemplate::Template message = |
| 3286 MessageTemplate::kInvalidDestructuringTarget; | 3279 MessageTemplate::kInvalidDestructuringTarget; |
| 3287 if (!this->IsAssignableIdentifier(expression)) { | 3280 const Scanner::Location location(begin, end); |
| 3288 const Scanner::Location location(begin, end); | 3281 if (expression->IsArrayLiteral() || expression->IsObjectLiteral() || |
| 3282 expression->IsAssignment()) | |
| 3283 return; | |
|
adamk
2015/12/16 09:45:42
Nit: wrap this in a block (required by style since
| |
| 3284 if (expression->IsProperty()) { | |
| 3289 classifier->RecordBindingPatternError(location, message); | 3285 classifier->RecordBindingPatternError(location, message); |
| 3290 if (!expression->IsProperty() && | 3286 } else if (!this->IsAssignableIdentifier(expression)) { |
| 3291 !(expression->IsObjectLiteral() || expression->IsArrayLiteral())) { | 3287 classifier->RecordPatternError(location, message); |
| 3292 classifier->RecordAssignmentPatternError(location, message); | |
| 3293 } | |
| 3294 } | 3288 } |
| 3295 } | 3289 } |
| 3296 | 3290 |
| 3297 | 3291 |
| 3298 #undef CHECK_OK | 3292 #undef CHECK_OK |
| 3299 #undef CHECK_OK_CUSTOM | 3293 #undef CHECK_OK_CUSTOM |
| 3300 | 3294 |
| 3301 | 3295 |
| 3302 template <typename Traits> | 3296 template <typename Traits> |
| 3303 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( | 3297 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3349 return; | 3343 return; |
| 3350 } | 3344 } |
| 3351 has_seen_constructor_ = true; | 3345 has_seen_constructor_ = true; |
| 3352 return; | 3346 return; |
| 3353 } | 3347 } |
| 3354 } | 3348 } |
| 3355 } // namespace internal | 3349 } // namespace internal |
| 3356 } // namespace v8 | 3350 } // namespace v8 |
| 3357 | 3351 |
| 3358 #endif // V8_PARSING_PARSER_BASE_H | 3352 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |