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/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1120 | 1120 |
1121 void ParseFormalParameter(FormalParametersT* parameters, | 1121 void ParseFormalParameter(FormalParametersT* parameters, |
1122 ExpressionClassifier* classifier, bool* ok); | 1122 ExpressionClassifier* classifier, bool* ok); |
1123 void ParseFormalParameterList(FormalParametersT* parameters, | 1123 void ParseFormalParameterList(FormalParametersT* parameters, |
1124 ExpressionClassifier* classifier, bool* ok); | 1124 ExpressionClassifier* classifier, bool* ok); |
1125 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1125 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
1126 bool has_rest, int formals_start_pos, | 1126 bool has_rest, int formals_start_pos, |
1127 int formals_end_pos, bool* ok); | 1127 int formals_end_pos, bool* ok); |
1128 | 1128 |
1129 bool IsNextLetKeyword(); | 1129 bool IsNextLetKeyword(); |
| 1130 bool IsTrivialExpression(); |
1130 | 1131 |
1131 // Checks if the expression is a valid reference expression (e.g., on the | 1132 // Checks if the expression is a valid reference expression (e.g., on the |
1132 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1133 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1133 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1134 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1134 ExpressionT CheckAndRewriteReferenceExpression( | 1135 ExpressionT CheckAndRewriteReferenceExpression( |
1135 ExpressionT expression, int beg_pos, int end_pos, | 1136 ExpressionT expression, int beg_pos, int end_pos, |
1136 MessageTemplate::Template message, bool* ok); | 1137 MessageTemplate::Template message, bool* ok); |
1137 ExpressionT CheckAndRewriteReferenceExpression( | 1138 ExpressionT CheckAndRewriteReferenceExpression( |
1138 ExpressionT expression, int beg_pos, int end_pos, | 1139 ExpressionT expression, int beg_pos, int end_pos, |
1139 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 1140 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1546 switch (peek()) { | 1547 switch (peek()) { |
1547 case Token::THIS: { | 1548 case Token::THIS: { |
1548 BindingPatternUnexpectedToken(classifier); | 1549 BindingPatternUnexpectedToken(classifier); |
1549 Consume(Token::THIS); | 1550 Consume(Token::THIS); |
1550 return this->ThisExpression(factory(), beg_pos); | 1551 return this->ThisExpression(factory(), beg_pos); |
1551 } | 1552 } |
1552 | 1553 |
1553 case Token::NULL_LITERAL: | 1554 case Token::NULL_LITERAL: |
1554 case Token::TRUE_LITERAL: | 1555 case Token::TRUE_LITERAL: |
1555 case Token::FALSE_LITERAL: | 1556 case Token::FALSE_LITERAL: |
1556 BindingPatternUnexpectedToken(classifier); | |
1557 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | |
1558 case Token::SMI: | 1557 case Token::SMI: |
1559 case Token::NUMBER: | 1558 case Token::NUMBER: |
1560 BindingPatternUnexpectedToken(classifier); | 1559 BindingPatternUnexpectedToken(classifier); |
1561 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); | 1560 return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory()); |
1562 | 1561 |
1563 case Token::ASYNC: | 1562 case Token::ASYNC: |
1564 if (allow_harmony_async_await() && | 1563 if (allow_harmony_async_await() && |
1565 !scanner()->HasAnyLineTerminatorAfterNext() && | 1564 !scanner()->HasAnyLineTerminatorAfterNext() && |
1566 PeekAhead() == Token::FUNCTION) { | 1565 PeekAhead() == Token::FUNCTION) { |
1567 Consume(Token::ASYNC); | 1566 Consume(Token::ASYNC); |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2300 Scope::Snapshot scope_snapshot(scope()); | 2299 Scope::Snapshot scope_snapshot(scope()); |
2301 | 2300 |
2302 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && | 2301 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && |
2303 !scanner()->HasAnyLineTerminatorAfterNext() && | 2302 !scanner()->HasAnyLineTerminatorAfterNext() && |
2304 IsValidArrowFormalParametersStart(PeekAhead()); | 2303 IsValidArrowFormalParametersStart(PeekAhead()); |
2305 | 2304 |
2306 bool parenthesized_formals = peek() == Token::LPAREN; | 2305 bool parenthesized_formals = peek() == Token::LPAREN; |
2307 if (!is_async && !parenthesized_formals) { | 2306 if (!is_async && !parenthesized_formals) { |
2308 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); | 2307 ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier); |
2309 } | 2308 } |
2310 ExpressionT expression = this->ParseConditionalExpression( | 2309 |
2311 accept_IN, &arrow_formals_classifier, CHECK_OK); | 2310 // Parse a simple, faster sub-grammar (primary expression) if it's evident |
| 2311 // that we have only a trivial expression to parse. |
| 2312 ExpressionT expression; |
| 2313 if (IsTrivialExpression()) { |
| 2314 expression = this->ParsePrimaryExpression(&arrow_formals_classifier, |
| 2315 &is_async, CHECK_OK); |
| 2316 } else { |
| 2317 expression = this->ParseConditionalExpression( |
| 2318 accept_IN, &arrow_formals_classifier, CHECK_OK); |
| 2319 } |
2312 | 2320 |
2313 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { | 2321 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { |
2314 // async Identifier => AsyncConciseBody | 2322 // async Identifier => AsyncConciseBody |
2315 IdentifierT name = | 2323 IdentifierT name = |
2316 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | 2324 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
2317 expression = this->ExpressionFromIdentifier( | 2325 expression = this->ExpressionFromIdentifier( |
2318 name, position(), scanner()->location().end_pos, factory()); | 2326 name, position(), scanner()->location().end_pos, factory()); |
2319 } | 2327 } |
2320 | 2328 |
2321 if (peek() == Token::ARROW) { | 2329 if (peek() == Token::ARROW) { |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3358 case Token::ASYNC: | 3366 case Token::ASYNC: |
3359 return true; | 3367 return true; |
3360 case Token::FUTURE_STRICT_RESERVED_WORD: | 3368 case Token::FUTURE_STRICT_RESERVED_WORD: |
3361 return is_sloppy(language_mode()); | 3369 return is_sloppy(language_mode()); |
3362 default: | 3370 default: |
3363 return false; | 3371 return false; |
3364 } | 3372 } |
3365 } | 3373 } |
3366 | 3374 |
3367 template <class Traits> | 3375 template <class Traits> |
| 3376 bool ParserBase<Traits>::IsTrivialExpression() { |
| 3377 Token::Value peek_token = peek(); |
| 3378 if (peek_token == Token::SMI || peek_token == Token::NUMBER || |
| 3379 peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL || |
| 3380 peek_token == Token::FALSE_LITERAL || peek_token == Token::STRING || |
| 3381 peek_token == Token::IDENTIFIER || peek_token == Token::THIS) { |
| 3382 // PeekAhead() is expensive & may not always be called, so we only call it |
| 3383 // after checking peek(). |
| 3384 Token::Value peek_ahead = PeekAhead(); |
| 3385 if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN || |
| 3386 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { |
| 3387 return true; |
| 3388 } |
| 3389 } |
| 3390 return false; |
| 3391 } |
| 3392 |
| 3393 template <class Traits> |
3368 typename ParserBase<Traits>::ExpressionT | 3394 typename ParserBase<Traits>::ExpressionT |
3369 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3395 ParserBase<Traits>::ParseArrowFunctionLiteral( |
3370 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, | 3396 bool accept_IN, const FormalParametersT& formal_parameters, bool is_async, |
3371 const ExpressionClassifier& formals_classifier, bool* ok) { | 3397 const ExpressionClassifier& formals_classifier, bool* ok) { |
3372 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3398 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3373 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3399 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3374 // `=> ...` is never a valid expression, so report as syntax error. | 3400 // `=> ...` is never a valid expression, so report as syntax error. |
3375 // If next token is not `=>`, it's a syntax error anyways. | 3401 // If next token is not `=>`, it's a syntax error anyways. |
3376 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3402 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3377 *ok = false; | 3403 *ok = false; |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3693 has_seen_constructor_ = true; | 3719 has_seen_constructor_ = true; |
3694 return; | 3720 return; |
3695 } | 3721 } |
3696 } | 3722 } |
3697 | 3723 |
3698 | 3724 |
3699 } // namespace internal | 3725 } // namespace internal |
3700 } // namespace v8 | 3726 } // namespace v8 |
3701 | 3727 |
3702 #endif // V8_PARSING_PARSER_BASE_H | 3728 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |