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 |