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 2263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2274 template <class Traits> | 2274 template <class Traits> |
2275 typename ParserBase<Traits>::ExpressionT | 2275 typename ParserBase<Traits>::ExpressionT |
2276 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 2276 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
2277 ExpressionClassifier* classifier, | 2277 ExpressionClassifier* classifier, |
2278 bool* ok) { | 2278 bool* ok) { |
2279 // AssignmentExpression :: | 2279 // AssignmentExpression :: |
2280 // ConditionalExpression | 2280 // ConditionalExpression |
2281 // ArrowFunction | 2281 // ArrowFunction |
2282 // YieldExpression | 2282 // YieldExpression |
2283 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2283 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2284 bool is_destructuring_assignment = false; | |
2285 int lhs_beg_pos = peek_position(); | 2284 int lhs_beg_pos = peek_position(); |
2286 | 2285 |
2287 if (peek() == Token::YIELD && is_generator()) { | 2286 if (peek() == Token::YIELD && is_generator()) { |
2288 return this->ParseYieldExpression(accept_IN, classifier, ok); | 2287 return this->ParseYieldExpression(accept_IN, classifier, ok); |
2289 } | 2288 } |
2290 | 2289 |
2291 FuncNameInferrer::State fni_state(fni_); | 2290 FuncNameInferrer::State fni_state(fni_); |
2292 ParserBase<Traits>::Checkpoint checkpoint(this); | 2291 ParserBase<Traits>::Checkpoint checkpoint(this); |
2293 ExpressionClassifier arrow_formals_classifier(this, | 2292 ExpressionClassifier arrow_formals_classifier(this, |
2294 classifier->duplicate_finder()); | 2293 classifier->duplicate_finder()); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2369 arrow_formals_classifier.Discard(); | 2368 arrow_formals_classifier.Discard(); |
2370 classifier->RecordPatternError(arrow_loc, | 2369 classifier->RecordPatternError(arrow_loc, |
2371 MessageTemplate::kUnexpectedToken, | 2370 MessageTemplate::kUnexpectedToken, |
2372 Token::String(Token::ARROW)); | 2371 Token::String(Token::ARROW)); |
2373 | 2372 |
2374 if (fni_ != nullptr) fni_->Infer(); | 2373 if (fni_ != nullptr) fni_->Infer(); |
2375 | 2374 |
2376 return expression; | 2375 return expression; |
2377 } | 2376 } |
2378 | 2377 |
| 2378 // "expression" was not itself an arrow function parameter list, but it might |
| 2379 // form part of one. Propagate speculative formal parameter error locations |
| 2380 // (including those for binding patterns, since formal parameters can |
| 2381 // themselves contain binding patterns). |
| 2382 // Do not merge pending non-pattern expressions yet! |
| 2383 unsigned productions = |
| 2384 ExpressionClassifier::FormalParametersProductions | |
| 2385 ExpressionClassifier::AsyncArrowFormalParametersProduction | |
| 2386 ExpressionClassifier::FormalParameterInitializerProduction; |
| 2387 |
| 2388 // Parenthesized identifiers and property references are allowed as part |
| 2389 // of a larger binding pattern, even though parenthesized patterns |
| 2390 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate |
| 2391 // assignment pattern errors if the parsed expression is more complex. |
2379 if (this->IsValidReferenceExpression(expression)) { | 2392 if (this->IsValidReferenceExpression(expression)) { |
2380 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2393 productions |= ExpressionClassifier::PatternProductions & |
| 2394 ~ExpressionClassifier::AssignmentPatternProduction; |
| 2395 } else { |
| 2396 productions |= ExpressionClassifier::PatternProductions; |
2381 } | 2397 } |
2382 | 2398 |
2383 // "expression" was not itself an arrow function parameter list, but it might | 2399 const bool is_destructuring_assignment = |
2384 // form part of one. Propagate speculative formal parameter error locations. | 2400 IsValidPattern(expression) && peek() == Token::ASSIGN; |
2385 // Do not merge pending non-pattern expressions yet! | 2401 if (!is_destructuring_assignment) { |
2386 classifier->Accumulate( | 2402 // This may be an expression or a pattern, so we must continue to |
2387 &arrow_formals_classifier, | 2403 // accumulate expression-related errors. |
2388 ExpressionClassifier::ExpressionProductions | | 2404 productions |= ExpressionClassifier::ExpressionProduction | |
2389 ExpressionClassifier::PatternProductions | | 2405 ExpressionClassifier::TailCallExpressionProduction | |
2390 ExpressionClassifier::FormalParametersProductions | | 2406 ExpressionClassifier::ObjectLiteralProduction; |
2391 ExpressionClassifier::ObjectLiteralProduction | | 2407 } |
2392 ExpressionClassifier::AsyncArrowFormalParametersProduction, | 2408 |
2393 false); | 2409 classifier->Accumulate(&arrow_formals_classifier, productions, false); |
2394 | 2410 |
2395 if (!Token::IsAssignmentOp(peek())) { | 2411 if (!Token::IsAssignmentOp(peek())) { |
2396 // Parsed conditional expression only (no assignment). | 2412 // Parsed conditional expression only (no assignment). |
2397 // Now pending non-pattern expressions must be merged. | 2413 // Now pending non-pattern expressions must be merged. |
2398 classifier->MergeNonPatterns(&arrow_formals_classifier); | 2414 classifier->MergeNonPatterns(&arrow_formals_classifier); |
2399 return expression; | 2415 return expression; |
2400 } | 2416 } |
2401 | 2417 |
2402 // Now pending non-pattern expressions must be discarded. | 2418 // Now pending non-pattern expressions must be discarded. |
2403 arrow_formals_classifier.Discard(); | 2419 arrow_formals_classifier.Discard(); |
2404 | 2420 |
2405 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2421 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2406 | 2422 |
2407 if (IsValidPattern(expression) && peek() == Token::ASSIGN) { | 2423 if (is_destructuring_assignment) { |
2408 classifier->ForgiveObjectLiteralError(); | |
2409 ValidateAssignmentPattern(classifier, CHECK_OK); | 2424 ValidateAssignmentPattern(classifier, CHECK_OK); |
2410 is_destructuring_assignment = true; | |
2411 } else { | 2425 } else { |
2412 expression = this->CheckAndRewriteReferenceExpression( | 2426 expression = this->CheckAndRewriteReferenceExpression( |
2413 expression, lhs_beg_pos, scanner()->location().end_pos, | 2427 expression, lhs_beg_pos, scanner()->location().end_pos, |
2414 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); | 2428 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); |
2415 } | 2429 } |
2416 | 2430 |
2417 expression = this->MarkExpressionAsAssigned(expression); | 2431 expression = this->MarkExpressionAsAssigned(expression); |
2418 | 2432 |
2419 Token::Value op = Next(); // Get assignment operator. | 2433 Token::Value op = Next(); // Get assignment operator. |
2420 if (op != Token::ASSIGN) { | 2434 if (op != Token::ASSIGN) { |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3701 has_seen_constructor_ = true; | 3715 has_seen_constructor_ = true; |
3702 return; | 3716 return; |
3703 } | 3717 } |
3704 } | 3718 } |
3705 | 3719 |
3706 | 3720 |
3707 } // namespace internal | 3721 } // namespace internal |
3708 } // namespace v8 | 3722 } // namespace v8 |
3709 | 3723 |
3710 #endif // V8_PARSING_PARSER_BASE_H | 3724 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |