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 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 DCHECK(is_resumable()); | 378 DCHECK(is_resumable()); |
379 generator_object_variable_ = variable; | 379 generator_object_variable_ = variable; |
380 } | 380 } |
381 typename Traits::Type::GeneratorVariable* generator_object_variable() | 381 typename Traits::Type::GeneratorVariable* generator_object_variable() |
382 const { | 382 const { |
383 return generator_object_variable_; | 383 return generator_object_variable_; |
384 } | 384 } |
385 | 385 |
386 typename Traits::Type::Factory* factory() { return factory_; } | 386 typename Traits::Type::Factory* factory() { return factory_; } |
387 | 387 |
388 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 388 const ZoneList<DestructuringAssignment>& |
389 const { | 389 destructuring_assignments_to_rewrite() const { |
390 return destructuring_assignments_to_rewrite_; | 390 return destructuring_assignments_to_rewrite_; |
391 } | 391 } |
392 | 392 |
393 TailCallExpressionList& tail_call_expressions() { | 393 TailCallExpressionList& tail_call_expressions() { |
394 return tail_call_expressions_; | 394 return tail_call_expressions_; |
395 } | 395 } |
396 void AddImplicitTailCallExpression(ExpressionT expression) { | 396 void AddImplicitTailCallExpression(ExpressionT expression) { |
397 if (return_expr_context() == | 397 if (return_expr_context() == |
398 ReturnExprContext::kInsideValidReturnStatement) { | 398 ReturnExprContext::kInsideValidReturnStatement) { |
399 tail_call_expressions_.AddImplicitTailCall(expression); | 399 tail_call_expressions_.AddImplicitTailCall(expression); |
400 } | 400 } |
401 } | 401 } |
402 void AddExplicitTailCallExpression(ExpressionT expression, | 402 void AddExplicitTailCallExpression(ExpressionT expression, |
403 const Scanner::Location& loc) { | 403 const Scanner::Location& loc) { |
404 DCHECK(expression->IsCall()); | 404 DCHECK(expression->IsCall()); |
405 if (return_expr_context() == | 405 if (return_expr_context() == |
406 ReturnExprContext::kInsideValidReturnStatement) { | 406 ReturnExprContext::kInsideValidReturnStatement) { |
407 tail_call_expressions_.AddExplicitTailCall(expression, loc); | 407 tail_call_expressions_.AddExplicitTailCall(expression, loc); |
408 } | 408 } |
409 } | 409 } |
410 | 410 |
| 411 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() { |
| 412 return &reported_errors_; |
| 413 } |
| 414 |
411 ReturnExprContext return_expr_context() const { | 415 ReturnExprContext return_expr_context() const { |
412 return return_expr_context_; | 416 return return_expr_context_; |
413 } | 417 } |
414 void set_return_expr_context(ReturnExprContext context) { | 418 void set_return_expr_context(ReturnExprContext context) { |
415 return_expr_context_ = context; | 419 return_expr_context_ = context; |
416 } | 420 } |
417 | 421 |
418 ZoneList<ExpressionT>* non_patterns_to_rewrite() { | 422 ZoneList<ExpressionT>* non_patterns_to_rewrite() { |
419 return &non_patterns_to_rewrite_; | 423 return &non_patterns_to_rewrite_; |
420 } | 424 } |
421 | 425 |
422 void next_function_is_parenthesized(bool parenthesized) { | 426 void next_function_is_parenthesized(bool parenthesized) { |
423 next_function_is_parenthesized_ = parenthesized; | 427 next_function_is_parenthesized_ = parenthesized; |
424 } | 428 } |
425 | 429 |
426 bool this_function_is_parenthesized() const { | 430 bool this_function_is_parenthesized() const { |
427 return this_function_is_parenthesized_; | 431 return this_function_is_parenthesized_; |
428 } | 432 } |
429 | 433 |
430 private: | 434 private: |
431 void AddDestructuringAssignment(DestructuringAssignment pair) { | 435 void AddDestructuringAssignment(DestructuringAssignment pair) { |
432 destructuring_assignments_to_rewrite_.Add(pair); | 436 destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone()); |
433 } | 437 } |
434 | 438 |
435 V8_INLINE Scope* scope() { return *scope_stack_; } | 439 V8_INLINE Scope* scope() { return *scope_stack_; } |
436 | 440 |
437 void AddNonPatternForRewriting(ExpressionT expr) { | 441 void AddNonPatternForRewriting(ExpressionT expr) { |
438 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); | 442 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); |
439 } | 443 } |
440 | 444 |
441 // Used to assign an index to each literal that needs materialization in | 445 // Used to assign an index to each literal that needs materialization in |
442 // the function. Includes regexp literals, and boilerplate for object and | 446 // the function. Includes regexp literals, and boilerplate for object and |
(...skipping 16 matching lines...) Expand all Loading... |
459 // For generators, this variable may hold the generator object. It variable | 463 // For generators, this variable may hold the generator object. It variable |
460 // is used by yield expressions and return statements. It is not necessary | 464 // is used by yield expressions and return statements. It is not necessary |
461 // for generator functions to have this variable set. | 465 // for generator functions to have this variable set. |
462 Variable* generator_object_variable_; | 466 Variable* generator_object_variable_; |
463 | 467 |
464 FunctionState** function_state_stack_; | 468 FunctionState** function_state_stack_; |
465 FunctionState* outer_function_state_; | 469 FunctionState* outer_function_state_; |
466 Scope** scope_stack_; | 470 Scope** scope_stack_; |
467 Scope* outer_scope_; | 471 Scope* outer_scope_; |
468 | 472 |
469 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 473 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
470 TailCallExpressionList tail_call_expressions_; | 474 TailCallExpressionList tail_call_expressions_; |
471 ReturnExprContext return_expr_context_; | 475 ReturnExprContext return_expr_context_; |
472 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 476 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
473 | 477 |
| 478 ZoneList<typename ExpressionClassifier::Error> reported_errors_; |
| 479 |
474 typename Traits::Type::Factory* factory_; | 480 typename Traits::Type::Factory* factory_; |
475 | 481 |
476 // If true, the next (and immediately following) function literal is | 482 // If true, the next (and immediately following) function literal is |
477 // preceded by a parenthesis. | 483 // preceded by a parenthesis. |
478 bool next_function_is_parenthesized_; | 484 bool next_function_is_parenthesized_; |
479 | 485 |
480 // The value of the parents' next_function_is_parenthesized_, as it applies | 486 // The value of the parents' next_function_is_parenthesized_, as it applies |
481 // to this function. Filled in by constructor. | 487 // to this function. Filled in by constructor. |
482 bool this_function_is_parenthesized_; | 488 bool this_function_is_parenthesized_; |
483 | 489 |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 expected_property_count_(0), | 1192 expected_property_count_(0), |
1187 this_location_(Scanner::Location::invalid()), | 1193 this_location_(Scanner::Location::invalid()), |
1188 return_location_(Scanner::Location::invalid()), | 1194 return_location_(Scanner::Location::invalid()), |
1189 super_location_(Scanner::Location::invalid()), | 1195 super_location_(Scanner::Location::invalid()), |
1190 kind_(kind), | 1196 kind_(kind), |
1191 generator_object_variable_(NULL), | 1197 generator_object_variable_(NULL), |
1192 function_state_stack_(function_state_stack), | 1198 function_state_stack_(function_state_stack), |
1193 outer_function_state_(*function_state_stack), | 1199 outer_function_state_(*function_state_stack), |
1194 scope_stack_(scope_stack), | 1200 scope_stack_(scope_stack), |
1195 outer_scope_(*scope_stack), | 1201 outer_scope_(*scope_stack), |
| 1202 destructuring_assignments_to_rewrite_(16, scope->zone()), |
1196 tail_call_expressions_(scope->zone()), | 1203 tail_call_expressions_(scope->zone()), |
1197 return_expr_context_(ReturnExprContext::kInsideValidBlock), | 1204 return_expr_context_(ReturnExprContext::kInsideValidBlock), |
1198 non_patterns_to_rewrite_(0, scope->zone()), | 1205 non_patterns_to_rewrite_(0, scope->zone()), |
| 1206 reported_errors_(16, scope->zone()), |
1199 factory_(factory), | 1207 factory_(factory), |
1200 next_function_is_parenthesized_(false), | 1208 next_function_is_parenthesized_(false), |
1201 this_function_is_parenthesized_(false) { | 1209 this_function_is_parenthesized_(false) { |
1202 *scope_stack_ = scope; | 1210 *scope_stack_ = scope; |
1203 *function_state_stack = this; | 1211 *function_state_stack = this; |
1204 if (outer_function_state_) { | 1212 if (outer_function_state_) { |
1205 this_function_is_parenthesized_ = | 1213 this_function_is_parenthesized_ = |
1206 outer_function_state_->next_function_is_parenthesized_; | 1214 outer_function_state_->next_function_is_parenthesized_; |
1207 outer_function_state_->next_function_is_parenthesized_ = false; | 1215 outer_function_state_->next_function_is_parenthesized_ = false; |
1208 } | 1216 } |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 | 1553 |
1546 case Token::LBRACE: | 1554 case Token::LBRACE: |
1547 return this->ParseObjectLiteral(classifier, ok); | 1555 return this->ParseObjectLiteral(classifier, ok); |
1548 | 1556 |
1549 case Token::LPAREN: { | 1557 case Token::LPAREN: { |
1550 // Arrow function formal parameters are either a single identifier or a | 1558 // Arrow function formal parameters are either a single identifier or a |
1551 // list of BindingPattern productions enclosed in parentheses. | 1559 // list of BindingPattern productions enclosed in parentheses. |
1552 // Parentheses are not valid on the LHS of a BindingPattern, so we use the | 1560 // Parentheses are not valid on the LHS of a BindingPattern, so we use the |
1553 // is_valid_binding_pattern() check to detect multiple levels of | 1561 // is_valid_binding_pattern() check to detect multiple levels of |
1554 // parenthesization. | 1562 // parenthesization. |
1555 if (!classifier->is_valid_binding_pattern()) { | 1563 bool pattern_error = !classifier->is_valid_binding_pattern(); |
1556 ArrowFormalParametersUnexpectedToken(classifier); | |
1557 } | |
1558 classifier->RecordPatternError(scanner()->peek_location(), | 1564 classifier->RecordPatternError(scanner()->peek_location(), |
1559 MessageTemplate::kUnexpectedToken, | 1565 MessageTemplate::kUnexpectedToken, |
1560 Token::String(Token::LPAREN)); | 1566 Token::String(Token::LPAREN)); |
| 1567 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier); |
1561 Consume(Token::LPAREN); | 1568 Consume(Token::LPAREN); |
1562 if (Check(Token::RPAREN)) { | 1569 if (Check(Token::RPAREN)) { |
1563 // ()=>x. The continuation that looks for the => is in | 1570 // ()=>x. The continuation that looks for the => is in |
1564 // ParseAssignmentExpression. | 1571 // ParseAssignmentExpression. |
1565 classifier->RecordExpressionError(scanner()->location(), | 1572 classifier->RecordExpressionError(scanner()->location(), |
1566 MessageTemplate::kUnexpectedToken, | 1573 MessageTemplate::kUnexpectedToken, |
1567 Token::String(Token::RPAREN)); | 1574 Token::String(Token::RPAREN)); |
1568 return factory()->NewEmptyParentheses(beg_pos); | 1575 return factory()->NewEmptyParentheses(beg_pos); |
1569 } else if (Check(Token::ELLIPSIS)) { | 1576 } else if (Check(Token::ELLIPSIS)) { |
1570 // (...x)=>x. The continuation that looks for the => is in | 1577 // (...x)=>x. The continuation that looks for the => is in |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 if (peek() == Token::ELLIPSIS) { | 1690 if (peek() == Token::ELLIPSIS) { |
1684 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1691 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
1685 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1692 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
1686 // valid expression or binding pattern. | 1693 // valid expression or binding pattern. |
1687 ExpressionUnexpectedToken(classifier); | 1694 ExpressionUnexpectedToken(classifier); |
1688 BindingPatternUnexpectedToken(classifier); | 1695 BindingPatternUnexpectedToken(classifier); |
1689 Consume(Token::ELLIPSIS); | 1696 Consume(Token::ELLIPSIS); |
1690 seen_rest = is_rest = true; | 1697 seen_rest = is_rest = true; |
1691 } | 1698 } |
1692 int pos = position(), expr_pos = peek_position(); | 1699 int pos = position(), expr_pos = peek_position(); |
| 1700 ExpressionClassifier binding_classifier(this); |
1693 ExpressionT right = this->ParseAssignmentExpression( | 1701 ExpressionT right = this->ParseAssignmentExpression( |
1694 accept_IN, &binding_classifier, CHECK_OK); | 1702 accept_IN, &binding_classifier, CHECK_OK); |
1695 classifier->Accumulate(&binding_classifier, | 1703 classifier->Accumulate(&binding_classifier, |
1696 ExpressionClassifier::AllProductions); | 1704 ExpressionClassifier::AllProductions); |
1697 if (is_rest) { | 1705 if (is_rest) { |
1698 if (!this->IsIdentifier(right) && !IsValidPattern(right)) { | 1706 if (!this->IsIdentifier(right) && !IsValidPattern(right)) { |
1699 classifier->RecordArrowFormalParametersError( | 1707 classifier->RecordArrowFormalParametersError( |
1700 Scanner::Location(pos, scanner()->location().end_pos), | 1708 Scanner::Location(pos, scanner()->location().end_pos), |
1701 MessageTemplate::kInvalidRestParameter); | 1709 MessageTemplate::kInvalidRestParameter); |
1702 } | 1710 } |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2217 | 2225 |
2218 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { | 2226 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { |
2219 // async Identifier => AsyncConciseBody | 2227 // async Identifier => AsyncConciseBody |
2220 IdentifierT name = | 2228 IdentifierT name = |
2221 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); | 2229 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); |
2222 expression = this->ExpressionFromIdentifier( | 2230 expression = this->ExpressionFromIdentifier( |
2223 name, position(), scanner()->location().end_pos, scope_, factory()); | 2231 name, position(), scanner()->location().end_pos, scope_, factory()); |
2224 } | 2232 } |
2225 | 2233 |
2226 if (peek() == Token::ARROW) { | 2234 if (peek() == Token::ARROW) { |
2227 classifier->RecordPatternError(scanner()->peek_location(), | 2235 Scanner::Location arrow_loc = scanner()->peek_location(); |
2228 MessageTemplate::kUnexpectedToken, | |
2229 Token::String(Token::ARROW)); | |
2230 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2236 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2231 parenthesized_formals, is_async, CHECK_OK); | 2237 parenthesized_formals, is_async, CHECK_OK); |
2232 // This reads strangely, but is correct: it checks whether any | 2238 // This reads strangely, but is correct: it checks whether any |
2233 // sub-expression of the parameter list failed to be a valid formal | 2239 // sub-expression of the parameter list failed to be a valid formal |
2234 // parameter initializer. Since YieldExpressions are banned anywhere | 2240 // parameter initializer. Since YieldExpressions are banned anywhere |
2235 // in an arrow parameter list, this is correct. | 2241 // in an arrow parameter list, this is correct. |
2236 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2242 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
2237 // "YieldExpression", which is its only use. | 2243 // "YieldExpression", which is its only use. |
2238 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2244 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
2239 | 2245 |
(...skipping 16 matching lines...) Expand all Loading... |
2256 scope->set_start_position(lhs_beg_pos); | 2262 scope->set_start_position(lhs_beg_pos); |
2257 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2263 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
2258 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, | 2264 this->ParseArrowFunctionFormalParameterList(¶meters, expression, loc, |
2259 &duplicate_loc, CHECK_OK); | 2265 &duplicate_loc, CHECK_OK); |
2260 if (duplicate_loc.IsValid()) { | 2266 if (duplicate_loc.IsValid()) { |
2261 arrow_formals_classifier.RecordDuplicateFormalParameterError( | 2267 arrow_formals_classifier.RecordDuplicateFormalParameterError( |
2262 duplicate_loc); | 2268 duplicate_loc); |
2263 } | 2269 } |
2264 expression = this->ParseArrowFunctionLiteral( | 2270 expression = this->ParseArrowFunctionLiteral( |
2265 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); | 2271 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); |
| 2272 arrow_formals_classifier.Discard(); |
| 2273 classifier->RecordPatternError(arrow_loc, |
| 2274 MessageTemplate::kUnexpectedToken, |
| 2275 Token::String(Token::ARROW)); |
2266 | 2276 |
2267 if (fni_ != nullptr) fni_->Infer(); | 2277 if (fni_ != nullptr) fni_->Infer(); |
2268 | 2278 |
2269 return expression; | 2279 return expression; |
2270 } | 2280 } |
2271 | 2281 |
2272 if (this->IsValidReferenceExpression(expression)) { | 2282 if (this->IsValidReferenceExpression(expression)) { |
2273 arrow_formals_classifier.ForgiveAssignmentPatternError(); | 2283 arrow_formals_classifier.ForgiveAssignmentPatternError(); |
2274 } | 2284 } |
2275 | 2285 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2495 // LogicalOrExpression | 2505 // LogicalOrExpression |
2496 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2506 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
2497 | 2507 |
2498 int pos = peek_position(); | 2508 int pos = peek_position(); |
2499 // We start using the binary expression parser for prec >= 4 only! | 2509 // We start using the binary expression parser for prec >= 4 only! |
2500 ExpressionT expression = | 2510 ExpressionT expression = |
2501 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); | 2511 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); |
2502 if (peek() != Token::CONDITIONAL) return expression; | 2512 if (peek() != Token::CONDITIONAL) return expression; |
2503 CheckNoTailCallExpressions(classifier, CHECK_OK); | 2513 CheckNoTailCallExpressions(classifier, CHECK_OK); |
2504 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2514 Traits::RewriteNonPattern(classifier, CHECK_OK); |
| 2515 BindingPatternUnexpectedToken(classifier); |
2505 ArrowFormalParametersUnexpectedToken(classifier); | 2516 ArrowFormalParametersUnexpectedToken(classifier); |
2506 BindingPatternUnexpectedToken(classifier); | |
2507 Consume(Token::CONDITIONAL); | 2517 Consume(Token::CONDITIONAL); |
2508 // In parsing the first assignment expression in conditional | 2518 // In parsing the first assignment expression in conditional |
2509 // expressions we always accept the 'in' keyword; see ECMA-262, | 2519 // expressions we always accept the 'in' keyword; see ECMA-262, |
2510 // section 11.12, page 58. | 2520 // section 11.12, page 58. |
2511 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); | 2521 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); |
2512 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2522 Traits::RewriteNonPattern(classifier, CHECK_OK); |
2513 Expect(Token::COLON, CHECK_OK); | 2523 Expect(Token::COLON, CHECK_OK); |
2514 ExpressionT right = | 2524 ExpressionT right = |
2515 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); | 2525 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); |
2516 Traits::RewriteNonPattern(classifier, CHECK_OK); | 2526 Traits::RewriteNonPattern(classifier, CHECK_OK); |
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3593 has_seen_constructor_ = true; | 3603 has_seen_constructor_ = true; |
3594 return; | 3604 return; |
3595 } | 3605 } |
3596 } | 3606 } |
3597 | 3607 |
3598 | 3608 |
3599 } // namespace internal | 3609 } // namespace internal |
3600 } // namespace v8 | 3610 } // namespace v8 |
3601 | 3611 |
3602 #endif // V8_PARSING_PARSER_BASE_H | 3612 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |