OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 DECLARE_FLAG(bool, profile_vm); | 61 DECLARE_FLAG(bool, profile_vm); |
62 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 62 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
63 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 63 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
64 | 64 |
65 // Quick access to the current thread, isolate and zone. | 65 // Quick access to the current thread, isolate and zone. |
66 #define T (thread()) | 66 #define T (thread()) |
67 #define I (isolate()) | 67 #define I (isolate()) |
68 #define Z (zone()) | 68 #define Z (zone()) |
69 | 69 |
70 // Quick synthetic token position. | 70 // Quick synthetic token position. |
71 #define ST(token_pos) Token::ToSynthetic(token_pos) | 71 #define ST(token_pos) ((token_pos).ToSynthetic()) |
72 | 72 |
73 #if defined(DEBUG) | 73 #if defined(DEBUG) |
74 class TraceParser : public ValueObject { | 74 class TraceParser : public ValueObject { |
75 public: | 75 public: |
76 TraceParser(intptr_t token_pos, | 76 TraceParser(TokenPosition token_pos, |
77 const Script& script, | 77 const Script& script, |
78 intptr_t* trace_indent, | 78 intptr_t* trace_indent, |
79 const char* msg) { | 79 const char* msg) { |
80 indent_ = trace_indent; | 80 indent_ = trace_indent; |
81 if (FLAG_trace_parser) { | 81 if (FLAG_trace_parser) { |
82 // Skips tracing of bootstrap libraries. | 82 // Skips tracing of bootstrap libraries. |
83 if (script.HasSource()) { | 83 if (script.HasSource()) { |
84 intptr_t line, column; | 84 intptr_t line, column; |
85 script.GetTokenLocation(token_pos, &line, &column); | 85 script.GetTokenLocation(token_pos, &line, &column); |
86 PrintIndent(); | 86 PrintIndent(); |
87 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", | 87 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", |
88 msg, line, column, token_pos); | 88 msg, line, column, token_pos.value()); |
89 } | 89 } |
90 (*indent_)++; | 90 (*indent_)++; |
91 } | 91 } |
92 } | 92 } |
93 ~TraceParser() { | 93 ~TraceParser() { |
94 if (FLAG_trace_parser) { | 94 if (FLAG_trace_parser) { |
95 (*indent_)--; | 95 (*indent_)--; |
96 ASSERT(*indent_ >= 0); | 96 ASSERT(*indent_ >= 0); |
97 } | 97 } |
98 } | 98 } |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 &found_captured_variables); | 256 &found_captured_variables); |
257 | 257 |
258 // Frame indices are relative to the frame pointer and are decreasing. | 258 // Frame indices are relative to the frame pointer and are decreasing. |
259 ASSERT(next_free_frame_index <= first_stack_local_index_); | 259 ASSERT(next_free_frame_index <= first_stack_local_index_); |
260 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 260 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
261 } | 261 } |
262 | 262 |
263 | 263 |
264 struct CatchParamDesc { | 264 struct CatchParamDesc { |
265 CatchParamDesc() | 265 CatchParamDesc() |
266 : token_pos(Token::kNoSourcePos), type(NULL), name(NULL), var(NULL) { } | 266 : token_pos(TokenPosition::kNoSource), |
267 intptr_t token_pos; | 267 type(NULL), |
| 268 name(NULL), |
| 269 var(NULL) { } |
| 270 TokenPosition token_pos; |
268 const AbstractType* type; | 271 const AbstractType* type; |
269 const String* name; | 272 const String* name; |
270 LocalVariable* var; | 273 LocalVariable* var; |
271 }; | 274 }; |
272 | 275 |
273 | 276 |
274 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 277 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
275 ASSERT(function().IsIrregexpFunction()); | 278 ASSERT(function().IsIrregexpFunction()); |
276 ASSERT(function().NumOptionalParameters() == 0); | 279 ASSERT(function().NumOptionalParameters() == 0); |
277 const intptr_t num_params = function().num_fixed_parameters(); | 280 const intptr_t num_params = function().num_fixed_parameters(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 DISALLOW_COPY_AND_ASSIGN(TryStack); | 346 DISALLOW_COPY_AND_ASSIGN(TryStack); |
344 }; | 347 }; |
345 | 348 |
346 | 349 |
347 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { | 350 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { |
348 inlined_finally_nodes_.Add(node); | 351 inlined_finally_nodes_.Add(node); |
349 } | 352 } |
350 | 353 |
351 | 354 |
352 // For parsing a compilation unit. | 355 // For parsing a compilation unit. |
353 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 356 Parser::Parser(const Script& script, |
| 357 const Library& library, |
| 358 TokenPosition token_pos) |
354 : isolate_(Thread::Current()->isolate()), | 359 : isolate_(Thread::Current()->isolate()), |
355 thread_(Thread::Current()), | 360 thread_(Thread::Current()), |
356 script_(Script::Handle(zone(), script.raw())), | 361 script_(Script::Handle(zone(), script.raw())), |
357 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), | 362 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
358 token_pos), | 363 token_pos), |
359 token_kind_(Token::kILLEGAL), | 364 token_kind_(Token::kILLEGAL), |
360 current_block_(NULL), | 365 current_block_(NULL), |
361 is_top_level_(false), | 366 is_top_level_(false), |
362 await_is_keyword_(false), | 367 await_is_keyword_(false), |
363 current_member_(NULL), | 368 current_member_(NULL), |
(...skipping 10 matching lines...) Expand all Loading... |
374 trace_indent_(0), | 379 trace_indent_(0), |
375 recursion_counter_(0) { | 380 recursion_counter_(0) { |
376 ASSERT(tokens_iterator_.IsValid()); | 381 ASSERT(tokens_iterator_.IsValid()); |
377 ASSERT(!library.IsNull()); | 382 ASSERT(!library.IsNull()); |
378 } | 383 } |
379 | 384 |
380 | 385 |
381 // For parsing a function. | 386 // For parsing a function. |
382 Parser::Parser(const Script& script, | 387 Parser::Parser(const Script& script, |
383 ParsedFunction* parsed_function, | 388 ParsedFunction* parsed_function, |
384 intptr_t token_position) | 389 TokenPosition token_pos) |
385 : isolate_(Thread::Current()->isolate()), | 390 : isolate_(Thread::Current()->isolate()), |
386 thread_(Thread::Current()), | 391 thread_(Thread::Current()), |
387 script_(Script::Handle(zone(), script.raw())), | 392 script_(Script::Handle(zone(), script.raw())), |
388 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), | 393 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
389 token_position), | 394 token_pos), |
390 token_kind_(Token::kILLEGAL), | 395 token_kind_(Token::kILLEGAL), |
391 current_block_(NULL), | 396 current_block_(NULL), |
392 is_top_level_(false), | 397 is_top_level_(false), |
393 await_is_keyword_(false), | 398 await_is_keyword_(false), |
394 current_member_(NULL), | 399 current_member_(NULL), |
395 allow_function_literals_(true), | 400 allow_function_literals_(true), |
396 parsed_function_(parsed_function), | 401 parsed_function_(parsed_function), |
397 innermost_function_(Function::Handle(zone(), | 402 innermost_function_(Function::Handle(zone(), |
398 parsed_function->function().raw())), | 403 parsed_function->function().raw())), |
399 literal_token_(LiteralToken::Handle(zone())), | 404 literal_token_(LiteralToken::Handle(zone())), |
(...skipping 29 matching lines...) Expand all Loading... |
429 // Each try in this function gets its own try index. | 434 // Each try in this function gets its own try index. |
430 // See definition of RawPcDescriptors::PcDescriptor. | 435 // See definition of RawPcDescriptors::PcDescriptor. |
431 int16_t Parser::AllocateTryIndex() { | 436 int16_t Parser::AllocateTryIndex() { |
432 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 437 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
433 ReportError("too many nested try statements"); | 438 ReportError("too many nested try statements"); |
434 } | 439 } |
435 return last_used_try_index_++; | 440 return last_used_try_index_++; |
436 } | 441 } |
437 | 442 |
438 | 443 |
439 void Parser::SetScript(const Script& script, intptr_t token_pos) { | 444 void Parser::SetScript(const Script& script, TokenPosition token_pos) { |
440 script_ = script.raw(); | 445 script_ = script.raw(); |
441 tokens_iterator_.SetStream( | 446 tokens_iterator_.SetStream( |
442 TokenStream::Handle(Z, script.tokens()), token_pos); | 447 TokenStream::Handle(Z, script.tokens()), token_pos); |
443 token_kind_ = Token::kILLEGAL; | 448 token_kind_ = Token::kILLEGAL; |
444 } | 449 } |
445 | 450 |
446 | 451 |
447 bool Parser::SetAllowFunctionLiterals(bool value) { | 452 bool Parser::SetAllowFunctionLiterals(bool value) { |
448 bool current_value = allow_function_literals_; | 453 bool current_value = allow_function_literals_; |
449 allow_function_literals_ = value; | 454 allow_function_literals_ = value; |
(...skipping 15 matching lines...) Expand all Loading... |
465 const Class& Parser::current_class() const { | 470 const Class& Parser::current_class() const { |
466 return current_class_; | 471 return current_class_; |
467 } | 472 } |
468 | 473 |
469 | 474 |
470 void Parser::set_current_class(const Class& value) { | 475 void Parser::set_current_class(const Class& value) { |
471 current_class_ = value.raw(); | 476 current_class_ = value.raw(); |
472 } | 477 } |
473 | 478 |
474 | 479 |
475 void Parser::SetPosition(intptr_t position) { | 480 void Parser::SetPosition(TokenPosition position) { |
476 tokens_iterator_.SetCurrentPosition(position); | 481 tokens_iterator_.SetCurrentPosition(position); |
477 token_kind_ = Token::kILLEGAL; | 482 token_kind_ = Token::kILLEGAL; |
478 prev_token_pos_ = position; | 483 prev_token_pos_ = position; |
479 } | 484 } |
480 | 485 |
481 | 486 |
482 void Parser::ParseCompilationUnit(const Library& library, | 487 void Parser::ParseCompilationUnit(const Library& library, |
483 const Script& script) { | 488 const Script& script) { |
484 Thread* thread = Thread::Current(); | 489 Thread* thread = Thread::Current(); |
485 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 490 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
486 CSTAT_TIMER_SCOPE(thread, parser_timer); | 491 CSTAT_TIMER_SCOPE(thread, parser_timer); |
487 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 492 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
488 TimelineDurationScope tds(thread, | 493 TimelineDurationScope tds(thread, |
489 thread->isolate()->GetCompilerStream(), | 494 thread->isolate()->GetCompilerStream(), |
490 "CompileTopLevel"); | 495 "CompileTopLevel"); |
491 if (tds.enabled()) { | 496 if (tds.enabled()) { |
492 tds.SetNumArguments(1); | 497 tds.SetNumArguments(1); |
493 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); | 498 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); |
494 } | 499 } |
495 | 500 |
496 Parser parser(script, library, 0); | 501 Parser parser(script, library, TokenPosition::kMinSource); |
497 parser.ParseTopLevel(); | 502 parser.ParseTopLevel(); |
498 } | 503 } |
499 | 504 |
500 | 505 |
501 void Parser::ComputeCurrentToken() { | 506 void Parser::ComputeCurrentToken() { |
502 ASSERT(token_kind_ == Token::kILLEGAL); | 507 ASSERT(token_kind_ == Token::kILLEGAL); |
503 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 508 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
504 if (token_kind_ == Token::kERROR) { | 509 if (token_kind_ == Token::kERROR) { |
505 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 510 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
506 } | 511 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 i.ToCString()); | 543 i.ToCString()); |
539 } | 544 } |
540 } | 545 } |
541 return ri; | 546 return ri; |
542 } | 547 } |
543 | 548 |
544 | 549 |
545 struct ParamDesc { | 550 struct ParamDesc { |
546 ParamDesc() | 551 ParamDesc() |
547 : type(NULL), | 552 : type(NULL), |
548 name_pos(Token::kNoSourcePos), | 553 name_pos(TokenPosition::kNoSource), |
549 name(NULL), | 554 name(NULL), |
550 default_value(NULL), | 555 default_value(NULL), |
551 metadata(NULL), | 556 metadata(NULL), |
552 var(NULL), | 557 var(NULL), |
553 is_final(false), | 558 is_final(false), |
554 is_field_initializer(false), | 559 is_field_initializer(false), |
555 has_explicit_type(false) { } | 560 has_explicit_type(false) { } |
556 const AbstractType* type; | 561 const AbstractType* type; |
557 intptr_t name_pos; | 562 TokenPosition name_pos; |
558 const String* name; | 563 const String* name; |
559 const Instance* default_value; // NULL if not an optional parameter. | 564 const Instance* default_value; // NULL if not an optional parameter. |
560 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 565 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
561 LocalVariable* var; // Scope variable allocated for this parameter. | 566 LocalVariable* var; // Scope variable allocated for this parameter. |
562 bool is_final; | 567 bool is_final; |
563 bool is_field_initializer; | 568 bool is_field_initializer; |
564 bool has_explicit_type; | 569 bool has_explicit_type; |
565 }; | 570 }; |
566 | 571 |
567 | 572 |
568 struct ParamList { | 573 struct ParamList { |
569 ParamList() { | 574 ParamList() { |
570 Clear(); | 575 Clear(); |
571 } | 576 } |
572 | 577 |
573 void Clear() { | 578 void Clear() { |
574 num_fixed_parameters = 0; | 579 num_fixed_parameters = 0; |
575 num_optional_parameters = 0; | 580 num_optional_parameters = 0; |
576 has_optional_positional_parameters = false; | 581 has_optional_positional_parameters = false; |
577 has_optional_named_parameters = false; | 582 has_optional_named_parameters = false; |
578 has_explicit_default_values = false; | 583 has_explicit_default_values = false; |
579 has_field_initializer = false; | 584 has_field_initializer = false; |
580 implicitly_final = false; | 585 implicitly_final = false; |
581 skipped = false; | 586 skipped = false; |
582 this->parameters = new ZoneGrowableArray<ParamDesc>(); | 587 this->parameters = new ZoneGrowableArray<ParamDesc>(); |
583 } | 588 } |
584 | 589 |
585 void AddFinalParameter(intptr_t name_pos, | 590 void AddFinalParameter(TokenPosition name_pos, |
586 const String* name, | 591 const String* name, |
587 const AbstractType* type) { | 592 const AbstractType* type) { |
588 this->num_fixed_parameters++; | 593 this->num_fixed_parameters++; |
589 ParamDesc param; | 594 ParamDesc param; |
590 param.name_pos = name_pos; | 595 param.name_pos = name_pos; |
591 param.name = name; | 596 param.name = name; |
592 param.is_final = true; | 597 param.is_final = true; |
593 param.type = type; | 598 param.type = type; |
594 this->parameters->Add(param); | 599 this->parameters->Add(param); |
595 } | 600 } |
596 | 601 |
597 void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) { | 602 void AddReceiver(const AbstractType* receiver_type, |
| 603 TokenPosition token_pos) { |
598 ASSERT(this->parameters->is_empty()); | 604 ASSERT(this->parameters->is_empty()); |
599 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); | 605 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); |
600 } | 606 } |
601 | 607 |
602 void EraseParameterTypes() { | 608 void EraseParameterTypes() { |
603 const int num_parameters = parameters->length(); | 609 const int num_parameters = parameters->length(); |
604 for (int i = 0; i < num_parameters; i++) { | 610 for (int i = 0; i < num_parameters; i++) { |
605 (*parameters)[i].type = &Object::dynamic_type(); | 611 (*parameters)[i].type = &Object::dynamic_type(); |
606 } | 612 } |
607 } | 613 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 void Clear() { | 649 void Clear() { |
644 has_abstract = false; | 650 has_abstract = false; |
645 has_external = false; | 651 has_external = false; |
646 has_final = false; | 652 has_final = false; |
647 has_const = false; | 653 has_const = false; |
648 has_static = false; | 654 has_static = false; |
649 has_var = false; | 655 has_var = false; |
650 has_factory = false; | 656 has_factory = false; |
651 has_operator = false; | 657 has_operator = false; |
652 has_native = false; | 658 has_native = false; |
653 metadata_pos = Token::kNoSourcePos; | 659 metadata_pos = TokenPosition::kNoSource; |
654 operator_token = Token::kILLEGAL; | 660 operator_token = Token::kILLEGAL; |
655 type = NULL; | 661 type = NULL; |
656 name_pos = Token::kNoSourcePos; | 662 name_pos = TokenPosition::kNoSource; |
657 name = NULL; | 663 name = NULL; |
658 redirect_name = NULL; | 664 redirect_name = NULL; |
659 dict_name = NULL; | 665 dict_name = NULL; |
660 params.Clear(); | 666 params.Clear(); |
661 kind = RawFunction::kRegularFunction; | 667 kind = RawFunction::kRegularFunction; |
662 field_ = NULL; | 668 field_ = NULL; |
663 } | 669 } |
664 | 670 |
665 bool IsConstructor() const { | 671 bool IsConstructor() const { |
666 return (kind == RawFunction::kConstructor) && !has_static; | 672 return (kind == RawFunction::kConstructor) && !has_static; |
(...skipping 29 matching lines...) Expand all Loading... |
696 } | 702 } |
697 bool has_abstract; | 703 bool has_abstract; |
698 bool has_external; | 704 bool has_external; |
699 bool has_final; | 705 bool has_final; |
700 bool has_const; | 706 bool has_const; |
701 bool has_static; | 707 bool has_static; |
702 bool has_var; | 708 bool has_var; |
703 bool has_factory; | 709 bool has_factory; |
704 bool has_operator; | 710 bool has_operator; |
705 bool has_native; | 711 bool has_native; |
706 intptr_t metadata_pos; | 712 TokenPosition metadata_pos; |
707 Token::Kind operator_token; | 713 Token::Kind operator_token; |
708 const AbstractType* type; | 714 const AbstractType* type; |
709 intptr_t name_pos; | 715 TokenPosition name_pos; |
710 intptr_t decl_begin_pos; | 716 TokenPosition decl_begin_pos; |
711 String* name; | 717 String* name; |
712 // For constructors: NULL or name of redirected to constructor. | 718 // For constructors: NULL or name of redirected to constructor. |
713 String* redirect_name; | 719 String* redirect_name; |
714 // dict_name is the name used for the class namespace, if it | 720 // dict_name is the name used for the class namespace, if it |
715 // differs from 'name'. | 721 // differs from 'name'. |
716 // For constructors: NULL for unnamed constructor, | 722 // For constructors: NULL for unnamed constructor, |
717 // identifier after classname for named constructors. | 723 // identifier after classname for named constructors. |
718 // For getters and setters: unmangled name. | 724 // For getters and setters: unmangled name. |
719 String* dict_name; | 725 String* dict_name; |
720 ParamList params; | 726 ParamList params; |
721 RawFunction::Kind kind; | 727 RawFunction::Kind kind; |
722 // NULL for functions, field object for static or instance fields. | 728 // NULL for functions, field object for static or instance fields. |
723 Field* field_; | 729 Field* field_; |
724 }; | 730 }; |
725 | 731 |
726 | 732 |
727 class ClassDesc : public ValueObject { | 733 class ClassDesc : public ValueObject { |
728 public: | 734 public: |
729 ClassDesc(Zone* zone, | 735 ClassDesc(Zone* zone, |
730 const Class& cls, | 736 const Class& cls, |
731 const String& cls_name, | 737 const String& cls_name, |
732 bool is_interface, | 738 bool is_interface, |
733 intptr_t token_pos) | 739 TokenPosition token_pos) |
734 : zone_(zone), | 740 : zone_(zone), |
735 clazz_(cls), | 741 clazz_(cls), |
736 class_name_(cls_name), | 742 class_name_(cls_name), |
737 token_pos_(token_pos), | 743 token_pos_(token_pos), |
738 functions_(zone, 4), | 744 functions_(zone, 4), |
739 fields_(zone, 4) { | 745 fields_(zone, 4) { |
740 } | 746 } |
741 | 747 |
742 void AddFunction(const Function& function) { | 748 void AddFunction(const Function& function) { |
743 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 749 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
(...skipping 22 matching lines...) Expand all Loading... |
766 bool has_constructor() const { | 772 bool has_constructor() const { |
767 for (int i = 0; i < functions_.length(); i++) { | 773 for (int i = 0; i < functions_.length(); i++) { |
768 const Function* func = functions_.At(i); | 774 const Function* func = functions_.At(i); |
769 if (func->kind() == RawFunction::kConstructor) { | 775 if (func->kind() == RawFunction::kConstructor) { |
770 return true; | 776 return true; |
771 } | 777 } |
772 } | 778 } |
773 return false; | 779 return false; |
774 } | 780 } |
775 | 781 |
776 intptr_t token_pos() const { | 782 TokenPosition token_pos() const { |
777 return token_pos_; | 783 return token_pos_; |
778 } | 784 } |
779 | 785 |
780 void AddMember(const MemberDesc& member) { | 786 void AddMember(const MemberDesc& member) { |
781 members_.Add(member); | 787 members_.Add(member); |
782 } | 788 } |
783 | 789 |
784 const GrowableArray<MemberDesc>& members() const { | 790 const GrowableArray<MemberDesc>& members() const { |
785 return members_; | 791 return members_; |
786 } | 792 } |
(...skipping 13 matching lines...) Expand all Loading... |
800 for (intptr_t i = 0; i < len; i++) { | 806 for (intptr_t i = 0; i < len; i++) { |
801 res.SetAt(i, *functions_[i]); | 807 res.SetAt(i, *functions_[i]); |
802 } | 808 } |
803 return res.raw(); | 809 return res.raw(); |
804 } | 810 } |
805 | 811 |
806 private: | 812 private: |
807 Zone* zone_; | 813 Zone* zone_; |
808 const Class& clazz_; | 814 const Class& clazz_; |
809 const String& class_name_; | 815 const String& class_name_; |
810 intptr_t token_pos_; // Token index of "class" keyword. | 816 TokenPosition token_pos_; // Token index of "class" keyword. |
811 GrowableArray<const Function*> functions_; | 817 GrowableArray<const Function*> functions_; |
812 GrowableArray<const Field*> fields_; | 818 GrowableArray<const Field*> fields_; |
813 GrowableArray<MemberDesc> members_; | 819 GrowableArray<MemberDesc> members_; |
814 }; | 820 }; |
815 | 821 |
816 | 822 |
817 class TopLevel : public ValueObject { | 823 class TopLevel : public ValueObject { |
818 public: | 824 public: |
819 explicit TopLevel(Zone* zone) : | 825 explicit TopLevel(Zone* zone) : |
820 zone_(zone), | 826 zone_(zone), |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 | 1068 |
1063 | 1069 |
1064 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 1070 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
1065 LongJumpScope jump; | 1071 LongJumpScope jump; |
1066 if (setjmp(*jump.Set()) == 0) { | 1072 if (setjmp(*jump.Set()) == 0) { |
1067 Thread* thread = Thread::Current(); | 1073 Thread* thread = Thread::Current(); |
1068 StackZone stack_zone(thread); | 1074 StackZone stack_zone(thread); |
1069 Zone* zone = stack_zone.GetZone(); | 1075 Zone* zone = stack_zone.GetZone(); |
1070 const Class& owner_class = Class::Handle(zone, meta_data.owner()); | 1076 const Class& owner_class = Class::Handle(zone, meta_data.owner()); |
1071 const Script& script = Script::Handle(zone, meta_data.script()); | 1077 const Script& script = Script::Handle(zone, meta_data.script()); |
1072 const intptr_t token_pos = meta_data.token_pos(); | 1078 const TokenPosition token_pos = meta_data.token_pos(); |
1073 // Parsing metadata can involve following paths in the parser that are | 1079 // Parsing metadata can involve following paths in the parser that are |
1074 // normally used for expressions and assume current_function is non-null, | 1080 // normally used for expressions and assume current_function is non-null, |
1075 // so we create a fake function to use as the current_function rather than | 1081 // so we create a fake function to use as the current_function rather than |
1076 // scattering special cases throughout the parser. | 1082 // scattering special cases throughout the parser. |
1077 const Function& fake_function = Function::ZoneHandle(zone, Function::New( | 1083 const Function& fake_function = Function::ZoneHandle(zone, Function::New( |
1078 Symbols::At(), | 1084 Symbols::At(), |
1079 RawFunction::kRegularFunction, | 1085 RawFunction::kRegularFunction, |
1080 true, // is_static | 1086 true, // is_static |
1081 false, // is_const | 1087 false, // is_const |
1082 false, // is_abstract | 1088 false, // is_abstract |
(...skipping 24 matching lines...) Expand all Loading... |
1107 return Object::null(); | 1113 return Object::null(); |
1108 } | 1114 } |
1109 | 1115 |
1110 | 1116 |
1111 RawArray* Parser::EvaluateMetadata() { | 1117 RawArray* Parser::EvaluateMetadata() { |
1112 CheckToken(Token::kAT, "Metadata character '@' expected"); | 1118 CheckToken(Token::kAT, "Metadata character '@' expected"); |
1113 GrowableObjectArray& meta_values = | 1119 GrowableObjectArray& meta_values = |
1114 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 1120 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
1115 while (CurrentToken() == Token::kAT) { | 1121 while (CurrentToken() == Token::kAT) { |
1116 ConsumeToken(); | 1122 ConsumeToken(); |
1117 intptr_t expr_pos = TokenPos(); | 1123 TokenPosition expr_pos = TokenPos(); |
1118 if (!IsIdentifier()) { | 1124 if (!IsIdentifier()) { |
1119 ExpectIdentifier("identifier expected"); | 1125 ExpectIdentifier("identifier expected"); |
1120 } | 1126 } |
1121 // Reject expressions with deferred library prefix eagerly. | 1127 // Reject expressions with deferred library prefix eagerly. |
1122 Object& obj = | 1128 Object& obj = |
1123 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); | 1129 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); |
1124 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 1130 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
1125 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 1131 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
1126 ReportError("Metadata must be compile-time constant"); | 1132 ReportError("Metadata must be compile-time constant"); |
1127 } | 1133 } |
(...skipping 23 matching lines...) Expand all Loading... |
1151 } | 1157 } |
1152 } | 1158 } |
1153 if (CurrentToken() == Token::kPERIOD) { | 1159 if (CurrentToken() == Token::kPERIOD) { |
1154 // C.x or L.C.X. | 1160 // C.x or L.C.X. |
1155 if (cls.IsNull()) { | 1161 if (cls.IsNull()) { |
1156 ReportError(expr_pos, | 1162 ReportError(expr_pos, |
1157 "Metadata expressions must refer to a const field " | 1163 "Metadata expressions must refer to a const field " |
1158 "or constructor"); | 1164 "or constructor"); |
1159 } | 1165 } |
1160 ConsumeToken(); | 1166 ConsumeToken(); |
1161 const intptr_t ident_pos = TokenPos(); | 1167 const TokenPosition ident_pos = TokenPos(); |
1162 String* ident = ExpectIdentifier("identifier expected"); | 1168 String* ident = ExpectIdentifier("identifier expected"); |
1163 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); | 1169 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); |
1164 if (field.IsNull()) { | 1170 if (field.IsNull()) { |
1165 ReportError(ident_pos, | 1171 ReportError(ident_pos, |
1166 "Class '%s' has no field '%s'", | 1172 "Class '%s' has no field '%s'", |
1167 cls.ToCString(), | 1173 cls.ToCString(), |
1168 ident->ToCString()); | 1174 ident->ToCString()); |
1169 } | 1175 } |
1170 if (!field.is_const()) { | 1176 if (!field.is_const()) { |
1171 ReportError(ident_pos, | 1177 ReportError(ident_pos, |
(...skipping 12 matching lines...) Expand all Loading... |
1184 } | 1190 } |
1185 return Array::MakeArray(meta_values); | 1191 return Array::MakeArray(meta_values); |
1186 } | 1192 } |
1187 | 1193 |
1188 | 1194 |
1189 SequenceNode* Parser::ParseStaticInitializer() { | 1195 SequenceNode* Parser::ParseStaticInitializer() { |
1190 ExpectIdentifier("field name expected"); | 1196 ExpectIdentifier("field name expected"); |
1191 CheckToken(Token::kASSIGN, "field initialier expected"); | 1197 CheckToken(Token::kASSIGN, "field initialier expected"); |
1192 ConsumeToken(); | 1198 ConsumeToken(); |
1193 OpenFunctionBlock(parsed_function()->function()); | 1199 OpenFunctionBlock(parsed_function()->function()); |
1194 intptr_t expr_pos = TokenPos(); | 1200 TokenPosition expr_pos = TokenPos(); |
1195 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1201 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1196 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); | 1202 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); |
1197 current_block_->statements->Add(ret); | 1203 current_block_->statements->Add(ret); |
1198 return CloseBlock(); | 1204 return CloseBlock(); |
1199 } | 1205 } |
1200 | 1206 |
1201 | 1207 |
1202 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1208 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
1203 ASSERT(field.is_static()); | 1209 ASSERT(field.is_static()); |
1204 Thread* thread = Thread::Current(); | 1210 Thread* thread = Thread::Current(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 TRACE_PARSER("ParseStaticFinalGetter"); | 1264 TRACE_PARSER("ParseStaticFinalGetter"); |
1259 ParamList params; | 1265 ParamList params; |
1260 ASSERT(func.num_fixed_parameters() == 0); // static. | 1266 ASSERT(func.num_fixed_parameters() == 0); // static. |
1261 ASSERT(!func.HasOptionalParameters()); | 1267 ASSERT(!func.HasOptionalParameters()); |
1262 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1268 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
1263 | 1269 |
1264 // Build local scope for function and populate with the formal parameters. | 1270 // Build local scope for function and populate with the formal parameters. |
1265 OpenFunctionBlock(func); | 1271 OpenFunctionBlock(func); |
1266 AddFormalParamsToScope(¶ms, current_block_->scope); | 1272 AddFormalParamsToScope(¶ms, current_block_->scope); |
1267 | 1273 |
1268 intptr_t ident_pos = TokenPos(); | 1274 TokenPosition ident_pos = TokenPos(); |
1269 const String& field_name = *ExpectIdentifier("field name expected"); | 1275 const String& field_name = *ExpectIdentifier("field name expected"); |
1270 const Class& field_class = Class::Handle(Z, func.Owner()); | 1276 const Class& field_class = Class::Handle(Z, func.Owner()); |
1271 const Field& field = | 1277 const Field& field = |
1272 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); | 1278 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); |
1273 ASSERT(!field.IsNull()); | 1279 ASSERT(!field.IsNull()); |
1274 | 1280 |
1275 // Static final fields must have an initializer. | 1281 // Static final fields must have an initializer. |
1276 ExpectToken(Token::kASSIGN); | 1282 ExpectToken(Token::kASSIGN); |
1277 | 1283 |
1278 const intptr_t expr_pos = TokenPos(); | 1284 const TokenPosition expr_pos = TokenPos(); |
1279 if (field.is_const()) { | 1285 if (field.is_const()) { |
1280 // We don't want to use ParseConstExpr() here because we don't want | 1286 // We don't want to use ParseConstExpr() here because we don't want |
1281 // the constant folding code to create, compile and execute a code | 1287 // the constant folding code to create, compile and execute a code |
1282 // fragment to evaluate the expression. Instead, we just make sure | 1288 // fragment to evaluate the expression. Instead, we just make sure |
1283 // the static const field initializer is a constant expression and | 1289 // the static const field initializer is a constant expression and |
1284 // leave the evaluation to the getter function. | 1290 // leave the evaluation to the getter function. |
1285 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1291 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1286 // This getter will only be called once at compile time. | 1292 // This getter will only be called once at compile time. |
1287 if (expr->EvalConstExpr() == NULL) { | 1293 if (expr->EvalConstExpr() == NULL) { |
1288 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1294 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
(...skipping 17 matching lines...) Expand all Loading... |
1306 | 1312 |
1307 | 1313 |
1308 // Create AstNodes for an implicit instance getter method: | 1314 // Create AstNodes for an implicit instance getter method: |
1309 // LoadLocalNode 0 ('this'); | 1315 // LoadLocalNode 0 ('this'); |
1310 // LoadInstanceFieldNode (field_name); | 1316 // LoadInstanceFieldNode (field_name); |
1311 // ReturnNode (field's value); | 1317 // ReturnNode (field's value); |
1312 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1318 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
1313 TRACE_PARSER("ParseInstanceGetter"); | 1319 TRACE_PARSER("ParseInstanceGetter"); |
1314 ParamList params; | 1320 ParamList params; |
1315 // func.token_pos() points to the name of the field. | 1321 // func.token_pos() points to the name of the field. |
1316 const intptr_t ident_pos = func.token_pos(); | 1322 const TokenPosition ident_pos = func.token_pos(); |
1317 ASSERT(current_class().raw() == func.Owner()); | 1323 ASSERT(current_class().raw() == func.Owner()); |
1318 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1324 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1319 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 1325 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
1320 ASSERT(!func.HasOptionalParameters()); | 1326 ASSERT(!func.HasOptionalParameters()); |
1321 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1327 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
1322 | 1328 |
1323 // Build local scope for function and populate with the formal parameters. | 1329 // Build local scope for function and populate with the formal parameters. |
1324 OpenFunctionBlock(func); | 1330 OpenFunctionBlock(func); |
1325 AddFormalParamsToScope(¶ms, current_block_->scope); | 1331 AddFormalParamsToScope(¶ms, current_block_->scope); |
1326 | 1332 |
(...skipping 18 matching lines...) Expand all Loading... |
1345 | 1351 |
1346 | 1352 |
1347 // Create AstNodes for an implicit instance setter method: | 1353 // Create AstNodes for an implicit instance setter method: |
1348 // LoadLocalNode 0 ('this') | 1354 // LoadLocalNode 0 ('this') |
1349 // LoadLocalNode 1 ('value') | 1355 // LoadLocalNode 1 ('value') |
1350 // SetInstanceField (field_name); | 1356 // SetInstanceField (field_name); |
1351 // ReturnNode (void); | 1357 // ReturnNode (void); |
1352 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1358 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
1353 TRACE_PARSER("ParseInstanceSetter"); | 1359 TRACE_PARSER("ParseInstanceSetter"); |
1354 // func.token_pos() points to the name of the field. | 1360 // func.token_pos() points to the name of the field. |
1355 const intptr_t ident_pos = func.token_pos(); | 1361 const TokenPosition ident_pos = func.token_pos(); |
1356 const String& field_name = *CurrentLiteral(); | 1362 const String& field_name = *CurrentLiteral(); |
1357 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); | 1363 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); |
1358 const Field& field = | 1364 const Field& field = |
1359 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1365 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
1360 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1366 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
1361 | 1367 |
1362 ParamList params; | 1368 ParamList params; |
1363 ASSERT(current_class().raw() == func.Owner()); | 1369 ASSERT(current_class().raw() == func.Owner()); |
1364 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1370 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1365 params.AddFinalParameter(ident_pos, | 1371 params.AddFinalParameter(ident_pos, |
(...skipping 16 matching lines...) Expand all Loading... |
1382 StoreInstanceFieldNode* store_field = | 1388 StoreInstanceFieldNode* store_field = |
1383 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1389 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
1384 current_block_->statements->Add(store_field); | 1390 current_block_->statements->Add(store_field); |
1385 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); | 1391 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); |
1386 return CloseBlock(); | 1392 return CloseBlock(); |
1387 } | 1393 } |
1388 | 1394 |
1389 | 1395 |
1390 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1396 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
1391 TRACE_PARSER("ParseConstructorClosure"); | 1397 TRACE_PARSER("ParseConstructorClosure"); |
1392 const intptr_t token_pos = func.token_pos(); | 1398 const TokenPosition token_pos = func.token_pos(); |
1393 | 1399 |
1394 Function& constructor = Function::ZoneHandle(Z); | 1400 Function& constructor = Function::ZoneHandle(Z); |
1395 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1401 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
1396 ParseConstructorClosurization(&constructor, &type_args); | 1402 ParseConstructorClosurization(&constructor, &type_args); |
1397 ASSERT(!constructor.IsNull()); | 1403 ASSERT(!constructor.IsNull()); |
1398 | 1404 |
1399 ParamList params; | 1405 ParamList params; |
1400 // The first parameter of the closure function is the | 1406 // The first parameter of the closure function is the |
1401 // implicit closure argument. | 1407 // implicit closure argument. |
1402 params.AddFinalParameter(token_pos, | 1408 params.AddFinalParameter(token_pos, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1436 AstNode* new_object = | 1442 AstNode* new_object = |
1437 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); | 1443 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); |
1438 ReturnNode* return_node = new ReturnNode(token_pos, new_object); | 1444 ReturnNode* return_node = new ReturnNode(token_pos, new_object); |
1439 current_block_->statements->Add(return_node); | 1445 current_block_->statements->Add(return_node); |
1440 return CloseBlock(); | 1446 return CloseBlock(); |
1441 } | 1447 } |
1442 | 1448 |
1443 | 1449 |
1444 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { | 1450 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { |
1445 TRACE_PARSER("ParseImplicitClosure"); | 1451 TRACE_PARSER("ParseImplicitClosure"); |
1446 intptr_t token_pos = func.token_pos(); | 1452 TokenPosition token_pos = func.token_pos(); |
1447 | 1453 |
1448 OpenFunctionBlock(func); | 1454 OpenFunctionBlock(func); |
1449 | 1455 |
1450 ParamList params; | 1456 ParamList params; |
1451 params.AddFinalParameter( | 1457 params.AddFinalParameter( |
1452 token_pos, | 1458 token_pos, |
1453 &Symbols::ClosureParameter(), | 1459 &Symbols::ClosureParameter(), |
1454 &Object::dynamic_type()); | 1460 &Object::dynamic_type()); |
1455 | 1461 |
1456 const Function& parent = Function::ZoneHandle(func.parent_function()); | 1462 const Function& parent = Function::ZoneHandle(func.parent_function()); |
1457 if (parent.IsImplicitSetterFunction()) { | 1463 if (parent.IsImplicitSetterFunction()) { |
1458 const intptr_t ident_pos = func.token_pos(); | 1464 const TokenPosition ident_pos = func.token_pos(); |
1459 ASSERT(IsIdentifier()); | 1465 ASSERT(IsIdentifier()); |
1460 const String& field_name = *CurrentLiteral(); | 1466 const String& field_name = *CurrentLiteral(); |
1461 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); | 1467 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); |
1462 const Field& field = | 1468 const Field& field = |
1463 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1469 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
1464 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1470 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
1465 params.AddFinalParameter(ident_pos, | 1471 params.AddFinalParameter(ident_pos, |
1466 &Symbols::Value(), | 1472 &Symbols::Value(), |
1467 &field_type); | 1473 &field_type); |
1468 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | 1474 ASSERT(func.num_fixed_parameters() == 2); // closure, value. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 current_block_->statements->Add(return_node); | 1508 current_block_->statements->Add(return_node); |
1503 return CloseBlock(); | 1509 return CloseBlock(); |
1504 } | 1510 } |
1505 | 1511 |
1506 | 1512 |
1507 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1513 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
1508 TRACE_PARSER("ParseMethodExtractor"); | 1514 TRACE_PARSER("ParseMethodExtractor"); |
1509 | 1515 |
1510 ParamList params; | 1516 ParamList params; |
1511 | 1517 |
1512 const intptr_t ident_pos = func.token_pos(); | 1518 const TokenPosition ident_pos = func.token_pos(); |
1513 ASSERT(func.token_pos() == ClassifyingTokenPositions::kMethodExtractor); | 1519 ASSERT(func.token_pos() == TokenPosition::kMethodExtractor); |
1514 ASSERT(current_class().raw() == func.Owner()); | 1520 ASSERT(current_class().raw() == func.Owner()); |
1515 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1521 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1516 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1522 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
1517 ASSERT(!func.HasOptionalParameters()); | 1523 ASSERT(!func.HasOptionalParameters()); |
1518 | 1524 |
1519 // Build local scope for function and populate with the formal parameters. | 1525 // Build local scope for function and populate with the formal parameters. |
1520 OpenFunctionBlock(func); | 1526 OpenFunctionBlock(func); |
1521 AddFormalParamsToScope(¶ms, current_block_->scope); | 1527 AddFormalParamsToScope(¶ms, current_block_->scope); |
1522 | 1528 |
1523 // Receiver is local 0. | 1529 // Receiver is local 0. |
1524 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1530 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1525 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1531 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
1526 | 1532 |
1527 ClosureNode* closure = new ClosureNode( | 1533 ClosureNode* closure = new ClosureNode( |
1528 ident_pos, | 1534 ident_pos, |
1529 Function::ZoneHandle(Z, func.extracted_method_closure()), | 1535 Function::ZoneHandle(Z, func.extracted_method_closure()), |
1530 load_receiver, | 1536 load_receiver, |
1531 NULL); | 1537 NULL); |
1532 | 1538 |
1533 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1539 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
1534 current_block_->statements->Add(return_node); | 1540 current_block_->statements->Add(return_node); |
1535 return CloseBlock(); | 1541 return CloseBlock(); |
1536 } | 1542 } |
1537 | 1543 |
1538 | 1544 |
1539 void Parser::BuildDispatcherScope(const Function& func, | 1545 void Parser::BuildDispatcherScope(const Function& func, |
1540 const ArgumentsDescriptor& desc) { | 1546 const ArgumentsDescriptor& desc) { |
1541 ParamList params; | 1547 ParamList params; |
1542 // Receiver first. | 1548 // Receiver first. |
1543 intptr_t token_pos = func.token_pos(); | 1549 TokenPosition token_pos = func.token_pos(); |
1544 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1550 params.AddReceiver(ReceiverType(current_class()), token_pos); |
1545 // Remaining positional parameters. | 1551 // Remaining positional parameters. |
1546 intptr_t i = 1; | 1552 intptr_t i = 1; |
1547 for (; i < desc.PositionalCount(); ++i) { | 1553 for (; i < desc.PositionalCount(); ++i) { |
1548 ParamDesc p; | 1554 ParamDesc p; |
1549 char name[64]; | 1555 char name[64]; |
1550 OS::SNPrint(name, 64, ":p%" Pd, i); | 1556 OS::SNPrint(name, 64, ":p%" Pd, i); |
1551 p.name = &String::ZoneHandle(Z, Symbols::New(name)); | 1557 p.name = &String::ZoneHandle(Z, Symbols::New(name)); |
1552 p.type = &Object::dynamic_type(); | 1558 p.type = &Object::dynamic_type(); |
1553 params.parameters->Add(p); | 1559 params.parameters->Add(p); |
(...skipping 19 matching lines...) Expand all Loading... |
1573 // Build local scope for function and populate with the formal parameters. | 1579 // Build local scope for function and populate with the formal parameters. |
1574 OpenFunctionBlock(func); | 1580 OpenFunctionBlock(func); |
1575 AddFormalParamsToScope(¶ms, current_block_->scope); | 1581 AddFormalParamsToScope(¶ms, current_block_->scope); |
1576 } | 1582 } |
1577 | 1583 |
1578 | 1584 |
1579 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { | 1585 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { |
1580 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1586 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
1581 ASSERT(FLAG_lazy_dispatchers); | 1587 ASSERT(FLAG_lazy_dispatchers); |
1582 ASSERT(func.IsNoSuchMethodDispatcher()); | 1588 ASSERT(func.IsNoSuchMethodDispatcher()); |
1583 intptr_t token_pos = func.token_pos(); | 1589 TokenPosition token_pos = func.token_pos(); |
1584 ASSERT(func.token_pos() == 0); | 1590 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
1585 ASSERT(current_class().raw() == func.Owner()); | 1591 ASSERT(current_class().raw() == func.Owner()); |
1586 | 1592 |
1587 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); | 1593 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); |
1588 ASSERT(desc.Count() > 0); | 1594 ASSERT(desc.Count() > 0); |
1589 | 1595 |
1590 // Set up scope for this function. | 1596 // Set up scope for this function. |
1591 BuildDispatcherScope(func, desc); | 1597 BuildDispatcherScope(func, desc); |
1592 | 1598 |
1593 // Receiver is local 0. | 1599 // Receiver is local 0. |
1594 LocalScope* scope = current_block_->scope; | 1600 LocalScope* scope = current_block_->scope; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 | 1634 |
1629 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1635 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1630 current_block_->statements->Add(return_node); | 1636 current_block_->statements->Add(return_node); |
1631 return CloseBlock(); | 1637 return CloseBlock(); |
1632 } | 1638 } |
1633 | 1639 |
1634 | 1640 |
1635 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { | 1641 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
1636 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1642 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
1637 ASSERT(func.IsInvokeFieldDispatcher()); | 1643 ASSERT(func.IsInvokeFieldDispatcher()); |
1638 intptr_t token_pos = func.token_pos(); | 1644 TokenPosition token_pos = func.token_pos(); |
1639 ASSERT(func.token_pos() == 0); | 1645 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
1640 ASSERT(current_class().raw() == func.Owner()); | 1646 ASSERT(current_class().raw() == func.Owner()); |
1641 | 1647 |
1642 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); | 1648 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
1643 ArgumentsDescriptor desc(args_desc); | 1649 ArgumentsDescriptor desc(args_desc); |
1644 ASSERT(desc.Count() > 0); | 1650 ASSERT(desc.Count() > 0); |
1645 | 1651 |
1646 // Set up scope for this function. | 1652 // Set up scope for this function. |
1647 BuildDispatcherScope(func, desc); | 1653 BuildDispatcherScope(func, desc); |
1648 | 1654 |
1649 // Receiver is local 0. | 1655 // Receiver is local 0. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 } else { | 1696 } else { |
1691 result = BuildClosureCall(token_pos, function_object, args); | 1697 result = BuildClosureCall(token_pos, function_object, args); |
1692 } | 1698 } |
1693 | 1699 |
1694 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1700 ReturnNode* return_node = new ReturnNode(token_pos, result); |
1695 current_block_->statements->Add(return_node); | 1701 current_block_->statements->Add(return_node); |
1696 return CloseBlock(); | 1702 return CloseBlock(); |
1697 } | 1703 } |
1698 | 1704 |
1699 | 1705 |
1700 AstNode* Parser::BuildClosureCall(intptr_t token_pos, | 1706 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, |
1701 AstNode* closure, | 1707 AstNode* closure, |
1702 ArgumentListNode* arguments) { | 1708 ArgumentListNode* arguments) { |
1703 return new InstanceCallNode(token_pos, | 1709 return new InstanceCallNode(token_pos, |
1704 closure, | 1710 closure, |
1705 Symbols::Call(), | 1711 Symbols::Call(), |
1706 arguments); | 1712 arguments); |
1707 } | 1713 } |
1708 | 1714 |
1709 | 1715 |
1710 void Parser::SkipToMatching() { | 1716 void Parser::SkipToMatching() { |
1711 Token::Kind opening_token = CurrentToken(); | 1717 Token::Kind opening_token = CurrentToken(); |
1712 ASSERT((opening_token == Token::kLBRACE) || | 1718 ASSERT((opening_token == Token::kLBRACE) || |
1713 (opening_token == Token::kLPAREN)); | 1719 (opening_token == Token::kLPAREN)); |
1714 GrowableArray<Token::Kind> token_stack(8); | 1720 GrowableArray<Token::Kind> token_stack(8); |
1715 GrowableArray<intptr_t> token_pos_stack(8); | 1721 GrowableArray<TokenPosition> token_pos_stack(8); |
1716 // Adding the first opening brace here, because it will be consumed | 1722 // Adding the first opening brace here, because it will be consumed |
1717 // in the loop right away. | 1723 // in the loop right away. |
1718 token_stack.Add(opening_token); | 1724 token_stack.Add(opening_token); |
1719 const intptr_t start_pos = TokenPos(); | 1725 const TokenPosition start_pos = TokenPos(); |
1720 intptr_t opening_pos = start_pos; | 1726 TokenPosition opening_pos = start_pos; |
1721 token_pos_stack.Add(start_pos); | 1727 token_pos_stack.Add(start_pos); |
1722 bool is_match = true; | 1728 bool is_match = true; |
1723 bool unexpected_token_found = false; | 1729 bool unexpected_token_found = false; |
1724 Token::Kind token = opening_token; | 1730 Token::Kind token = opening_token; |
1725 intptr_t token_pos; | 1731 TokenPosition token_pos; |
1726 do { | 1732 do { |
1727 ConsumeToken(); | 1733 ConsumeToken(); |
1728 token = CurrentToken(); | 1734 token = CurrentToken(); |
1729 token_pos = TokenPos(); | 1735 token_pos = TokenPos(); |
1730 switch (token) { | 1736 switch (token) { |
1731 case Token::kLBRACE: | 1737 case Token::kLBRACE: |
1732 case Token::kLPAREN: | 1738 case Token::kLPAREN: |
1733 case Token::kLBRACK: | 1739 case Token::kLBRACK: |
1734 token_stack.Add(token); | 1740 token_stack.Add(token); |
1735 token_pos_stack.Add(token_pos); | 1741 token_pos_stack.Add(token_pos); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1906 const bool no_explicit_default_values = false; | 1912 const bool no_explicit_default_values = false; |
1907 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 1913 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
1908 | 1914 |
1909 // In top-level and mixin functions, the source may be in a different | 1915 // In top-level and mixin functions, the source may be in a different |
1910 // script than the script of the current class. However, we never reparse | 1916 // script than the script of the current class. However, we never reparse |
1911 // signature functions (except typedef signature functions), therefore | 1917 // signature functions (except typedef signature functions), therefore |
1912 // we do not need to keep the correct script via a patch class. Use the | 1918 // we do not need to keep the correct script via a patch class. Use the |
1913 // actual current class as owner of the signature function. | 1919 // actual current class as owner of the signature function. |
1914 const Function& signature_function = Function::Handle(Z, | 1920 const Function& signature_function = Function::Handle(Z, |
1915 Function::NewSignatureFunction(current_class(), | 1921 Function::NewSignatureFunction(current_class(), |
1916 Token::kNoSourcePos)); | 1922 TokenPosition::kNoSource)); |
1917 signature_function.set_result_type(result_type); | 1923 signature_function.set_result_type(result_type); |
1918 AddFormalParamsToFunction(&func_params, signature_function); | 1924 AddFormalParamsToFunction(&func_params, signature_function); |
1919 FunctionType& signature_type = | 1925 FunctionType& signature_type = |
1920 FunctionType::ZoneHandle(Z, signature_function.SignatureType()); | 1926 FunctionType::ZoneHandle(Z, signature_function.SignatureType()); |
1921 if (!is_top_level_) { | 1927 if (!is_top_level_) { |
1922 signature_type ^= ClassFinalizer::FinalizeType( | 1928 signature_type ^= ClassFinalizer::FinalizeType( |
1923 current_class(), signature_type, ClassFinalizer::kCanonicalize); | 1929 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
1924 signature_function.SetSignatureType(signature_type); | 1930 signature_function.SetSignatureType(signature_type); |
1925 } | 1931 } |
1926 ASSERT(is_top_level_ || signature_type.IsFinalized()); | 1932 ASSERT(is_top_level_ || signature_type.IsFinalized()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2047 String& native_name = *CurrentLiteral(); | 2053 String& native_name = *CurrentLiteral(); |
2048 ConsumeToken(); | 2054 ConsumeToken(); |
2049 return native_name; | 2055 return native_name; |
2050 } | 2056 } |
2051 | 2057 |
2052 | 2058 |
2053 // Resolve and return the dynamic function of the given name in the superclass. | 2059 // Resolve and return the dynamic function of the given name in the superclass. |
2054 // If it is not found, and resolve_getter is true, try to resolve a getter of | 2060 // If it is not found, and resolve_getter is true, try to resolve a getter of |
2055 // the same name. If it is still not found, return noSuchMethod and | 2061 // the same name. If it is still not found, return noSuchMethod and |
2056 // set is_no_such_method to true.. | 2062 // set is_no_such_method to true.. |
2057 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 2063 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, |
2058 const String& name, | 2064 const String& name, |
2059 ArgumentListNode* arguments, | 2065 ArgumentListNode* arguments, |
2060 bool resolve_getter, | 2066 bool resolve_getter, |
2061 bool* is_no_such_method) { | 2067 bool* is_no_such_method) { |
2062 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); | 2068 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
2063 if (super_class.IsNull()) { | 2069 if (super_class.IsNull()) { |
2064 ReportError(token_pos, "class '%s' does not have a superclass", | 2070 ReportError(token_pos, "class '%s' does not have a superclass", |
2065 String::Handle(Z, current_class().Name()).ToCString()); | 2071 String::Handle(Z, current_class().Name()).ToCString()); |
2066 } | 2072 } |
2067 Function& super_func = Function::Handle(Z, | 2073 Function& super_func = Function::Handle(Z, |
(...skipping 15 matching lines...) Expand all Loading... |
2083 ASSERT(!super_func.IsNull()); | 2089 ASSERT(!super_func.IsNull()); |
2084 *is_no_such_method = true; | 2090 *is_no_such_method = true; |
2085 } else { | 2091 } else { |
2086 *is_no_such_method = false; | 2092 *is_no_such_method = false; |
2087 } | 2093 } |
2088 return super_func.raw(); | 2094 return super_func.raw(); |
2089 } | 2095 } |
2090 | 2096 |
2091 | 2097 |
2092 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 2098 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
2093 intptr_t call_pos, | 2099 TokenPosition call_pos, |
2094 const String& function_name, | 2100 const String& function_name, |
2095 const ArgumentListNode& function_args, | 2101 const ArgumentListNode& function_args, |
2096 const LocalVariable* temp_for_last_arg, | 2102 const LocalVariable* temp_for_last_arg, |
2097 bool is_super_invocation) { | 2103 bool is_super_invocation) { |
2098 const intptr_t args_pos = function_args.token_pos(); | 2104 const TokenPosition args_pos = function_args.token_pos(); |
2099 // Build arguments to the call to the static | 2105 // Build arguments to the call to the static |
2100 // InvocationMirror._allocateInvocationMirror method. | 2106 // InvocationMirror._allocateInvocationMirror method. |
2101 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2107 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2102 // The first argument is the original function name. | 2108 // The first argument is the original function name. |
2103 arguments->Add(new LiteralNode(args_pos, function_name)); | 2109 arguments->Add(new LiteralNode(args_pos, function_name)); |
2104 // The second argument is the arguments descriptor of the original function. | 2110 // The second argument is the arguments descriptor of the original function. |
2105 const Array& args_descriptor = | 2111 const Array& args_descriptor = |
2106 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 2112 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), |
2107 function_args.names())); | 2113 function_args.names())); |
2108 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 2114 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
(...skipping 23 matching lines...) Expand all Loading... |
2132 ASSERT(!mirror_class.IsNull()); | 2138 ASSERT(!mirror_class.IsNull()); |
2133 const Function& allocation_function = Function::ZoneHandle( | 2139 const Function& allocation_function = Function::ZoneHandle( |
2134 mirror_class.LookupStaticFunction( | 2140 mirror_class.LookupStaticFunction( |
2135 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 2141 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
2136 ASSERT(!allocation_function.IsNull()); | 2142 ASSERT(!allocation_function.IsNull()); |
2137 return new StaticCallNode(call_pos, allocation_function, arguments); | 2143 return new StaticCallNode(call_pos, allocation_function, arguments); |
2138 } | 2144 } |
2139 | 2145 |
2140 | 2146 |
2141 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 2147 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
2142 intptr_t call_pos, | 2148 TokenPosition call_pos, |
2143 const String& function_name, | 2149 const String& function_name, |
2144 const ArgumentListNode& function_args, | 2150 const ArgumentListNode& function_args, |
2145 const LocalVariable* temp_for_last_arg, | 2151 const LocalVariable* temp_for_last_arg, |
2146 bool is_super_invocation) { | 2152 bool is_super_invocation) { |
2147 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 2153 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
2148 const intptr_t args_pos = function_args.token_pos(); | 2154 const TokenPosition args_pos = function_args.token_pos(); |
2149 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2155 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2150 arguments->Add(function_args.NodeAt(0)); | 2156 arguments->Add(function_args.NodeAt(0)); |
2151 // The second argument is the invocation mirror. | 2157 // The second argument is the invocation mirror. |
2152 arguments->Add(BuildInvocationMirrorAllocation(call_pos, | 2158 arguments->Add(BuildInvocationMirrorAllocation(call_pos, |
2153 function_name, | 2159 function_name, |
2154 function_args, | 2160 function_args, |
2155 temp_for_last_arg, | 2161 temp_for_last_arg, |
2156 is_super_invocation)); | 2162 is_super_invocation)); |
2157 return arguments; | 2163 return arguments; |
2158 } | 2164 } |
2159 | 2165 |
2160 | 2166 |
2161 AstNode* Parser::ParseSuperCall(const String& function_name) { | 2167 AstNode* Parser::ParseSuperCall(const String& function_name) { |
2162 TRACE_PARSER("ParseSuperCall"); | 2168 TRACE_PARSER("ParseSuperCall"); |
2163 ASSERT(CurrentToken() == Token::kLPAREN); | 2169 ASSERT(CurrentToken() == Token::kLPAREN); |
2164 const intptr_t supercall_pos = TokenPos(); | 2170 const TokenPosition supercall_pos = TokenPos(); |
2165 | 2171 |
2166 // 'this' parameter is the first argument to super call. | 2172 // 'this' parameter is the first argument to super call. |
2167 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2173 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
2168 AstNode* receiver = LoadReceiver(supercall_pos); | 2174 AstNode* receiver = LoadReceiver(supercall_pos); |
2169 arguments->Add(receiver); | 2175 arguments->Add(receiver); |
2170 ParseActualParameters(arguments, kAllowConst); | 2176 ParseActualParameters(arguments, kAllowConst); |
2171 | 2177 |
2172 const bool kResolveGetter = true; | 2178 const bool kResolveGetter = true; |
2173 bool is_no_such_method = false; | 2179 bool is_no_such_method = false; |
2174 const Function& super_function = Function::ZoneHandle(Z, | 2180 const Function& super_function = Function::ZoneHandle(Z, |
(...skipping 27 matching lines...) Expand all Loading... |
2202 | 2208 |
2203 // Simple test if a node is side effect free. | 2209 // Simple test if a node is side effect free. |
2204 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 2210 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
2205 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 2211 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
2206 } | 2212 } |
2207 | 2213 |
2208 | 2214 |
2209 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 2215 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
2210 ASSERT(super->IsSuper()); | 2216 ASSERT(super->IsSuper()); |
2211 AstNode* super_op = NULL; | 2217 AstNode* super_op = NULL; |
2212 const intptr_t super_pos = super->token_pos(); | 2218 const TokenPosition super_pos = super->token_pos(); |
2213 if ((op == Token::kNEGATE) || | 2219 if ((op == Token::kNEGATE) || |
2214 (op == Token::kBIT_NOT)) { | 2220 (op == Token::kBIT_NOT)) { |
2215 // Resolve the operator function in the superclass. | 2221 // Resolve the operator function in the superclass. |
2216 const String& operator_function_name = | 2222 const String& operator_function_name = |
2217 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); | 2223 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); |
2218 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 2224 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
2219 AstNode* receiver = LoadReceiver(super_pos); | 2225 AstNode* receiver = LoadReceiver(super_pos); |
2220 op_arguments->Add(receiver); | 2226 op_arguments->Add(receiver); |
2221 const bool kResolveGetter = false; | 2227 const bool kResolveGetter = false; |
2222 bool is_no_such_method = false; | 2228 bool is_no_such_method = false; |
(...skipping 11 matching lines...) Expand all Loading... |
2234 } else { | 2240 } else { |
2235 ReportError(super_pos, "illegal super operator call"); | 2241 ReportError(super_pos, "illegal super operator call"); |
2236 } | 2242 } |
2237 return super_op; | 2243 return super_op; |
2238 } | 2244 } |
2239 | 2245 |
2240 | 2246 |
2241 AstNode* Parser::ParseSuperOperator() { | 2247 AstNode* Parser::ParseSuperOperator() { |
2242 TRACE_PARSER("ParseSuperOperator"); | 2248 TRACE_PARSER("ParseSuperOperator"); |
2243 AstNode* super_op = NULL; | 2249 AstNode* super_op = NULL; |
2244 const intptr_t operator_pos = TokenPos(); | 2250 const TokenPosition operator_pos = TokenPos(); |
2245 | 2251 |
2246 if (CurrentToken() == Token::kLBRACK) { | 2252 if (CurrentToken() == Token::kLBRACK) { |
2247 ConsumeToken(); | 2253 ConsumeToken(); |
2248 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2254 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2249 ExpectToken(Token::kRBRACK); | 2255 ExpectToken(Token::kRBRACK); |
2250 AstNode* receiver = LoadReceiver(operator_pos); | 2256 AstNode* receiver = LoadReceiver(operator_pos); |
2251 const Class& super_class = | 2257 const Class& super_class = |
2252 Class::ZoneHandle(Z, current_class().SuperClass()); | 2258 Class::ZoneHandle(Z, current_class().SuperClass()); |
2253 ASSERT(!super_class.IsNull()); | 2259 ASSERT(!super_class.IsNull()); |
2254 super_op = | 2260 super_op = |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2297 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
2292 if (negate_result) { | 2298 if (negate_result) { |
2293 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2299 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
2294 } | 2300 } |
2295 } | 2301 } |
2296 return super_op; | 2302 return super_op; |
2297 } | 2303 } |
2298 | 2304 |
2299 | 2305 |
2300 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2306 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
2301 intptr_t token_pos, | 2307 TokenPosition token_pos, |
2302 AstNode* receiver) { | 2308 AstNode* receiver) { |
2303 Function& implicit_closure_function = | 2309 Function& implicit_closure_function = |
2304 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); | 2310 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); |
2305 if (receiver != NULL) { | 2311 if (receiver != NULL) { |
2306 // If we create an implicit instance closure from inside a closure of a | 2312 // If we create an implicit instance closure from inside a closure of a |
2307 // parameterized class, make sure that the receiver is captured as | 2313 // parameterized class, make sure that the receiver is captured as |
2308 // instantiator. | 2314 // instantiator. |
2309 if (current_block_->scope->function_level() > 0) { | 2315 if (current_block_->scope->function_level() > 0) { |
2310 const FunctionType& signature_type = FunctionType::Handle(Z, | 2316 const FunctionType& signature_type = FunctionType::Handle(Z, |
2311 implicit_closure_function.SignatureType()); | 2317 implicit_closure_function.SignatureType()); |
2312 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); | 2318 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); |
2313 if (scope_class.IsGeneric()) { | 2319 if (scope_class.IsGeneric()) { |
2314 CaptureInstantiator(); | 2320 CaptureInstantiator(); |
2315 } | 2321 } |
2316 } | 2322 } |
2317 } | 2323 } |
2318 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2324 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
2319 } | 2325 } |
2320 | 2326 |
2321 | 2327 |
2322 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2328 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
2323 intptr_t field_pos) { | 2329 TokenPosition field_pos) { |
2324 TRACE_PARSER("ParseSuperFieldAccess"); | 2330 TRACE_PARSER("ParseSuperFieldAccess"); |
2325 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); | 2331 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); |
2326 if (super_class.IsNull()) { | 2332 if (super_class.IsNull()) { |
2327 ReportError("class '%s' does not have a superclass", | 2333 ReportError("class '%s' does not have a superclass", |
2328 String::Handle(Z, current_class().Name()).ToCString()); | 2334 String::Handle(Z, current_class().Name()).ToCString()); |
2329 } | 2335 } |
2330 AstNode* implicit_argument = LoadReceiver(field_pos); | 2336 AstNode* implicit_argument = LoadReceiver(field_pos); |
2331 | 2337 |
2332 const String& getter_name = | 2338 const String& getter_name = |
2333 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); | 2339 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); |
(...skipping 26 matching lines...) Expand all Loading... |
2360 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2366 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
2361 } | 2367 } |
2362 } | 2368 } |
2363 return new(Z) StaticGetterNode( | 2369 return new(Z) StaticGetterNode( |
2364 field_pos, implicit_argument, super_class, field_name); | 2370 field_pos, implicit_argument, super_class, field_name); |
2365 } | 2371 } |
2366 | 2372 |
2367 | 2373 |
2368 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2374 StaticCallNode* Parser::GenerateSuperConstructorCall( |
2369 const Class& cls, | 2375 const Class& cls, |
2370 intptr_t supercall_pos, | 2376 TokenPosition supercall_pos, |
2371 LocalVariable* receiver, | 2377 LocalVariable* receiver, |
2372 ArgumentListNode* forwarding_args) { | 2378 ArgumentListNode* forwarding_args) { |
2373 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2379 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2374 // Omit the implicit super() if there is no super class (i.e. | 2380 // Omit the implicit super() if there is no super class (i.e. |
2375 // we're not compiling class Object), or if the super class is an | 2381 // we're not compiling class Object), or if the super class is an |
2376 // artificially generated "wrapper class" that has no constructor. | 2382 // artificially generated "wrapper class" that has no constructor. |
2377 if (super_class.IsNull() || | 2383 if (super_class.IsNull() || |
2378 (super_class.num_native_fields() > 0 && | 2384 (super_class.num_native_fields() > 0 && |
2379 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { | 2385 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { |
2380 return NULL; | 2386 return NULL; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2427 error_message.ToCString()); | 2433 error_message.ToCString()); |
2428 } | 2434 } |
2429 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2435 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2430 } | 2436 } |
2431 | 2437 |
2432 | 2438 |
2433 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, | 2439 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, |
2434 LocalVariable* receiver) { | 2440 LocalVariable* receiver) { |
2435 TRACE_PARSER("ParseSuperInitializer"); | 2441 TRACE_PARSER("ParseSuperInitializer"); |
2436 ASSERT(CurrentToken() == Token::kSUPER); | 2442 ASSERT(CurrentToken() == Token::kSUPER); |
2437 const intptr_t supercall_pos = TokenPos(); | 2443 const TokenPosition supercall_pos = TokenPos(); |
2438 ConsumeToken(); | 2444 ConsumeToken(); |
2439 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2445 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2440 ASSERT(!super_class.IsNull()); | 2446 ASSERT(!super_class.IsNull()); |
2441 String& ctor_name = String::Handle(Z, super_class.Name()); | 2447 String& ctor_name = String::Handle(Z, super_class.Name()); |
2442 ctor_name = Symbols::FromConcat(ctor_name, Symbols::Dot()); | 2448 ctor_name = Symbols::FromConcat(ctor_name, Symbols::Dot()); |
2443 if (CurrentToken() == Token::kPERIOD) { | 2449 if (CurrentToken() == Token::kPERIOD) { |
2444 ConsumeToken(); | 2450 ConsumeToken(); |
2445 ctor_name = Symbols::FromConcat( | 2451 ctor_name = Symbols::FromConcat( |
2446 ctor_name, *ExpectIdentifier("constructor name expected")); | 2452 ctor_name, *ExpectIdentifier("constructor name expected")); |
2447 } | 2453 } |
(...skipping 30 matching lines...) Expand all Loading... |
2478 error_message.ToCString()); | 2484 error_message.ToCString()); |
2479 } | 2485 } |
2480 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2486 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2481 } | 2487 } |
2482 | 2488 |
2483 | 2489 |
2484 AstNode* Parser::ParseInitializer(const Class& cls, | 2490 AstNode* Parser::ParseInitializer(const Class& cls, |
2485 LocalVariable* receiver, | 2491 LocalVariable* receiver, |
2486 GrowableArray<Field*>* initialized_fields) { | 2492 GrowableArray<Field*>* initialized_fields) { |
2487 TRACE_PARSER("ParseInitializer"); | 2493 TRACE_PARSER("ParseInitializer"); |
2488 const intptr_t field_pos = TokenPos(); | 2494 const TokenPosition field_pos = TokenPos(); |
2489 if (CurrentToken() == Token::kTHIS) { | 2495 if (CurrentToken() == Token::kTHIS) { |
2490 ConsumeToken(); | 2496 ConsumeToken(); |
2491 ExpectToken(Token::kPERIOD); | 2497 ExpectToken(Token::kPERIOD); |
2492 } | 2498 } |
2493 const String& field_name = *ExpectIdentifier("field name expected"); | 2499 const String& field_name = *ExpectIdentifier("field name expected"); |
2494 ExpectToken(Token::kASSIGN); | 2500 ExpectToken(Token::kASSIGN); |
2495 | 2501 |
2496 const bool saved_mode = SetAllowFunctionLiterals(false); | 2502 const bool saved_mode = SetAllowFunctionLiterals(false); |
2497 // "this" must not be accessible in initializer expressions. | 2503 // "this" must not be accessible in initializer expressions. |
2498 receiver->set_invisible(true); | 2504 receiver->set_invisible(true); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2554 | 2560 |
2555 | 2561 |
2556 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2562 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
2557 // Only use this function if the initialized field originates | 2563 // Only use this function if the initialized field originates |
2558 // from a different class. We need to save and restore current | 2564 // from a different class. We need to save and restore current |
2559 // class, library, and token stream (script). | 2565 // class, library, and token stream (script). |
2560 ASSERT(current_class().raw() != field.origin()); | 2566 ASSERT(current_class().raw() != field.origin()); |
2561 const Class& saved_class = Class::Handle(Z, current_class().raw()); | 2567 const Class& saved_class = Class::Handle(Z, current_class().raw()); |
2562 const Library& saved_library = Library::Handle(Z, library().raw()); | 2568 const Library& saved_library = Library::Handle(Z, library().raw()); |
2563 const Script& saved_script = Script::Handle(Z, script().raw()); | 2569 const Script& saved_script = Script::Handle(Z, script().raw()); |
2564 const intptr_t saved_token_pos = TokenPos(); | 2570 const TokenPosition saved_token_pos = TokenPos(); |
2565 | 2571 |
2566 set_current_class(Class::Handle(Z, field.origin())); | 2572 set_current_class(Class::Handle(Z, field.origin())); |
2567 set_library(Library::Handle(Z, current_class().library())); | 2573 set_library(Library::Handle(Z, current_class().library())); |
2568 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); | 2574 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); |
2569 | 2575 |
2570 ASSERT(IsIdentifier()); | 2576 ASSERT(IsIdentifier()); |
2571 ConsumeToken(); | 2577 ConsumeToken(); |
2572 ExpectToken(Token::kASSIGN); | 2578 ExpectToken(Token::kASSIGN); |
2573 AstNode* init_expr = NULL; | 2579 AstNode* init_expr = NULL; |
2574 intptr_t expr_pos = TokenPos(); | 2580 TokenPosition expr_pos = TokenPos(); |
2575 if (field.is_const()) { | 2581 if (field.is_const()) { |
2576 init_expr = ParseConstExpr(); | 2582 init_expr = ParseConstExpr(); |
2577 } else { | 2583 } else { |
2578 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2584 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2579 if (init_expr->EvalConstExpr() != NULL) { | 2585 if (init_expr->EvalConstExpr() != NULL) { |
2580 Instance& expr_value = Instance::ZoneHandle(Z); | 2586 Instance& expr_value = Instance::ZoneHandle(Z); |
2581 if (!GetCachedConstant(expr_pos, &expr_value)) { | 2587 if (!GetCachedConstant(expr_pos, &expr_value)) { |
2582 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); | 2588 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); |
2583 CacheConstantValue(expr_pos, expr_value); | 2589 CacheConstantValue(expr_pos, expr_value); |
2584 } | 2590 } |
2585 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); | 2591 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); |
2586 } | 2592 } |
2587 } | 2593 } |
2588 set_current_class(saved_class); | 2594 set_current_class(saved_class); |
2589 set_library(saved_library); | 2595 set_library(saved_library); |
2590 SetScript(saved_script, saved_token_pos); | 2596 SetScript(saved_script, saved_token_pos); |
2591 return init_expr; | 2597 return init_expr; |
2592 } | 2598 } |
2593 | 2599 |
2594 | 2600 |
2595 void Parser::ParseInitializedInstanceFields(const Class& cls, | 2601 void Parser::ParseInitializedInstanceFields(const Class& cls, |
2596 LocalVariable* receiver, | 2602 LocalVariable* receiver, |
2597 GrowableArray<Field*>* initialized_fields) { | 2603 GrowableArray<Field*>* initialized_fields) { |
2598 TRACE_PARSER("ParseInitializedInstanceFields"); | 2604 TRACE_PARSER("ParseInitializedInstanceFields"); |
2599 const Array& fields = Array::Handle(Z, cls.fields()); | 2605 const Array& fields = Array::Handle(Z, cls.fields()); |
2600 Field& f = Field::Handle(Z); | 2606 Field& f = Field::Handle(Z); |
2601 const intptr_t saved_pos = TokenPos(); | 2607 const TokenPosition saved_pos = TokenPos(); |
2602 for (int i = 0; i < fields.Length(); i++) { | 2608 for (int i = 0; i < fields.Length(); i++) { |
2603 f ^= fields.At(i); | 2609 f ^= fields.At(i); |
2604 if (!f.is_static() && f.has_initializer()) { | 2610 if (!f.is_static() && f.has_initializer()) { |
2605 Field& field = Field::ZoneHandle(Z); | 2611 Field& field = Field::ZoneHandle(Z); |
2606 field ^= fields.At(i); | 2612 field ^= fields.At(i); |
2607 if (field.is_final()) { | 2613 if (field.is_final()) { |
2608 // Final fields with initializer expression may not be initialized | 2614 // Final fields with initializer expression may not be initialized |
2609 // again by constructors. Remember that this field is already | 2615 // again by constructors. Remember that this field is already |
2610 // initialized. | 2616 // initialized. |
2611 initialized_fields->Add(&field); | 2617 initialized_fields->Add(&field); |
2612 } | 2618 } |
2613 AstNode* init_expr = NULL; | 2619 AstNode* init_expr = NULL; |
2614 if (current_class().raw() != field.origin()) { | 2620 if (current_class().raw() != field.origin()) { |
2615 init_expr = ParseExternalInitializedField(field); | 2621 init_expr = ParseExternalInitializedField(field); |
2616 } else { | 2622 } else { |
2617 SetPosition(field.token_pos()); | 2623 SetPosition(field.token_pos()); |
2618 ASSERT(IsIdentifier()); | 2624 ASSERT(IsIdentifier()); |
2619 ConsumeToken(); | 2625 ConsumeToken(); |
2620 ExpectToken(Token::kASSIGN); | 2626 ExpectToken(Token::kASSIGN); |
2621 if (current_class().is_const()) { | 2627 if (current_class().is_const()) { |
2622 // If the class has a const contructor, the initializer | 2628 // If the class has a const contructor, the initializer |
2623 // expression must be a compile-time constant. | 2629 // expression must be a compile-time constant. |
2624 init_expr = ParseConstExpr(); | 2630 init_expr = ParseConstExpr(); |
2625 } else { | 2631 } else { |
2626 intptr_t expr_pos = TokenPos(); | 2632 TokenPosition expr_pos = TokenPos(); |
2627 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2633 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2628 if (init_expr->EvalConstExpr() != NULL) { | 2634 if (init_expr->EvalConstExpr() != NULL) { |
2629 Instance& expr_value = Instance::ZoneHandle(Z); | 2635 Instance& expr_value = Instance::ZoneHandle(Z); |
2630 if (!GetCachedConstant(expr_pos, &expr_value)) { | 2636 if (!GetCachedConstant(expr_pos, &expr_value)) { |
2631 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); | 2637 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); |
2632 CacheConstantValue(expr_pos, expr_value); | 2638 CacheConstantValue(expr_pos, expr_value); |
2633 } | 2639 } |
2634 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); | 2640 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); |
2635 } | 2641 } |
2636 } | 2642 } |
2637 } | 2643 } |
2638 ASSERT(init_expr != NULL); | 2644 ASSERT(init_expr != NULL); |
2639 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); | 2645 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
2640 EnsureExpressionTemp(); | 2646 EnsureExpressionTemp(); |
2641 AstNode* field_init = | 2647 AstNode* field_init = |
2642 new StoreInstanceFieldNode(field.token_pos(), | 2648 new StoreInstanceFieldNode(field.token_pos(), |
2643 instance, | 2649 instance, |
2644 field, | 2650 field, |
2645 init_expr); | 2651 init_expr); |
2646 current_block_->statements->Add(field_init); | 2652 current_block_->statements->Add(field_init); |
2647 } | 2653 } |
2648 } | 2654 } |
2649 initialized_fields->Add(NULL); // End of inline initializers. | 2655 initialized_fields->Add(NULL); // End of inline initializers. |
2650 SetPosition(saved_pos); | 2656 SetPosition(saved_pos); |
2651 } | 2657 } |
2652 | 2658 |
2653 | 2659 |
2654 AstNode* Parser::CheckDuplicateFieldInit( | 2660 AstNode* Parser::CheckDuplicateFieldInit( |
2655 intptr_t init_pos, | 2661 TokenPosition init_pos, |
2656 GrowableArray<Field*>* initialized_fields, | 2662 GrowableArray<Field*>* initialized_fields, |
2657 AstNode* instance, | 2663 AstNode* instance, |
2658 Field* field, | 2664 Field* field, |
2659 AstNode* init_value) { | 2665 AstNode* init_value) { |
2660 ASSERT(!field->is_static()); | 2666 ASSERT(!field->is_static()); |
2661 AstNode* result = NULL; | 2667 AstNode* result = NULL; |
2662 | 2668 |
2663 // The initializer_list is divided into two sections. The sections | 2669 // The initializer_list is divided into two sections. The sections |
2664 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] | 2670 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] |
2665 // The first fields f0 .. fn are final fields of the class that | 2671 // The first fields f0 .. fn are final fields of the class that |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2818 } | 2824 } |
2819 CheckFieldsInitialized(cls); | 2825 CheckFieldsInitialized(cls); |
2820 } | 2826 } |
2821 | 2827 |
2822 | 2828 |
2823 void Parser::ParseConstructorRedirection(const Class& cls, | 2829 void Parser::ParseConstructorRedirection(const Class& cls, |
2824 LocalVariable* receiver) { | 2830 LocalVariable* receiver) { |
2825 TRACE_PARSER("ParseConstructorRedirection"); | 2831 TRACE_PARSER("ParseConstructorRedirection"); |
2826 ExpectToken(Token::kCOLON); | 2832 ExpectToken(Token::kCOLON); |
2827 ASSERT(CurrentToken() == Token::kTHIS); | 2833 ASSERT(CurrentToken() == Token::kTHIS); |
2828 const intptr_t call_pos = TokenPos(); | 2834 const TokenPosition call_pos = TokenPos(); |
2829 ConsumeToken(); | 2835 ConsumeToken(); |
2830 String& ctor_name = String::Handle(Z, cls.Name()); | 2836 String& ctor_name = String::Handle(Z, cls.Name()); |
2831 GrowableHandlePtrArray<const String> pieces(Z, 3); | 2837 GrowableHandlePtrArray<const String> pieces(Z, 3); |
2832 pieces.Add(ctor_name); | 2838 pieces.Add(ctor_name); |
2833 pieces.Add(Symbols::Dot()); | 2839 pieces.Add(Symbols::Dot()); |
2834 if (CurrentToken() == Token::kPERIOD) { | 2840 if (CurrentToken() == Token::kPERIOD) { |
2835 ConsumeToken(); | 2841 ConsumeToken(); |
2836 pieces.Add(*ExpectIdentifier("constructor name expected")); | 2842 pieces.Add(*ExpectIdentifier("constructor name expected")); |
2837 } | 2843 } |
2838 ctor_name = Symbols::FromConcatAll(pieces); | 2844 ctor_name = Symbols::FromConcatAll(pieces); |
(...skipping 23 matching lines...) Expand all Loading... |
2862 error_message.ToCString()); | 2868 error_message.ToCString()); |
2863 } | 2869 } |
2864 current_block_->statements->Add( | 2870 current_block_->statements->Add( |
2865 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2871 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
2866 } | 2872 } |
2867 | 2873 |
2868 | 2874 |
2869 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2875 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
2870 ASSERT(func.IsGenerativeConstructor()); | 2876 ASSERT(func.IsGenerativeConstructor()); |
2871 ASSERT(func.Owner() == current_class().raw()); | 2877 ASSERT(func.Owner() == current_class().raw()); |
2872 const intptr_t ctor_pos = TokenPos(); | 2878 const TokenPosition ctor_pos = TokenPos(); |
2873 OpenFunctionBlock(func); | 2879 OpenFunctionBlock(func); |
2874 | 2880 |
2875 LocalVariable* receiver = new LocalVariable( | 2881 LocalVariable* receiver = new LocalVariable( |
2876 Token::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); | 2882 TokenPosition::kNoSource, |
| 2883 Symbols::This(), |
| 2884 *ReceiverType(current_class())); |
2877 current_block_->scope->InsertParameterAt(0, receiver); | 2885 current_block_->scope->InsertParameterAt(0, receiver); |
2878 | 2886 |
2879 // Parse expressions of instance fields that have an explicit | 2887 // Parse expressions of instance fields that have an explicit |
2880 // initializer expression. | 2888 // initializer expression. |
2881 // The receiver must not be visible to field initializer expressions. | 2889 // The receiver must not be visible to field initializer expressions. |
2882 receiver->set_invisible(true); | 2890 receiver->set_invisible(true); |
2883 GrowableArray<Field*> initialized_fields; | 2891 GrowableArray<Field*> initialized_fields; |
2884 ParseInitializedInstanceFields( | 2892 ParseInitializedInstanceFields( |
2885 current_class(), receiver, &initialized_fields); | 2893 current_class(), receiver, &initialized_fields); |
2886 receiver->set_invisible(false); | 2894 receiver->set_invisible(false); |
(...skipping 25 matching lines...) Expand all Loading... |
2912 "optional parameters and invoke it via super from a " | 2920 "optional parameters and invoke it via super from a " |
2913 "constructor of the class extending the mixin application", | 2921 "constructor of the class extending the mixin application", |
2914 String::Handle(Z, super_class.Name()).ToCString()); | 2922 String::Handle(Z, super_class.Name()).ToCString()); |
2915 } | 2923 } |
2916 | 2924 |
2917 // Prepare user-defined arguments to be forwarded to super call. | 2925 // Prepare user-defined arguments to be forwarded to super call. |
2918 // The first user-defined argument is at position 1. | 2926 // The first user-defined argument is at position 1. |
2919 forwarding_args = new ArgumentListNode(ST(ctor_pos)); | 2927 forwarding_args = new ArgumentListNode(ST(ctor_pos)); |
2920 for (int i = 1; i < func.NumParameters(); i++) { | 2928 for (int i = 1; i < func.NumParameters(); i++) { |
2921 LocalVariable* param = new LocalVariable( | 2929 LocalVariable* param = new LocalVariable( |
2922 Token::kNoSourcePos, | 2930 TokenPosition::kNoSource, |
2923 String::ZoneHandle(Z, func.ParameterNameAt(i)), | 2931 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
2924 Object::dynamic_type()); | 2932 Object::dynamic_type()); |
2925 current_block_->scope->InsertParameterAt(i, param); | 2933 current_block_->scope->InsertParameterAt(i, param); |
2926 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); | 2934 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); |
2927 } | 2935 } |
2928 } | 2936 } |
2929 | 2937 |
2930 AstNode* super_call = GenerateSuperConstructorCall( | 2938 AstNode* super_call = GenerateSuperConstructorCall( |
2931 current_class(), | 2939 current_class(), |
2932 ctor_pos, | 2940 ctor_pos, |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3269 if (IsInstantiatorRequired()) { | 3277 if (IsInstantiatorRequired()) { |
3270 // Make sure that the receiver of the enclosing instance function | 3278 // Make sure that the receiver of the enclosing instance function |
3271 // (or implicit first parameter of an enclosing factory) is marked as | 3279 // (or implicit first parameter of an enclosing factory) is marked as |
3272 // captured if type checks are enabled, because they may access it to | 3280 // captured if type checks are enabled, because they may access it to |
3273 // instantiate types. | 3281 // instantiate types. |
3274 CaptureInstantiator(); | 3282 CaptureInstantiator(); |
3275 } | 3283 } |
3276 } | 3284 } |
3277 } | 3285 } |
3278 | 3286 |
3279 const intptr_t modifier_pos = TokenPos(); | 3287 const TokenPosition modifier_pos = TokenPos(); |
3280 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3288 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
3281 if (!func.is_generated_body()) { | 3289 if (!func.is_generated_body()) { |
3282 // Don't add a modifier to the closure representing the body of | 3290 // Don't add a modifier to the closure representing the body of |
3283 // the asynchronous function or generator. | 3291 // the asynchronous function or generator. |
3284 func.set_modifier(func_modifier); | 3292 func.set_modifier(func_modifier); |
3285 } | 3293 } |
3286 | 3294 |
3287 OpenBlock(); // Open a nested scope for the outermost function block. | 3295 OpenBlock(); // Open a nested scope for the outermost function block. |
3288 | 3296 |
3289 Function& generated_body_closure = Function::ZoneHandle(Z); | 3297 Function& generated_body_closure = Function::ZoneHandle(Z); |
(...skipping 18 matching lines...) Expand all Loading... |
3308 func.set_is_debuggable(false); | 3316 func.set_is_debuggable(false); |
3309 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); | 3317 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); |
3310 } else if (func.IsAsyncGenClosure()) { | 3318 } else if (func.IsAsyncGenClosure()) { |
3311 // The closure containing the body of an async* function is debuggable. | 3319 // The closure containing the body of an async* function is debuggable. |
3312 ASSERT(func.is_debuggable()); | 3320 ASSERT(func.is_debuggable()); |
3313 OpenAsyncGeneratorClosure(); | 3321 OpenAsyncGeneratorClosure(); |
3314 } | 3322 } |
3315 | 3323 |
3316 BoolScope allow_await(&this->await_is_keyword_, | 3324 BoolScope allow_await(&this->await_is_keyword_, |
3317 func.IsAsyncOrGenerator() || func.is_generated_body()); | 3325 func.IsAsyncOrGenerator() || func.is_generated_body()); |
3318 intptr_t end_token_pos = Token::kNoSourcePos; | 3326 TokenPosition end_token_pos = TokenPosition::kNoSource; |
3319 if (CurrentToken() == Token::kLBRACE) { | 3327 if (CurrentToken() == Token::kLBRACE) { |
3320 ConsumeToken(); | 3328 ConsumeToken(); |
3321 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { | 3329 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
3322 const Class& owner = Class::Handle(Z, func.Owner()); | 3330 const Class& owner = Class::Handle(Z, func.Owner()); |
3323 if (!owner.IsObjectClass()) { | 3331 if (!owner.IsObjectClass()) { |
3324 AddEqualityNullCheck(); | 3332 AddEqualityNullCheck(); |
3325 } | 3333 } |
3326 } | 3334 } |
3327 ParseStatementSequence(); | 3335 ParseStatementSequence(); |
3328 end_token_pos = TokenPos(); | 3336 end_token_pos = TokenPos(); |
3329 ExpectToken(Token::kRBRACE); | 3337 ExpectToken(Token::kRBRACE); |
3330 } else if (CurrentToken() == Token::kARROW) { | 3338 } else if (CurrentToken() == Token::kARROW) { |
3331 if (func.IsGenerator()) { | 3339 if (func.IsGenerator()) { |
3332 ReportError(modifier_pos, | 3340 ReportError(modifier_pos, |
3333 "=> style function may not be sync* or async* generator"); | 3341 "=> style function may not be sync* or async* generator"); |
3334 } | 3342 } |
3335 ConsumeToken(); | 3343 ConsumeToken(); |
3336 if (String::Handle(Z, func.name()).Equals( | 3344 if (String::Handle(Z, func.name()).Equals( |
3337 Symbols::EqualOperator())) { | 3345 Symbols::EqualOperator())) { |
3338 const Class& owner = Class::Handle(Z, func.Owner()); | 3346 const Class& owner = Class::Handle(Z, func.Owner()); |
3339 if (!owner.IsObjectClass()) { | 3347 if (!owner.IsObjectClass()) { |
3340 AddEqualityNullCheck(); | 3348 AddEqualityNullCheck(); |
3341 } | 3349 } |
3342 } | 3350 } |
3343 const intptr_t expr_pos = TokenPos(); | 3351 const TokenPosition expr_pos = TokenPos(); |
3344 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3352 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
3345 ASSERT(expr != NULL); | 3353 ASSERT(expr != NULL); |
3346 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3354 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
3347 end_token_pos = TokenPos(); | 3355 end_token_pos = TokenPos(); |
3348 if (check_semicolon) { | 3356 if (check_semicolon) { |
3349 ExpectSemicolon(); | 3357 ExpectSemicolon(); |
3350 } | 3358 } |
3351 } else if (IsSymbol(Symbols::Native())) { | 3359 } else if (IsSymbol(Symbols::Native())) { |
3352 if (String::Handle(Z, func.name()).Equals( | 3360 if (String::Handle(Z, func.name()).Equals( |
3353 Symbols::EqualOperator())) { | 3361 Symbols::EqualOperator())) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3401 current_block_->statements->Add(body); | 3409 current_block_->statements->Add(body); |
3402 innermost_function_ = saved_innermost_function.raw(); | 3410 innermost_function_ = saved_innermost_function.raw(); |
3403 last_used_try_index_ = saved_try_index; | 3411 last_used_try_index_ = saved_try_index; |
3404 async_temp_scope_ = saved_async_temp_scope; | 3412 async_temp_scope_ = saved_async_temp_scope; |
3405 return CloseBlock(); | 3413 return CloseBlock(); |
3406 } | 3414 } |
3407 | 3415 |
3408 | 3416 |
3409 void Parser::AddEqualityNullCheck() { | 3417 void Parser::AddEqualityNullCheck() { |
3410 AstNode* argument = | 3418 AstNode* argument = |
3411 new LoadLocalNode(Token::kNoSourcePos, | 3419 new LoadLocalNode(TokenPosition::kNoSource, |
3412 current_block_->scope->parent()->VariableAt(1)); | 3420 current_block_->scope->parent()->VariableAt(1)); |
3413 LiteralNode* null_operand = | 3421 LiteralNode* null_operand = |
3414 new LiteralNode(Token::kNoSourcePos, Instance::ZoneHandle(Z)); | 3422 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); |
3415 ComparisonNode* check_arg = | 3423 ComparisonNode* check_arg = |
3416 new ComparisonNode(Token::kNoSourcePos, | 3424 new ComparisonNode(TokenPosition::kNoSource, |
3417 Token::kEQ_STRICT, | 3425 Token::kEQ_STRICT, |
3418 argument, | 3426 argument, |
3419 null_operand); | 3427 null_operand); |
3420 ComparisonNode* result = | 3428 ComparisonNode* result = |
3421 new ComparisonNode(Token::kNoSourcePos, | 3429 new ComparisonNode(TokenPosition::kNoSource, |
3422 Token::kEQ_STRICT, | 3430 Token::kEQ_STRICT, |
3423 LoadReceiver(Token::kNoSourcePos), | 3431 LoadReceiver(TokenPosition::kNoSource), |
3424 null_operand); | 3432 null_operand); |
3425 SequenceNode* arg_is_null = new SequenceNode(Token::kNoSourcePos, | 3433 SequenceNode* arg_is_null = new SequenceNode(TokenPosition::kNoSource, |
3426 current_block_->scope); | 3434 current_block_->scope); |
3427 arg_is_null->Add(new ReturnNode(Token::kNoSourcePos, result)); | 3435 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); |
3428 IfNode* if_arg_null = new IfNode(Token::kNoSourcePos, | 3436 IfNode* if_arg_null = new IfNode(TokenPosition::kNoSource, |
3429 check_arg, | 3437 check_arg, |
3430 arg_is_null, | 3438 arg_is_null, |
3431 NULL); | 3439 NULL); |
3432 current_block_->statements->Add(if_arg_null); | 3440 current_block_->statements->Add(if_arg_null); |
3433 } | 3441 } |
3434 | 3442 |
3435 | 3443 |
3436 void Parser::SkipIf(Token::Kind token) { | 3444 void Parser::SkipIf(Token::Kind token) { |
3437 if (CurrentToken() == token) { | 3445 if (CurrentToken() == token) { |
3438 ConsumeToken(); | 3446 ConsumeToken(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3530 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 3538 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
3531 ReportError(method->name_pos, "constructor cannot be abstract"); | 3539 ReportError(method->name_pos, "constructor cannot be abstract"); |
3532 } | 3540 } |
3533 if (method->has_const && method->IsConstructor()) { | 3541 if (method->has_const && method->IsConstructor()) { |
3534 current_class().set_is_const(); | 3542 current_class().set_is_const(); |
3535 } | 3543 } |
3536 | 3544 |
3537 // Parse the formal parameters. | 3545 // Parse the formal parameters. |
3538 const bool are_implicitly_final = method->has_const; | 3546 const bool are_implicitly_final = method->has_const; |
3539 const bool allow_explicit_default_values = true; | 3547 const bool allow_explicit_default_values = true; |
3540 const intptr_t formal_param_pos = TokenPos(); | 3548 const TokenPosition formal_param_pos = TokenPos(); |
3541 method->params.Clear(); | 3549 method->params.Clear(); |
3542 // Static functions do not have a receiver. | 3550 // Static functions do not have a receiver. |
3543 // The first parameter of a factory is the TypeArguments vector of | 3551 // The first parameter of a factory is the TypeArguments vector of |
3544 // the type of the instance to be allocated. | 3552 // the type of the instance to be allocated. |
3545 if (!method->has_static || method->IsConstructor()) { | 3553 if (!method->has_static || method->IsConstructor()) { |
3546 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); | 3554 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); |
3547 } else if (method->IsFactory()) { | 3555 } else if (method->IsFactory()) { |
3548 method->params.AddFinalParameter( | 3556 method->params.AddFinalParameter( |
3549 formal_param_pos, | 3557 formal_param_pos, |
3550 &Symbols::TypeArgumentsParameter(), | 3558 &Symbols::TypeArgumentsParameter(), |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3604 ReportError("redirecting factory '%s' may not specify default values " | 3612 ReportError("redirecting factory '%s' may not specify default values " |
3605 "for optional parameters", | 3613 "for optional parameters", |
3606 method->name->ToCString()); | 3614 method->name->ToCString()); |
3607 } | 3615 } |
3608 if (method->has_external) { | 3616 if (method->has_external) { |
3609 ReportError(TokenPos(), | 3617 ReportError(TokenPos(), |
3610 "external factory constructor '%s' may not have redirection", | 3618 "external factory constructor '%s' may not have redirection", |
3611 method->name->ToCString()); | 3619 method->name->ToCString()); |
3612 } | 3620 } |
3613 ConsumeToken(); | 3621 ConsumeToken(); |
3614 const intptr_t type_pos = TokenPos(); | 3622 const TokenPosition type_pos = TokenPos(); |
3615 is_redirecting = true; | 3623 is_redirecting = true; |
3616 const bool consume_unresolved_prefix = | 3624 const bool consume_unresolved_prefix = |
3617 (LookaheadToken(3) == Token::kLT) || | 3625 (LookaheadToken(3) == Token::kLT) || |
3618 (LookaheadToken(3) == Token::kPERIOD); | 3626 (LookaheadToken(3) == Token::kPERIOD); |
3619 const AbstractType& type = AbstractType::Handle(Z, | 3627 const AbstractType& type = AbstractType::Handle(Z, |
3620 ParseType(ClassFinalizer::kResolveTypeParameters, | 3628 ParseType(ClassFinalizer::kResolveTypeParameters, |
3621 true, | 3629 true, |
3622 consume_unresolved_prefix)); | 3630 consume_unresolved_prefix)); |
3623 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3631 if (!type.IsMalformed() && type.IsTypeParameter()) { |
3624 // Replace the type with a malformed type and compile a throw when called. | 3632 // Replace the type with a malformed type and compile a throw when called. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3683 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3691 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
3684 | 3692 |
3685 if (method->IsConstructor() && | 3693 if (method->IsConstructor() && |
3686 method->has_external && | 3694 method->has_external && |
3687 method->params.has_field_initializer) { | 3695 method->params.has_field_initializer) { |
3688 ReportError(method->name_pos, | 3696 ReportError(method->name_pos, |
3689 "external constructor '%s' may not have field initializers", | 3697 "external constructor '%s' may not have field initializers", |
3690 method->name->ToCString()); | 3698 method->name->ToCString()); |
3691 } | 3699 } |
3692 | 3700 |
3693 const intptr_t modifier_pos = TokenPos(); | 3701 const TokenPosition modifier_pos = TokenPos(); |
3694 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 3702 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
3695 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && | 3703 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && |
3696 (async_modifier != RawFunction::kNoModifier)) { | 3704 (async_modifier != RawFunction::kNoModifier)) { |
3697 ReportError(modifier_pos, | 3705 ReportError(modifier_pos, |
3698 "%s '%s' may not be async, async* or sync*", | 3706 "%s '%s' may not be async, async* or sync*", |
3699 (method->IsSetter()) ? "setter" : "constructor", | 3707 (method->IsSetter()) ? "setter" : "constructor", |
3700 method->name->ToCString()); | 3708 method->name->ToCString()); |
3701 } | 3709 } |
3702 | 3710 |
3703 intptr_t method_end_pos = TokenPos(); | 3711 TokenPosition method_end_pos = TokenPos(); |
3704 String* native_name = NULL; | 3712 String* native_name = NULL; |
3705 if ((CurrentToken() == Token::kLBRACE) || | 3713 if ((CurrentToken() == Token::kLBRACE) || |
3706 (CurrentToken() == Token::kARROW)) { | 3714 (CurrentToken() == Token::kARROW)) { |
3707 if (method->has_abstract) { | 3715 if (method->has_abstract) { |
3708 ReportError(TokenPos(), | 3716 ReportError(TokenPos(), |
3709 "abstract method '%s' may not have a function body", | 3717 "abstract method '%s' may not have a function body", |
3710 method->name->ToCString()); | 3718 method->name->ToCString()); |
3711 } else if (method->has_external) { | 3719 } else if (method->has_external) { |
3712 ReportError(TokenPos(), | 3720 ReportError(TokenPos(), |
3713 "external %s '%s' may not have a function body", | 3721 "external %s '%s' may not have a function body", |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3825 method->has_native, | 3833 method->has_native, |
3826 current_class(), | 3834 current_class(), |
3827 method->decl_begin_pos)); | 3835 method->decl_begin_pos)); |
3828 func.set_result_type(*method->type); | 3836 func.set_result_type(*method->type); |
3829 func.set_end_token_pos(method_end_pos); | 3837 func.set_end_token_pos(method_end_pos); |
3830 func.set_is_redirecting(is_redirecting); | 3838 func.set_is_redirecting(is_redirecting); |
3831 func.set_modifier(async_modifier); | 3839 func.set_modifier(async_modifier); |
3832 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { | 3840 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { |
3833 func.set_is_reflectable(false); | 3841 func.set_is_reflectable(false); |
3834 } | 3842 } |
3835 if (FLAG_enable_mirrors && (method->metadata_pos >= 0)) { | 3843 if (FLAG_enable_mirrors && (method->metadata_pos.IsReal())) { |
3836 library_.AddFunctionMetadata(func, method->metadata_pos); | 3844 library_.AddFunctionMetadata(func, method->metadata_pos); |
3837 } | 3845 } |
3838 if (method->has_native) { | 3846 if (method->has_native) { |
3839 func.set_native_name(*native_name); | 3847 func.set_native_name(*native_name); |
3840 } | 3848 } |
3841 | 3849 |
3842 // If this method is a redirecting factory, set the redirection information. | 3850 // If this method is a redirecting factory, set the redirection information. |
3843 if (!redirection_type.IsNull()) { | 3851 if (!redirection_type.IsNull()) { |
3844 ASSERT(func.IsFactory()); | 3852 ASSERT(func.IsFactory()); |
3845 func.SetRedirectionType(redirection_type); | 3853 func.SetRedirectionType(redirection_type); |
(...skipping 10 matching lines...) Expand all Loading... |
3856 | 3864 |
3857 | 3865 |
3858 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 3866 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
3859 TRACE_PARSER("ParseFieldDefinition"); | 3867 TRACE_PARSER("ParseFieldDefinition"); |
3860 // The parser has read the first field name and is now at the token | 3868 // The parser has read the first field name and is now at the token |
3861 // after the field name. | 3869 // after the field name. |
3862 ASSERT(CurrentToken() == Token::kSEMICOLON || | 3870 ASSERT(CurrentToken() == Token::kSEMICOLON || |
3863 CurrentToken() == Token::kCOMMA || | 3871 CurrentToken() == Token::kCOMMA || |
3864 CurrentToken() == Token::kASSIGN); | 3872 CurrentToken() == Token::kASSIGN); |
3865 ASSERT(field->type != NULL); | 3873 ASSERT(field->type != NULL); |
3866 ASSERT(field->name_pos >= 0); | 3874 ASSERT(field->name_pos.IsReal()); |
3867 ASSERT(current_member_ == field); | 3875 ASSERT(current_member_ == field); |
3868 // All const fields are also final. | 3876 // All const fields are also final. |
3869 ASSERT(!field->has_const || field->has_final); | 3877 ASSERT(!field->has_const || field->has_final); |
3870 | 3878 |
3871 if (field->has_abstract) { | 3879 if (field->has_abstract) { |
3872 ReportError("keyword 'abstract' not allowed in field declaration"); | 3880 ReportError("keyword 'abstract' not allowed in field declaration"); |
3873 } | 3881 } |
3874 if (field->has_external) { | 3882 if (field->has_external) { |
3875 ReportError("keyword 'external' not allowed in field declaration"); | 3883 ReportError("keyword 'external' not allowed in field declaration"); |
3876 } | 3884 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3925 field->has_static, | 3933 field->has_static, |
3926 field->has_final, | 3934 field->has_final, |
3927 field->has_const, | 3935 field->has_const, |
3928 is_reflectable, | 3936 is_reflectable, |
3929 current_class(), | 3937 current_class(), |
3930 *field->type, | 3938 *field->type, |
3931 field->name_pos); | 3939 field->name_pos); |
3932 class_field.set_has_initializer(has_initializer); | 3940 class_field.set_has_initializer(has_initializer); |
3933 members->AddField(class_field); | 3941 members->AddField(class_field); |
3934 field->field_ = &class_field; | 3942 field->field_ = &class_field; |
3935 if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) { | 3943 if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) { |
3936 library_.AddFieldMetadata(class_field, field->metadata_pos); | 3944 library_.AddFieldMetadata(class_field, field->metadata_pos); |
3937 } | 3945 } |
3938 | 3946 |
3939 // Start tracking types for fields with simple initializers in their | 3947 // Start tracking types for fields with simple initializers in their |
3940 // definition. This avoids some of the overhead to track this at runtime | 3948 // definition. This avoids some of the overhead to track this at runtime |
3941 // and rules out many fields from being unnecessary unboxing candidates. | 3949 // and rules out many fields from being unnecessary unboxing candidates. |
3942 if (!field->has_static && has_initializer && has_simple_literal) { | 3950 if (!field->has_static && has_initializer && has_simple_literal) { |
3943 class_field.RecordStore(init_value); | 3951 class_field.RecordStore(init_value); |
3944 if (!init_value.IsNull() && init_value.IsDouble()) { | 3952 if (!init_value.IsNull() && init_value.IsDouble()) { |
3945 class_field.set_is_double_initialized(true); | 3953 class_field.set_is_double_initialized(true); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4072 "%s '%s' conflicts with previously declared %s", | 4080 "%s '%s' conflicts with previously declared %s", |
4073 member->ToCString(), | 4081 member->ToCString(), |
4074 name.ToCString(), | 4082 name.ToCString(), |
4075 existing_member->ToCString()); | 4083 existing_member->ToCString()); |
4076 } | 4084 } |
4077 } | 4085 } |
4078 } | 4086 } |
4079 | 4087 |
4080 | 4088 |
4081 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4089 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
4082 intptr_t metadata_pos) { | 4090 TokenPosition metadata_pos) { |
4083 TRACE_PARSER("ParseClassMemberDefinition"); | 4091 TRACE_PARSER("ParseClassMemberDefinition"); |
4084 MemberDesc member; | 4092 MemberDesc member; |
4085 current_member_ = &member; | 4093 current_member_ = &member; |
4086 member.metadata_pos = metadata_pos; | 4094 member.metadata_pos = metadata_pos; |
4087 member.decl_begin_pos = TokenPos(); | 4095 member.decl_begin_pos = TokenPos(); |
4088 if ((CurrentToken() == Token::kEXTERNAL) && | 4096 if ((CurrentToken() == Token::kEXTERNAL) && |
4089 (LookaheadToken(1) != Token::kLPAREN)) { | 4097 (LookaheadToken(1) != Token::kLPAREN)) { |
4090 ConsumeToken(); | 4098 ConsumeToken(); |
4091 member.has_external = true; | 4099 member.has_external = true; |
4092 } | 4100 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4283 UnexpectedToken(); | 4291 UnexpectedToken(); |
4284 } | 4292 } |
4285 current_member_ = NULL; | 4293 current_member_ = NULL; |
4286 CheckMemberNameConflict(members, &member); | 4294 CheckMemberNameConflict(members, &member); |
4287 members->AddMember(member); | 4295 members->AddMember(member); |
4288 } | 4296 } |
4289 | 4297 |
4290 | 4298 |
4291 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, | 4299 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
4292 const Object& tl_owner, | 4300 const Object& tl_owner, |
4293 intptr_t metadata_pos) { | 4301 TokenPosition metadata_pos) { |
4294 TRACE_PARSER("ParseEnumDeclaration"); | 4302 TRACE_PARSER("ParseEnumDeclaration"); |
4295 const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos | 4303 const TokenPosition declaration_pos = |
4296 : TokenPos(); | 4304 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); |
4297 ConsumeToken(); | 4305 ConsumeToken(); |
4298 const intptr_t name_pos = TokenPos(); | 4306 const TokenPosition name_pos = TokenPos(); |
4299 String* enum_name = | 4307 String* enum_name = |
4300 ExpectUserDefinedTypeIdentifier("enum type name expected"); | 4308 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
4301 if (FLAG_trace_parser) { | 4309 if (FLAG_trace_parser) { |
4302 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); | 4310 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); |
4303 } | 4311 } |
4304 ExpectToken(Token::kLBRACE); | 4312 ExpectToken(Token::kLBRACE); |
4305 if (!IsIdentifier()) { | 4313 if (!IsIdentifier()) { |
4306 ReportError("Enumeration must have at least one name"); | 4314 ReportError("Enumeration must have at least one name"); |
4307 } | 4315 } |
4308 while (IsIdentifier()) { | 4316 while (IsIdentifier()) { |
(...skipping 14 matching lines...) Expand all Loading... |
4323 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); | 4331 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); |
4324 if (!obj.IsNull()) { | 4332 if (!obj.IsNull()) { |
4325 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); | 4333 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); |
4326 } | 4334 } |
4327 Class& cls = Class::Handle(Z); | 4335 Class& cls = Class::Handle(Z); |
4328 cls = Class::New(*enum_name, script_, declaration_pos); | 4336 cls = Class::New(*enum_name, script_, declaration_pos); |
4329 cls.set_library(library_); | 4337 cls.set_library(library_); |
4330 library_.AddClass(cls); | 4338 library_.AddClass(cls); |
4331 cls.set_is_synthesized_class(); | 4339 cls.set_is_synthesized_class(); |
4332 cls.set_is_enum_class(); | 4340 cls.set_is_enum_class(); |
4333 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4341 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { |
4334 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4342 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
4335 } | 4343 } |
4336 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); | 4344 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
4337 pending_classes.Add(cls, Heap::kOld); | 4345 pending_classes.Add(cls, Heap::kOld); |
4338 } | 4346 } |
4339 | 4347 |
4340 | 4348 |
4341 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4349 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
4342 const Object& tl_owner, | 4350 const Object& tl_owner, |
4343 intptr_t metadata_pos) { | 4351 TokenPosition metadata_pos) { |
4344 TRACE_PARSER("ParseClassDeclaration"); | 4352 TRACE_PARSER("ParseClassDeclaration"); |
4345 bool is_patch = false; | 4353 bool is_patch = false; |
4346 bool is_abstract = false; | 4354 bool is_abstract = false; |
4347 intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos(); | 4355 TokenPosition declaration_pos = |
| 4356 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
4348 if (is_patch_source() && | 4357 if (is_patch_source() && |
4349 (CurrentToken() == Token::kIDENT) && | 4358 (CurrentToken() == Token::kIDENT) && |
4350 CurrentLiteral()->Equals("patch")) { | 4359 CurrentLiteral()->Equals("patch")) { |
4351 ConsumeToken(); | 4360 ConsumeToken(); |
4352 is_patch = true; | 4361 is_patch = true; |
4353 } else if (CurrentToken() == Token::kABSTRACT) { | 4362 } else if (CurrentToken() == Token::kABSTRACT) { |
4354 is_abstract = true; | 4363 is_abstract = true; |
4355 ConsumeToken(); | 4364 ConsumeToken(); |
4356 } | 4365 } |
4357 ExpectToken(Token::kCLASS); | 4366 ExpectToken(Token::kCLASS); |
4358 const intptr_t classname_pos = TokenPos(); | 4367 const TokenPosition classname_pos = TokenPos(); |
4359 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4368 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
4360 if (FLAG_trace_parser) { | 4369 if (FLAG_trace_parser) { |
4361 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 4370 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
4362 } | 4371 } |
4363 Class& cls = Class::Handle(Z); | 4372 Class& cls = Class::Handle(Z); |
4364 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); | 4373 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); |
4365 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4374 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
4366 if (obj.IsNull()) { | 4375 if (obj.IsNull()) { |
4367 if (is_patch) { | 4376 if (is_patch) { |
4368 ReportError(classname_pos, "missing class '%s' cannot be patched", | 4377 ReportError(classname_pos, "missing class '%s' cannot be patched", |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4442 class_name.ToCString(), | 4451 class_name.ToCString(), |
4443 String::Handle(orig_bound.UserVisibleName()).ToCString()); | 4452 String::Handle(orig_bound.UserVisibleName()).ToCString()); |
4444 } | 4453 } |
4445 } | 4454 } |
4446 cls.set_type_parameters(orig_type_parameters); | 4455 cls.set_type_parameters(orig_type_parameters); |
4447 } | 4456 } |
4448 | 4457 |
4449 if (is_abstract) { | 4458 if (is_abstract) { |
4450 cls.set_is_abstract(); | 4459 cls.set_is_abstract(); |
4451 } | 4460 } |
4452 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4461 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
4453 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4462 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
4454 } | 4463 } |
4455 | 4464 |
4456 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 4465 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
4457 if (is_mixin_declaration && is_patch) { | 4466 if (is_mixin_declaration && is_patch) { |
4458 ReportError(classname_pos, | 4467 ReportError(classname_pos, |
4459 "mixin application '%s' may not be a patch class", | 4468 "mixin application '%s' may not be a patch class", |
4460 class_name.ToCString()); | 4469 class_name.ToCString()); |
4461 } | 4470 } |
4462 | 4471 |
4463 AbstractType& super_type = Type::Handle(Z); | 4472 AbstractType& super_type = Type::Handle(Z); |
4464 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4473 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
4465 ConsumeToken(); // extends or = | 4474 ConsumeToken(); // extends or = |
4466 const intptr_t type_pos = TokenPos(); | 4475 const TokenPosition type_pos = TokenPos(); |
4467 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4476 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
4468 if (super_type.IsMalformedOrMalbounded()) { | 4477 if (super_type.IsMalformedOrMalbounded()) { |
4469 ReportError(Error::Handle(Z, super_type.error())); | 4478 ReportError(Error::Handle(Z, super_type.error())); |
4470 } | 4479 } |
4471 if (super_type.IsDynamicType()) { | 4480 if (super_type.IsDynamicType()) { |
4472 // Unlikely here, since super type is not resolved yet. | 4481 // Unlikely here, since super type is not resolved yet. |
4473 ReportError(type_pos, | 4482 ReportError(type_pos, |
4474 "class '%s' may not extend 'dynamic'", | 4483 "class '%s' may not extend 'dynamic'", |
4475 class_name.ToCString()); | 4484 class_name.ToCString()); |
4476 } | 4485 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4533 String& class_name = String::Handle(Z, cls.Name()); | 4542 String& class_name = String::Handle(Z, cls.Name()); |
4534 SkipMetadata(); | 4543 SkipMetadata(); |
4535 if (is_patch_source() && | 4544 if (is_patch_source() && |
4536 (CurrentToken() == Token::kIDENT) && | 4545 (CurrentToken() == Token::kIDENT) && |
4537 CurrentLiteral()->Equals("patch")) { | 4546 CurrentLiteral()->Equals("patch")) { |
4538 ConsumeToken(); | 4547 ConsumeToken(); |
4539 } else if (CurrentToken() == Token::kABSTRACT) { | 4548 } else if (CurrentToken() == Token::kABSTRACT) { |
4540 ConsumeToken(); | 4549 ConsumeToken(); |
4541 } | 4550 } |
4542 ExpectToken(Token::kCLASS); | 4551 ExpectToken(Token::kCLASS); |
4543 const intptr_t class_pos = TokenPos(); | 4552 const TokenPosition class_pos = TokenPos(); |
4544 ClassDesc members(Z, cls, class_name, false, class_pos); | 4553 ClassDesc members(Z, cls, class_name, false, class_pos); |
4545 while (CurrentToken() != Token::kLBRACE) { | 4554 while (CurrentToken() != Token::kLBRACE) { |
4546 ConsumeToken(); | 4555 ConsumeToken(); |
4547 } | 4556 } |
4548 ExpectToken(Token::kLBRACE); | 4557 ExpectToken(Token::kLBRACE); |
4549 while (CurrentToken() != Token::kRBRACE) { | 4558 while (CurrentToken() != Token::kRBRACE) { |
4550 intptr_t metadata_pos = SkipMetadata(); | 4559 TokenPosition metadata_pos = SkipMetadata(); |
4551 ParseClassMemberDefinition(&members, metadata_pos); | 4560 ParseClassMemberDefinition(&members, metadata_pos); |
4552 } | 4561 } |
4553 ExpectToken(Token::kRBRACE); | 4562 ExpectToken(Token::kRBRACE); |
4554 | 4563 |
4555 CheckConstructors(&members); | 4564 CheckConstructors(&members); |
4556 | 4565 |
4557 // Need to compute this here since MakeArray() will clear the | 4566 // Need to compute this here since MakeArray() will clear the |
4558 // functions array in members. | 4567 // functions array in members. |
4559 const bool need_implicit_constructor = | 4568 const bool need_implicit_constructor = |
4560 !members.has_constructor() && !cls.is_patch(); | 4569 !members.has_constructor() && !cls.is_patch(); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4819 ctors.Add(member); | 4828 ctors.Add(member); |
4820 member = class_desc->LookupMember(*member->redirect_name); | 4829 member = class_desc->LookupMember(*member->redirect_name); |
4821 } | 4830 } |
4822 } | 4831 } |
4823 } | 4832 } |
4824 | 4833 |
4825 | 4834 |
4826 void Parser::ParseMixinAppAlias( | 4835 void Parser::ParseMixinAppAlias( |
4827 const GrowableObjectArray& pending_classes, | 4836 const GrowableObjectArray& pending_classes, |
4828 const Object& tl_owner, | 4837 const Object& tl_owner, |
4829 intptr_t metadata_pos) { | 4838 TokenPosition metadata_pos) { |
4830 TRACE_PARSER("ParseMixinAppAlias"); | 4839 TRACE_PARSER("ParseMixinAppAlias"); |
4831 const intptr_t classname_pos = TokenPos(); | 4840 const TokenPosition classname_pos = TokenPos(); |
4832 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4841 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
4833 if (FLAG_trace_parser) { | 4842 if (FLAG_trace_parser) { |
4834 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4843 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
4835 class_name.ToCString()); | 4844 class_name.ToCString()); |
4836 } | 4845 } |
4837 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4846 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
4838 if (!obj.IsNull()) { | 4847 if (!obj.IsNull()) { |
4839 ReportError(classname_pos, "'%s' is already defined", | 4848 ReportError(classname_pos, "'%s' is already defined", |
4840 class_name.ToCString()); | 4849 class_name.ToCString()); |
4841 } | 4850 } |
4842 const Class& mixin_application = | 4851 const Class& mixin_application = |
4843 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); | 4852 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); |
4844 mixin_application.set_is_mixin_app_alias(); | 4853 mixin_application.set_is_mixin_app_alias(); |
4845 library_.AddClass(mixin_application); | 4854 library_.AddClass(mixin_application); |
4846 set_current_class(mixin_application); | 4855 set_current_class(mixin_application); |
4847 ParseTypeParameters(mixin_application); | 4856 ParseTypeParameters(mixin_application); |
4848 | 4857 |
4849 ExpectToken(Token::kASSIGN); | 4858 ExpectToken(Token::kASSIGN); |
4850 | 4859 |
4851 if (CurrentToken() == Token::kABSTRACT) { | 4860 if (CurrentToken() == Token::kABSTRACT) { |
4852 mixin_application.set_is_abstract(); | 4861 mixin_application.set_is_abstract(); |
4853 ConsumeToken(); | 4862 ConsumeToken(); |
4854 } | 4863 } |
4855 | 4864 |
4856 const intptr_t type_pos = TokenPos(); | 4865 const TokenPosition type_pos = TokenPos(); |
4857 AbstractType& type = | 4866 AbstractType& type = |
4858 AbstractType::Handle(Z, | 4867 AbstractType::Handle(Z, |
4859 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4868 ParseType(ClassFinalizer::kResolveTypeParameters)); |
4860 if (type.IsTypeParameter()) { | 4869 if (type.IsTypeParameter()) { |
4861 ReportError(type_pos, | 4870 ReportError(type_pos, |
4862 "class '%s' may not extend type parameter '%s'", | 4871 "class '%s' may not extend type parameter '%s'", |
4863 class_name.ToCString(), | 4872 class_name.ToCString(), |
4864 String::Handle(Z, type.UserVisibleName()).ToCString()); | 4873 String::Handle(Z, type.UserVisibleName()).ToCString()); |
4865 } | 4874 } |
4866 | 4875 |
4867 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4876 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
4868 type = ParseMixins(type); | 4877 type = ParseMixins(type); |
4869 | 4878 |
4870 mixin_application.set_super_type(type); | 4879 mixin_application.set_super_type(type); |
4871 mixin_application.set_is_synthesized_class(); | 4880 mixin_application.set_is_synthesized_class(); |
4872 | 4881 |
4873 // This mixin application alias needs an implicit constructor, but it is | 4882 // This mixin application alias needs an implicit constructor, but it is |
4874 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4883 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
4875 // because this class should be lazily compiled. | 4884 // because this class should be lazily compiled. |
4876 if (CurrentToken() == Token::kIMPLEMENTS) { | 4885 if (CurrentToken() == Token::kIMPLEMENTS) { |
4877 ParseInterfaceList(mixin_application); | 4886 ParseInterfaceList(mixin_application); |
4878 } | 4887 } |
4879 ExpectSemicolon(); | 4888 ExpectSemicolon(); |
4880 pending_classes.Add(mixin_application, Heap::kOld); | 4889 pending_classes.Add(mixin_application, Heap::kOld); |
4881 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4890 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
4882 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); | 4891 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); |
4883 } | 4892 } |
4884 } | 4893 } |
4885 | 4894 |
4886 | 4895 |
4887 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 4896 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
4888 // We need this lookahead to distinguish between the optional return type | 4897 // We need this lookahead to distinguish between the optional return type |
4889 // and the alias name of a function type alias. | 4898 // and the alias name of a function type alias. |
4890 // Token position remains unchanged. | 4899 // Token position remains unchanged. |
4891 bool Parser::IsFunctionTypeAliasName() { | 4900 bool Parser::IsFunctionTypeAliasName() { |
4892 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4901 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
4893 return true; | 4902 return true; |
4894 } | 4903 } |
4895 const intptr_t saved_pos = TokenPos(); | 4904 const TokenPosition saved_pos = TokenPos(); |
4896 bool is_alias_name = false; | 4905 bool is_alias_name = false; |
4897 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4906 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
4898 ConsumeToken(); | 4907 ConsumeToken(); |
4899 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { | 4908 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { |
4900 is_alias_name = true; | 4909 is_alias_name = true; |
4901 } | 4910 } |
4902 } | 4911 } |
4903 SetPosition(saved_pos); | 4912 SetPosition(saved_pos); |
4904 return is_alias_name; | 4913 return is_alias_name; |
4905 } | 4914 } |
4906 | 4915 |
4907 | 4916 |
4908 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". | 4917 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". |
4909 // Token position remains unchanged. | 4918 // Token position remains unchanged. |
4910 bool Parser::IsMixinAppAlias() { | 4919 bool Parser::IsMixinAppAlias() { |
4911 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { | 4920 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { |
4912 return true; | 4921 return true; |
4913 } | 4922 } |
4914 const intptr_t saved_pos = TokenPos(); | 4923 const TokenPosition saved_pos = TokenPos(); |
4915 bool is_mixin_def = false; | 4924 bool is_mixin_def = false; |
4916 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4925 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
4917 ConsumeToken(); | 4926 ConsumeToken(); |
4918 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { | 4927 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { |
4919 is_mixin_def = true; | 4928 is_mixin_def = true; |
4920 } | 4929 } |
4921 } | 4930 } |
4922 SetPosition(saved_pos); | 4931 SetPosition(saved_pos); |
4923 return is_mixin_def; | 4932 return is_mixin_def; |
4924 } | 4933 } |
4925 | 4934 |
4926 | 4935 |
4927 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4936 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
4928 const Object& tl_owner, | 4937 const Object& tl_owner, |
4929 intptr_t metadata_pos) { | 4938 TokenPosition metadata_pos) { |
4930 TRACE_PARSER("ParseTypedef"); | 4939 TRACE_PARSER("ParseTypedef"); |
4931 intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos(); | 4940 TokenPosition declaration_pos = |
| 4941 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
4932 ExpectToken(Token::kTYPEDEF); | 4942 ExpectToken(Token::kTYPEDEF); |
4933 | 4943 |
4934 if (IsMixinAppAlias()) { | 4944 if (IsMixinAppAlias()) { |
4935 if (FLAG_warn_mixin_typedef) { | 4945 if (FLAG_warn_mixin_typedef) { |
4936 ReportWarning(TokenPos(), "deprecated mixin application typedef"); | 4946 ReportWarning(TokenPos(), "deprecated mixin application typedef"); |
4937 } | 4947 } |
4938 ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos); | 4948 ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos); |
4939 return; | 4949 return; |
4940 } | 4950 } |
4941 | 4951 |
4942 // Parse the result type of the function type. | 4952 // Parse the result type of the function type. |
4943 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 4953 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
4944 if (CurrentToken() == Token::kVOID) { | 4954 if (CurrentToken() == Token::kVOID) { |
4945 ConsumeToken(); | 4955 ConsumeToken(); |
4946 result_type = Type::VoidType(); | 4956 result_type = Type::VoidType(); |
4947 } else if (!IsFunctionTypeAliasName()) { | 4957 } else if (!IsFunctionTypeAliasName()) { |
4948 // Type annotations in typedef are never ignored, even in production mode. | 4958 // Type annotations in typedef are never ignored, even in production mode. |
4949 // Wait until we have an owner class before resolving the result type. | 4959 // Wait until we have an owner class before resolving the result type. |
4950 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4960 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
4951 } | 4961 } |
4952 | 4962 |
4953 const intptr_t alias_name_pos = TokenPos(); | 4963 const TokenPosition alias_name_pos = TokenPos(); |
4954 const String* alias_name = | 4964 const String* alias_name = |
4955 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4965 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
4956 | 4966 |
4957 // Lookup alias name and report an error if it is already defined in | 4967 // Lookup alias name and report an error if it is already defined in |
4958 // the library scope. | 4968 // the library scope. |
4959 const Object& obj = | 4969 const Object& obj = |
4960 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); | 4970 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); |
4961 if (!obj.IsNull()) { | 4971 if (!obj.IsNull()) { |
4962 ReportError(alias_name_pos, | 4972 ReportError(alias_name_pos, |
4963 "'%s' is already defined", alias_name->ToCString()); | 4973 "'%s' is already defined", alias_name->ToCString()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5006 function_type_alias.set_signature_function(signature_function); | 5016 function_type_alias.set_signature_function(signature_function); |
5007 | 5017 |
5008 if (FLAG_trace_parser) { | 5018 if (FLAG_trace_parser) { |
5009 OS::Print("TopLevel parsing function type alias '%s'\n", | 5019 OS::Print("TopLevel parsing function type alias '%s'\n", |
5010 String::Handle(Z, signature_function.Signature()).ToCString()); | 5020 String::Handle(Z, signature_function.Signature()).ToCString()); |
5011 } | 5021 } |
5012 // The alias should not be marked as finalized yet, since it needs to be | 5022 // The alias should not be marked as finalized yet, since it needs to be |
5013 // checked in the class finalizer for illegal self references. | 5023 // checked in the class finalizer for illegal self references. |
5014 ASSERT(!function_type_alias.is_finalized()); | 5024 ASSERT(!function_type_alias.is_finalized()); |
5015 pending_classes.Add(function_type_alias, Heap::kOld); | 5025 pending_classes.Add(function_type_alias, Heap::kOld); |
5016 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5026 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5017 library_.AddClassMetadata(function_type_alias, | 5027 library_.AddClassMetadata(function_type_alias, |
5018 tl_owner, | 5028 tl_owner, |
5019 metadata_pos); | 5029 metadata_pos); |
5020 } | 5030 } |
5021 } | 5031 } |
5022 | 5032 |
5023 | 5033 |
5024 // Consumes exactly one right angle bracket. If the current token is a single | 5034 // Consumes exactly one right angle bracket. If the current token is a single |
5025 // bracket token, it is consumed normally. However, if it is a double or triple | 5035 // bracket token, it is consumed normally. However, if it is a double or triple |
5026 // bracket, it is replaced by a single or double bracket token without | 5036 // bracket, it is replaced by a single or double bracket token without |
5027 // incrementing the token index. | 5037 // incrementing the token index. |
5028 void Parser::ConsumeRightAngleBracket() { | 5038 void Parser::ConsumeRightAngleBracket() { |
5029 if (token_kind_ == Token::kGT) { | 5039 if (token_kind_ == Token::kGT) { |
5030 ConsumeToken(); | 5040 ConsumeToken(); |
5031 } else if (token_kind_ == Token::kSHR) { | 5041 } else if (token_kind_ == Token::kSHR) { |
5032 token_kind_ = Token::kGT; | 5042 token_kind_ = Token::kGT; |
5033 } else { | 5043 } else { |
5034 UNREACHABLE(); | 5044 UNREACHABLE(); |
5035 } | 5045 } |
5036 } | 5046 } |
5037 | 5047 |
5038 | 5048 |
5039 intptr_t Parser::SkipMetadata() { | 5049 TokenPosition Parser::SkipMetadata() { |
5040 if (CurrentToken() != Token::kAT) { | 5050 if (CurrentToken() != Token::kAT) { |
5041 return Token::kNoSourcePos; | 5051 return TokenPosition::kNoSource; |
5042 } | 5052 } |
5043 intptr_t metadata_pos = TokenPos(); | 5053 TokenPosition metadata_pos = TokenPos(); |
5044 while (CurrentToken() == Token::kAT) { | 5054 while (CurrentToken() == Token::kAT) { |
5045 ConsumeToken(); | 5055 ConsumeToken(); |
5046 ExpectIdentifier("identifier expected"); | 5056 ExpectIdentifier("identifier expected"); |
5047 if (CurrentToken() == Token::kPERIOD) { | 5057 if (CurrentToken() == Token::kPERIOD) { |
5048 ConsumeToken(); | 5058 ConsumeToken(); |
5049 ExpectIdentifier("identifier expected"); | 5059 ExpectIdentifier("identifier expected"); |
5050 if (CurrentToken() == Token::kPERIOD) { | 5060 if (CurrentToken() == Token::kPERIOD) { |
5051 ConsumeToken(); | 5061 ConsumeToken(); |
5052 ExpectIdentifier("identifier expected"); | 5062 ExpectIdentifier("identifier expected"); |
5053 } | 5063 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5097 TRACE_PARSER("ParseTypeParameters"); | 5107 TRACE_PARSER("ParseTypeParameters"); |
5098 if (CurrentToken() == Token::kLT) { | 5108 if (CurrentToken() == Token::kLT) { |
5099 GrowableArray<AbstractType*> type_parameters_array(Z, 2); | 5109 GrowableArray<AbstractType*> type_parameters_array(Z, 2); |
5100 intptr_t index = 0; | 5110 intptr_t index = 0; |
5101 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5111 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
5102 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5112 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
5103 String& existing_type_parameter_name = String::Handle(Z); | 5113 String& existing_type_parameter_name = String::Handle(Z); |
5104 AbstractType& type_parameter_bound = Type::Handle(Z); | 5114 AbstractType& type_parameter_bound = Type::Handle(Z); |
5105 do { | 5115 do { |
5106 ConsumeToken(); | 5116 ConsumeToken(); |
5107 const intptr_t metadata_pos = SkipMetadata(); | 5117 const TokenPosition metadata_pos = SkipMetadata(); |
5108 const intptr_t type_parameter_pos = TokenPos(); | 5118 const TokenPosition type_parameter_pos = TokenPos(); |
5109 const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos | 5119 const TokenPosition declaration_pos = |
5110 : type_parameter_pos; | 5120 metadata_pos.IsReal() ? metadata_pos : type_parameter_pos; |
5111 String& type_parameter_name = | 5121 String& type_parameter_name = |
5112 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 5122 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
5113 // Check for duplicate type parameters. | 5123 // Check for duplicate type parameters. |
5114 for (intptr_t i = 0; i < index; i++) { | 5124 for (intptr_t i = 0; i < index; i++) { |
5115 existing_type_parameter ^= type_parameters_array.At(i)->raw(); | 5125 existing_type_parameter ^= type_parameters_array.At(i)->raw(); |
5116 existing_type_parameter_name = existing_type_parameter.name(); | 5126 existing_type_parameter_name = existing_type_parameter.name(); |
5117 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 5127 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
5118 ReportError(type_parameter_pos, "duplicate type parameter '%s'", | 5128 ReportError(type_parameter_pos, "duplicate type parameter '%s'", |
5119 type_parameter_name.ToCString()); | 5129 type_parameter_name.ToCString()); |
5120 } | 5130 } |
5121 } | 5131 } |
5122 if (CurrentToken() == Token::kEXTENDS) { | 5132 if (CurrentToken() == Token::kEXTENDS) { |
5123 ConsumeToken(); | 5133 ConsumeToken(); |
5124 // A bound may refer to the owner of the type parameter it applies to, | 5134 // A bound may refer to the owner of the type parameter it applies to, |
5125 // i.e. to the class or interface currently being parsed. | 5135 // i.e. to the class or interface currently being parsed. |
5126 // Postpone resolution in order to avoid resolving the class and its | 5136 // Postpone resolution in order to avoid resolving the class and its |
5127 // type parameters, as they are not fully parsed yet. | 5137 // type parameters, as they are not fully parsed yet. |
5128 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 5138 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
5129 } else { | 5139 } else { |
5130 type_parameter_bound = I->object_store()->object_type(); | 5140 type_parameter_bound = I->object_store()->object_type(); |
5131 } | 5141 } |
5132 type_parameter = TypeParameter::New(cls, | 5142 type_parameter = TypeParameter::New(cls, |
5133 index, | 5143 index, |
5134 type_parameter_name, | 5144 type_parameter_name, |
5135 type_parameter_bound, | 5145 type_parameter_bound, |
5136 declaration_pos); | 5146 declaration_pos); |
5137 type_parameters_array.Add( | 5147 type_parameters_array.Add( |
5138 &AbstractType::ZoneHandle(Z, type_parameter.raw())); | 5148 &AbstractType::ZoneHandle(Z, type_parameter.raw())); |
5139 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5149 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5140 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 5150 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
5141 } | 5151 } |
5142 index++; | 5152 index++; |
5143 } while (CurrentToken() == Token::kCOMMA); | 5153 } while (CurrentToken() == Token::kCOMMA); |
5144 Token::Kind token = CurrentToken(); | 5154 Token::Kind token = CurrentToken(); |
5145 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5155 if ((token == Token::kGT) || (token == Token::kSHR)) { |
5146 ConsumeRightAngleBracket(); | 5156 ConsumeRightAngleBracket(); |
5147 } else { | 5157 } else { |
5148 ReportError("right angle bracket expected"); | 5158 ReportError("right angle bracket expected"); |
5149 } | 5159 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5204 AbstractType& interface = AbstractType::Handle(Z); | 5214 AbstractType& interface = AbstractType::Handle(Z); |
5205 // First get all the interfaces already implemented by class. | 5215 // First get all the interfaces already implemented by class. |
5206 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); | 5216 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); |
5207 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 5217 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
5208 interface ^= cls_interfaces.At(i); | 5218 interface ^= cls_interfaces.At(i); |
5209 all_interfaces.Add(interface); | 5219 all_interfaces.Add(interface); |
5210 } | 5220 } |
5211 // Now parse and add the new interfaces. | 5221 // Now parse and add the new interfaces. |
5212 do { | 5222 do { |
5213 ConsumeToken(); | 5223 ConsumeToken(); |
5214 intptr_t interface_pos = TokenPos(); | 5224 TokenPosition interface_pos = TokenPos(); |
5215 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 5225 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
5216 if (interface.IsTypeParameter()) { | 5226 if (interface.IsTypeParameter()) { |
5217 ReportError(interface_pos, | 5227 ReportError(interface_pos, |
5218 "type parameter '%s' may not be used in interface list", | 5228 "type parameter '%s' may not be used in interface list", |
5219 String::Handle(Z, interface.UserVisibleName()).ToCString()); | 5229 String::Handle(Z, interface.UserVisibleName()).ToCString()); |
5220 } | 5230 } |
5221 all_interfaces.Add(interface); | 5231 all_interfaces.Add(interface); |
5222 } while (CurrentToken() == Token::kCOMMA); | 5232 } while (CurrentToken() == Token::kCOMMA); |
5223 cls_interfaces = Array::MakeArray(all_interfaces); | 5233 cls_interfaces = Array::MakeArray(all_interfaces); |
5224 cls.set_interfaces(cls_interfaces); | 5234 cls.set_interfaces(cls_interfaces); |
(...skipping 21 matching lines...) Expand all Loading... |
5246 } | 5256 } |
5247 mixin_types.Add(mixin_type); | 5257 mixin_types.Add(mixin_type); |
5248 } while (CurrentToken() == Token::kCOMMA); | 5258 } while (CurrentToken() == Token::kCOMMA); |
5249 return MixinAppType::New(super_type, | 5259 return MixinAppType::New(super_type, |
5250 Array::Handle(Z, Array::MakeArray(mixin_types))); | 5260 Array::Handle(Z, Array::MakeArray(mixin_types))); |
5251 } | 5261 } |
5252 | 5262 |
5253 | 5263 |
5254 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5264 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
5255 const Object& owner, | 5265 const Object& owner, |
5256 intptr_t metadata_pos) { | 5266 TokenPosition metadata_pos) { |
5257 TRACE_PARSER("ParseTopLevelVariable"); | 5267 TRACE_PARSER("ParseTopLevelVariable"); |
5258 const bool is_const = (CurrentToken() == Token::kCONST); | 5268 const bool is_const = (CurrentToken() == Token::kCONST); |
5259 // Const fields are implicitly final. | 5269 // Const fields are implicitly final. |
5260 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5270 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
5261 const bool is_static = true; | 5271 const bool is_static = true; |
5262 const AbstractType& type = AbstractType::ZoneHandle(Z, | 5272 const AbstractType& type = AbstractType::ZoneHandle(Z, |
5263 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5273 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
5264 Field& field = Field::Handle(Z); | 5274 Field& field = Field::Handle(Z); |
5265 Function& getter = Function::Handle(Z); | 5275 Function& getter = Function::Handle(Z); |
5266 while (true) { | 5276 while (true) { |
5267 const intptr_t name_pos = TokenPos(); | 5277 const TokenPosition name_pos = TokenPos(); |
5268 String& var_name = *ExpectIdentifier("variable name expected"); | 5278 String& var_name = *ExpectIdentifier("variable name expected"); |
5269 | 5279 |
5270 if (library_.LookupLocalObject(var_name) != Object::null()) { | 5280 if (library_.LookupLocalObject(var_name) != Object::null()) { |
5271 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); | 5281 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); |
5272 } | 5282 } |
5273 | 5283 |
5274 // Check whether a getter or setter for this name exists. A const | 5284 // Check whether a getter or setter for this name exists. A const |
5275 // or final field implies a setter which throws a NoSuchMethodError, | 5285 // or final field implies a setter which throws a NoSuchMethodError, |
5276 // thus we need to check for conflicts with existing setters and | 5286 // thus we need to check for conflicts with existing setters and |
5277 // getters. | 5287 // getters. |
(...skipping 10 matching lines...) Expand all Loading... |
5288 | 5298 |
5289 const bool is_reflectable = | 5299 const bool is_reflectable = |
5290 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); | 5300 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); |
5291 | 5301 |
5292 field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos); | 5302 field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos); |
5293 field.SetFieldType(type); | 5303 field.SetFieldType(type); |
5294 field.set_is_reflectable(is_reflectable); | 5304 field.set_is_reflectable(is_reflectable); |
5295 field.SetStaticValue(Object::null_instance(), true); | 5305 field.SetStaticValue(Object::null_instance(), true); |
5296 top_level->AddField(field); | 5306 top_level->AddField(field); |
5297 library_.AddObject(field, var_name); | 5307 library_.AddObject(field, var_name); |
5298 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5308 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5299 library_.AddFieldMetadata(field, metadata_pos); | 5309 library_.AddFieldMetadata(field, metadata_pos); |
5300 } | 5310 } |
5301 if (CurrentToken() == Token::kASSIGN) { | 5311 if (CurrentToken() == Token::kASSIGN) { |
5302 ConsumeToken(); | 5312 ConsumeToken(); |
5303 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); | 5313 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); |
5304 bool has_simple_literal = false; | 5314 bool has_simple_literal = false; |
5305 if (LookaheadToken(1) == Token::kSEMICOLON) { | 5315 if (LookaheadToken(1) == Token::kSEMICOLON) { |
5306 has_simple_literal = IsSimpleLiteral(type, &field_value); | 5316 has_simple_literal = IsSimpleLiteral(type, &field_value); |
5307 } | 5317 } |
5308 SkipExpr(); | 5318 SkipExpr(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5364 ConsumeToken(); | 5374 ConsumeToken(); |
5365 ConsumeToken(); | 5375 ConsumeToken(); |
5366 return RawFunction::kSyncGen; | 5376 return RawFunction::kSyncGen; |
5367 } | 5377 } |
5368 return RawFunction::kNoModifier; | 5378 return RawFunction::kNoModifier; |
5369 } | 5379 } |
5370 | 5380 |
5371 | 5381 |
5372 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5382 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
5373 const Object& owner, | 5383 const Object& owner, |
5374 intptr_t metadata_pos) { | 5384 TokenPosition metadata_pos) { |
5375 TRACE_PARSER("ParseTopLevelFunction"); | 5385 TRACE_PARSER("ParseTopLevelFunction"); |
5376 const intptr_t decl_begin_pos = TokenPos(); | 5386 const TokenPosition decl_begin_pos = TokenPos(); |
5377 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5387 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
5378 const bool is_static = true; | 5388 const bool is_static = true; |
5379 bool is_external = false; | 5389 bool is_external = false; |
5380 bool is_patch = false; | 5390 bool is_patch = false; |
5381 if (is_patch_source() && | 5391 if (is_patch_source() && |
5382 (CurrentToken() == Token::kIDENT) && | 5392 (CurrentToken() == Token::kIDENT) && |
5383 CurrentLiteral()->Equals("patch") && | 5393 CurrentLiteral()->Equals("patch") && |
5384 (LookaheadToken(1) != Token::kLPAREN)) { | 5394 (LookaheadToken(1) != Token::kLPAREN)) { |
5385 ConsumeToken(); | 5395 ConsumeToken(); |
5386 is_patch = true; | 5396 is_patch = true; |
5387 } else if (CurrentToken() == Token::kEXTERNAL) { | 5397 } else if (CurrentToken() == Token::kEXTERNAL) { |
5388 ConsumeToken(); | 5398 ConsumeToken(); |
5389 is_external = true; | 5399 is_external = true; |
5390 } | 5400 } |
5391 if (CurrentToken() == Token::kVOID) { | 5401 if (CurrentToken() == Token::kVOID) { |
5392 ConsumeToken(); | 5402 ConsumeToken(); |
5393 result_type = Type::VoidType(); | 5403 result_type = Type::VoidType(); |
5394 } else { | 5404 } else { |
5395 // Parse optional type. | 5405 // Parse optional type. |
5396 if ((CurrentToken() == Token::kIDENT) && | 5406 if ((CurrentToken() == Token::kIDENT) && |
5397 (LookaheadToken(1) != Token::kLPAREN)) { | 5407 (LookaheadToken(1) != Token::kLPAREN)) { |
5398 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5408 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
5399 } | 5409 } |
5400 } | 5410 } |
5401 const intptr_t name_pos = TokenPos(); | 5411 const TokenPosition name_pos = TokenPos(); |
5402 const String& func_name = *ExpectIdentifier("function name expected"); | 5412 const String& func_name = *ExpectIdentifier("function name expected"); |
5403 | 5413 |
5404 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 5414 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
5405 if (found && !is_patch) { | 5415 if (found && !is_patch) { |
5406 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); | 5416 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); |
5407 } else if (!found && is_patch) { | 5417 } else if (!found && is_patch) { |
5408 ReportError(name_pos, "missing '%s' cannot be patched", | 5418 ReportError(name_pos, "missing '%s' cannot be patched", |
5409 func_name.ToCString()); | 5419 func_name.ToCString()); |
5410 } | 5420 } |
5411 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); | 5421 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); |
5412 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5422 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
5413 ReportError(name_pos, "'%s' is already defined as getter", | 5423 ReportError(name_pos, "'%s' is already defined as getter", |
5414 func_name.ToCString()); | 5424 func_name.ToCString()); |
5415 } | 5425 } |
5416 // A setter named x= may co-exist with a function named x, thus we do | 5426 // A setter named x= may co-exist with a function named x, thus we do |
5417 // not need to check setters. | 5427 // not need to check setters. |
5418 | 5428 |
5419 CheckToken(Token::kLPAREN); | 5429 CheckToken(Token::kLPAREN); |
5420 const intptr_t function_pos = TokenPos(); | 5430 const TokenPosition function_pos = TokenPos(); |
5421 ParamList params; | 5431 ParamList params; |
5422 const bool allow_explicit_default_values = true; | 5432 const bool allow_explicit_default_values = true; |
5423 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5433 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
5424 | 5434 |
5425 const intptr_t modifier_pos = TokenPos(); | 5435 const TokenPosition modifier_pos = TokenPos(); |
5426 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5436 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
5427 | 5437 |
5428 intptr_t function_end_pos = function_pos; | 5438 TokenPosition function_end_pos = function_pos; |
5429 bool is_native = false; | 5439 bool is_native = false; |
5430 String* native_name = NULL; | 5440 String* native_name = NULL; |
5431 if (is_external) { | 5441 if (is_external) { |
5432 function_end_pos = TokenPos(); | 5442 function_end_pos = TokenPos(); |
5433 ExpectSemicolon(); | 5443 ExpectSemicolon(); |
5434 } else if (CurrentToken() == Token::kLBRACE) { | 5444 } else if (CurrentToken() == Token::kLBRACE) { |
5435 SkipBlock(); | 5445 SkipBlock(); |
5436 function_end_pos = TokenPos(); | 5446 function_end_pos = TokenPos(); |
5437 ExpectToken(Token::kRBRACE); | 5447 ExpectToken(Token::kRBRACE); |
5438 } else if (CurrentToken() == Token::kARROW) { | 5448 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5479 library_.AddObject(func, func_name); | 5489 library_.AddObject(func, func_name); |
5480 } else { | 5490 } else { |
5481 // Need to remove the previously added function that is being patched. | 5491 // Need to remove the previously added function that is being patched. |
5482 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); | 5492 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); |
5483 const Function& replaced_func = | 5493 const Function& replaced_func = |
5484 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); | 5494 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); |
5485 ASSERT(!replaced_func.IsNull()); | 5495 ASSERT(!replaced_func.IsNull()); |
5486 toplevel_cls.RemoveFunction(replaced_func); | 5496 toplevel_cls.RemoveFunction(replaced_func); |
5487 library_.ReplaceObject(func, func_name); | 5497 library_.ReplaceObject(func, func_name); |
5488 } | 5498 } |
5489 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5499 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5490 library_.AddFunctionMetadata(func, metadata_pos); | 5500 library_.AddFunctionMetadata(func, metadata_pos); |
5491 } | 5501 } |
5492 } | 5502 } |
5493 | 5503 |
5494 | 5504 |
5495 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 5505 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
5496 const Object& owner, | 5506 const Object& owner, |
5497 intptr_t metadata_pos) { | 5507 TokenPosition metadata_pos) { |
5498 TRACE_PARSER("ParseTopLevelAccessor"); | 5508 TRACE_PARSER("ParseTopLevelAccessor"); |
5499 const intptr_t decl_begin_pos = TokenPos(); | 5509 const TokenPosition decl_begin_pos = TokenPos(); |
5500 const bool is_static = true; | 5510 const bool is_static = true; |
5501 bool is_external = false; | 5511 bool is_external = false; |
5502 bool is_patch = false; | 5512 bool is_patch = false; |
5503 AbstractType& result_type = AbstractType::Handle(Z); | 5513 AbstractType& result_type = AbstractType::Handle(Z); |
5504 if (is_patch_source() && | 5514 if (is_patch_source() && |
5505 (CurrentToken() == Token::kIDENT) && | 5515 (CurrentToken() == Token::kIDENT) && |
5506 CurrentLiteral()->Equals("patch")) { | 5516 CurrentLiteral()->Equals("patch")) { |
5507 ConsumeToken(); | 5517 ConsumeToken(); |
5508 is_patch = true; | 5518 is_patch = true; |
5509 } else if (CurrentToken() == Token::kEXTERNAL) { | 5519 } else if (CurrentToken() == Token::kEXTERNAL) { |
(...skipping 12 matching lines...) Expand all Loading... |
5522 } else { | 5532 } else { |
5523 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5533 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
5524 } | 5534 } |
5525 is_getter = (CurrentToken() == Token::kGET); | 5535 is_getter = (CurrentToken() == Token::kGET); |
5526 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 5536 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
5527 ConsumeToken(); | 5537 ConsumeToken(); |
5528 } else { | 5538 } else { |
5529 UnexpectedToken(); | 5539 UnexpectedToken(); |
5530 } | 5540 } |
5531 } | 5541 } |
5532 const intptr_t name_pos = TokenPos(); | 5542 const TokenPosition name_pos = TokenPos(); |
5533 const String* field_name = ExpectIdentifier("accessor name expected"); | 5543 const String* field_name = ExpectIdentifier("accessor name expected"); |
5534 | 5544 |
5535 const intptr_t accessor_pos = TokenPos(); | 5545 const TokenPosition accessor_pos = TokenPos(); |
5536 ParamList params; | 5546 ParamList params; |
5537 | 5547 |
5538 if (!is_getter) { | 5548 if (!is_getter) { |
5539 const bool allow_explicit_default_values = true; | 5549 const bool allow_explicit_default_values = true; |
5540 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5550 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
5541 } | 5551 } |
5542 String& accessor_name = String::ZoneHandle(Z); | 5552 String& accessor_name = String::ZoneHandle(Z); |
5543 int expected_num_parameters = -1; | 5553 int expected_num_parameters = -1; |
5544 if (is_getter) { | 5554 if (is_getter) { |
5545 expected_num_parameters = 0; | 5555 expected_num_parameters = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
5572 if (found && !is_patch) { | 5582 if (found && !is_patch) { |
5573 ReportError(name_pos, "%s for '%s' is already defined", | 5583 ReportError(name_pos, "%s for '%s' is already defined", |
5574 is_getter ? "getter" : "setter", | 5584 is_getter ? "getter" : "setter", |
5575 field_name->ToCString()); | 5585 field_name->ToCString()); |
5576 } else if (!found && is_patch) { | 5586 } else if (!found && is_patch) { |
5577 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5587 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
5578 is_getter ? "getter" : "setter", | 5588 is_getter ? "getter" : "setter", |
5579 field_name->ToCString()); | 5589 field_name->ToCString()); |
5580 } | 5590 } |
5581 | 5591 |
5582 const intptr_t modifier_pos = TokenPos(); | 5592 const TokenPosition modifier_pos = TokenPos(); |
5583 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5593 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
5584 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { | 5594 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { |
5585 ReportError(modifier_pos, | 5595 ReportError(modifier_pos, |
5586 "setter function cannot be async, async* or sync*"); | 5596 "setter function cannot be async, async* or sync*"); |
5587 } | 5597 } |
5588 | 5598 |
5589 intptr_t accessor_end_pos = accessor_pos; | 5599 TokenPosition accessor_end_pos = accessor_pos; |
5590 bool is_native = false; | 5600 bool is_native = false; |
5591 String* native_name = NULL; | 5601 String* native_name = NULL; |
5592 if (is_external) { | 5602 if (is_external) { |
5593 accessor_end_pos = TokenPos(); | 5603 accessor_end_pos = TokenPos(); |
5594 ExpectSemicolon(); | 5604 ExpectSemicolon(); |
5595 } else if (CurrentToken() == Token::kLBRACE) { | 5605 } else if (CurrentToken() == Token::kLBRACE) { |
5596 SkipBlock(); | 5606 SkipBlock(); |
5597 accessor_end_pos = TokenPos(); | 5607 accessor_end_pos = TokenPos(); |
5598 ExpectToken(Token::kRBRACE); | 5608 ExpectToken(Token::kRBRACE); |
5599 } else if (CurrentToken() == Token::kARROW) { | 5609 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5644 // Need to remove the previously added accessor that is being patched. | 5654 // Need to remove the previously added accessor that is being patched. |
5645 const Class& toplevel_cls = Class::Handle(Z, | 5655 const Class& toplevel_cls = Class::Handle(Z, |
5646 owner.IsClass() ? Class::Cast(owner).raw() | 5656 owner.IsClass() ? Class::Cast(owner).raw() |
5647 : PatchClass::Cast(owner).patched_class()); | 5657 : PatchClass::Cast(owner).patched_class()); |
5648 const Function& replaced_func = | 5658 const Function& replaced_func = |
5649 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); | 5659 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); |
5650 ASSERT(!replaced_func.IsNull()); | 5660 ASSERT(!replaced_func.IsNull()); |
5651 toplevel_cls.RemoveFunction(replaced_func); | 5661 toplevel_cls.RemoveFunction(replaced_func); |
5652 library_.ReplaceObject(func, accessor_name); | 5662 library_.ReplaceObject(func, accessor_name); |
5653 } | 5663 } |
5654 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5664 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5655 library_.AddFunctionMetadata(func, metadata_pos); | 5665 library_.AddFunctionMetadata(func, metadata_pos); |
5656 } | 5666 } |
5657 } | 5667 } |
5658 | 5668 |
5659 | 5669 |
5660 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, | 5670 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, |
5661 intptr_t token_pos, | 5671 TokenPosition token_pos, |
5662 const String& url) { | 5672 const String& url) { |
5663 Dart_LibraryTagHandler handler = I->library_tag_handler(); | 5673 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
5664 if (handler == NULL) { | 5674 if (handler == NULL) { |
5665 if (url.StartsWith(Symbols::DartScheme())) { | 5675 if (url.StartsWith(Symbols::DartScheme())) { |
5666 if (tag == Dart_kCanonicalizeUrl) { | 5676 if (tag == Dart_kCanonicalizeUrl) { |
5667 return url.raw(); | 5677 return url.raw(); |
5668 } | 5678 } |
5669 return Object::null(); | 5679 return Object::null(); |
5670 } | 5680 } |
5671 ReportError(token_pos, "no library handler registered"); | 5681 ReportError(token_pos, "no library handler registered"); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5726 ConsumeToken(); // Identifier. | 5736 ConsumeToken(); // Identifier. |
5727 if (CurrentToken() != Token::kCOMMA) { | 5737 if (CurrentToken() != Token::kCOMMA) { |
5728 return; | 5738 return; |
5729 } | 5739 } |
5730 ConsumeToken(); // Comma. | 5740 ConsumeToken(); // Comma. |
5731 } | 5741 } |
5732 } | 5742 } |
5733 | 5743 |
5734 | 5744 |
5735 void Parser::ParseLibraryImportExport(const Object& tl_owner, | 5745 void Parser::ParseLibraryImportExport(const Object& tl_owner, |
5736 intptr_t metadata_pos) { | 5746 TokenPosition metadata_pos) { |
5737 bool is_import = (CurrentToken() == Token::kIMPORT); | 5747 bool is_import = (CurrentToken() == Token::kIMPORT); |
5738 bool is_export = (CurrentToken() == Token::kEXPORT); | 5748 bool is_export = (CurrentToken() == Token::kEXPORT); |
5739 ASSERT(is_import || is_export); | 5749 ASSERT(is_import || is_export); |
5740 const intptr_t import_pos = TokenPos(); | 5750 const TokenPosition import_pos = TokenPos(); |
5741 ConsumeToken(); | 5751 ConsumeToken(); |
5742 CheckToken(Token::kSTRING, "library url expected"); | 5752 CheckToken(Token::kSTRING, "library url expected"); |
5743 AstNode* url_literal = ParseStringLiteral(false); | 5753 AstNode* url_literal = ParseStringLiteral(false); |
5744 if (FLAG_conditional_directives) { | 5754 if (FLAG_conditional_directives) { |
5745 bool condition_triggered = false; | 5755 bool condition_triggered = false; |
5746 while (CurrentToken() == Token::kIF) { | 5756 while (CurrentToken() == Token::kIF) { |
5747 // Conditional import: if (env == val) uri. | 5757 // Conditional import: if (env == val) uri. |
5748 ConsumeToken(); | 5758 ConsumeToken(); |
5749 ExpectToken(Token::kLPAREN); | 5759 ExpectToken(Token::kLPAREN); |
5750 // Parse dotted name. | 5760 // Parse dotted name. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5794 if (url.Length() == 0) { | 5804 if (url.Length() == 0) { |
5795 ReportError("library url expected"); | 5805 ReportError("library url expected"); |
5796 } | 5806 } |
5797 bool is_deferred_import = false; | 5807 bool is_deferred_import = false; |
5798 if (is_import && (IsSymbol(Symbols::Deferred()))) { | 5808 if (is_import && (IsSymbol(Symbols::Deferred()))) { |
5799 is_deferred_import = true; | 5809 is_deferred_import = true; |
5800 ConsumeToken(); | 5810 ConsumeToken(); |
5801 CheckToken(Token::kAS, "'as' expected"); | 5811 CheckToken(Token::kAS, "'as' expected"); |
5802 } | 5812 } |
5803 String& prefix = String::Handle(Z); | 5813 String& prefix = String::Handle(Z); |
5804 intptr_t prefix_pos = Token::kNoSourcePos; | 5814 TokenPosition prefix_pos = TokenPosition::kNoSource; |
5805 if (is_import && (CurrentToken() == Token::kAS)) { | 5815 if (is_import && (CurrentToken() == Token::kAS)) { |
5806 ConsumeToken(); | 5816 ConsumeToken(); |
5807 prefix_pos = TokenPos(); | 5817 prefix_pos = TokenPos(); |
5808 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5818 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
5809 } | 5819 } |
5810 | 5820 |
5811 Array& show_names = Array::Handle(Z); | 5821 Array& show_names = Array::Handle(Z); |
5812 Array& hide_names = Array::Handle(Z); | 5822 Array& hide_names = Array::Handle(Z); |
5813 if (is_deferred_import || | 5823 if (is_deferred_import || |
5814 IsSymbol(Symbols::Show()) || | 5824 IsSymbol(Symbols::Show()) || |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5857 // library import, call the library tag handler to request loading | 5867 // library import, call the library tag handler to request loading |
5858 // the library. | 5868 // the library. |
5859 if (library.LoadNotStarted() && | 5869 if (library.LoadNotStarted() && |
5860 (!is_deferred_import || FLAG_load_deferred_eagerly)) { | 5870 (!is_deferred_import || FLAG_load_deferred_eagerly)) { |
5861 library.SetLoadRequested(); | 5871 library.SetLoadRequested(); |
5862 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 5872 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
5863 } | 5873 } |
5864 | 5874 |
5865 Namespace& ns = Namespace::Handle(Z, | 5875 Namespace& ns = Namespace::Handle(Z, |
5866 Namespace::New(library, show_names, hide_names)); | 5876 Namespace::New(library, show_names, hide_names)); |
5867 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5877 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5868 ns.AddMetadata(tl_owner, metadata_pos); | 5878 ns.AddMetadata(tl_owner, metadata_pos); |
5869 } | 5879 } |
5870 | 5880 |
5871 // Ensure that private dart:_ libraries are only imported into dart: | 5881 // Ensure that private dart:_ libraries are only imported into dart: |
5872 // libraries, including indirectly through exports. | 5882 // libraries, including indirectly through exports. |
5873 const String& lib_url = String::Handle(Z, library_.url()); | 5883 const String& lib_url = String::Handle(Z, library_.url()); |
5874 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5884 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
5875 !lib_url.StartsWith(Symbols::DartScheme())) { | 5885 !lib_url.StartsWith(Symbols::DartScheme())) { |
5876 ReportError(import_pos, "private library is not accessible"); | 5886 ReportError(import_pos, "private library is not accessible"); |
5877 } | 5887 } |
(...skipping 29 matching lines...) Expand all Loading... |
5907 } | 5917 } |
5908 } | 5918 } |
5909 } else { | 5919 } else { |
5910 ASSERT(is_export); | 5920 ASSERT(is_export); |
5911 library_.AddExport(ns); | 5921 library_.AddExport(ns); |
5912 } | 5922 } |
5913 } | 5923 } |
5914 | 5924 |
5915 | 5925 |
5916 void Parser::ParseLibraryPart() { | 5926 void Parser::ParseLibraryPart() { |
5917 const intptr_t source_pos = TokenPos(); | 5927 const TokenPosition source_pos = TokenPos(); |
5918 ConsumeToken(); // Consume "part". | 5928 ConsumeToken(); // Consume "part". |
5919 CheckToken(Token::kSTRING, "url expected"); | 5929 CheckToken(Token::kSTRING, "url expected"); |
5920 AstNode* url_literal = ParseStringLiteral(false); | 5930 AstNode* url_literal = ParseStringLiteral(false); |
5921 ASSERT(url_literal->IsLiteralNode()); | 5931 ASSERT(url_literal->IsLiteralNode()); |
5922 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 5932 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
5923 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 5933 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
5924 ExpectSemicolon(); | 5934 ExpectSemicolon(); |
5925 const String& canon_url = String::CheckedHandle( | 5935 const String& canon_url = String::CheckedHandle( |
5926 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); | 5936 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); |
5927 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); | 5937 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); |
5928 } | 5938 } |
5929 | 5939 |
5930 | 5940 |
5931 void Parser::ParseLibraryDefinition(const Object& tl_owner) { | 5941 void Parser::ParseLibraryDefinition(const Object& tl_owner) { |
5932 TRACE_PARSER("ParseLibraryDefinition"); | 5942 TRACE_PARSER("ParseLibraryDefinition"); |
5933 | 5943 |
5934 // Handle the script tag. | 5944 // Handle the script tag. |
5935 if (CurrentToken() == Token::kSCRIPTTAG) { | 5945 if (CurrentToken() == Token::kSCRIPTTAG) { |
5936 // Nothing to do for script tags except to skip them. | 5946 // Nothing to do for script tags except to skip them. |
5937 ConsumeToken(); | 5947 ConsumeToken(); |
5938 } | 5948 } |
5939 | 5949 |
5940 ASSERT(script_.kind() != RawScript::kSourceTag); | 5950 ASSERT(script_.kind() != RawScript::kSourceTag); |
5941 | 5951 |
5942 // We may read metadata tokens that are part of the toplevel | 5952 // We may read metadata tokens that are part of the toplevel |
5943 // declaration that follows the library definitions. Therefore, we | 5953 // declaration that follows the library definitions. Therefore, we |
5944 // need to remember the position of the last token that was | 5954 // need to remember the position of the last token that was |
5945 // successfully consumed. | 5955 // successfully consumed. |
5946 intptr_t rewind_pos = TokenPos(); | 5956 TokenPosition rewind_pos = TokenPos(); |
5947 intptr_t metadata_pos = SkipMetadata(); | 5957 TokenPosition metadata_pos = SkipMetadata(); |
5948 if (CurrentToken() == Token::kLIBRARY) { | 5958 if (CurrentToken() == Token::kLIBRARY) { |
5949 if (is_patch_source()) { | 5959 if (is_patch_source()) { |
5950 ReportError("patch cannot override library name"); | 5960 ReportError("patch cannot override library name"); |
5951 } | 5961 } |
5952 ParseLibraryName(); | 5962 ParseLibraryName(); |
5953 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5963 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5954 library_.AddLibraryMetadata(tl_owner, metadata_pos); | 5964 library_.AddLibraryMetadata(tl_owner, metadata_pos); |
5955 } | 5965 } |
5956 rewind_pos = TokenPos(); | 5966 rewind_pos = TokenPos(); |
5957 metadata_pos = SkipMetadata(); | 5967 metadata_pos = SkipMetadata(); |
5958 } | 5968 } |
5959 while ((CurrentToken() == Token::kIMPORT) || | 5969 while ((CurrentToken() == Token::kIMPORT) || |
5960 (CurrentToken() == Token::kEXPORT)) { | 5970 (CurrentToken() == Token::kEXPORT)) { |
5961 ParseLibraryImportExport(tl_owner, metadata_pos); | 5971 ParseLibraryImportExport(tl_owner, metadata_pos); |
5962 rewind_pos = TokenPos(); | 5972 rewind_pos = TokenPos(); |
5963 metadata_pos = SkipMetadata(); | 5973 metadata_pos = SkipMetadata(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6000 | 6010 |
6001 | 6011 |
6002 void Parser::ParseTopLevel() { | 6012 void Parser::ParseTopLevel() { |
6003 TRACE_PARSER("ParseTopLevel"); | 6013 TRACE_PARSER("ParseTopLevel"); |
6004 // Collect the classes found at the top level in this growable array. | 6014 // Collect the classes found at the top level in this growable array. |
6005 // They need to be registered with class finalization after parsing | 6015 // They need to be registered with class finalization after parsing |
6006 // has been completed. | 6016 // has been completed. |
6007 ObjectStore* object_store = I->object_store(); | 6017 ObjectStore* object_store = I->object_store(); |
6008 const GrowableObjectArray& pending_classes = | 6018 const GrowableObjectArray& pending_classes = |
6009 GrowableObjectArray::Handle(Z, object_store->pending_classes()); | 6019 GrowableObjectArray::Handle(Z, object_store->pending_classes()); |
6010 SetPosition(0); | 6020 SetPosition(TokenPosition::kMinSource); |
6011 is_top_level_ = true; | 6021 is_top_level_ = true; |
6012 TopLevel top_level(Z); | 6022 TopLevel top_level(Z); |
6013 | 6023 |
6014 Object& tl_owner = Object::Handle(Z); | 6024 Object& tl_owner = Object::Handle(Z); |
6015 Class& toplevel_class = Class::Handle(Z, library_.toplevel_class()); | 6025 Class& toplevel_class = Class::Handle(Z, library_.toplevel_class()); |
6016 if (toplevel_class.IsNull()) { | 6026 if (toplevel_class.IsNull()) { |
6017 toplevel_class = Class::New(Symbols::TopLevel(), script_, TokenPos()); | 6027 toplevel_class = Class::New(Symbols::TopLevel(), script_, TokenPos()); |
6018 toplevel_class.set_library(library_); | 6028 toplevel_class.set_library(library_); |
6019 library_.set_toplevel_class(toplevel_class); | 6029 library_.set_toplevel_class(toplevel_class); |
6020 tl_owner = toplevel_class.raw(); | 6030 tl_owner = toplevel_class.raw(); |
6021 } else { | 6031 } else { |
6022 tl_owner = PatchClass::New(toplevel_class, script_); | 6032 tl_owner = PatchClass::New(toplevel_class, script_); |
6023 } | 6033 } |
6024 | 6034 |
6025 if (is_library_source() || is_patch_source()) { | 6035 if (is_library_source() || is_patch_source()) { |
6026 set_current_class(toplevel_class); | 6036 set_current_class(toplevel_class); |
6027 ParseLibraryDefinition(tl_owner); | 6037 ParseLibraryDefinition(tl_owner); |
6028 } else if (is_part_source()) { | 6038 } else if (is_part_source()) { |
6029 ParsePartHeader(); | 6039 ParsePartHeader(); |
6030 } | 6040 } |
6031 | 6041 |
6032 const Class& cls = Class::Handle(Z); | 6042 const Class& cls = Class::Handle(Z); |
6033 while (true) { | 6043 while (true) { |
6034 set_current_class(cls); // No current class. | 6044 set_current_class(cls); // No current class. |
6035 intptr_t metadata_pos = SkipMetadata(); | 6045 TokenPosition metadata_pos = SkipMetadata(); |
6036 if (CurrentToken() == Token::kCLASS) { | 6046 if (CurrentToken() == Token::kCLASS) { |
6037 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); | 6047 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); |
6038 } else if (CurrentToken() == Token::kENUM) { | 6048 } else if (CurrentToken() == Token::kENUM) { |
6039 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); | 6049 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); |
6040 } else if ((CurrentToken() == Token::kTYPEDEF) && | 6050 } else if ((CurrentToken() == Token::kTYPEDEF) && |
6041 (LookaheadToken(1) != Token::kLPAREN)) { | 6051 (LookaheadToken(1) != Token::kLPAREN)) { |
6042 set_current_class(toplevel_class); | 6052 set_current_class(toplevel_class); |
6043 ParseTypedef(pending_classes, tl_owner, metadata_pos); | 6053 ParseTypedef(pending_classes, tl_owner, metadata_pos); |
6044 } else if ((CurrentToken() == Token::kABSTRACT) && | 6054 } else if ((CurrentToken() == Token::kABSTRACT) && |
6045 (LookaheadToken(1) == Token::kCLASS)) { | 6055 (LookaheadToken(1) == Token::kCLASS)) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6150 | 6160 |
6151 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { | 6161 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { |
6152 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); | 6162 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); |
6153 // The generated try-catch-finally that wraps the async generator function | 6163 // The generated try-catch-finally that wraps the async generator function |
6154 // body is the outermost try statement. | 6164 // body is the outermost try statement. |
6155 ASSERT(try_stack_ != NULL); | 6165 ASSERT(try_stack_ != NULL); |
6156 ASSERT(try_stack_->outer_try() == NULL); | 6166 ASSERT(try_stack_->outer_try() == NULL); |
6157 // We only get here when parsing an async generator body. | 6167 // We only get here when parsing an async generator body. |
6158 ASSERT(innermost_function().IsAsyncGenClosure()); | 6168 ASSERT(innermost_function().IsAsyncGenClosure()); |
6159 | 6169 |
6160 const intptr_t try_end_pos = innermost_function().end_token_pos(); | 6170 const TokenPosition try_end_pos = innermost_function().end_token_pos(); |
6161 | 6171 |
6162 // The try-block (closure body code) has been parsed. We are now | 6172 // The try-block (closure body code) has been parsed. We are now |
6163 // generating the code for the catch block. | 6173 // generating the code for the catch block. |
6164 LocalScope* try_scope = current_block_->scope; | 6174 LocalScope* try_scope = current_block_->scope; |
6165 try_stack_->enter_catch(); | 6175 try_stack_->enter_catch(); |
6166 OpenBlock(); // Catch handler list. | 6176 OpenBlock(); // Catch handler list. |
6167 OpenBlock(); // Catch block. | 6177 OpenBlock(); // Catch block. |
6168 | 6178 |
6169 // Add the exception and stack trace parameters to the scope. | 6179 // Add the exception and stack trace parameters to the scope. |
6170 CatchParamDesc exception_param; | 6180 CatchParamDesc exception_param; |
6171 CatchParamDesc stack_trace_param; | 6181 CatchParamDesc stack_trace_param; |
6172 exception_param.token_pos = Token::kNoSourcePos; | 6182 exception_param.token_pos = TokenPosition::kNoSource; |
6173 exception_param.type = &Object::dynamic_type(); | 6183 exception_param.type = &Object::dynamic_type(); |
6174 exception_param.name = &Symbols::ExceptionParameter(); | 6184 exception_param.name = &Symbols::ExceptionParameter(); |
6175 stack_trace_param.token_pos = Token::kNoSourcePos; | 6185 stack_trace_param.token_pos = TokenPosition::kNoSource; |
6176 stack_trace_param.type = &Object::dynamic_type(); | 6186 stack_trace_param.type = &Object::dynamic_type(); |
6177 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6187 stack_trace_param.name = &Symbols::StackTraceParameter(); |
6178 | 6188 |
6179 AddCatchParamsToScope( | 6189 AddCatchParamsToScope( |
6180 &exception_param, &stack_trace_param, current_block_->scope); | 6190 &exception_param, &stack_trace_param, current_block_->scope); |
6181 | 6191 |
6182 // Generate code to save the exception object and stack trace | 6192 // Generate code to save the exception object and stack trace |
6183 // in local variables. | 6193 // in local variables. |
6184 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6194 LocalVariable* context_var = try_scope->LocalLookupVariable( |
6185 Symbols::SavedTryContextVar()); | 6195 Symbols::SavedTryContextVar()); |
6186 ASSERT(context_var != NULL); | 6196 ASSERT(context_var != NULL); |
6187 | 6197 |
6188 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6198 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
6189 Symbols::ExceptionVar()); | 6199 Symbols::ExceptionVar()); |
6190 ASSERT(exception_var != NULL); | 6200 ASSERT(exception_var != NULL); |
6191 if (exception_param.var != NULL) { | 6201 if (exception_param.var != NULL) { |
6192 // Generate code to load the exception object (:exception_var) into | 6202 // Generate code to load the exception object (:exception_var) into |
6193 // the exception variable specified in this block. | 6203 // the exception variable specified in this block. |
6194 current_block_->statements->Add(new(Z) StoreLocalNode( | 6204 current_block_->statements->Add(new(Z) StoreLocalNode( |
6195 Token::kNoSourcePos, | 6205 TokenPosition::kNoSource, |
6196 exception_param.var, | 6206 exception_param.var, |
6197 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 6207 new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
6198 } | 6208 } |
6199 | 6209 |
6200 LocalVariable* stack_trace_var = | 6210 LocalVariable* stack_trace_var = |
6201 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6211 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
6202 ASSERT(stack_trace_var != NULL); | 6212 ASSERT(stack_trace_var != NULL); |
6203 if (stack_trace_param.var != NULL) { | 6213 if (stack_trace_param.var != NULL) { |
6204 // A stack trace variable is specified in this block, so generate code | 6214 // A stack trace variable is specified in this block, so generate code |
6205 // to load the stack trace object (:stack_trace_var) into the stack | 6215 // to load the stack trace object (:stack_trace_var) into the stack |
6206 // trace variable specified in this block. | 6216 // trace variable specified in this block. |
6207 current_block_->statements->Add(new(Z) StoreLocalNode( | 6217 current_block_->statements->Add(new(Z) StoreLocalNode( |
6208 Token::kNoSourcePos, | 6218 TokenPosition::kNoSource, |
6209 stack_trace_param.var, | 6219 stack_trace_param.var, |
6210 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 6220 new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
6211 } | 6221 } |
6212 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6222 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
6213 Symbols::SavedExceptionVar()); | 6223 Symbols::SavedExceptionVar()); |
6214 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6224 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
6215 Symbols::SavedStackTraceVar()); | 6225 Symbols::SavedStackTraceVar()); |
6216 SaveExceptionAndStacktrace(current_block_->statements, | 6226 SaveExceptionAndStacktrace(current_block_->statements, |
6217 exception_var, | 6227 exception_var, |
6218 stack_trace_var, | 6228 stack_trace_var, |
6219 saved_exception_var, | 6229 saved_exception_var, |
6220 saved_stack_trace_var); | 6230 saved_stack_trace_var); |
6221 | 6231 |
6222 // Catch block: add the error to the stream. | 6232 // Catch block: add the error to the stream. |
6223 // :controller.AddError(:exception, :stack_trace); | 6233 // :controller.AddError(:exception, :stack_trace); |
6224 // return; // The finally block will close the stream. | 6234 // return; // The finally block will close the stream. |
6225 LocalVariable* controller = | 6235 LocalVariable* controller = |
6226 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6236 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
6227 ASSERT(controller != NULL); | 6237 ASSERT(controller != NULL); |
6228 ArgumentListNode* args = | 6238 ArgumentListNode* args = |
6229 new(Z) ArgumentListNode(Token::kNoSourcePos); | 6239 new(Z) ArgumentListNode(TokenPosition::kNoSource); |
6230 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); | 6240 args->Add(new(Z) LoadLocalNode( |
6231 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); | 6241 TokenPosition::kNoSource, exception_param.var)); |
| 6242 args->Add(new(Z) LoadLocalNode( |
| 6243 TokenPosition::kNoSource, stack_trace_param.var)); |
6232 current_block_->statements->Add( | 6244 current_block_->statements->Add( |
6233 new(Z) InstanceCallNode(try_end_pos, | 6245 new(Z) InstanceCallNode(try_end_pos, |
6234 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), | 6246 new(Z) LoadLocalNode(TokenPosition::kNoSource, controller), |
6235 Symbols::AddError(), | 6247 Symbols::AddError(), |
6236 args)); | 6248 args)); |
6237 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos); | 6249 ReturnNode* return_node = new(Z) ReturnNode(TokenPosition::kNoSource); |
6238 AddNodeForFinallyInlining(return_node); | 6250 AddNodeForFinallyInlining(return_node); |
6239 current_block_->statements->Add(return_node); | 6251 current_block_->statements->Add(return_node); |
6240 AstNode* catch_block = CloseBlock(); | 6252 AstNode* catch_block = CloseBlock(); |
6241 current_block_->statements->Add(catch_block); | 6253 current_block_->statements->Add(catch_block); |
6242 SequenceNode* catch_handler_list = CloseBlock(); | 6254 SequenceNode* catch_handler_list = CloseBlock(); |
6243 | 6255 |
6244 TryStack* try_statement = PopTry(); | 6256 TryStack* try_statement = PopTry(); |
6245 ASSERT(try_stack_ == NULL); // We popped the outermost try block. | 6257 ASSERT(try_stack_ == NULL); // We popped the outermost try block. |
6246 | 6258 |
6247 // Finally block: closing the stream and returning. Instead of simply | 6259 // Finally block: closing the stream and returning. Instead of simply |
6248 // returning, create an await state and suspend. There may be outstanding | 6260 // returning, create an await state and suspend. There may be outstanding |
6249 // calls to schedule the generator body. This suspension ensures that we | 6261 // calls to schedule the generator body. This suspension ensures that we |
6250 // do not repeat any code of the generator body. | 6262 // do not repeat any code of the generator body. |
6251 // :controller.close(); | 6263 // :controller.close(); |
6252 // suspend; | 6264 // suspend; |
6253 // We need to inline this code in all recorded exit points. | 6265 // We need to inline this code in all recorded exit points. |
6254 intptr_t node_index = 0; | 6266 intptr_t node_index = 0; |
6255 SequenceNode* finally_clause = NULL; | 6267 SequenceNode* finally_clause = NULL; |
6256 if (try_stack_ != NULL) { | 6268 if (try_stack_ != NULL) { |
6257 try_stack_->enter_finally(); | 6269 try_stack_->enter_finally(); |
6258 } | 6270 } |
6259 do { | 6271 do { |
6260 OpenBlock(); | 6272 OpenBlock(); |
6261 ArgumentListNode* no_args = | 6273 ArgumentListNode* no_args = |
6262 new(Z) ArgumentListNode(Token::kNoSourcePos); | 6274 new(Z) ArgumentListNode(TokenPosition::kNoSource); |
6263 current_block_->statements->Add( | 6275 current_block_->statements->Add( |
6264 new(Z) InstanceCallNode(try_end_pos, | 6276 new(Z) InstanceCallNode(try_end_pos, |
6265 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), | 6277 new(Z) LoadLocalNode(TokenPosition::kNoSource, controller), |
6266 Symbols::Close(), | 6278 Symbols::Close(), |
6267 no_args)); | 6279 no_args)); |
6268 | 6280 |
6269 // Suspend after the close. | 6281 // Suspend after the close. |
6270 AwaitMarkerNode* await_marker = | 6282 AwaitMarkerNode* await_marker = |
6271 new(Z) AwaitMarkerNode(async_temp_scope_, | 6283 new(Z) AwaitMarkerNode(async_temp_scope_, |
6272 current_block_->scope, | 6284 current_block_->scope, |
6273 Token::kNoSourcePos); | 6285 TokenPosition::kNoSource); |
6274 current_block_->statements->Add(await_marker); | 6286 current_block_->statements->Add(await_marker); |
6275 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); | 6287 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); |
6276 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); | 6288 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); |
6277 current_block_->statements->Add(continuation_ret); | 6289 current_block_->statements->Add(continuation_ret); |
6278 | 6290 |
6279 finally_clause = CloseBlock(); | 6291 finally_clause = CloseBlock(); |
6280 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 6292 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
6281 if (node_to_inline != NULL) { | 6293 if (node_to_inline != NULL) { |
6282 InlinedFinallyNode* node = | 6294 InlinedFinallyNode* node = |
6283 new(Z) InlinedFinallyNode(try_end_pos, | 6295 new(Z) InlinedFinallyNode(try_end_pos, |
(...skipping 10 matching lines...) Expand all Loading... |
6294 if (try_stack_ != NULL) { | 6306 if (try_stack_ != NULL) { |
6295 try_stack_->exit_finally(); | 6307 try_stack_->exit_finally(); |
6296 } | 6308 } |
6297 | 6309 |
6298 const GrowableObjectArray& handler_types = | 6310 const GrowableObjectArray& handler_types = |
6299 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6311 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
6300 // Catch block handles all exceptions. | 6312 // Catch block handles all exceptions. |
6301 handler_types.Add(Object::dynamic_type()); | 6313 handler_types.Add(Object::dynamic_type()); |
6302 | 6314 |
6303 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 6315 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
6304 Token::kNoSourcePos, | 6316 TokenPosition::kNoSource, |
6305 catch_handler_list, | 6317 catch_handler_list, |
6306 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6318 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
6307 context_var, | 6319 context_var, |
6308 exception_var, | 6320 exception_var, |
6309 stack_trace_var, | 6321 stack_trace_var, |
6310 saved_exception_var, | 6322 saved_exception_var, |
6311 saved_stack_trace_var, | 6323 saved_stack_trace_var, |
6312 AllocateTryIndex(), | 6324 AllocateTryIndex(), |
6313 true); | 6325 true); |
6314 | 6326 |
6315 const intptr_t try_index = try_statement->try_index(); | 6327 const intptr_t try_index = try_statement->try_index(); |
6316 | 6328 |
6317 AstNode* try_catch_node = | 6329 AstNode* try_catch_node = |
6318 new(Z) TryCatchNode(Token::kNoSourcePos, | 6330 new(Z) TryCatchNode(TokenPosition::kNoSource, |
6319 body, | 6331 body, |
6320 context_var, | 6332 context_var, |
6321 catch_clause, | 6333 catch_clause, |
6322 finally_clause, | 6334 finally_clause, |
6323 try_index, | 6335 try_index, |
6324 finally_clause); | 6336 finally_clause); |
6325 current_block_->statements->Add(try_catch_node); | 6337 current_block_->statements->Add(try_catch_node); |
6326 return CloseBlock(); | 6338 return CloseBlock(); |
6327 } | 6339 } |
6328 | 6340 |
6329 | 6341 |
6330 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 6342 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { |
6331 // This is the outermost try-catch of the function. | 6343 // This is the outermost try-catch of the function. |
6332 ASSERT(try_stack_ != NULL); | 6344 ASSERT(try_stack_ != NULL); |
6333 ASSERT(try_stack_->outer_try() == NULL); | 6345 ASSERT(try_stack_->outer_try() == NULL); |
6334 ASSERT(innermost_function().IsAsyncClosure()); | 6346 ASSERT(innermost_function().IsAsyncClosure()); |
6335 LocalScope* try_scope = current_block_->scope; | 6347 LocalScope* try_scope = current_block_->scope; |
6336 | 6348 |
6337 try_stack_->enter_catch(); | 6349 try_stack_->enter_catch(); |
6338 | 6350 |
6339 OpenBlock(); // Catch handler list. | 6351 OpenBlock(); // Catch handler list. |
6340 OpenBlock(); // Catch block. | 6352 OpenBlock(); // Catch block. |
6341 CatchParamDesc exception_param; | 6353 CatchParamDesc exception_param; |
6342 CatchParamDesc stack_trace_param; | 6354 CatchParamDesc stack_trace_param; |
6343 exception_param.token_pos = Token::kNoSourcePos; | 6355 exception_param.token_pos = TokenPosition::kNoSource; |
6344 exception_param.type = &Object::dynamic_type(); | 6356 exception_param.type = &Object::dynamic_type(); |
6345 exception_param.name = &Symbols::ExceptionParameter(); | 6357 exception_param.name = &Symbols::ExceptionParameter(); |
6346 stack_trace_param.token_pos = Token::kNoSourcePos; | 6358 stack_trace_param.token_pos = TokenPosition::kNoSource; |
6347 stack_trace_param.type = &Object::dynamic_type(); | 6359 stack_trace_param.type = &Object::dynamic_type(); |
6348 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6360 stack_trace_param.name = &Symbols::StackTraceParameter(); |
6349 | 6361 |
6350 AddCatchParamsToScope( | 6362 AddCatchParamsToScope( |
6351 &exception_param, &stack_trace_param, current_block_->scope); | 6363 &exception_param, &stack_trace_param, current_block_->scope); |
6352 | 6364 |
6353 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6365 LocalVariable* context_var = try_scope->LocalLookupVariable( |
6354 Symbols::SavedTryContextVar()); | 6366 Symbols::SavedTryContextVar()); |
6355 ASSERT(context_var != NULL); | 6367 ASSERT(context_var != NULL); |
6356 | 6368 |
6357 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6369 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
6358 Symbols::ExceptionVar()); | 6370 Symbols::ExceptionVar()); |
6359 if (exception_param.var != NULL) { | 6371 if (exception_param.var != NULL) { |
6360 // Generate code to load the exception object (:exception_var) into | 6372 // Generate code to load the exception object (:exception_var) into |
6361 // the exception variable specified in this block. | 6373 // the exception variable specified in this block. |
6362 ASSERT(exception_var != NULL); | 6374 ASSERT(exception_var != NULL); |
6363 current_block_->statements->Add(new(Z) StoreLocalNode( | 6375 current_block_->statements->Add(new(Z) StoreLocalNode( |
6364 Token::kNoSourcePos, | 6376 TokenPosition::kNoSource, |
6365 exception_param.var, | 6377 exception_param.var, |
6366 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 6378 new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
6367 } | 6379 } |
6368 | 6380 |
6369 LocalVariable* stack_trace_var = | 6381 LocalVariable* stack_trace_var = |
6370 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6382 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
6371 if (stack_trace_param.var != NULL) { | 6383 if (stack_trace_param.var != NULL) { |
6372 // A stack trace variable is specified in this block, so generate code | 6384 // A stack trace variable is specified in this block, so generate code |
6373 // to load the stack trace object (:stack_trace_var) into the stack | 6385 // to load the stack trace object (:stack_trace_var) into the stack |
6374 // trace variable specified in this block. | 6386 // trace variable specified in this block. |
6375 ASSERT(stack_trace_var != NULL); | 6387 ASSERT(stack_trace_var != NULL); |
6376 current_block_->statements->Add(new(Z) StoreLocalNode( | 6388 current_block_->statements->Add(new(Z) StoreLocalNode( |
6377 Token::kNoSourcePos, | 6389 TokenPosition::kNoSource, |
6378 stack_trace_param.var, | 6390 stack_trace_param.var, |
6379 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 6391 new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
6380 } | 6392 } |
6381 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6393 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
6382 Symbols::SavedExceptionVar()); | 6394 Symbols::SavedExceptionVar()); |
6383 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6395 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
6384 Symbols::SavedStackTraceVar()); | 6396 Symbols::SavedStackTraceVar()); |
6385 SaveExceptionAndStacktrace(current_block_->statements, | 6397 SaveExceptionAndStacktrace(current_block_->statements, |
6386 exception_var, | 6398 exception_var, |
6387 stack_trace_var, | 6399 stack_trace_var, |
6388 saved_exception_var, | 6400 saved_exception_var, |
6389 saved_stack_trace_var); | 6401 saved_stack_trace_var); |
6390 | 6402 |
6391 // Complete the async future with an error. This catch block executes | 6403 // Complete the async future with an error. This catch block executes |
6392 // unconditionally, there is no need to generate a type check for. | 6404 // unconditionally, there is no need to generate a type check for. |
6393 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6405 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
6394 Symbols::AsyncCompleter(), false); | 6406 Symbols::AsyncCompleter(), false); |
6395 ASSERT(async_completer != NULL); | 6407 ASSERT(async_completer != NULL); |
6396 ArgumentListNode* completer_args = | 6408 ArgumentListNode* completer_args = |
6397 new (Z) ArgumentListNode(Token::kNoSourcePos); | 6409 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
6398 completer_args->Add( | 6410 completer_args->Add( |
6399 new (Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); | 6411 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_param.var)); |
6400 completer_args->Add( | 6412 completer_args->Add( |
6401 new (Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); | 6413 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
| 6414 stack_trace_param.var)); |
6402 current_block_->statements->Add(new (Z) InstanceCallNode( | 6415 current_block_->statements->Add(new (Z) InstanceCallNode( |
6403 TokenPos(), | 6416 TokenPos(), |
6404 new (Z) LoadLocalNode(Token::kNoSourcePos, async_completer), | 6417 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_completer), |
6405 Symbols::CompleterCompleteError(), | 6418 Symbols::CompleterCompleteError(), |
6406 completer_args)); | 6419 completer_args)); |
6407 ReturnNode* return_node = new (Z) ReturnNode(Token::kNoSourcePos); | 6420 ReturnNode* return_node = new (Z) ReturnNode(TokenPosition::kNoSource); |
6408 // Behavior like a continuation return, i.e,. don't call a completer. | 6421 // Behavior like a continuation return, i.e,. don't call a completer. |
6409 return_node->set_return_type(ReturnNode::kContinuation); | 6422 return_node->set_return_type(ReturnNode::kContinuation); |
6410 current_block_->statements->Add(return_node); | 6423 current_block_->statements->Add(return_node); |
6411 AstNode* catch_block = CloseBlock(); | 6424 AstNode* catch_block = CloseBlock(); |
6412 current_block_->statements->Add(catch_block); | 6425 current_block_->statements->Add(catch_block); |
6413 SequenceNode* catch_handler_list = CloseBlock(); | 6426 SequenceNode* catch_handler_list = CloseBlock(); |
6414 | 6427 |
6415 const GrowableObjectArray& handler_types = | 6428 const GrowableObjectArray& handler_types = |
6416 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6429 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
6417 handler_types.SetLength(0); | 6430 handler_types.SetLength(0); |
6418 handler_types.Add(*exception_param.type); | 6431 handler_types.Add(*exception_param.type); |
6419 | 6432 |
6420 TryStack* try_statement = PopTry(); | 6433 TryStack* try_statement = PopTry(); |
6421 const intptr_t try_index = try_statement->try_index(); | 6434 const intptr_t try_index = try_statement->try_index(); |
6422 | 6435 |
6423 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( | 6436 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
6424 Token::kNoSourcePos, | 6437 TokenPosition::kNoSource, |
6425 catch_handler_list, | 6438 catch_handler_list, |
6426 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6439 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
6427 context_var, | 6440 context_var, |
6428 exception_var, | 6441 exception_var, |
6429 stack_trace_var, | 6442 stack_trace_var, |
6430 saved_exception_var, | 6443 saved_exception_var, |
6431 saved_stack_trace_var, | 6444 saved_stack_trace_var, |
6432 CatchClauseNode::kInvalidTryIndex, | 6445 CatchClauseNode::kInvalidTryIndex, |
6433 true); | 6446 true); |
6434 AstNode* try_catch_node = new (Z) TryCatchNode( | 6447 AstNode* try_catch_node = new (Z) TryCatchNode( |
6435 Token::kNoSourcePos, | 6448 TokenPosition::kNoSource, |
6436 try_block, | 6449 try_block, |
6437 context_var, | 6450 context_var, |
6438 catch_clause, | 6451 catch_clause, |
6439 NULL, // No finally clause. | 6452 NULL, // No finally clause. |
6440 try_index, | 6453 try_index, |
6441 NULL); // No rethrow-finally clause. | 6454 NULL); // No rethrow-finally clause. |
6442 current_block_->statements->Add(try_catch_node); | 6455 current_block_->statements->Add(try_catch_node); |
6443 return CloseBlock(); | 6456 return CloseBlock(); |
6444 } | 6457 } |
6445 | 6458 |
(...skipping 25 matching lines...) Expand all Loading... |
6471 } | 6484 } |
6472 | 6485 |
6473 | 6486 |
6474 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6487 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
6475 // Create the parameter list for the body closure of a sync generator: | 6488 // Create the parameter list for the body closure of a sync generator: |
6476 // 1) Implicit closure parameter; | 6489 // 1) Implicit closure parameter; |
6477 // 2) Iterator | 6490 // 2) Iterator |
6478 // Add implicit closure parameter if not already present. | 6491 // Add implicit closure parameter if not already present. |
6479 if (params->parameters->length() == 0) { | 6492 if (params->parameters->length() == 0) { |
6480 params->AddFinalParameter( | 6493 params->AddFinalParameter( |
6481 0, &Symbols::ClosureParameter(), &Object::dynamic_type()); | 6494 TokenPosition::kMinSource, |
| 6495 &Symbols::ClosureParameter(), |
| 6496 &Object::dynamic_type()); |
6482 } | 6497 } |
6483 ParamDesc iterator_param; | 6498 ParamDesc iterator_param; |
6484 iterator_param.name = &Symbols::IteratorParameter(); | 6499 iterator_param.name = &Symbols::IteratorParameter(); |
6485 iterator_param.type = &Object::dynamic_type(); | 6500 iterator_param.type = &Object::dynamic_type(); |
6486 params->parameters->Add(iterator_param); | 6501 params->parameters->Add(iterator_param); |
6487 params->num_fixed_parameters++; | 6502 params->num_fixed_parameters++; |
6488 } | 6503 } |
6489 | 6504 |
6490 | 6505 |
6491 void Parser::AddAsyncGenClosureParameters(ParamList* params) { | 6506 void Parser::AddAsyncGenClosureParameters(ParamList* params) { |
6492 // Create the parameter list for the body closure of an async generator. | 6507 // Create the parameter list for the body closure of an async generator. |
6493 // The closure has the same parameters as an asynchronous non-generator. | 6508 // The closure has the same parameters as an asynchronous non-generator. |
6494 AddAsyncClosureParameters(params); | 6509 AddAsyncClosureParameters(params); |
6495 } | 6510 } |
6496 | 6511 |
6497 | 6512 |
6498 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { | 6513 RawFunction* Parser::OpenSyncGeneratorFunction(TokenPosition func_pos) { |
6499 Function& body = Function::Handle(Z); | 6514 Function& body = Function::Handle(Z); |
6500 String& body_closure_name = String::Handle(Z); | 6515 String& body_closure_name = String::Handle(Z); |
6501 bool is_new_closure = false; | 6516 bool is_new_closure = false; |
6502 | 6517 |
6503 AddContinuationVariables(); | 6518 AddContinuationVariables(); |
6504 | 6519 |
6505 // Check whether a function for the body of this generator | 6520 // Check whether a function for the body of this generator |
6506 // function has already been created by a previous | 6521 // function has already been created by a previous |
6507 // compilation. | 6522 // compilation. |
6508 const Function& found_func = Function::Handle( | 6523 const Function& found_func = Function::Handle( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6555 LocalVariable* existing_var = | 6570 LocalVariable* existing_var = |
6556 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 6571 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
6557 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6572 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
6558 existing_var = | 6573 existing_var = |
6559 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 6574 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
6560 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6575 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
6561 | 6576 |
6562 // :await_jump_var = -1; | 6577 // :await_jump_var = -1; |
6563 LocalVariable* jump_var = | 6578 LocalVariable* jump_var = |
6564 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6579 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
6565 LiteralNode* init_value = | 6580 LiteralNode* init_value = new(Z) LiteralNode(TokenPosition::kNoSource, |
6566 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6581 Smi::ZoneHandle(Smi::New(-1))); |
6567 current_block_->statements->Add( | 6582 current_block_->statements->Add( |
6568 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); | 6583 new(Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); |
6569 | 6584 |
6570 // return new SyncIterable(body_closure); | 6585 // return new SyncIterable(body_closure); |
6571 const Class& iterable_class = | 6586 const Class& iterable_class = |
6572 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); | 6587 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); |
6573 ASSERT(!iterable_class.IsNull()); | 6588 ASSERT(!iterable_class.IsNull()); |
6574 const Function& iterable_constructor = Function::ZoneHandle(Z, | 6589 const Function& iterable_constructor = Function::ZoneHandle(Z, |
6575 iterable_class.LookupConstructorAllowPrivate( | 6590 iterable_class.LookupConstructorAllowPrivate( |
6576 Symbols::_SyncIterableConstructor())); | 6591 Symbols::_SyncIterableConstructor())); |
6577 ASSERT(!iterable_constructor.IsNull()); | 6592 ASSERT(!iterable_constructor.IsNull()); |
6578 | 6593 |
6579 const String& closure_name = String::Handle(Z, closure.name()); | 6594 const String& closure_name = String::Handle(Z, closure.name()); |
6580 ASSERT(closure_name.IsSymbol()); | 6595 ASSERT(closure_name.IsSymbol()); |
6581 | 6596 |
6582 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); | 6597 ArgumentListNode* arguments = |
| 6598 new(Z) ArgumentListNode(TokenPosition::kNoSource); |
6583 ClosureNode* closure_obj = new(Z) ClosureNode( | 6599 ClosureNode* closure_obj = new(Z) ClosureNode( |
6584 Token::kNoSourcePos, closure, NULL, closure_body->scope()); | 6600 TokenPosition::kNoSource, closure, NULL, closure_body->scope()); |
6585 arguments->Add(closure_obj); | 6601 arguments->Add(closure_obj); |
6586 ConstructorCallNode* new_iterable = | 6602 ConstructorCallNode* new_iterable = |
6587 new(Z) ConstructorCallNode(Token::kNoSourcePos, | 6603 new(Z) ConstructorCallNode(TokenPosition::kNoSource, |
6588 TypeArguments::ZoneHandle(Z), | 6604 TypeArguments::ZoneHandle(Z), |
6589 iterable_constructor, | 6605 iterable_constructor, |
6590 arguments); | 6606 arguments); |
6591 ReturnNode* return_node = | 6607 ReturnNode* return_node = |
6592 new (Z) ReturnNode(Token::kNoSourcePos, new_iterable); | 6608 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); |
6593 current_block_->statements->Add(return_node); | 6609 current_block_->statements->Add(return_node); |
6594 return CloseBlock(); | 6610 return CloseBlock(); |
6595 } | 6611 } |
6596 | 6612 |
6597 | 6613 |
6598 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6614 void Parser::AddAsyncClosureParameters(ParamList* params) { |
6599 // Async closures have three optional parameters: | 6615 // Async closures have three optional parameters: |
6600 // * A continuation result. | 6616 // * A continuation result. |
6601 // * A continuation error. | 6617 // * A continuation error. |
6602 // * A continuation stack trace. | 6618 // * A continuation stack trace. |
6603 ASSERT(params->parameters->length() <= 1); | 6619 ASSERT(params->parameters->length() <= 1); |
6604 // Add implicit closure parameter if not yet present. | 6620 // Add implicit closure parameter if not yet present. |
6605 if (params->parameters->length() == 0) { | 6621 if (params->parameters->length() == 0) { |
6606 params->AddFinalParameter( | 6622 params->AddFinalParameter( |
6607 0, &Symbols::ClosureParameter(), &Object::dynamic_type()); | 6623 TokenPosition::kMinSource, |
| 6624 &Symbols::ClosureParameter(), |
| 6625 &Object::dynamic_type()); |
6608 } | 6626 } |
6609 ParamDesc result_param; | 6627 ParamDesc result_param; |
6610 result_param.name = &Symbols::AsyncOperationParam(); | 6628 result_param.name = &Symbols::AsyncOperationParam(); |
6611 result_param.default_value = &Object::null_instance(); | 6629 result_param.default_value = &Object::null_instance(); |
6612 result_param.type = &Object::dynamic_type(); | 6630 result_param.type = &Object::dynamic_type(); |
6613 params->parameters->Add(result_param); | 6631 params->parameters->Add(result_param); |
6614 ParamDesc error_param; | 6632 ParamDesc error_param; |
6615 error_param.name = &Symbols::AsyncOperationErrorParam(); | 6633 error_param.name = &Symbols::AsyncOperationErrorParam(); |
6616 error_param.default_value = &Object::null_instance(); | 6634 error_param.default_value = &Object::null_instance(); |
6617 error_param.type = &Object::dynamic_type(); | 6635 error_param.type = &Object::dynamic_type(); |
6618 params->parameters->Add(error_param); | 6636 params->parameters->Add(error_param); |
6619 ParamDesc stack_trace_param; | 6637 ParamDesc stack_trace_param; |
6620 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | 6638 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); |
6621 stack_trace_param.default_value = &Object::null_instance(); | 6639 stack_trace_param.default_value = &Object::null_instance(); |
6622 stack_trace_param.type = &Object::dynamic_type(); | 6640 stack_trace_param.type = &Object::dynamic_type(); |
6623 params->parameters->Add(stack_trace_param); | 6641 params->parameters->Add(stack_trace_param); |
6624 params->has_optional_positional_parameters = true; | 6642 params->has_optional_positional_parameters = true; |
6625 params->num_optional_parameters += 3; | 6643 params->num_optional_parameters += 3; |
6626 } | 6644 } |
6627 | 6645 |
6628 | 6646 |
6629 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { | 6647 RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) { |
6630 TRACE_PARSER("OpenAsyncFunction"); | 6648 TRACE_PARSER("OpenAsyncFunction"); |
6631 AddContinuationVariables(); | 6649 AddContinuationVariables(); |
6632 AddAsyncClosureVariables(); | 6650 AddAsyncClosureVariables(); |
6633 Function& closure = Function::Handle(Z); | 6651 Function& closure = Function::Handle(Z); |
6634 bool is_new_closure = false; | 6652 bool is_new_closure = false; |
6635 | 6653 |
6636 // Check whether a function for the asynchronous function body of | 6654 // Check whether a function for the asynchronous function body of |
6637 // this async function has already been created by a previous | 6655 // this async function has already been created by a previous |
6638 // compilation of this function. | 6656 // compilation of this function. |
6639 const Function& found_func = Function::Handle( | 6657 const Function& found_func = Function::Handle( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6676 async_temp_scope_ = current_block_->scope; | 6694 async_temp_scope_ = current_block_->scope; |
6677 return closure.raw(); | 6695 return closure.raw(); |
6678 } | 6696 } |
6679 | 6697 |
6680 | 6698 |
6681 void Parser::AddContinuationVariables() { | 6699 void Parser::AddContinuationVariables() { |
6682 // Add to current block's scope: | 6700 // Add to current block's scope: |
6683 // var :await_jump_var; | 6701 // var :await_jump_var; |
6684 // var :await_ctx_var; | 6702 // var :await_ctx_var; |
6685 LocalVariable* await_jump_var = new (Z) LocalVariable( | 6703 LocalVariable* await_jump_var = new (Z) LocalVariable( |
6686 Token::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type()); | 6704 TokenPosition::kNoSource, |
| 6705 Symbols::AwaitJumpVar(), |
| 6706 Object::dynamic_type()); |
6687 current_block_->scope->AddVariable(await_jump_var); | 6707 current_block_->scope->AddVariable(await_jump_var); |
6688 LocalVariable* await_ctx_var = new (Z) LocalVariable( | 6708 LocalVariable* await_ctx_var = new (Z) LocalVariable( |
6689 Token::kNoSourcePos, | 6709 TokenPosition::kNoSource, |
6690 Symbols::AwaitContextVar(), | 6710 Symbols::AwaitContextVar(), |
6691 Object::dynamic_type()); | 6711 Object::dynamic_type()); |
6692 current_block_->scope->AddVariable(await_ctx_var); | 6712 current_block_->scope->AddVariable(await_ctx_var); |
6693 } | 6713 } |
6694 | 6714 |
6695 | 6715 |
6696 void Parser::AddAsyncClosureVariables() { | 6716 void Parser::AddAsyncClosureVariables() { |
6697 // Add to current block's scope: | 6717 // Add to current block's scope: |
6698 // var :async_op; | 6718 // var :async_op; |
6699 // var :async_then_callback; | 6719 // var :async_then_callback; |
6700 // var :async_catch_error_callback; | 6720 // var :async_catch_error_callback; |
6701 // var :async_completer; | 6721 // var :async_completer; |
6702 LocalVariable* async_op_var = new(Z) LocalVariable( | 6722 LocalVariable* async_op_var = new(Z) LocalVariable( |
6703 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6723 TokenPosition::kNoSource, |
| 6724 Symbols::AsyncOperation(), |
| 6725 Object::dynamic_type()); |
6704 current_block_->scope->AddVariable(async_op_var); | 6726 current_block_->scope->AddVariable(async_op_var); |
6705 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6727 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
6706 Token::kNoSourcePos, | 6728 TokenPosition::kNoSource, |
6707 Symbols::AsyncThenCallback(), | 6729 Symbols::AsyncThenCallback(), |
6708 Object::dynamic_type()); | 6730 Object::dynamic_type()); |
6709 current_block_->scope->AddVariable(async_then_callback_var); | 6731 current_block_->scope->AddVariable(async_then_callback_var); |
6710 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6732 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
6711 Token::kNoSourcePos, | 6733 TokenPosition::kNoSource, |
6712 Symbols::AsyncCatchErrorCallback(), | 6734 Symbols::AsyncCatchErrorCallback(), |
6713 Object::dynamic_type()); | 6735 Object::dynamic_type()); |
6714 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6736 current_block_->scope->AddVariable(async_catch_error_callback_var); |
6715 LocalVariable* async_completer = new(Z) LocalVariable( | 6737 LocalVariable* async_completer = new(Z) LocalVariable( |
6716 Token::kNoSourcePos, | 6738 TokenPosition::kNoSource, |
6717 Symbols::AsyncCompleter(), | 6739 Symbols::AsyncCompleter(), |
6718 Object::dynamic_type()); | 6740 Object::dynamic_type()); |
6719 current_block_->scope->AddVariable(async_completer); | 6741 current_block_->scope->AddVariable(async_completer); |
6720 } | 6742 } |
6721 | 6743 |
6722 | 6744 |
6723 void Parser::AddAsyncGeneratorVariables() { | 6745 void Parser::AddAsyncGeneratorVariables() { |
6724 // Add to current block's scope: | 6746 // Add to current block's scope: |
6725 // var :controller; | 6747 // var :controller; |
6726 // The :controller variable is used by the async generator closure to | 6748 // The :controller variable is used by the async generator closure to |
6727 // store the StreamController object to which the yielded expressions | 6749 // store the StreamController object to which the yielded expressions |
6728 // are added. | 6750 // are added. |
6729 // var :async_op; | 6751 // var :async_op; |
6730 // var :async_then_callback; | 6752 // var :async_then_callback; |
6731 // var :async_catch_error_callback; | 6753 // var :async_catch_error_callback; |
6732 // These variables are used to store the async generator closure containing | 6754 // These variables are used to store the async generator closure containing |
6733 // the body of the async* function. They are used by the await operator. | 6755 // the body of the async* function. They are used by the await operator. |
6734 LocalVariable* controller_var = new(Z) LocalVariable( | 6756 LocalVariable* controller_var = new(Z) LocalVariable( |
6735 Token::kNoSourcePos, Symbols::Controller(), Object::dynamic_type()); | 6757 TokenPosition::kNoSource, |
| 6758 Symbols::Controller(), |
| 6759 Object::dynamic_type()); |
6736 current_block_->scope->AddVariable(controller_var); | 6760 current_block_->scope->AddVariable(controller_var); |
6737 LocalVariable* async_op_var = new(Z) LocalVariable( | 6761 LocalVariable* async_op_var = new(Z) LocalVariable( |
6738 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6762 TokenPosition::kNoSource, |
| 6763 Symbols::AsyncOperation(), |
| 6764 Object::dynamic_type()); |
6739 current_block_->scope->AddVariable(async_op_var); | 6765 current_block_->scope->AddVariable(async_op_var); |
6740 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6766 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
6741 Token::kNoSourcePos, | 6767 TokenPosition::kNoSource, |
6742 Symbols::AsyncThenCallback(), | 6768 Symbols::AsyncThenCallback(), |
6743 Object::dynamic_type()); | 6769 Object::dynamic_type()); |
6744 current_block_->scope->AddVariable(async_then_callback_var); | 6770 current_block_->scope->AddVariable(async_then_callback_var); |
6745 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6771 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
6746 Token::kNoSourcePos, | 6772 TokenPosition::kNoSource, |
6747 Symbols::AsyncCatchErrorCallback(), | 6773 Symbols::AsyncCatchErrorCallback(), |
6748 Object::dynamic_type()); | 6774 Object::dynamic_type()); |
6749 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6775 current_block_->scope->AddVariable(async_catch_error_callback_var); |
6750 } | 6776 } |
6751 | 6777 |
6752 | 6778 |
6753 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) { | 6779 RawFunction* Parser::OpenAsyncGeneratorFunction( |
| 6780 TokenPosition async_func_pos) { |
6754 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 6781 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
6755 AddContinuationVariables(); | 6782 AddContinuationVariables(); |
6756 AddAsyncGeneratorVariables(); | 6783 AddAsyncGeneratorVariables(); |
6757 | 6784 |
6758 Function& closure = Function::Handle(Z); | 6785 Function& closure = Function::Handle(Z); |
6759 bool is_new_closure = false; | 6786 bool is_new_closure = false; |
6760 | 6787 |
6761 // Check whether a function for the asynchronous function body of | 6788 // Check whether a function for the asynchronous function body of |
6762 // this async generator has already been created by a previous | 6789 // this async generator has already been created by a previous |
6763 // compilation of this function. | 6790 // compilation of this function. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6854 async_lib.LookupClassAllowPrivate( | 6881 async_lib.LookupClassAllowPrivate( |
6855 Symbols::_AsyncStarStreamController())); | 6882 Symbols::_AsyncStarStreamController())); |
6856 ASSERT(!controller_class.IsNull()); | 6883 ASSERT(!controller_class.IsNull()); |
6857 const Function& controller_constructor = Function::ZoneHandle(Z, | 6884 const Function& controller_constructor = Function::ZoneHandle(Z, |
6858 controller_class.LookupConstructorAllowPrivate( | 6885 controller_class.LookupConstructorAllowPrivate( |
6859 Symbols::_AsyncStarStreamControllerConstructor())); | 6886 Symbols::_AsyncStarStreamControllerConstructor())); |
6860 | 6887 |
6861 // :await_jump_var = -1; | 6888 // :await_jump_var = -1; |
6862 LocalVariable* jump_var = | 6889 LocalVariable* jump_var = |
6863 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6890 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
6864 LiteralNode* init_value = | 6891 LiteralNode* init_value = new(Z) LiteralNode(TokenPosition::kNoSource, |
6865 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6892 Smi::ZoneHandle(Smi::New(-1))); |
6866 current_block_->statements->Add( | 6893 current_block_->statements->Add( |
6867 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); | 6894 new(Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); |
6868 | 6895 |
6869 // Add to AST: | 6896 // Add to AST: |
6870 // :async_op = <closure>; (containing the original body) | 6897 // :async_op = <closure>; (containing the original body) |
6871 LocalVariable* async_op_var = | 6898 LocalVariable* async_op_var = |
6872 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 6899 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
6873 ClosureNode* closure_obj = new(Z) ClosureNode( | 6900 ClosureNode* closure_obj = new(Z) ClosureNode( |
6874 Token::kNoSourcePos, closure_func, NULL, closure_body->scope()); | 6901 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); |
6875 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 6902 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
6876 Token::kNoSourcePos, | 6903 TokenPosition::kNoSource, |
6877 async_op_var, | 6904 async_op_var, |
6878 closure_obj); | 6905 closure_obj); |
6879 | 6906 |
6880 current_block_->statements->Add(store_async_op); | 6907 current_block_->statements->Add(store_async_op); |
6881 | 6908 |
6882 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 6909 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
6883 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 6910 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
6884 Z, async_lib.LookupFunctionAllowPrivate( | 6911 Z, async_lib.LookupFunctionAllowPrivate( |
6885 Symbols::AsyncThenWrapperHelper())); | 6912 Symbols::AsyncThenWrapperHelper())); |
6886 ASSERT(!async_then_wrapper_helper.IsNull()); | 6913 ASSERT(!async_then_wrapper_helper.IsNull()); |
6887 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 6914 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( |
6888 Token::kNoSourcePos); | 6915 TokenPosition::kNoSource); |
6889 async_then_wrapper_helper_args->Add( | 6916 async_then_wrapper_helper_args->Add( |
6890 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6917 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); |
6891 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 6918 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( |
6892 Token::kNoSourcePos, | 6919 TokenPosition::kNoSource, |
6893 async_then_wrapper_helper, | 6920 async_then_wrapper_helper, |
6894 async_then_wrapper_helper_args); | 6921 async_then_wrapper_helper_args); |
6895 LocalVariable* async_then_callback_var = | 6922 LocalVariable* async_then_callback_var = |
6896 current_block_->scope->LookupVariable( | 6923 current_block_->scope->LookupVariable( |
6897 Symbols::AsyncThenCallback(), false); | 6924 Symbols::AsyncThenCallback(), false); |
6898 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 6925 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( |
6899 Token::kNoSourcePos, | 6926 TokenPosition::kNoSource, |
6900 async_then_callback_var, | 6927 async_then_callback_var, |
6901 then_wrapper_call); | 6928 then_wrapper_call); |
6902 | 6929 |
6903 current_block_->statements->Add(store_async_then_callback); | 6930 current_block_->statements->Add(store_async_then_callback); |
6904 | 6931 |
6905 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 6932 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
6906 | 6933 |
6907 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 6934 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
6908 Z, async_lib.LookupFunctionAllowPrivate( | 6935 Z, async_lib.LookupFunctionAllowPrivate( |
6909 Symbols::AsyncErrorWrapperHelper())); | 6936 Symbols::AsyncErrorWrapperHelper())); |
6910 ASSERT(!async_error_wrapper_helper.IsNull()); | 6937 ASSERT(!async_error_wrapper_helper.IsNull()); |
6911 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 6938 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( |
6912 Token::kNoSourcePos); | 6939 TokenPosition::kNoSource); |
6913 async_error_wrapper_helper_args->Add( | 6940 async_error_wrapper_helper_args->Add( |
6914 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6941 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); |
6915 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 6942 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( |
6916 Token::kNoSourcePos, | 6943 TokenPosition::kNoSource, |
6917 async_error_wrapper_helper, | 6944 async_error_wrapper_helper, |
6918 async_error_wrapper_helper_args); | 6945 async_error_wrapper_helper_args); |
6919 LocalVariable* async_catch_error_callback_var = | 6946 LocalVariable* async_catch_error_callback_var = |
6920 current_block_->scope->LookupVariable( | 6947 current_block_->scope->LookupVariable( |
6921 Symbols::AsyncCatchErrorCallback(), false); | 6948 Symbols::AsyncCatchErrorCallback(), false); |
6922 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 6949 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( |
6923 Token::kNoSourcePos, | 6950 TokenPosition::kNoSource, |
6924 async_catch_error_callback_var, | 6951 async_catch_error_callback_var, |
6925 error_wrapper_call); | 6952 error_wrapper_call); |
6926 | 6953 |
6927 current_block_->statements->Add(store_async_catch_error_callback); | 6954 current_block_->statements->Add(store_async_catch_error_callback); |
6928 | 6955 |
6929 // :controller = new _AsyncStarStreamController(body_closure); | 6956 // :controller = new _AsyncStarStreamController(body_closure); |
6930 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); | 6957 ArgumentListNode* arguments = |
6931 arguments->Add(new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6958 new(Z) ArgumentListNode(TokenPosition::kNoSource); |
| 6959 arguments->Add( |
| 6960 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); |
6932 ConstructorCallNode* controller_constructor_call = | 6961 ConstructorCallNode* controller_constructor_call = |
6933 new(Z) ConstructorCallNode(Token::kNoSourcePos, | 6962 new(Z) ConstructorCallNode(TokenPosition::kNoSource, |
6934 TypeArguments::ZoneHandle(Z), | 6963 TypeArguments::ZoneHandle(Z), |
6935 controller_constructor, | 6964 controller_constructor, |
6936 arguments); | 6965 arguments); |
6937 LocalVariable* controller_var = | 6966 LocalVariable* controller_var = |
6938 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6967 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
6939 StoreLocalNode* store_controller = | 6968 StoreLocalNode* store_controller = |
6940 new(Z) StoreLocalNode(Token::kNoSourcePos, | 6969 new(Z) StoreLocalNode(TokenPosition::kNoSource, |
6941 controller_var, | 6970 controller_var, |
6942 controller_constructor_call); | 6971 controller_constructor_call); |
6943 current_block_->statements->Add(store_controller); | 6972 current_block_->statements->Add(store_controller); |
6944 | 6973 |
6945 // return :controller.stream; | 6974 // return :controller.stream; |
6946 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos, | 6975 ReturnNode* return_node = new(Z) ReturnNode(TokenPosition::kNoSource, |
6947 new(Z) InstanceGetterNode(Token::kNoSourcePos, | 6976 new(Z) InstanceGetterNode(TokenPosition::kNoSource, |
6948 new(Z) LoadLocalNode(Token::kNoSourcePos, | 6977 new(Z) LoadLocalNode(TokenPosition::kNoSource, |
6949 controller_var), | 6978 controller_var), |
6950 Symbols::Stream())); | 6979 Symbols::Stream())); |
6951 current_block_->statements->Add(return_node); | 6980 current_block_->statements->Add(return_node); |
6952 return CloseBlock(); | 6981 return CloseBlock(); |
6953 } | 6982 } |
6954 | 6983 |
6955 | 6984 |
6956 void Parser::OpenAsyncGeneratorClosure() { | 6985 void Parser::OpenAsyncGeneratorClosure() { |
6957 async_temp_scope_ = current_block_->scope; | 6986 async_temp_scope_ = current_block_->scope; |
6958 OpenAsyncTryBlock(); | 6987 OpenAsyncTryBlock(); |
6959 } | 6988 } |
6960 | 6989 |
6961 | 6990 |
6962 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { | 6991 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { |
6963 // We need a temporary expression to store intermediate return values. | 6992 // We need a temporary expression to store intermediate return values. |
6964 parsed_function()->EnsureExpressionTemp(); | 6993 parsed_function()->EnsureExpressionTemp(); |
6965 | 6994 |
6966 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); | 6995 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); |
6967 ASSERT(new_body != NULL); | 6996 ASSERT(new_body != NULL); |
6968 ASSERT(new_body->scope() != NULL); | 6997 ASSERT(new_body->scope() != NULL); |
6969 return new_body; | 6998 return new_body; |
6970 } | 6999 } |
6971 | 7000 |
6972 | 7001 |
6973 // Add a return node to the sequence if necessary. | 7002 // Add a return node to the sequence if necessary. |
6974 void Parser::EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos) { | 7003 void Parser::EnsureHasReturnStatement(SequenceNode* seq, |
| 7004 TokenPosition return_pos) { |
6975 if ((seq->length() == 0) || | 7005 if ((seq->length() == 0) || |
6976 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { | 7006 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { |
6977 const Function& func = innermost_function(); | 7007 const Function& func = innermost_function(); |
6978 // The implicit return value of synchronous generator closures is false, | 7008 // The implicit return value of synchronous generator closures is false, |
6979 // to indicate that there are no more elements in the iterable. | 7009 // to indicate that there are no more elements in the iterable. |
6980 // In other cases the implicit return value is null. | 7010 // In other cases the implicit return value is null. |
6981 AstNode* return_value = func.IsSyncGenClosure() | 7011 AstNode* return_value = func.IsSyncGenClosure() |
6982 ? new LiteralNode(return_pos, Bool::False()) | 7012 ? new LiteralNode(return_pos, Bool::False()) |
6983 : new LiteralNode(return_pos, Instance::ZoneHandle()); | 7013 : new LiteralNode(return_pos, Instance::ZoneHandle()); |
6984 seq->Add(new ReturnNode(return_pos, return_value)); | 7014 seq->Add(new ReturnNode(return_pos, return_value)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7032 const Class& completer = | 7062 const Class& completer = |
7033 Class::ZoneHandle(Z, I->object_store()->completer_class()); | 7063 Class::ZoneHandle(Z, I->object_store()->completer_class()); |
7034 ASSERT(!completer.IsNull()); | 7064 ASSERT(!completer.IsNull()); |
7035 const Function& completer_constructor = Function::ZoneHandle(Z, | 7065 const Function& completer_constructor = Function::ZoneHandle(Z, |
7036 completer.LookupFunction(Symbols::CompleterSyncConstructor())); | 7066 completer.LookupFunction(Symbols::CompleterSyncConstructor())); |
7037 ASSERT(!completer_constructor.IsNull()); | 7067 ASSERT(!completer_constructor.IsNull()); |
7038 | 7068 |
7039 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 7069 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
7040 Symbols::AsyncCompleter(), false); | 7070 Symbols::AsyncCompleter(), false); |
7041 | 7071 |
7042 const intptr_t token_pos = ST(closure_body->token_pos()); | 7072 const TokenPosition token_pos = ST(closure_body->token_pos()); |
7043 // Add to AST: | 7073 // Add to AST: |
7044 // :async_completer = new Completer.sync(); | 7074 // :async_completer = new Completer.sync(); |
7045 ArgumentListNode* empty_args = | 7075 ArgumentListNode* empty_args = |
7046 new (Z) ArgumentListNode(token_pos); | 7076 new (Z) ArgumentListNode(token_pos); |
7047 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( | 7077 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( |
7048 token_pos, | 7078 token_pos, |
7049 TypeArguments::ZoneHandle(Z), | 7079 TypeArguments::ZoneHandle(Z), |
7050 completer_constructor, | 7080 completer_constructor, |
7051 empty_args); | 7081 empty_args); |
7052 StoreLocalNode* store_completer = new (Z) StoreLocalNode( | 7082 StoreLocalNode* store_completer = new (Z) StoreLocalNode( |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7278 | 7308 |
7279 void Parser::CaptureInstantiator() { | 7309 void Parser::CaptureInstantiator() { |
7280 ASSERT(current_block_->scope->function_level() > 0); | 7310 ASSERT(current_block_->scope->function_level() > 0); |
7281 const String* variable_name = current_function().IsInFactoryScope() ? | 7311 const String* variable_name = current_function().IsInFactoryScope() ? |
7282 &Symbols::TypeArgumentsParameter() : &Symbols::This(); | 7312 &Symbols::TypeArgumentsParameter() : &Symbols::This(); |
7283 current_block_->scope->CaptureVariable( | 7313 current_block_->scope->CaptureVariable( |
7284 current_block_->scope->LookupVariable(*variable_name, true)); | 7314 current_block_->scope->LookupVariable(*variable_name, true)); |
7285 } | 7315 } |
7286 | 7316 |
7287 | 7317 |
7288 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 7318 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { |
7289 // A nested function may access 'this', referring to the receiver of the | 7319 // A nested function may access 'this', referring to the receiver of the |
7290 // outermost enclosing function. | 7320 // outermost enclosing function. |
7291 const bool kTestOnly = false; | 7321 const bool kTestOnly = false; |
7292 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7322 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
7293 if (receiver == NULL) { | 7323 if (receiver == NULL) { |
7294 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7324 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
7295 } | 7325 } |
7296 return new(Z) LoadLocalNode(TokenPos(), receiver); | 7326 return new(Z) LoadLocalNode(TokenPos(), receiver); |
7297 } | 7327 } |
7298 | 7328 |
7299 | 7329 |
7300 InstanceGetterNode* Parser::CallGetter(intptr_t token_pos, | 7330 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, |
7301 AstNode* object, | 7331 AstNode* object, |
7302 const String& name) { | 7332 const String& name) { |
7303 return new(Z) InstanceGetterNode(token_pos, object, name); | 7333 return new(Z) InstanceGetterNode(token_pos, object, name); |
7304 } | 7334 } |
7305 | 7335 |
7306 | 7336 |
7307 // Returns ast nodes of the variable initialization. | 7337 // Returns ast nodes of the variable initialization. |
7308 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7338 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
7309 bool is_final, | 7339 bool is_final, |
7310 bool is_const, | 7340 bool is_const, |
7311 SequenceNode** await_preamble) { | 7341 SequenceNode** await_preamble) { |
7312 TRACE_PARSER("ParseVariableDeclaration"); | 7342 TRACE_PARSER("ParseVariableDeclaration"); |
7313 ASSERT(IsIdentifier()); | 7343 ASSERT(IsIdentifier()); |
7314 const intptr_t ident_pos = TokenPos(); | 7344 const TokenPosition ident_pos = TokenPos(); |
7315 const String& ident = *CurrentLiteral(); | 7345 const String& ident = *CurrentLiteral(); |
7316 ConsumeToken(); // Variable identifier. | 7346 ConsumeToken(); // Variable identifier. |
7317 const intptr_t assign_pos = TokenPos(); | 7347 const TokenPosition assign_pos = TokenPos(); |
7318 AstNode* initialization = NULL; | 7348 AstNode* initialization = NULL; |
7319 LocalVariable* variable = NULL; | 7349 LocalVariable* variable = NULL; |
7320 if (CurrentToken() == Token::kASSIGN) { | 7350 if (CurrentToken() == Token::kASSIGN) { |
7321 // Variable initialization. | 7351 // Variable initialization. |
7322 ConsumeToken(); | 7352 ConsumeToken(); |
7323 AstNode* expr = ParseAwaitableExpr( | 7353 AstNode* expr = ParseAwaitableExpr( |
7324 is_const, kConsumeCascades, await_preamble); | 7354 is_const, kConsumeCascades, await_preamble); |
7325 const intptr_t expr_end_pos = TokenPos(); | 7355 const TokenPosition expr_end_pos = TokenPos(); |
7326 variable = new(Z) LocalVariable( | 7356 variable = new(Z) LocalVariable( |
7327 expr_end_pos, ident, type); | 7357 expr_end_pos, ident, type); |
7328 initialization = new(Z) StoreLocalNode( | 7358 initialization = new(Z) StoreLocalNode( |
7329 assign_pos, variable, expr); | 7359 assign_pos, variable, expr); |
7330 if (is_const) { | 7360 if (is_const) { |
7331 ASSERT(expr->IsLiteralNode()); | 7361 ASSERT(expr->IsLiteralNode()); |
7332 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 7362 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
7333 } | 7363 } |
7334 } else if (is_final || is_const) { | 7364 } else if (is_final || is_const) { |
7335 ReportError(ident_pos, | 7365 ReportError(ident_pos, |
7336 "missing initialization of 'final' or 'const' variable"); | 7366 "missing initialization of 'final' or 'const' variable"); |
7337 } else { | 7367 } else { |
7338 // Initialize variable with null. | 7368 // Initialize variable with null. |
7339 variable = new(Z) LocalVariable( | 7369 variable = new(Z) LocalVariable( |
7340 assign_pos, ident, type); | 7370 assign_pos, ident, type); |
7341 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); | 7371 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); |
7342 initialization = new(Z) StoreLocalNode( | 7372 initialization = new(Z) StoreLocalNode( |
7343 ident_pos, variable, null_expr); | 7373 ident_pos, variable, null_expr); |
7344 } | 7374 } |
7345 | 7375 |
7346 ASSERT(current_block_ != NULL); | 7376 ASSERT(current_block_ != NULL); |
7347 const intptr_t previous_pos = | 7377 const TokenPosition previous_pos = |
7348 current_block_->scope->PreviousReferencePos(ident); | 7378 current_block_->scope->PreviousReferencePos(ident); |
7349 if (previous_pos >= 0) { | 7379 if (previous_pos.IsReal()) { |
7350 ASSERT(!script_.IsNull()); | 7380 ASSERT(!script_.IsNull()); |
7351 if (previous_pos > ident_pos) { | 7381 if (previous_pos > ident_pos) { |
7352 ReportError(ident_pos, | 7382 ReportError(ident_pos, |
7353 "initializer of '%s' may not refer to itself", | 7383 "initializer of '%s' may not refer to itself", |
7354 ident.ToCString()); | 7384 ident.ToCString()); |
7355 | 7385 |
7356 } else { | 7386 } else { |
7357 intptr_t line_number; | 7387 intptr_t line_number; |
7358 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7388 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7359 ReportError(ident_pos, | 7389 ReportError(ident_pos, |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7466 | 7496 |
7467 | 7497 |
7468 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7498 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
7469 TRACE_PARSER("ParseFunctionStatement"); | 7499 TRACE_PARSER("ParseFunctionStatement"); |
7470 AbstractType& result_type = AbstractType::Handle(Z); | 7500 AbstractType& result_type = AbstractType::Handle(Z); |
7471 const String* variable_name = NULL; | 7501 const String* variable_name = NULL; |
7472 const String* function_name = NULL; | 7502 const String* function_name = NULL; |
7473 | 7503 |
7474 result_type = Type::DynamicType(); | 7504 result_type = Type::DynamicType(); |
7475 | 7505 |
7476 const intptr_t function_pos = TokenPos(); | 7506 const TokenPosition function_pos = TokenPos(); |
7477 intptr_t metadata_pos = Token::kNoSourcePos; | 7507 TokenPosition metadata_pos = TokenPosition::kNoSource; |
7478 if (is_literal) { | 7508 if (is_literal) { |
7479 ASSERT(CurrentToken() == Token::kLPAREN); | 7509 ASSERT(CurrentToken() == Token::kLPAREN); |
7480 function_name = &Symbols::AnonymousClosure(); | 7510 function_name = &Symbols::AnonymousClosure(); |
7481 } else { | 7511 } else { |
7482 metadata_pos = SkipMetadata(); | 7512 metadata_pos = SkipMetadata(); |
7483 if (CurrentToken() == Token::kVOID) { | 7513 if (CurrentToken() == Token::kVOID) { |
7484 ConsumeToken(); | 7514 ConsumeToken(); |
7485 result_type = Type::VoidType(); | 7515 result_type = Type::VoidType(); |
7486 } else if ((CurrentToken() == Token::kIDENT) && | 7516 } else if ((CurrentToken() == Token::kIDENT) && |
7487 (LookaheadToken(1) != Token::kLPAREN)) { | 7517 (LookaheadToken(1) != Token::kLPAREN)) { |
7488 result_type = ParseType(ClassFinalizer::kCanonicalize); | 7518 result_type = ParseType(ClassFinalizer::kCanonicalize); |
7489 } | 7519 } |
7490 const intptr_t name_pos = TokenPos(); | 7520 const TokenPosition name_pos = TokenPos(); |
7491 variable_name = ExpectIdentifier("function name expected"); | 7521 variable_name = ExpectIdentifier("function name expected"); |
7492 function_name = variable_name; | 7522 function_name = variable_name; |
7493 | 7523 |
7494 // Check that the function name has not been referenced | 7524 // Check that the function name has not been referenced |
7495 // before this declaration. | 7525 // before this declaration. |
7496 ASSERT(current_block_ != NULL); | 7526 ASSERT(current_block_ != NULL); |
7497 const intptr_t previous_pos = | 7527 const TokenPosition previous_pos = |
7498 current_block_->scope->PreviousReferencePos(*function_name); | 7528 current_block_->scope->PreviousReferencePos(*function_name); |
7499 if (previous_pos >= 0) { | 7529 if (previous_pos.IsReal()) { |
7500 ASSERT(!script_.IsNull()); | 7530 ASSERT(!script_.IsNull()); |
7501 intptr_t line_number; | 7531 intptr_t line_number; |
7502 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7532 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7503 ReportError(name_pos, | 7533 ReportError(name_pos, |
7504 "identifier '%s' previously used in line %" Pd "", | 7534 "identifier '%s' previously used in line %" Pd "", |
7505 function_name->ToCString(), | 7535 function_name->ToCString(), |
7506 line_number); | 7536 line_number); |
7507 } | 7537 } |
7508 } | 7538 } |
7509 CheckToken(Token::kLPAREN); | 7539 CheckToken(Token::kLPAREN); |
7510 | 7540 |
7511 // Check whether we have parsed this closure function before, in a previous | 7541 // Check whether we have parsed this closure function before, in a previous |
7512 // compilation. If so, reuse the function object, else create a new one | 7542 // compilation. If so, reuse the function object, else create a new one |
7513 // and register it in the current class. | 7543 // and register it in the current class. |
7514 // Note that we cannot share the same closure function between the closurized | 7544 // Note that we cannot share the same closure function between the closurized |
7515 // and non-closurized versions of the same parent function. | 7545 // and non-closurized versions of the same parent function. |
7516 Function& function = Function::ZoneHandle(Z); | 7546 Function& function = Function::ZoneHandle(Z); |
7517 // TODO(hausner): There could be two different closures at the given | 7547 // TODO(hausner): There could be two different closures at the given |
7518 // function_pos, one enclosed in a closurized function and one enclosed in the | 7548 // function_pos, one enclosed in a closurized function and one enclosed in the |
7519 // non-closurized version of this same function. | 7549 // non-closurized version of this same function. |
7520 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7550 function = I->LookupClosureFunction(innermost_function(), function_pos); |
7521 if (function.IsNull()) { | 7551 if (function.IsNull()) { |
7522 // The function will be registered in the lookup table by the | 7552 // The function will be registered in the lookup table by the |
7523 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7553 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
7524 // function has been properly setup. | 7554 // function has been properly setup. |
7525 function = Function::NewClosureFunction(*function_name, | 7555 function = Function::NewClosureFunction(*function_name, |
7526 innermost_function(), | 7556 innermost_function(), |
7527 function_pos); | 7557 function_pos); |
7528 function.set_result_type(result_type); | 7558 function.set_result_type(result_type); |
7529 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 7559 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
7530 library_.AddFunctionMetadata(function, metadata_pos); | 7560 library_.AddFunctionMetadata(function, metadata_pos); |
7531 } | 7561 } |
7532 } | 7562 } |
7533 | 7563 |
7534 // The function type needs to be finalized at compile time, since the closure | 7564 // The function type needs to be finalized at compile time, since the closure |
7535 // may be type checked at run time when assigned to a function variable, | 7565 // may be type checked at run time when assigned to a function variable, |
7536 // passed as a function argument, or returned as a function result. | 7566 // passed as a function argument, or returned as a function result. |
7537 | 7567 |
7538 LocalVariable* function_variable = NULL; | 7568 LocalVariable* function_variable = NULL; |
7539 FunctionType& function_type = FunctionType::ZoneHandle(Z); | 7569 FunctionType& function_type = FunctionType::ZoneHandle(Z); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7795 // | const [type] ident (';' | '=' | ',') | 7825 // | const [type] ident (';' | '=' | ',') |
7796 // | type ident (';' | '=' | ',') | 7826 // | type ident (';' | '=' | ',') |
7797 // Token position remains unchanged. | 7827 // Token position remains unchanged. |
7798 bool Parser::IsVariableDeclaration() { | 7828 bool Parser::IsVariableDeclaration() { |
7799 if ((CurrentToken() == Token::kVAR) || | 7829 if ((CurrentToken() == Token::kVAR) || |
7800 (CurrentToken() == Token::kFINAL)) { | 7830 (CurrentToken() == Token::kFINAL)) { |
7801 return true; | 7831 return true; |
7802 } | 7832 } |
7803 // Skip optional metadata. | 7833 // Skip optional metadata. |
7804 if (CurrentToken() == Token::kAT) { | 7834 if (CurrentToken() == Token::kAT) { |
7805 const intptr_t saved_pos = TokenPos(); | 7835 const TokenPosition saved_pos = TokenPos(); |
7806 SkipMetadata(); | 7836 SkipMetadata(); |
7807 const bool is_var_decl = IsVariableDeclaration(); | 7837 const bool is_var_decl = IsVariableDeclaration(); |
7808 SetPosition(saved_pos); | 7838 SetPosition(saved_pos); |
7809 return is_var_decl; | 7839 return is_var_decl; |
7810 } | 7840 } |
7811 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { | 7841 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { |
7812 // Not a legal type identifier or const keyword or metadata. | 7842 // Not a legal type identifier or const keyword or metadata. |
7813 return false; | 7843 return false; |
7814 } | 7844 } |
7815 const intptr_t saved_pos = TokenPos(); | 7845 const TokenPosition saved_pos = TokenPos(); |
7816 bool is_var_decl = false; | 7846 bool is_var_decl = false; |
7817 bool have_type = false; | 7847 bool have_type = false; |
7818 if (CurrentToken() == Token::kCONST) { | 7848 if (CurrentToken() == Token::kCONST) { |
7819 ConsumeToken(); | 7849 ConsumeToken(); |
7820 have_type = true; // Type is dynamic. | 7850 have_type = true; // Type is dynamic. |
7821 } | 7851 } |
7822 if (IsIdentifier()) { // Type or variable name. | 7852 if (IsIdentifier()) { // Type or variable name. |
7823 Token::Kind follower = LookaheadToken(1); | 7853 Token::Kind follower = LookaheadToken(1); |
7824 if ((follower == Token::kLT) || // Parameterized type. | 7854 if ((follower == Token::kLT) || // Parameterized type. |
7825 (follower == Token::kPERIOD) || // Qualified class name of type. | 7855 (follower == Token::kPERIOD) || // Qualified class name of type. |
7826 Token::IsIdentifier(follower)) { // Variable name following a type. | 7856 Token::IsIdentifier(follower)) { // Variable name following a type. |
7827 // We see the beginning of something that could be a type. | 7857 // We see the beginning of something that could be a type. |
7828 const intptr_t type_pos = TokenPos(); | 7858 const TokenPosition type_pos = TokenPos(); |
7829 if (TryParseOptionalType()) { | 7859 if (TryParseOptionalType()) { |
7830 have_type = true; | 7860 have_type = true; |
7831 } else { | 7861 } else { |
7832 SetPosition(type_pos); | 7862 SetPosition(type_pos); |
7833 } | 7863 } |
7834 } | 7864 } |
7835 if (have_type && IsIdentifier()) { | 7865 if (have_type && IsIdentifier()) { |
7836 ConsumeToken(); | 7866 ConsumeToken(); |
7837 if ((CurrentToken() == Token::kSEMICOLON) || | 7867 if ((CurrentToken() == Token::kSEMICOLON) || |
7838 (CurrentToken() == Token::kCOMMA) || | 7868 (CurrentToken() == Token::kCOMMA) || |
7839 (CurrentToken() == Token::kASSIGN)) { | 7869 (CurrentToken() == Token::kASSIGN)) { |
7840 is_var_decl = true; | 7870 is_var_decl = true; |
7841 } | 7871 } |
7842 } | 7872 } |
7843 } | 7873 } |
7844 SetPosition(saved_pos); | 7874 SetPosition(saved_pos); |
7845 return is_var_decl; | 7875 return is_var_decl; |
7846 } | 7876 } |
7847 | 7877 |
7848 | 7878 |
7849 // Look ahead to detect whether the next tokens should be parsed as | 7879 // Look ahead to detect whether the next tokens should be parsed as |
7850 // a function declaration. Token position remains unchanged. | 7880 // a function declaration. Token position remains unchanged. |
7851 bool Parser::IsFunctionDeclaration() { | 7881 bool Parser::IsFunctionDeclaration() { |
7852 const intptr_t saved_pos = TokenPos(); | 7882 const TokenPosition saved_pos = TokenPos(); |
7853 bool is_external = false; | 7883 bool is_external = false; |
7854 SkipMetadata(); | 7884 SkipMetadata(); |
7855 if (is_top_level_) { | 7885 if (is_top_level_) { |
7856 if (is_patch_source() && | 7886 if (is_patch_source() && |
7857 (CurrentToken() == Token::kIDENT) && | 7887 (CurrentToken() == Token::kIDENT) && |
7858 CurrentLiteral()->Equals("patch") && | 7888 CurrentLiteral()->Equals("patch") && |
7859 (LookaheadToken(1) != Token::kLPAREN)) { | 7889 (LookaheadToken(1) != Token::kLPAREN)) { |
7860 // Skip over 'patch' for top-level function declarations in patch sources. | 7890 // Skip over 'patch' for top-level function declarations in patch sources. |
7861 ConsumeToken(); | 7891 ConsumeToken(); |
7862 } else if (CurrentToken() == Token::kEXTERNAL) { | 7892 } else if (CurrentToken() == Token::kEXTERNAL) { |
(...skipping 27 matching lines...) Expand all Loading... |
7890 SetPosition(saved_pos); | 7920 SetPosition(saved_pos); |
7891 return true; | 7921 return true; |
7892 } | 7922 } |
7893 } | 7923 } |
7894 SetPosition(saved_pos); | 7924 SetPosition(saved_pos); |
7895 return false; | 7925 return false; |
7896 } | 7926 } |
7897 | 7927 |
7898 | 7928 |
7899 bool Parser::IsTopLevelAccessor() { | 7929 bool Parser::IsTopLevelAccessor() { |
7900 const intptr_t saved_pos = TokenPos(); | 7930 const TokenPosition saved_pos = TokenPos(); |
7901 if (is_patch_source() && IsSymbol(Symbols::Patch())) { | 7931 if (is_patch_source() && IsSymbol(Symbols::Patch())) { |
7902 ConsumeToken(); | 7932 ConsumeToken(); |
7903 } else if (CurrentToken() == Token::kEXTERNAL) { | 7933 } else if (CurrentToken() == Token::kEXTERNAL) { |
7904 ConsumeToken(); | 7934 ConsumeToken(); |
7905 } | 7935 } |
7906 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 7936 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
7907 SetPosition(saved_pos); | 7937 SetPosition(saved_pos); |
7908 return true; | 7938 return true; |
7909 } | 7939 } |
7910 if (TryParseReturnType()) { | 7940 if (TryParseReturnType()) { |
7911 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 7941 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
7912 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 7942 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
7913 SetPosition(saved_pos); | 7943 SetPosition(saved_pos); |
7914 return true; | 7944 return true; |
7915 } | 7945 } |
7916 } | 7946 } |
7917 } | 7947 } |
7918 SetPosition(saved_pos); | 7948 SetPosition(saved_pos); |
7919 return false; | 7949 return false; |
7920 } | 7950 } |
7921 | 7951 |
7922 | 7952 |
7923 bool Parser::IsFunctionLiteral() { | 7953 bool Parser::IsFunctionLiteral() { |
7924 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { | 7954 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { |
7925 return false; | 7955 return false; |
7926 } | 7956 } |
7927 const intptr_t saved_pos = TokenPos(); | 7957 const TokenPosition saved_pos = TokenPos(); |
7928 bool is_function_literal = false; | 7958 bool is_function_literal = false; |
7929 SkipToMatchingParenthesis(); | 7959 SkipToMatchingParenthesis(); |
7930 ParseFunctionModifier(); | 7960 ParseFunctionModifier(); |
7931 if ((CurrentToken() == Token::kLBRACE) || | 7961 if ((CurrentToken() == Token::kLBRACE) || |
7932 (CurrentToken() == Token::kARROW)) { | 7962 (CurrentToken() == Token::kARROW)) { |
7933 is_function_literal = true; | 7963 is_function_literal = true; |
7934 } | 7964 } |
7935 SetPosition(saved_pos); | 7965 SetPosition(saved_pos); |
7936 return is_function_literal; | 7966 return is_function_literal; |
7937 } | 7967 } |
7938 | 7968 |
7939 | 7969 |
7940 // Current token position is the token after the opening ( of the for | 7970 // Current token position is the token after the opening ( of the for |
7941 // statement. Returns true if we recognize a for ( .. in expr) | 7971 // statement. Returns true if we recognize a for ( .. in expr) |
7942 // statement. | 7972 // statement. |
7943 bool Parser::IsForInStatement() { | 7973 bool Parser::IsForInStatement() { |
7944 const intptr_t saved_pos = TokenPos(); | 7974 const TokenPosition saved_pos = TokenPos(); |
7945 bool result = false; | 7975 bool result = false; |
7946 // Allow const modifier as well when recognizing a for-in statement | 7976 // Allow const modifier as well when recognizing a for-in statement |
7947 // pattern. We will get an error later if the loop variable is | 7977 // pattern. We will get an error later if the loop variable is |
7948 // declared with const. | 7978 // declared with const. |
7949 if (CurrentToken() == Token::kVAR || | 7979 if (CurrentToken() == Token::kVAR || |
7950 CurrentToken() == Token::kFINAL || | 7980 CurrentToken() == Token::kFINAL || |
7951 CurrentToken() == Token::kCONST) { | 7981 CurrentToken() == Token::kCONST) { |
7952 ConsumeToken(); | 7982 ConsumeToken(); |
7953 } | 7983 } |
7954 if (IsIdentifier()) { | 7984 if (IsIdentifier()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7986 return false; | 8016 return false; |
7987 } | 8017 } |
7988 | 8018 |
7989 | 8019 |
7990 void Parser::ParseStatementSequence() { | 8020 void Parser::ParseStatementSequence() { |
7991 TRACE_PARSER("ParseStatementSequence"); | 8021 TRACE_PARSER("ParseStatementSequence"); |
7992 const bool dead_code_allowed = true; | 8022 const bool dead_code_allowed = true; |
7993 bool abrupt_completing_seen = false; | 8023 bool abrupt_completing_seen = false; |
7994 RecursionChecker rc(this); | 8024 RecursionChecker rc(this); |
7995 while (CurrentToken() != Token::kRBRACE) { | 8025 while (CurrentToken() != Token::kRBRACE) { |
7996 const intptr_t statement_pos = TokenPos(); | 8026 const TokenPosition statement_pos = TokenPos(); |
7997 AstNode* statement = ParseStatement(); | 8027 AstNode* statement = ParseStatement(); |
7998 // Do not add statements with no effect (e.g., LoadLocalNode). | 8028 // Do not add statements with no effect (e.g., LoadLocalNode). |
7999 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 8029 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
8000 // Skip load local. | 8030 // Skip load local. |
8001 continue; | 8031 continue; |
8002 } | 8032 } |
8003 if (statement != NULL) { | 8033 if (statement != NULL) { |
8004 if (!dead_code_allowed && abrupt_completing_seen) { | 8034 if (!dead_code_allowed && abrupt_completing_seen) { |
8005 ReportError(statement_pos, | 8035 ReportError(statement_pos, |
8006 "dead code after abrupt completing statement"); | 8036 "dead code after abrupt completing statement"); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8038 } | 8068 } |
8039 } | 8069 } |
8040 SequenceNode* sequence = CloseBlock(); | 8070 SequenceNode* sequence = CloseBlock(); |
8041 return sequence; | 8071 return sequence; |
8042 } | 8072 } |
8043 | 8073 |
8044 | 8074 |
8045 AstNode* Parser::ParseIfStatement(String* label_name) { | 8075 AstNode* Parser::ParseIfStatement(String* label_name) { |
8046 TRACE_PARSER("ParseIfStatement"); | 8076 TRACE_PARSER("ParseIfStatement"); |
8047 ASSERT(CurrentToken() == Token::kIF); | 8077 ASSERT(CurrentToken() == Token::kIF); |
8048 const intptr_t if_pos = TokenPos(); | 8078 const TokenPosition if_pos = TokenPos(); |
8049 SourceLabel* label = NULL; | 8079 SourceLabel* label = NULL; |
8050 if (label_name != NULL) { | 8080 if (label_name != NULL) { |
8051 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 8081 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
8052 OpenBlock(); | 8082 OpenBlock(); |
8053 current_block_->scope->AddLabel(label); | 8083 current_block_->scope->AddLabel(label); |
8054 } | 8084 } |
8055 ConsumeToken(); | 8085 ConsumeToken(); |
8056 ExpectToken(Token::kLPAREN); | 8086 ExpectToken(Token::kLPAREN); |
8057 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8087 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8058 ExpectToken(Token::kRPAREN); | 8088 ExpectToken(Token::kRPAREN); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8093 // of a LiteralNode. | 8123 // of a LiteralNode. |
8094 RawClass* Parser::CheckCaseExpressions( | 8124 RawClass* Parser::CheckCaseExpressions( |
8095 const GrowableArray<LiteralNode*>& values) { | 8125 const GrowableArray<LiteralNode*>& values) { |
8096 const intptr_t num_expressions = values.length(); | 8126 const intptr_t num_expressions = values.length(); |
8097 if (num_expressions == 0) { | 8127 if (num_expressions == 0) { |
8098 return Object::dynamic_class(); | 8128 return Object::dynamic_class(); |
8099 } | 8129 } |
8100 const Instance& first_value = values[0]->literal(); | 8130 const Instance& first_value = values[0]->literal(); |
8101 for (intptr_t i = 0; i < num_expressions; i++) { | 8131 for (intptr_t i = 0; i < num_expressions; i++) { |
8102 const Instance& val = values[i]->literal(); | 8132 const Instance& val = values[i]->literal(); |
8103 const intptr_t val_pos = values[i]->token_pos(); | 8133 const TokenPosition val_pos = values[i]->token_pos(); |
8104 if (first_value.IsInteger()) { | 8134 if (first_value.IsInteger()) { |
8105 if (!val.IsInteger()) { | 8135 if (!val.IsInteger()) { |
8106 ReportError(val_pos, "expected case expression of type int"); | 8136 ReportError(val_pos, "expected case expression of type int"); |
8107 } | 8137 } |
8108 continue; | 8138 continue; |
8109 } | 8139 } |
8110 if (first_value.IsString()) { | 8140 if (first_value.IsString()) { |
8111 if (!val.IsString()) { | 8141 if (!val.IsString()) { |
8112 ReportError(val_pos, "expected case expression of type String"); | 8142 ReportError(val_pos, "expected case expression of type String"); |
8113 } | 8143 } |
(...skipping 27 matching lines...) Expand all Loading... |
8141 } | 8171 } |
8142 return first_value.clazz(); | 8172 return first_value.clazz(); |
8143 } | 8173 } |
8144 | 8174 |
8145 | 8175 |
8146 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 8176 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
8147 GrowableArray<LiteralNode*>* case_expr_values, | 8177 GrowableArray<LiteralNode*>* case_expr_values, |
8148 SourceLabel* case_label) { | 8178 SourceLabel* case_label) { |
8149 TRACE_PARSER("ParseCaseClause"); | 8179 TRACE_PARSER("ParseCaseClause"); |
8150 bool default_seen = false; | 8180 bool default_seen = false; |
8151 const intptr_t case_pos = TokenPos(); | 8181 const TokenPosition case_pos = TokenPos(); |
8152 // The case expressions node sequence does not own the enclosing scope. | 8182 // The case expressions node sequence does not own the enclosing scope. |
8153 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); | 8183 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); |
8154 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 8184 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
8155 if (CurrentToken() == Token::kCASE) { | 8185 if (CurrentToken() == Token::kCASE) { |
8156 if (default_seen) { | 8186 if (default_seen) { |
8157 ReportError("default clause must be last case"); | 8187 ReportError("default clause must be last case"); |
8158 } | 8188 } |
8159 ConsumeToken(); // Keyword case. | 8189 ConsumeToken(); // Keyword case. |
8160 const intptr_t expr_pos = TokenPos(); | 8190 const TokenPosition expr_pos = TokenPos(); |
8161 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 8191 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
8162 ASSERT(expr->IsLiteralNode()); | 8192 ASSERT(expr->IsLiteralNode()); |
8163 case_expr_values->Add(expr->AsLiteralNode()); | 8193 case_expr_values->Add(expr->AsLiteralNode()); |
8164 | 8194 |
8165 AstNode* switch_expr_load = new(Z) LoadLocalNode( | 8195 AstNode* switch_expr_load = new(Z) LoadLocalNode( |
8166 case_pos, switch_expr_value); | 8196 case_pos, switch_expr_value); |
8167 AstNode* case_comparison = new(Z) ComparisonNode( | 8197 AstNode* case_comparison = new(Z) ComparisonNode( |
8168 expr_pos, Token::kEQ, expr, switch_expr_load); | 8198 expr_pos, Token::kEQ, expr, switch_expr_load); |
8169 case_expressions->Add(case_comparison); | 8199 case_expressions->Add(case_comparison); |
8170 } else { | 8200 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
8193 if (next_token == Token::kRBRACE) { | 8223 if (next_token == Token::kRBRACE) { |
8194 // End of switch statement. | 8224 // End of switch statement. |
8195 break; | 8225 break; |
8196 } | 8226 } |
8197 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 8227 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
8198 // End of this case clause. If there is a possible fall-through to | 8228 // End of this case clause. If there is a possible fall-through to |
8199 // the next case clause, throw an implicit FallThroughError. | 8229 // the next case clause, throw an implicit FallThroughError. |
8200 if (!abrupt_completing_seen) { | 8230 if (!abrupt_completing_seen) { |
8201 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); | 8231 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); |
8202 arguments->Add(new(Z) LiteralNode( | 8232 arguments->Add(new(Z) LiteralNode( |
8203 TokenPos(), Integer::ZoneHandle(Z, Integer::New(TokenPos())))); | 8233 TokenPos(), |
| 8234 Integer::ZoneHandle(Z, Integer::New(TokenPos().value())))); |
8204 current_block_->statements->Add( | 8235 current_block_->statements->Add( |
8205 MakeStaticCall(Symbols::FallThroughError(), | 8236 MakeStaticCall(Symbols::FallThroughError(), |
8206 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 8237 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
8207 arguments)); | 8238 arguments)); |
8208 } | 8239 } |
8209 break; | 8240 break; |
8210 } | 8241 } |
8211 // The next statement still belongs to this case. | 8242 // The next statement still belongs to this case. |
8212 AstNode* statement = ParseStatement(); | 8243 AstNode* statement = ParseStatement(); |
8213 if (statement != NULL) { | 8244 if (statement != NULL) { |
8214 current_block_->statements->Add(statement); | 8245 current_block_->statements->Add(statement); |
8215 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8246 abrupt_completing_seen |= IsAbruptCompleting(statement); |
8216 } | 8247 } |
8217 } | 8248 } |
8218 SequenceNode* statements = CloseBlock(); | 8249 SequenceNode* statements = CloseBlock(); |
8219 return new(Z) CaseNode(case_pos, case_label, | 8250 return new(Z) CaseNode(case_pos, case_label, |
8220 case_expressions, default_seen, switch_expr_value, statements); | 8251 case_expressions, default_seen, switch_expr_value, statements); |
8221 } | 8252 } |
8222 | 8253 |
8223 | 8254 |
8224 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 8255 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
8225 TRACE_PARSER("ParseSwitchStatement"); | 8256 TRACE_PARSER("ParseSwitchStatement"); |
8226 ASSERT(CurrentToken() == Token::kSWITCH); | 8257 ASSERT(CurrentToken() == Token::kSWITCH); |
8227 const intptr_t switch_pos = TokenPos(); | 8258 const TokenPosition switch_pos = TokenPos(); |
8228 SourceLabel* label = | 8259 SourceLabel* label = |
8229 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 8260 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
8230 ConsumeToken(); | 8261 ConsumeToken(); |
8231 ExpectToken(Token::kLPAREN); | 8262 ExpectToken(Token::kLPAREN); |
8232 const intptr_t expr_pos = TokenPos(); | 8263 const TokenPosition expr_pos = TokenPos(); |
8233 AstNode* switch_expr = ParseAwaitableExpr( | 8264 AstNode* switch_expr = ParseAwaitableExpr( |
8234 kAllowConst, kConsumeCascades, NULL); | 8265 kAllowConst, kConsumeCascades, NULL); |
8235 ExpectToken(Token::kRPAREN); | 8266 ExpectToken(Token::kRPAREN); |
8236 ExpectToken(Token::kLBRACE); | 8267 ExpectToken(Token::kLBRACE); |
8237 OpenBlock(); | 8268 OpenBlock(); |
8238 current_block_->scope->AddLabel(label); | 8269 current_block_->scope->AddLabel(label); |
8239 | 8270 |
8240 // Store switch expression in temporary local variable. The type of the | 8271 // Store switch expression in temporary local variable. The type of the |
8241 // variable is set to dynamic. It will later be patched to match the | 8272 // variable is set to dynamic. It will later be patched to match the |
8242 // type of the case clause expressions. Therefore, we have to allocate | 8273 // type of the case clause expressions. Therefore, we have to allocate |
(...skipping 13 matching lines...) Expand all Loading... |
8256 | 8287 |
8257 // Parse case clauses | 8288 // Parse case clauses |
8258 bool default_seen = false; | 8289 bool default_seen = false; |
8259 GrowableArray<LiteralNode*> case_expr_values; | 8290 GrowableArray<LiteralNode*> case_expr_values; |
8260 while (true) { | 8291 while (true) { |
8261 // Check for statement label | 8292 // Check for statement label |
8262 SourceLabel* case_label = NULL; | 8293 SourceLabel* case_label = NULL; |
8263 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 8294 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
8264 // Case statements start with a label. | 8295 // Case statements start with a label. |
8265 String* label_name = CurrentLiteral(); | 8296 String* label_name = CurrentLiteral(); |
8266 const intptr_t label_pos = TokenPos(); | 8297 const TokenPosition label_pos = TokenPos(); |
8267 ConsumeToken(); // Consume label identifier. | 8298 ConsumeToken(); // Consume label identifier. |
8268 ConsumeToken(); // Consume colon. | 8299 ConsumeToken(); // Consume colon. |
8269 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 8300 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
8270 if (case_label == NULL) { | 8301 if (case_label == NULL) { |
8271 // Label does not exist yet. Add it to scope of switch statement. | 8302 // Label does not exist yet. Add it to scope of switch statement. |
8272 case_label = new(Z) SourceLabel( | 8303 case_label = new(Z) SourceLabel( |
8273 label_pos, *label_name, SourceLabel::kCase); | 8304 label_pos, *label_name, SourceLabel::kCase); |
8274 current_block_->scope->AddLabel(case_label); | 8305 current_block_->scope->AddLabel(case_label); |
8275 } else if (case_label->kind() == SourceLabel::kForward) { | 8306 } else if (case_label->kind() == SourceLabel::kForward) { |
8276 // We have seen a 'continue' with this label name. Resolve | 8307 // We have seen a 'continue' with this label name. Resolve |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8316 } | 8347 } |
8317 | 8348 |
8318 SequenceNode* switch_body = CloseBlock(); | 8349 SequenceNode* switch_body = CloseBlock(); |
8319 ExpectToken(Token::kRBRACE); | 8350 ExpectToken(Token::kRBRACE); |
8320 return new(Z) SwitchNode(switch_pos, label, switch_body); | 8351 return new(Z) SwitchNode(switch_pos, label, switch_body); |
8321 } | 8352 } |
8322 | 8353 |
8323 | 8354 |
8324 AstNode* Parser::ParseWhileStatement(String* label_name) { | 8355 AstNode* Parser::ParseWhileStatement(String* label_name) { |
8325 TRACE_PARSER("ParseWhileStatement"); | 8356 TRACE_PARSER("ParseWhileStatement"); |
8326 const intptr_t while_pos = TokenPos(); | 8357 const TokenPosition while_pos = TokenPos(); |
8327 SourceLabel* label = | 8358 SourceLabel* label = |
8328 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 8359 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
8329 ConsumeToken(); | 8360 ConsumeToken(); |
8330 ExpectToken(Token::kLPAREN); | 8361 ExpectToken(Token::kLPAREN); |
8331 SequenceNode* await_preamble = NULL; | 8362 SequenceNode* await_preamble = NULL; |
8332 AstNode* cond_expr = ParseAwaitableExpr( | 8363 AstNode* cond_expr = ParseAwaitableExpr( |
8333 kAllowConst, kConsumeCascades, &await_preamble); | 8364 kAllowConst, kConsumeCascades, &await_preamble); |
8334 ExpectToken(Token::kRPAREN); | 8365 ExpectToken(Token::kRPAREN); |
8335 const bool parsing_loop_body = true; | 8366 const bool parsing_loop_body = true; |
8336 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 8367 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
8337 WhileNode* while_node = new (Z) WhileNode(while_pos, | 8368 WhileNode* while_node = new (Z) WhileNode(while_pos, |
8338 label, | 8369 label, |
8339 cond_expr, | 8370 cond_expr, |
8340 await_preamble, | 8371 await_preamble, |
8341 while_body); | 8372 while_body); |
8342 return while_node; | 8373 return while_node; |
8343 } | 8374 } |
8344 | 8375 |
8345 | 8376 |
8346 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 8377 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
8347 TRACE_PARSER("ParseDoWhileStatement"); | 8378 TRACE_PARSER("ParseDoWhileStatement"); |
8348 const intptr_t do_pos = TokenPos(); | 8379 const TokenPosition do_pos = TokenPos(); |
8349 SourceLabel* label = | 8380 SourceLabel* label = |
8350 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 8381 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
8351 ConsumeToken(); | 8382 ConsumeToken(); |
8352 const bool parsing_loop_body = true; | 8383 const bool parsing_loop_body = true; |
8353 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 8384 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
8354 ExpectToken(Token::kWHILE); | 8385 ExpectToken(Token::kWHILE); |
8355 ExpectToken(Token::kLPAREN); | 8386 ExpectToken(Token::kLPAREN); |
8356 SequenceNode* await_preamble = NULL; | 8387 SequenceNode* await_preamble = NULL; |
8357 intptr_t expr_pos = TokenPos(); | 8388 TokenPosition expr_pos = TokenPos(); |
8358 AstNode* cond_expr = | 8389 AstNode* cond_expr = |
8359 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8390 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
8360 if (await_preamble != NULL) { | 8391 if (await_preamble != NULL) { |
8361 // Prepend the preamble to the condition. | 8392 // Prepend the preamble to the condition. |
8362 LetNode* await_cond = new(Z) LetNode(expr_pos); | 8393 LetNode* await_cond = new(Z) LetNode(expr_pos); |
8363 await_cond->AddNode(await_preamble); | 8394 await_cond->AddNode(await_preamble); |
8364 await_cond->AddNode(cond_expr); | 8395 await_cond->AddNode(cond_expr); |
8365 cond_expr = await_cond; | 8396 cond_expr = await_cond; |
8366 } | 8397 } |
8367 ExpectToken(Token::kRPAREN); | 8398 ExpectToken(Token::kRPAREN); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8448 } | 8479 } |
8449 | 8480 |
8450 | 8481 |
8451 // Build an AST node for static call to Dart function print(str). | 8482 // Build an AST node for static call to Dart function print(str). |
8452 // Used during debugging to insert print in generated dart code. | 8483 // Used during debugging to insert print in generated dart code. |
8453 AstNode* Parser::DartPrint(const char* str) { | 8484 AstNode* Parser::DartPrint(const char* str) { |
8454 const Library& lib = Library::Handle(Library::CoreLibrary()); | 8485 const Library& lib = Library::Handle(Library::CoreLibrary()); |
8455 const Function& print_fn = Function::ZoneHandle( | 8486 const Function& print_fn = Function::ZoneHandle( |
8456 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 8487 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
8457 ASSERT(!print_fn.IsNull()); | 8488 ASSERT(!print_fn.IsNull()); |
8458 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Token::kNoSourcePos); | 8489 ArgumentListNode* one_arg = |
| 8490 new(Z) ArgumentListNode(TokenPosition::kNoSource); |
8459 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); | 8491 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); |
8460 one_arg->Add(new(Z) LiteralNode(Token::kNoSourcePos, msg)); | 8492 one_arg->Add(new(Z) LiteralNode(TokenPosition::kNoSource, msg)); |
8461 AstNode* print_call = | 8493 AstNode* print_call = |
8462 new(Z) StaticCallNode(Token::kNoSourcePos, print_fn, one_arg); | 8494 new(Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); |
8463 return print_call; | 8495 return print_call; |
8464 } | 8496 } |
8465 | 8497 |
8466 | 8498 |
8467 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 8499 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
8468 TRACE_PARSER("ParseAwaitForStatement"); | 8500 TRACE_PARSER("ParseAwaitForStatement"); |
8469 ASSERT(IsAwaitKeyword()); | 8501 ASSERT(IsAwaitKeyword()); |
8470 const intptr_t await_for_pos = TokenPos(); | 8502 const TokenPosition await_for_pos = TokenPos(); |
8471 ConsumeToken(); // await. | 8503 ConsumeToken(); // await. |
8472 ASSERT(CurrentToken() == Token::kFOR); | 8504 ASSERT(CurrentToken() == Token::kFOR); |
8473 ConsumeToken(); // for. | 8505 ConsumeToken(); // for. |
8474 ExpectToken(Token::kLPAREN); | 8506 ExpectToken(Token::kLPAREN); |
8475 | 8507 |
8476 if (!innermost_function().IsAsyncFunction() && | 8508 if (!innermost_function().IsAsyncFunction() && |
8477 !innermost_function().IsAsyncClosure() && | 8509 !innermost_function().IsAsyncClosure() && |
8478 !innermost_function().IsAsyncGenerator() && | 8510 !innermost_function().IsAsyncGenerator() && |
8479 !innermost_function().IsAsyncGenClosure()) { | 8511 !innermost_function().IsAsyncGenClosure()) { |
8480 ReportError(await_for_pos, | 8512 ReportError(await_for_pos, |
8481 "await for loop is only allowed in an asynchronous function"); | 8513 "await for loop is only allowed in an asynchronous function"); |
8482 } | 8514 } |
8483 | 8515 |
8484 // Parse loop variable. | 8516 // Parse loop variable. |
8485 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8517 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
8486 if (CurrentToken() == Token::kCONST) { | 8518 if (CurrentToken() == Token::kCONST) { |
8487 ReportError("Loop variable cannot be 'const'"); | 8519 ReportError("Loop variable cannot be 'const'"); |
8488 } | 8520 } |
8489 bool new_loop_var = false; | 8521 bool new_loop_var = false; |
8490 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8522 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
8491 if (LookaheadToken(1) != Token::kIN) { | 8523 if (LookaheadToken(1) != Token::kIN) { |
8492 // Declaration of a new loop variable. | 8524 // Declaration of a new loop variable. |
8493 // Delay creation of the local variable until we know its actual | 8525 // Delay creation of the local variable until we know its actual |
8494 // position, which is inside the loop body. | 8526 // position, which is inside the loop body. |
8495 new_loop_var = true; | 8527 new_loop_var = true; |
8496 loop_var_type = ParseConstFinalVarOrType( | 8528 loop_var_type = ParseConstFinalVarOrType( |
8497 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8529 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
8498 ClassFinalizer::kIgnore); | 8530 ClassFinalizer::kIgnore); |
8499 } | 8531 } |
8500 intptr_t loop_var_pos = TokenPos(); | 8532 TokenPosition loop_var_pos = TokenPos(); |
8501 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 8533 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
8502 | 8534 |
8503 // Parse stream expression. | 8535 // Parse stream expression. |
8504 ExpectToken(Token::kIN); | 8536 ExpectToken(Token::kIN); |
8505 const intptr_t stream_expr_pos = TokenPos(); | 8537 const TokenPosition stream_expr_pos = TokenPos(); |
8506 AstNode* stream_expr = | 8538 AstNode* stream_expr = |
8507 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8539 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8508 ExpectToken(Token::kRPAREN); | 8540 ExpectToken(Token::kRPAREN); |
8509 | 8541 |
8510 // Open a block for the iterator variable and the try-finally | 8542 // Open a block for the iterator variable and the try-finally |
8511 // statement that contains the loop. | 8543 // statement that contains the loop. |
8512 OpenBlock(); | 8544 OpenBlock(); |
8513 const Block* loop_block = current_block_; | 8545 const Block* loop_block = current_block_; |
8514 | 8546 |
8515 // Build creation of implicit StreamIterator. | 8547 // Build creation of implicit StreamIterator. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8592 | 8624 |
8593 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8625 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
8594 // here, but that does not work well because we have to insert an implicit | 8626 // here, but that does not work well because we have to insert an implicit |
8595 // variable assignment and potentially a variable declaration in the | 8627 // variable assignment and potentially a variable declaration in the |
8596 // loop body. | 8628 // loop body. |
8597 OpenLoopBlock(); | 8629 OpenLoopBlock(); |
8598 | 8630 |
8599 SourceLabel* label = | 8631 SourceLabel* label = |
8600 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); | 8632 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); |
8601 current_block_->scope->AddLabel(label); | 8633 current_block_->scope->AddLabel(label); |
8602 const intptr_t loop_var_assignment_pos = TokenPos(); | 8634 const TokenPosition loop_var_assignment_pos = TokenPos(); |
8603 | 8635 |
8604 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8636 AstNode* iterator_current = new(Z) InstanceGetterNode( |
8605 loop_var_assignment_pos, | 8637 loop_var_assignment_pos, |
8606 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8638 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
8607 Symbols::Current()); | 8639 Symbols::Current()); |
8608 | 8640 |
8609 // Generate assignment of next iterator value to loop variable. | 8641 // Generate assignment of next iterator value to loop variable. |
8610 AstNode* loop_var_assignment = NULL; | 8642 AstNode* loop_var_assignment = NULL; |
8611 if (new_loop_var) { | 8643 if (new_loop_var) { |
8612 // The for loop variable is new for each iteration. | 8644 // The for loop variable is new for each iteration. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8657 current_block_->statements->Add(while_node); | 8689 current_block_->statements->Add(while_node); |
8658 SequenceNode* try_block = CloseBlock(); | 8690 SequenceNode* try_block = CloseBlock(); |
8659 | 8691 |
8660 // Create an empty "catch all" block that rethrows the current | 8692 // Create an empty "catch all" block that rethrows the current |
8661 // exception and stacktrace. | 8693 // exception and stacktrace. |
8662 try_stack_->enter_catch(); | 8694 try_stack_->enter_catch(); |
8663 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); | 8695 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); |
8664 | 8696 |
8665 if (outer_saved_try_ctx != NULL) { | 8697 if (outer_saved_try_ctx != NULL) { |
8666 catch_block->Add(new (Z) StoreLocalNode( | 8698 catch_block->Add(new (Z) StoreLocalNode( |
8667 Token::kNoSourcePos, | 8699 TokenPosition::kNoSource, |
8668 outer_saved_try_ctx, | 8700 outer_saved_try_ctx, |
8669 new (Z) LoadLocalNode(Token::kNoSourcePos, | 8701 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
8670 outer_async_saved_try_ctx))); | 8702 outer_async_saved_try_ctx))); |
8671 } | 8703 } |
8672 | 8704 |
8673 // We don't need to copy the current exception and stack trace variables | 8705 // We don't need to copy the current exception and stack trace variables |
8674 // into :saved_exception_var and :saved_stack_trace_var here because there | 8706 // into :saved_exception_var and :saved_stack_trace_var here because there |
8675 // is no code in the catch clause that could suspend the function. | 8707 // is no code in the catch clause that could suspend the function. |
8676 | 8708 |
8677 // Rethrow the exception. | 8709 // Rethrow the exception. |
8678 catch_block->Add(new(Z) ThrowNode( | 8710 catch_block->Add(new(Z) ThrowNode( |
8679 await_for_pos, | 8711 await_for_pos, |
(...skipping 11 matching lines...) Expand all Loading... |
8691 | 8723 |
8692 // Inline the finally block to the exit points in the try block. | 8724 // Inline the finally block to the exit points in the try block. |
8693 intptr_t node_index = 0; | 8725 intptr_t node_index = 0; |
8694 SequenceNode* finally_clause = NULL; | 8726 SequenceNode* finally_clause = NULL; |
8695 if (try_stack_ != NULL) { | 8727 if (try_stack_ != NULL) { |
8696 try_stack_->enter_finally(); | 8728 try_stack_->enter_finally(); |
8697 } | 8729 } |
8698 do { | 8730 do { |
8699 OpenBlock(); | 8731 OpenBlock(); |
8700 ArgumentListNode* no_args = | 8732 ArgumentListNode* no_args = |
8701 new(Z) ArgumentListNode(Token::kNoSourcePos); | 8733 new(Z) ArgumentListNode(TokenPosition::kNoSource); |
8702 current_block_->statements->Add( | 8734 current_block_->statements->Add( |
8703 new(Z) InstanceCallNode(Token::kNoSourcePos, | 8735 new(Z) InstanceCallNode(TokenPosition::kNoSource, |
8704 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_var), | 8736 new(Z) LoadLocalNode(TokenPosition::kNoSource, iterator_var), |
8705 Symbols::Cancel(), | 8737 Symbols::Cancel(), |
8706 no_args)); | 8738 no_args)); |
8707 finally_clause = CloseBlock(); | 8739 finally_clause = CloseBlock(); |
8708 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 8740 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
8709 if (node_to_inline != NULL) { | 8741 if (node_to_inline != NULL) { |
8710 InlinedFinallyNode* node = | 8742 InlinedFinallyNode* node = |
8711 new(Z) InlinedFinallyNode(Token::kNoSourcePos, | 8743 new(Z) InlinedFinallyNode(TokenPosition::kNoSource, |
8712 finally_clause, | 8744 finally_clause, |
8713 context_var, | 8745 context_var, |
8714 outer_try_index); | 8746 outer_try_index); |
8715 finally_clause = NULL; | 8747 finally_clause = NULL; |
8716 AddFinallyClauseToNode(true, node_to_inline, node); | 8748 AddFinallyClauseToNode(true, node_to_inline, node); |
8717 node_index++; | 8749 node_index++; |
8718 } | 8750 } |
8719 } while (finally_clause == NULL); | 8751 } while (finally_clause == NULL); |
8720 | 8752 |
8721 if (try_stack_ != NULL) { | 8753 if (try_stack_ != NULL) { |
(...skipping 27 matching lines...) Expand all Loading... |
8749 try_index, | 8781 try_index, |
8750 finally_clause); | 8782 finally_clause); |
8751 | 8783 |
8752 ASSERT(current_block_ == loop_block); | 8784 ASSERT(current_block_ == loop_block); |
8753 loop_block->statements->Add(try_catch_node); | 8785 loop_block->statements->Add(try_catch_node); |
8754 | 8786 |
8755 return CloseBlock(); // Implicit block around while loop. | 8787 return CloseBlock(); // Implicit block around while loop. |
8756 } | 8788 } |
8757 | 8789 |
8758 | 8790 |
8759 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 8791 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, |
8760 SourceLabel* label) { | 8792 SourceLabel* label) { |
8761 TRACE_PARSER("ParseForInStatement"); | 8793 TRACE_PARSER("ParseForInStatement"); |
8762 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8794 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
8763 if (CurrentToken() == Token::kCONST) { | 8795 if (CurrentToken() == Token::kCONST) { |
8764 ReportError("Loop variable cannot be 'const'"); | 8796 ReportError("Loop variable cannot be 'const'"); |
8765 } | 8797 } |
8766 const String* loop_var_name = NULL; | 8798 const String* loop_var_name = NULL; |
8767 intptr_t loop_var_pos = Token::kNoSourcePos; | 8799 TokenPosition loop_var_pos = TokenPosition::kNoSource; |
8768 bool new_loop_var = false; | 8800 bool new_loop_var = false; |
8769 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8801 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
8770 if (LookaheadToken(1) == Token::kIN) { | 8802 if (LookaheadToken(1) == Token::kIN) { |
8771 loop_var_pos = TokenPos(); | 8803 loop_var_pos = TokenPos(); |
8772 loop_var_name = ExpectIdentifier("variable name expected"); | 8804 loop_var_name = ExpectIdentifier("variable name expected"); |
8773 } else { | 8805 } else { |
8774 // The case without a type is handled above, so require a type here. | 8806 // The case without a type is handled above, so require a type here. |
8775 // Delay creation of the local variable until we know its actual | 8807 // Delay creation of the local variable until we know its actual |
8776 // position, which is inside the loop body. | 8808 // position, which is inside the loop body. |
8777 new_loop_var = true; | 8809 new_loop_var = true; |
8778 loop_var_type = ParseConstFinalVarOrType( | 8810 loop_var_type = ParseConstFinalVarOrType( |
8779 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8811 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
8780 ClassFinalizer::kIgnore); | 8812 ClassFinalizer::kIgnore); |
8781 loop_var_name = ExpectIdentifier("variable name expected"); | 8813 loop_var_name = ExpectIdentifier("variable name expected"); |
8782 } | 8814 } |
8783 ExpectToken(Token::kIN); | 8815 ExpectToken(Token::kIN); |
8784 const intptr_t collection_pos = TokenPos(); | 8816 const TokenPosition collection_pos = TokenPos(); |
8785 AstNode* collection_expr = | 8817 AstNode* collection_expr = |
8786 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8818 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8787 ExpectToken(Token::kRPAREN); | 8819 ExpectToken(Token::kRPAREN); |
8788 | 8820 |
8789 OpenBlock(); // Implicit block around while loop. | 8821 OpenBlock(); // Implicit block around while loop. |
8790 | 8822 |
8791 // Generate implicit iterator variable and add to scope. | 8823 // Generate implicit iterator variable and add to scope. |
8792 // We could set the type of the implicit iterator variable to Iterator<T> | 8824 // We could set the type of the implicit iterator variable to Iterator<T> |
8793 // where T is the type of the for loop variable. However, the type error | 8825 // where T is the type of the for loop variable. However, the type error |
8794 // would refer to the compiler generated iterator and could confuse the user. | 8826 // would refer to the compiler generated iterator and could confuse the user. |
(...skipping 18 matching lines...) Expand all Loading... |
8813 new(Z) LoadLocalNode(collection_pos, iterator_var), | 8845 new(Z) LoadLocalNode(collection_pos, iterator_var), |
8814 Symbols::MoveNext(), | 8846 Symbols::MoveNext(), |
8815 no_args); | 8847 no_args); |
8816 | 8848 |
8817 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8849 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
8818 // here, but that does not work well because we have to insert an implicit | 8850 // here, but that does not work well because we have to insert an implicit |
8819 // variable assignment and potentially a variable declaration in the | 8851 // variable assignment and potentially a variable declaration in the |
8820 // loop body. | 8852 // loop body. |
8821 OpenLoopBlock(); | 8853 OpenLoopBlock(); |
8822 current_block_->scope->AddLabel(label); | 8854 current_block_->scope->AddLabel(label); |
8823 const intptr_t loop_var_assignment_pos = TokenPos(); | 8855 const TokenPosition loop_var_assignment_pos = TokenPos(); |
8824 | 8856 |
8825 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8857 AstNode* iterator_current = new(Z) InstanceGetterNode( |
8826 loop_var_assignment_pos, | 8858 loop_var_assignment_pos, |
8827 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8859 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
8828 Symbols::Current()); | 8860 Symbols::Current()); |
8829 | 8861 |
8830 // Generate assignment of next iterator value to loop variable. | 8862 // Generate assignment of next iterator value to loop variable. |
8831 AstNode* loop_var_assignment = NULL; | 8863 AstNode* loop_var_assignment = NULL; |
8832 if (new_loop_var) { | 8864 if (new_loop_var) { |
8833 // The for loop variable is new for each iteration. | 8865 // The for loop variable is new for each iteration. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8871 AstNode* while_statement = new(Z) WhileNode( | 8903 AstNode* while_statement = new(Z) WhileNode( |
8872 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 8904 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
8873 current_block_->statements->Add(while_statement); | 8905 current_block_->statements->Add(while_statement); |
8874 | 8906 |
8875 return CloseBlock(); // Implicit block around while loop. | 8907 return CloseBlock(); // Implicit block around while loop. |
8876 } | 8908 } |
8877 | 8909 |
8878 | 8910 |
8879 AstNode* Parser::ParseForStatement(String* label_name) { | 8911 AstNode* Parser::ParseForStatement(String* label_name) { |
8880 TRACE_PARSER("ParseForStatement"); | 8912 TRACE_PARSER("ParseForStatement"); |
8881 const intptr_t for_pos = TokenPos(); | 8913 const TokenPosition for_pos = TokenPos(); |
8882 ConsumeToken(); | 8914 ConsumeToken(); |
8883 ExpectToken(Token::kLPAREN); | 8915 ExpectToken(Token::kLPAREN); |
8884 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 8916 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
8885 if (IsForInStatement()) { | 8917 if (IsForInStatement()) { |
8886 return ParseForInStatement(for_pos, label); | 8918 return ParseForInStatement(for_pos, label); |
8887 } | 8919 } |
8888 // Open a block that contains the loop variable. Make it a loop block so | 8920 // Open a block that contains the loop variable. Make it a loop block so |
8889 // that we allocate a new context if the loop variable is captured. | 8921 // that we allocate a new context if the loop variable is captured. |
8890 OpenLoopBlock(); | 8922 OpenLoopBlock(); |
8891 AstNode* initializer = NULL; | 8923 AstNode* initializer = NULL; |
8892 const intptr_t init_pos = TokenPos(); | 8924 const TokenPosition init_pos = TokenPos(); |
8893 LocalScope* init_scope = current_block_->scope; | 8925 LocalScope* init_scope = current_block_->scope; |
8894 if (CurrentToken() != Token::kSEMICOLON) { | 8926 if (CurrentToken() != Token::kSEMICOLON) { |
8895 if (IsVariableDeclaration()) { | 8927 if (IsVariableDeclaration()) { |
8896 initializer = ParseVariableDeclarationList(); | 8928 initializer = ParseVariableDeclarationList(); |
8897 } else { | 8929 } else { |
8898 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8930 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8899 } | 8931 } |
8900 } | 8932 } |
8901 ExpectSemicolon(); | 8933 ExpectSemicolon(); |
8902 AstNode* condition = NULL; | 8934 AstNode* condition = NULL; |
8903 SequenceNode* condition_preamble = NULL; | 8935 SequenceNode* condition_preamble = NULL; |
8904 if (CurrentToken() != Token::kSEMICOLON) { | 8936 if (CurrentToken() != Token::kSEMICOLON) { |
8905 condition = ParseAwaitableExpr( | 8937 condition = ParseAwaitableExpr( |
8906 kAllowConst, kConsumeCascades, &condition_preamble); | 8938 kAllowConst, kConsumeCascades, &condition_preamble); |
8907 } | 8939 } |
8908 ExpectSemicolon(); | 8940 ExpectSemicolon(); |
8909 AstNode* increment = NULL; | 8941 AstNode* increment = NULL; |
8910 const intptr_t incr_pos = TokenPos(); | 8942 const TokenPosition incr_pos = TokenPos(); |
8911 if (CurrentToken() != Token::kRPAREN) { | 8943 if (CurrentToken() != Token::kRPAREN) { |
8912 increment = ParseAwaitableExprList(); | 8944 increment = ParseAwaitableExprList(); |
8913 } | 8945 } |
8914 ExpectToken(Token::kRPAREN); | 8946 ExpectToken(Token::kRPAREN); |
8915 const bool parsing_loop_body = true; | 8947 const bool parsing_loop_body = true; |
8916 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 8948 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
8917 | 8949 |
8918 // Check whether any of the variables in the initializer part of | 8950 // Check whether any of the variables in the initializer part of |
8919 // the for statement are captured by a closure. If so, we insert a | 8951 // the for statement are captured by a closure. If so, we insert a |
8920 // node that creates a new Context for the loop variable before | 8952 // node that creates a new Context for the loop variable before |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8953 const Function& func = Function::ZoneHandle(Z, | 8985 const Function& func = Function::ZoneHandle(Z, |
8954 Resolver::ResolveStatic(cls, | 8986 Resolver::ResolveStatic(cls, |
8955 func_name, | 8987 func_name, |
8956 arguments->length(), | 8988 arguments->length(), |
8957 arguments->names())); | 8989 arguments->names())); |
8958 ASSERT(!func.IsNull()); | 8990 ASSERT(!func.IsNull()); |
8959 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); | 8991 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); |
8960 } | 8992 } |
8961 | 8993 |
8962 | 8994 |
8963 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 8995 AstNode* Parser::MakeAssertCall(TokenPosition begin, TokenPosition end) { |
8964 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); | 8996 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); |
8965 arguments->Add(new(Z) LiteralNode(begin, | 8997 arguments->Add(new(Z) LiteralNode(begin, |
8966 Integer::ZoneHandle(Z, Integer::New(begin)))); | 8998 Integer::ZoneHandle(Z, Integer::New(begin.value())))); |
8967 arguments->Add(new(Z) LiteralNode(end, | 8999 arguments->Add(new(Z) LiteralNode(end, |
8968 Integer::ZoneHandle(Z, Integer::New(end)))); | 9000 Integer::ZoneHandle(Z, Integer::New(end.value())))); |
8969 return MakeStaticCall(Symbols::AssertionError(), | 9001 return MakeStaticCall(Symbols::AssertionError(), |
8970 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 9002 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
8971 arguments); | 9003 arguments); |
8972 } | 9004 } |
8973 | 9005 |
8974 | 9006 |
8975 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 9007 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
8976 if (condition->IsClosureNode() || | 9008 if (condition->IsClosureNode() || |
8977 (condition->IsStoreLocalNode() && | 9009 (condition->IsStoreLocalNode() && |
8978 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 9010 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
8979 // Function literal in assert implies a call. | 9011 // Function literal in assert implies a call. |
8980 const intptr_t pos = condition->token_pos(); | 9012 const TokenPosition pos = condition->token_pos(); |
8981 condition = BuildClosureCall(pos, | 9013 condition = BuildClosureCall(pos, |
8982 condition, | 9014 condition, |
8983 new(Z) ArgumentListNode(pos)); | 9015 new(Z) ArgumentListNode(pos)); |
8984 } else if (condition->IsConditionalExprNode()) { | 9016 } else if (condition->IsConditionalExprNode()) { |
8985 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 9017 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
8986 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 9018 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
8987 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 9019 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
8988 } | 9020 } |
8989 return condition; | 9021 return condition; |
8990 } | 9022 } |
8991 | 9023 |
8992 | 9024 |
8993 AstNode* Parser::ParseAssertStatement() { | 9025 AstNode* Parser::ParseAssertStatement() { |
8994 TRACE_PARSER("ParseAssertStatement"); | 9026 TRACE_PARSER("ParseAssertStatement"); |
8995 ConsumeToken(); // Consume assert keyword. | 9027 ConsumeToken(); // Consume assert keyword. |
8996 ExpectToken(Token::kLPAREN); | 9028 ExpectToken(Token::kLPAREN); |
8997 const intptr_t condition_pos = TokenPos(); | 9029 const TokenPosition condition_pos = TokenPos(); |
8998 if (!I->flags().asserts()) { | 9030 if (!I->flags().asserts()) { |
8999 SkipExpr(); | 9031 SkipExpr(); |
9000 ExpectToken(Token::kRPAREN); | 9032 ExpectToken(Token::kRPAREN); |
9001 return NULL; | 9033 return NULL; |
9002 } | 9034 } |
9003 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9035 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9004 const intptr_t condition_end = TokenPos(); | 9036 const TokenPosition condition_end = TokenPos(); |
9005 ExpectToken(Token::kRPAREN); | 9037 ExpectToken(Token::kRPAREN); |
9006 condition = InsertClosureCallNodes(condition); | 9038 condition = InsertClosureCallNodes(condition); |
9007 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); | 9039 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); |
9008 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 9040 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
9009 return new(Z) IfNode( | 9041 return new(Z) IfNode( |
9010 condition_pos, | 9042 condition_pos, |
9011 condition, | 9043 condition, |
9012 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 9044 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
9013 NULL); | 9045 NULL); |
9014 } | 9046 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9058 ASSERT(innermost_function().IsAsyncClosure() || | 9090 ASSERT(innermost_function().IsAsyncClosure() || |
9059 innermost_function().IsAsyncFunction() || | 9091 innermost_function().IsAsyncFunction() || |
9060 innermost_function().IsSyncGenClosure() || | 9092 innermost_function().IsSyncGenClosure() || |
9061 innermost_function().IsSyncGenerator() || | 9093 innermost_function().IsSyncGenerator() || |
9062 innermost_function().IsAsyncGenClosure() || | 9094 innermost_function().IsAsyncGenClosure() || |
9063 innermost_function().IsAsyncGenerator()); | 9095 innermost_function().IsAsyncGenerator()); |
9064 | 9096 |
9065 ASSERT(saved_exception_var != NULL); | 9097 ASSERT(saved_exception_var != NULL); |
9066 ASSERT(exception_var != NULL); | 9098 ASSERT(exception_var != NULL); |
9067 statements->Add(new(Z) StoreLocalNode( | 9099 statements->Add(new(Z) StoreLocalNode( |
9068 Token::kNoSourcePos, | 9100 TokenPosition::kNoSource, |
9069 saved_exception_var, | 9101 saved_exception_var, |
9070 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 9102 new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
9071 | 9103 |
9072 ASSERT(saved_stack_trace_var != NULL); | 9104 ASSERT(saved_stack_trace_var != NULL); |
9073 ASSERT(stack_trace_var != NULL); | 9105 ASSERT(stack_trace_var != NULL); |
9074 statements->Add(new(Z) StoreLocalNode( | 9106 statements->Add(new(Z) StoreLocalNode( |
9075 Token::kNoSourcePos, | 9107 TokenPosition::kNoSource, |
9076 saved_stack_trace_var, | 9108 saved_stack_trace_var, |
9077 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 9109 new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
9078 } | 9110 } |
9079 | 9111 |
9080 | 9112 |
9081 SequenceNode* Parser::EnsureFinallyClause( | 9113 SequenceNode* Parser::EnsureFinallyClause( |
9082 bool parse, | 9114 bool parse, |
9083 bool is_async, | 9115 bool is_async, |
9084 LocalVariable* exception_var, | 9116 LocalVariable* exception_var, |
9085 LocalVariable* stack_trace_var, | 9117 LocalVariable* stack_trace_var, |
9086 LocalVariable* rethrow_exception_var, | 9118 LocalVariable* rethrow_exception_var, |
9087 LocalVariable* rethrow_stack_trace_var) { | 9119 LocalVariable* rethrow_stack_trace_var) { |
(...skipping 14 matching lines...) Expand all Loading... |
9102 if (try_stack_ != NULL) { | 9134 if (try_stack_ != NULL) { |
9103 LocalScope* scope = try_stack_->try_block()->scope; | 9135 LocalScope* scope = try_stack_->try_block()->scope; |
9104 if (scope->function_level() == current_block_->scope->function_level()) { | 9136 if (scope->function_level() == current_block_->scope->function_level()) { |
9105 LocalVariable* saved_try_ctx = | 9137 LocalVariable* saved_try_ctx = |
9106 LookupSavedTryContextVar(scope->parent()); | 9138 LookupSavedTryContextVar(scope->parent()); |
9107 LocalVariable* async_saved_try_ctx = | 9139 LocalVariable* async_saved_try_ctx = |
9108 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9140 LookupAsyncSavedTryContextVar(async_temp_scope_, |
9109 try_stack_->try_index()); | 9141 try_stack_->try_index()); |
9110 current_block_->statements->Add( | 9142 current_block_->statements->Add( |
9111 new (Z) StoreLocalNode( | 9143 new (Z) StoreLocalNode( |
9112 Token::kNoSourcePos, | 9144 TokenPosition::kNoSource, |
9113 saved_try_ctx, | 9145 saved_try_ctx, |
9114 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9146 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9115 async_saved_try_ctx))); | 9147 async_saved_try_ctx))); |
9116 } | 9148 } |
9117 } | 9149 } |
9118 // We need to save the exception variables as in catch clauses, whether | 9150 // We need to save the exception variables as in catch clauses, whether |
9119 // there is an outer try or not. Note that this is only necessary if the | 9151 // there is an outer try or not. Note that this is only necessary if the |
9120 // finally clause contains an await or yield. | 9152 // finally clause contains an await or yield. |
9121 // TODO(hausner): Optimize. | 9153 // TODO(hausner): Optimize. |
9122 SaveExceptionAndStacktrace(current_block_->statements, | 9154 SaveExceptionAndStacktrace(current_block_->statements, |
9123 exception_var, | 9155 exception_var, |
9124 stack_trace_var, | 9156 stack_trace_var, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9188 return_node->AddInlinedFinallyNode(finally_clause); | 9220 return_node->AddInlinedFinallyNode(finally_clause); |
9189 return; | 9221 return; |
9190 } | 9222 } |
9191 JumpNode* jump_node = node->AsJumpNode(); | 9223 JumpNode* jump_node = node->AsJumpNode(); |
9192 ASSERT(jump_node != NULL); | 9224 ASSERT(jump_node != NULL); |
9193 jump_node->AddInlinedFinallyNode(finally_clause); | 9225 jump_node->AddInlinedFinallyNode(finally_clause); |
9194 } | 9226 } |
9195 | 9227 |
9196 | 9228 |
9197 SequenceNode* Parser::ParseCatchClauses( | 9229 SequenceNode* Parser::ParseCatchClauses( |
9198 intptr_t handler_pos, | 9230 TokenPosition handler_pos, |
9199 bool is_async, | 9231 bool is_async, |
9200 LocalVariable* exception_var, | 9232 LocalVariable* exception_var, |
9201 LocalVariable* stack_trace_var, | 9233 LocalVariable* stack_trace_var, |
9202 LocalVariable* rethrow_exception_var, | 9234 LocalVariable* rethrow_exception_var, |
9203 LocalVariable* rethrow_stack_trace_var, | 9235 LocalVariable* rethrow_stack_trace_var, |
9204 const GrowableObjectArray& handler_types, | 9236 const GrowableObjectArray& handler_types, |
9205 bool* needs_stack_trace) { | 9237 bool* needs_stack_trace) { |
9206 // All catch blocks are merged into an if-then-else sequence of the | 9238 // All catch blocks are merged into an if-then-else sequence of the |
9207 // different types specified using the 'is' operator. While parsing | 9239 // different types specified using the 'is' operator. While parsing |
9208 // record the type tests (either a ComparisonNode or else the LiteralNode | 9240 // record the type tests (either a ComparisonNode or else the LiteralNode |
9209 // true for a generic catch) and the catch bodies in a pair of parallel | 9241 // true for a generic catch) and the catch bodies in a pair of parallel |
9210 // lists. Afterward, construct the nested if-then-else. | 9242 // lists. Afterward, construct the nested if-then-else. |
9211 bool generic_catch_seen = false; | 9243 bool generic_catch_seen = false; |
9212 GrowableArray<AstNode*> type_tests; | 9244 GrowableArray<AstNode*> type_tests; |
9213 GrowableArray<SequenceNode*> catch_blocks; | 9245 GrowableArray<SequenceNode*> catch_blocks; |
9214 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { | 9246 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { |
9215 // Open a block that contains the if or an unconditional body. It's | 9247 // Open a block that contains the if or an unconditional body. It's |
9216 // closed in the loop that builds the if-then-else nest. | 9248 // closed in the loop that builds the if-then-else nest. |
9217 OpenBlock(); | 9249 OpenBlock(); |
9218 const intptr_t catch_pos = TokenPos(); | 9250 const TokenPosition catch_pos = TokenPos(); |
9219 CatchParamDesc exception_param; | 9251 CatchParamDesc exception_param; |
9220 CatchParamDesc stack_trace_param; | 9252 CatchParamDesc stack_trace_param; |
9221 if (IsSymbol(Symbols::On())) { | 9253 if (IsSymbol(Symbols::On())) { |
9222 ConsumeToken(); | 9254 ConsumeToken(); |
9223 exception_param.type = &AbstractType::ZoneHandle(Z, | 9255 exception_param.type = &AbstractType::ZoneHandle(Z, |
9224 ParseType(ClassFinalizer::kCanonicalize)); | 9256 ParseType(ClassFinalizer::kCanonicalize)); |
9225 } else { | 9257 } else { |
9226 exception_param.type = &Object::dynamic_type(); | 9258 exception_param.type = &Object::dynamic_type(); |
9227 } | 9259 } |
9228 if (CurrentToken() == Token::kCATCH) { | 9260 if (CurrentToken() == Token::kCATCH) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9375 if (try_block != NULL) { | 9407 if (try_block != NULL) { |
9376 LocalScope* scope = try_block->try_block()->scope; | 9408 LocalScope* scope = try_block->try_block()->scope; |
9377 if (scope->function_level() == current_block_->scope->function_level()) { | 9409 if (scope->function_level() == current_block_->scope->function_level()) { |
9378 LocalVariable* saved_try_ctx = | 9410 LocalVariable* saved_try_ctx = |
9379 LookupSavedTryContextVar(scope->parent()); | 9411 LookupSavedTryContextVar(scope->parent()); |
9380 LocalVariable* async_saved_try_ctx = | 9412 LocalVariable* async_saved_try_ctx = |
9381 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9413 LookupAsyncSavedTryContextVar(async_temp_scope_, |
9382 try_block->try_index()); | 9414 try_block->try_index()); |
9383 async_code->Add( | 9415 async_code->Add( |
9384 new (Z) StoreLocalNode( | 9416 new (Z) StoreLocalNode( |
9385 Token::kNoSourcePos, | 9417 TokenPosition::kNoSource, |
9386 saved_try_ctx, | 9418 saved_try_ctx, |
9387 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9419 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9388 async_saved_try_ctx))); | 9420 async_saved_try_ctx))); |
9389 } | 9421 } |
9390 } | 9422 } |
9391 SaveExceptionAndStacktrace(async_code, | 9423 SaveExceptionAndStacktrace(async_code, |
9392 exception_var, | 9424 exception_var, |
9393 stack_trace_var, | 9425 stack_trace_var, |
9394 rethrow_exception_var, | 9426 rethrow_exception_var, |
9395 rethrow_stack_trace_var); | 9427 rethrow_stack_trace_var); |
9396 // The async_code node sequence contains code to restore the context (if | 9428 // The async_code node sequence contains code to restore the context (if |
9397 // an outer try block is present) and code to save the exception and | 9429 // an outer try block is present) and code to save the exception and |
9398 // stack trace variables. | 9430 // stack trace variables. |
9399 // This async code is inserted before the current node sequence containing | 9431 // This async code is inserted before the current node sequence containing |
9400 // the chain of if/then/else handling all catch clauses. | 9432 // the chain of if/then/else handling all catch clauses. |
9401 async_code->Add(current); | 9433 async_code->Add(current); |
9402 current = async_code; | 9434 current = async_code; |
9403 } | 9435 } |
9404 return current; | 9436 return current; |
9405 } | 9437 } |
9406 | 9438 |
9407 | 9439 |
9408 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 9440 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
9409 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, | 9441 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, |
9410 Symbols::NewFormatted("%s%d", | 9442 Symbols::NewFormatted("%s%d", |
9411 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 9443 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
9412 last_used_try_index_ - 1)); | 9444 last_used_try_index_ - 1)); |
9413 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 9445 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
9414 Token::kNoSourcePos, | 9446 TokenPosition::kNoSource, |
9415 async_saved_try_ctx_name, | 9447 async_saved_try_ctx_name, |
9416 Object::dynamic_type()); | 9448 Object::dynamic_type()); |
9417 ASSERT(async_temp_scope_ != NULL); | 9449 ASSERT(async_temp_scope_ != NULL); |
9418 async_temp_scope_->AddVariable(async_saved_try_ctx); | 9450 async_temp_scope_->AddVariable(async_saved_try_ctx); |
9419 ASSERT(saved_try_context != NULL); | 9451 ASSERT(saved_try_context != NULL); |
9420 current_block_->statements->Add(new(Z) StoreLocalNode( | 9452 current_block_->statements->Add(new(Z) StoreLocalNode( |
9421 Token::kNoSourcePos, | 9453 TokenPosition::kNoSource, |
9422 async_saved_try_ctx, | 9454 async_saved_try_ctx, |
9423 new(Z) LoadLocalNode(Token::kNoSourcePos, saved_try_context))); | 9455 new(Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); |
9424 } | 9456 } |
9425 | 9457 |
9426 | 9458 |
9427 // We create three variables for exceptions: | 9459 // We create three variables for exceptions: |
9428 // ':saved_try_context_var' - Used to save the context before the start of | 9460 // ':saved_try_context_var' - Used to save the context before the start of |
9429 // the try block. The context register is | 9461 // the try block. The context register is |
9430 // restored from this variable before | 9462 // restored from this variable before |
9431 // processing the catch block handler. | 9463 // processing the catch block handler. |
9432 // ':exception_var' - Used to save the current exception object that was | 9464 // ':exception_var' - Used to save the current exception object that was |
9433 // thrown. | 9465 // thrown. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9492 Object::dynamic_type()); | 9524 Object::dynamic_type()); |
9493 try_scope->AddVariable(*saved_stack_trace_var); | 9525 try_scope->AddVariable(*saved_stack_trace_var); |
9494 } | 9526 } |
9495 } | 9527 } |
9496 } | 9528 } |
9497 | 9529 |
9498 | 9530 |
9499 AstNode* Parser::ParseTryStatement(String* label_name) { | 9531 AstNode* Parser::ParseTryStatement(String* label_name) { |
9500 TRACE_PARSER("ParseTryStatement"); | 9532 TRACE_PARSER("ParseTryStatement"); |
9501 | 9533 |
9502 const intptr_t try_pos = TokenPos(); | 9534 const TokenPosition try_pos = TokenPos(); |
9503 SourceLabel* try_label = NULL; | 9535 SourceLabel* try_label = NULL; |
9504 if (label_name != NULL) { | 9536 if (label_name != NULL) { |
9505 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 9537 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
9506 OpenBlock(); | 9538 OpenBlock(); |
9507 current_block_->scope->AddLabel(try_label); | 9539 current_block_->scope->AddLabel(try_label); |
9508 } | 9540 } |
9509 | 9541 |
9510 const bool is_async = innermost_function().IsAsyncClosure() || | 9542 const bool is_async = innermost_function().IsAsyncClosure() || |
9511 innermost_function().IsAsyncFunction() || | 9543 innermost_function().IsAsyncFunction() || |
9512 innermost_function().IsSyncGenClosure() || | 9544 innermost_function().IsSyncGenClosure() || |
(...skipping 28 matching lines...) Expand all Loading... |
9541 ExpectToken(Token::kRBRACE); | 9573 ExpectToken(Token::kRBRACE); |
9542 SequenceNode* try_block = CloseBlock(); | 9574 SequenceNode* try_block = CloseBlock(); |
9543 | 9575 |
9544 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && | 9576 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && |
9545 (CurrentToken() != Token::kFINALLY)) { | 9577 (CurrentToken() != Token::kFINALLY)) { |
9546 ReportError("catch or finally clause expected"); | 9578 ReportError("catch or finally clause expected"); |
9547 } | 9579 } |
9548 | 9580 |
9549 // Now parse the 'catch' blocks if any. | 9581 // Now parse the 'catch' blocks if any. |
9550 try_stack_->enter_catch(); | 9582 try_stack_->enter_catch(); |
9551 const intptr_t handler_pos = TokenPos(); | 9583 const TokenPosition handler_pos = TokenPos(); |
9552 const GrowableObjectArray& handler_types = | 9584 const GrowableObjectArray& handler_types = |
9553 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 9585 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
9554 bool needs_stack_trace = false; | 9586 bool needs_stack_trace = false; |
9555 SequenceNode* catch_handler_list = | 9587 SequenceNode* catch_handler_list = |
9556 ParseCatchClauses(handler_pos, | 9588 ParseCatchClauses(handler_pos, |
9557 is_async, | 9589 is_async, |
9558 exception_var, | 9590 exception_var, |
9559 stack_trace_var, | 9591 stack_trace_var, |
9560 is_async ? saved_exception_var : exception_var, | 9592 is_async ? saved_exception_var : exception_var, |
9561 is_async ? saved_stack_trace_var : stack_trace_var, | 9593 is_async ? saved_stack_trace_var : stack_trace_var, |
(...skipping 10 matching lines...) Expand all Loading... |
9572 // A finally clause is required in async code to restore the saved try context | 9604 // A finally clause is required in async code to restore the saved try context |
9573 // of an existing outer try. Generate a finally clause to this purpose if it | 9605 // of an existing outer try. Generate a finally clause to this purpose if it |
9574 // is not declared. | 9606 // is not declared. |
9575 SequenceNode* finally_clause = NULL; | 9607 SequenceNode* finally_clause = NULL; |
9576 SequenceNode* rethrow_clause = NULL; | 9608 SequenceNode* rethrow_clause = NULL; |
9577 const bool parse = CurrentToken() == Token::kFINALLY; | 9609 const bool parse = CurrentToken() == Token::kFINALLY; |
9578 if (parse || (is_async && (try_stack_ != NULL))) { | 9610 if (parse || (is_async && (try_stack_ != NULL))) { |
9579 if (parse) { | 9611 if (parse) { |
9580 ConsumeToken(); // Consume the 'finally'. | 9612 ConsumeToken(); // Consume the 'finally'. |
9581 } | 9613 } |
9582 const intptr_t finally_pos = TokenPos(); | 9614 const TokenPosition finally_pos = TokenPos(); |
9583 // Add the finally block to the exit points recorded so far. | 9615 // Add the finally block to the exit points recorded so far. |
9584 intptr_t node_index = 0; | 9616 intptr_t node_index = 0; |
9585 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 9617 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
9586 while (node_to_inline != NULL) { | 9618 while (node_to_inline != NULL) { |
9587 finally_clause = EnsureFinallyClause( | 9619 finally_clause = EnsureFinallyClause( |
9588 parse, | 9620 parse, |
9589 is_async, | 9621 is_async, |
9590 exception_var, | 9622 exception_var, |
9591 stack_trace_var, | 9623 stack_trace_var, |
9592 is_async ? saved_exception_var : exception_var, | 9624 is_async ? saved_exception_var : exception_var, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9652 } | 9684 } |
9653 | 9685 |
9654 return try_catch_node; | 9686 return try_catch_node; |
9655 } | 9687 } |
9656 | 9688 |
9657 | 9689 |
9658 AstNode* Parser::ParseJump(String* label_name) { | 9690 AstNode* Parser::ParseJump(String* label_name) { |
9659 TRACE_PARSER("ParseJump"); | 9691 TRACE_PARSER("ParseJump"); |
9660 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 9692 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
9661 Token::Kind jump_kind = CurrentToken(); | 9693 Token::Kind jump_kind = CurrentToken(); |
9662 const intptr_t jump_pos = TokenPos(); | 9694 const TokenPosition jump_pos = TokenPos(); |
9663 SourceLabel* target = NULL; | 9695 SourceLabel* target = NULL; |
9664 ConsumeToken(); | 9696 ConsumeToken(); |
9665 if (IsIdentifier()) { | 9697 if (IsIdentifier()) { |
9666 // Explicit label after break/continue. | 9698 // Explicit label after break/continue. |
9667 const String& target_name = *CurrentLiteral(); | 9699 const String& target_name = *CurrentLiteral(); |
9668 ConsumeToken(); | 9700 ConsumeToken(); |
9669 // Handle pathological cases first. | 9701 // Handle pathological cases first. |
9670 if (label_name != NULL && target_name.Equals(*label_name)) { | 9702 if (label_name != NULL && target_name.Equals(*label_name)) { |
9671 if (jump_kind == Token::kCONTINUE) { | 9703 if (jump_kind == Token::kCONTINUE) { |
9672 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", | 9704 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9717 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 9749 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
9718 ReportError(jump_pos, "'%s' target must be in same function context", | 9750 ReportError(jump_pos, "'%s' target must be in same function context", |
9719 Token::Str(jump_kind)); | 9751 Token::Str(jump_kind)); |
9720 } | 9752 } |
9721 return new(Z) JumpNode(jump_pos, jump_kind, target); | 9753 return new(Z) JumpNode(jump_pos, jump_kind, target); |
9722 } | 9754 } |
9723 | 9755 |
9724 | 9756 |
9725 AstNode* Parser::ParseYieldStatement() { | 9757 AstNode* Parser::ParseYieldStatement() { |
9726 bool is_yield_each = false; | 9758 bool is_yield_each = false; |
9727 const intptr_t yield_pos = TokenPos(); | 9759 const TokenPosition yield_pos = TokenPos(); |
9728 ConsumeToken(); // yield reserved word. | 9760 ConsumeToken(); // yield reserved word. |
9729 if (CurrentToken() == Token::kMUL) { | 9761 if (CurrentToken() == Token::kMUL) { |
9730 is_yield_each = true; | 9762 is_yield_each = true; |
9731 ConsumeToken(); | 9763 ConsumeToken(); |
9732 } | 9764 } |
9733 if (!innermost_function().IsGenerator() && | 9765 if (!innermost_function().IsGenerator() && |
9734 !innermost_function().IsGeneratorClosure()) { | 9766 !innermost_function().IsGeneratorClosure()) { |
9735 ReportError(yield_pos, | 9767 ReportError(yield_pos, |
9736 "yield%s statement only allowed in generator functions", | 9768 "yield%s statement only allowed in generator functions", |
9737 is_yield_each ? "*" : ""); | 9769 is_yield_each ? "*" : ""); |
9738 } | 9770 } |
9739 | 9771 |
9740 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9772 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9741 | 9773 |
9742 LetNode* yield = new(Z) LetNode(yield_pos); | 9774 LetNode* yield = new(Z) LetNode(yield_pos); |
9743 if (innermost_function().IsSyncGenerator() || | 9775 if (innermost_function().IsSyncGenerator() || |
9744 innermost_function().IsSyncGenClosure()) { | 9776 innermost_function().IsSyncGenClosure()) { |
9745 // Yield statement in sync* function. | 9777 // Yield statement in sync* function. |
9746 | 9778 |
9747 LocalVariable* iterator_param = | 9779 LocalVariable* iterator_param = |
9748 LookupLocalScope(Symbols::IteratorParameter()); | 9780 LookupLocalScope(Symbols::IteratorParameter()); |
9749 ASSERT(iterator_param != NULL); | 9781 ASSERT(iterator_param != NULL); |
9750 // Generate :iterator.current = expr; | 9782 // Generate :iterator.current = expr; |
9751 AstNode* iterator = | 9783 AstNode* iterator = |
9752 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_param); | 9784 new(Z) LoadLocalNode(TokenPosition::kNoSource, iterator_param); |
9753 AstNode* store_current = | 9785 AstNode* store_current = |
9754 new(Z) InstanceSetterNode(Token::kNoSourcePos, | 9786 new(Z) InstanceSetterNode(TokenPosition::kNoSource, |
9755 iterator, | 9787 iterator, |
9756 String::ZoneHandle(Symbols::Current().raw()), | 9788 String::ZoneHandle(Symbols::Current().raw()), |
9757 expr); | 9789 expr); |
9758 yield->AddNode(store_current); | 9790 yield->AddNode(store_current); |
9759 if (is_yield_each) { | 9791 if (is_yield_each) { |
9760 // Generate :iterator.isYieldEach = true; | 9792 // Generate :iterator.isYieldEach = true; |
9761 AstNode* set_is_yield_each = | 9793 AstNode* set_is_yield_each = |
9762 new(Z) InstanceSetterNode(Token::kNoSourcePos, | 9794 new(Z) InstanceSetterNode(TokenPosition::kNoSource, |
9763 iterator, | 9795 iterator, |
9764 String::ZoneHandle(Symbols::IsYieldEach().raw()), | 9796 String::ZoneHandle(Symbols::IsYieldEach().raw()), |
9765 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9797 new(Z) LiteralNode(TokenPos(), Bool::True())); |
9766 yield->AddNode(set_is_yield_each); | 9798 yield->AddNode(set_is_yield_each); |
9767 } | 9799 } |
9768 AwaitMarkerNode* await_marker = | 9800 AwaitMarkerNode* await_marker = |
9769 new(Z) AwaitMarkerNode(async_temp_scope_, | 9801 new(Z) AwaitMarkerNode(async_temp_scope_, |
9770 current_block_->scope, | 9802 current_block_->scope, |
9771 Token::kNoSourcePos); | 9803 TokenPosition::kNoSource); |
9772 yield->AddNode(await_marker); | 9804 yield->AddNode(await_marker); |
9773 // Return true to indicate that a value has been generated. | 9805 // Return true to indicate that a value has been generated. |
9774 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, | 9806 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, |
9775 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9807 new(Z) LiteralNode(TokenPos(), Bool::True())); |
9776 return_true->set_return_type(ReturnNode::kContinuationTarget); | 9808 return_true->set_return_type(ReturnNode::kContinuationTarget); |
9777 yield->AddNode(return_true); | 9809 yield->AddNode(return_true); |
9778 | 9810 |
9779 // If this expression is part of a try block, also append the code for | 9811 // If this expression is part of a try block, also append the code for |
9780 // restoring the saved try context that lives on the stack and possibly the | 9812 // restoring the saved try context that lives on the stack and possibly the |
9781 // saved try context of the outer try block. | 9813 // saved try context of the outer try block. |
9782 LocalVariable* saved_try_ctx; | 9814 LocalVariable* saved_try_ctx; |
9783 LocalVariable* async_saved_try_ctx; | 9815 LocalVariable* async_saved_try_ctx; |
9784 LocalVariable* outer_saved_try_ctx; | 9816 LocalVariable* outer_saved_try_ctx; |
9785 LocalVariable* outer_async_saved_try_ctx; | 9817 LocalVariable* outer_async_saved_try_ctx; |
9786 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9818 CheckAsyncOpInTryBlock(&saved_try_ctx, |
9787 &async_saved_try_ctx, | 9819 &async_saved_try_ctx, |
9788 &outer_saved_try_ctx, | 9820 &outer_saved_try_ctx, |
9789 &outer_async_saved_try_ctx); | 9821 &outer_async_saved_try_ctx); |
9790 if (saved_try_ctx != NULL) { | 9822 if (saved_try_ctx != NULL) { |
9791 yield->AddNode(new (Z) StoreLocalNode( | 9823 yield->AddNode(new (Z) StoreLocalNode( |
9792 Token::kNoSourcePos, | 9824 TokenPosition::kNoSource, |
9793 saved_try_ctx, | 9825 saved_try_ctx, |
9794 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9826 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9795 async_saved_try_ctx))); | 9827 async_saved_try_ctx))); |
9796 if (outer_saved_try_ctx != NULL) { | 9828 if (outer_saved_try_ctx != NULL) { |
9797 yield->AddNode(new (Z) StoreLocalNode( | 9829 yield->AddNode(new (Z) StoreLocalNode( |
9798 Token::kNoSourcePos, | 9830 TokenPosition::kNoSource, |
9799 outer_saved_try_ctx, | 9831 outer_saved_try_ctx, |
9800 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9832 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9801 outer_async_saved_try_ctx))); | 9833 outer_async_saved_try_ctx))); |
9802 } | 9834 } |
9803 } else { | 9835 } else { |
9804 ASSERT(outer_saved_try_ctx == NULL); | 9836 ASSERT(outer_saved_try_ctx == NULL); |
9805 } | 9837 } |
9806 } else { | 9838 } else { |
9807 // yield statement in async* function. | 9839 // yield statement in async* function. |
9808 ASSERT(innermost_function().IsAsyncGenerator() || | 9840 ASSERT(innermost_function().IsAsyncGenerator() || |
9809 innermost_function().IsAsyncGenClosure()); | 9841 innermost_function().IsAsyncGenClosure()); |
9810 | 9842 |
9811 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); | 9843 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); |
9812 ASSERT(controller_var != NULL); | 9844 ASSERT(controller_var != NULL); |
9813 // :controller.add[Stream](expr); | 9845 // :controller.add[Stream](expr); |
9814 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); | 9846 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); |
9815 add_args->Add(expr); | 9847 add_args->Add(expr); |
9816 AstNode* add_call = | 9848 AstNode* add_call = |
9817 new(Z) InstanceCallNode(yield_pos, | 9849 new(Z) InstanceCallNode(yield_pos, |
9818 new(Z) LoadLocalNode(Token::kNoSourcePos, controller_var), | 9850 new(Z) LoadLocalNode(TokenPosition::kNoSource, controller_var), |
9819 is_yield_each ? Symbols::AddStream() : Symbols::add(), | 9851 is_yield_each ? Symbols::AddStream() : Symbols::add(), |
9820 add_args); | 9852 add_args); |
9821 | 9853 |
9822 // if (:controller.add[Stream](expr)) { | 9854 // if (:controller.add[Stream](expr)) { |
9823 // return; | 9855 // return; |
9824 // } | 9856 // } |
9825 // await_marker; | 9857 // await_marker; |
9826 // continuation_return; | 9858 // continuation_return; |
9827 // restore saved_try_context | 9859 // restore saved_try_context |
9828 | 9860 |
9829 SequenceNode* true_branch = | 9861 SequenceNode* true_branch = |
9830 new(Z) SequenceNode(Token::kNoSourcePos, NULL); | 9862 new(Z) SequenceNode(TokenPosition::kNoSource, NULL); |
9831 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); | 9863 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); |
9832 true_branch->Add(return_from_generator); | 9864 true_branch->Add(return_from_generator); |
9833 AddNodeForFinallyInlining(return_from_generator); | 9865 AddNodeForFinallyInlining(return_from_generator); |
9834 AstNode* if_is_cancelled = | 9866 AstNode* if_is_cancelled = |
9835 new(Z) IfNode(Token::kNoSourcePos, add_call, true_branch, NULL); | 9867 new(Z) IfNode(TokenPosition::kNoSource, add_call, true_branch, NULL); |
9836 yield->AddNode(if_is_cancelled); | 9868 yield->AddNode(if_is_cancelled); |
9837 | 9869 |
9838 AwaitMarkerNode* await_marker = | 9870 AwaitMarkerNode* await_marker = |
9839 new(Z) AwaitMarkerNode(async_temp_scope_, | 9871 new(Z) AwaitMarkerNode(async_temp_scope_, |
9840 current_block_->scope, | 9872 current_block_->scope, |
9841 Token::kNoSourcePos); | 9873 TokenPosition::kNoSource); |
9842 yield->AddNode(await_marker); | 9874 yield->AddNode(await_marker); |
9843 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); | 9875 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); |
9844 continuation_return->set_return_type(ReturnNode::kContinuationTarget); | 9876 continuation_return->set_return_type(ReturnNode::kContinuationTarget); |
9845 yield->AddNode(continuation_return); | 9877 yield->AddNode(continuation_return); |
9846 | 9878 |
9847 // If this expression is part of a try block, also append the code for | 9879 // If this expression is part of a try block, also append the code for |
9848 // restoring the saved try context that lives on the stack and possibly the | 9880 // restoring the saved try context that lives on the stack and possibly the |
9849 // saved try context of the outer try block. | 9881 // saved try context of the outer try block. |
9850 LocalVariable* saved_try_ctx; | 9882 LocalVariable* saved_try_ctx; |
9851 LocalVariable* async_saved_try_ctx; | 9883 LocalVariable* async_saved_try_ctx; |
9852 LocalVariable* outer_saved_try_ctx; | 9884 LocalVariable* outer_saved_try_ctx; |
9853 LocalVariable* outer_async_saved_try_ctx; | 9885 LocalVariable* outer_async_saved_try_ctx; |
9854 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9886 CheckAsyncOpInTryBlock(&saved_try_ctx, |
9855 &async_saved_try_ctx, | 9887 &async_saved_try_ctx, |
9856 &outer_saved_try_ctx, | 9888 &outer_saved_try_ctx, |
9857 &outer_async_saved_try_ctx); | 9889 &outer_async_saved_try_ctx); |
9858 if (saved_try_ctx != NULL) { | 9890 if (saved_try_ctx != NULL) { |
9859 yield->AddNode(new (Z) StoreLocalNode( | 9891 yield->AddNode(new (Z) StoreLocalNode( |
9860 Token::kNoSourcePos, | 9892 TokenPosition::kNoSource, |
9861 saved_try_ctx, | 9893 saved_try_ctx, |
9862 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9894 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9863 async_saved_try_ctx))); | 9895 async_saved_try_ctx))); |
9864 if (outer_saved_try_ctx != NULL) { | 9896 if (outer_saved_try_ctx != NULL) { |
9865 yield->AddNode(new (Z) StoreLocalNode( | 9897 yield->AddNode(new (Z) StoreLocalNode( |
9866 Token::kNoSourcePos, | 9898 TokenPosition::kNoSource, |
9867 outer_saved_try_ctx, | 9899 outer_saved_try_ctx, |
9868 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9900 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
9869 outer_async_saved_try_ctx))); | 9901 outer_async_saved_try_ctx))); |
9870 } | 9902 } |
9871 } else { | 9903 } else { |
9872 ASSERT(outer_saved_try_ctx == NULL); | 9904 ASSERT(outer_saved_try_ctx == NULL); |
9873 } | 9905 } |
9874 } | 9906 } |
9875 return yield; | 9907 return yield; |
9876 } | 9908 } |
9877 | 9909 |
9878 | 9910 |
9879 AstNode* Parser::ParseStatement() { | 9911 AstNode* Parser::ParseStatement() { |
9880 TRACE_PARSER("ParseStatement"); | 9912 TRACE_PARSER("ParseStatement"); |
9881 AstNode* statement = NULL; | 9913 AstNode* statement = NULL; |
9882 intptr_t label_pos = Token::kNoSourcePos; | 9914 TokenPosition label_pos = TokenPosition::kNoSource; |
9883 String* label_name = NULL; | 9915 String* label_name = NULL; |
9884 if (IsIdentifier()) { | 9916 if (IsIdentifier()) { |
9885 if (LookaheadToken(1) == Token::kCOLON) { | 9917 if (LookaheadToken(1) == Token::kCOLON) { |
9886 // Statement starts with a label. | 9918 // Statement starts with a label. |
9887 label_name = CurrentLiteral(); | 9919 label_name = CurrentLiteral(); |
9888 label_pos = TokenPos(); | 9920 label_pos = TokenPos(); |
9889 ASSERT(label_pos >= 0); | 9921 ASSERT(label_pos.IsReal()); |
9890 ConsumeToken(); // Consume identifier. | 9922 ConsumeToken(); // Consume identifier. |
9891 ConsumeToken(); // Consume colon. | 9923 ConsumeToken(); // Consume colon. |
9892 } | 9924 } |
9893 } | 9925 } |
9894 const intptr_t statement_pos = TokenPos(); | 9926 const TokenPosition statement_pos = TokenPos(); |
9895 const Token::Kind token = CurrentToken(); | 9927 const Token::Kind token = CurrentToken(); |
9896 | 9928 |
9897 if (token == Token::kWHILE) { | 9929 if (token == Token::kWHILE) { |
9898 statement = ParseWhileStatement(label_name); | 9930 statement = ParseWhileStatement(label_name); |
9899 } else if (token == Token::kFOR) { | 9931 } else if (token == Token::kFOR) { |
9900 statement = ParseForStatement(label_name); | 9932 statement = ParseForStatement(label_name); |
9901 } else if (IsAwaitKeyword() && (LookaheadToken(1) == Token::kFOR)) { | 9933 } else if (IsAwaitKeyword() && (LookaheadToken(1) == Token::kFOR)) { |
9902 statement = ParseAwaitForStatement(label_name); | 9934 statement = ParseAwaitForStatement(label_name); |
9903 } else if (token == Token::kDO) { | 9935 } else if (token == Token::kDO) { |
9904 statement = ParseDoWhileStatement(label_name); | 9936 statement = ParseDoWhileStatement(label_name); |
9905 } else if (token == Token::kSWITCH) { | 9937 } else if (token == Token::kSWITCH) { |
9906 statement = ParseSwitchStatement(label_name); | 9938 statement = ParseSwitchStatement(label_name); |
9907 } else if (token == Token::kTRY) { | 9939 } else if (token == Token::kTRY) { |
9908 statement = ParseTryStatement(label_name); | 9940 statement = ParseTryStatement(label_name); |
9909 } else if (token == Token::kRETURN) { | 9941 } else if (token == Token::kRETURN) { |
9910 const intptr_t return_pos = TokenPos(); | 9942 const TokenPosition return_pos = TokenPos(); |
9911 ConsumeToken(); | 9943 ConsumeToken(); |
9912 if (CurrentToken() != Token::kSEMICOLON) { | 9944 if (CurrentToken() != Token::kSEMICOLON) { |
9913 const intptr_t expr_pos = TokenPos(); | 9945 const TokenPosition expr_pos = TokenPos(); |
9914 if (current_function().IsGenerativeConstructor() && | 9946 if (current_function().IsGenerativeConstructor() && |
9915 (current_block_->scope->function_level() == 0)) { | 9947 (current_block_->scope->function_level() == 0)) { |
9916 ReportError(expr_pos, | 9948 ReportError(expr_pos, |
9917 "return of a value is not allowed in constructors"); | 9949 "return of a value is not allowed in constructors"); |
9918 } else if (current_function().IsGeneratorClosure() && | 9950 } else if (current_function().IsGeneratorClosure() && |
9919 (current_block_->scope->function_level() == 0)) { | 9951 (current_block_->scope->function_level() == 0)) { |
9920 ReportError(expr_pos, "generator functions may not return a value"); | 9952 ReportError(expr_pos, "generator functions may not return a value"); |
9921 } | 9953 } |
9922 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9954 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9923 statement = new(Z) ReturnNode(statement_pos, expr); | 9955 statement = new(Z) ReturnNode(statement_pos, expr); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10019 } | 10051 } |
10020 | 10052 |
10021 | 10053 |
10022 void Parser::ReportError(const Error& error) { | 10054 void Parser::ReportError(const Error& error) { |
10023 Report::LongJump(error); | 10055 Report::LongJump(error); |
10024 UNREACHABLE(); | 10056 UNREACHABLE(); |
10025 } | 10057 } |
10026 | 10058 |
10027 | 10059 |
10028 void Parser::ReportErrors(const Error& prev_error, | 10060 void Parser::ReportErrors(const Error& prev_error, |
10029 const Script& script, intptr_t token_pos, | 10061 const Script& script, TokenPosition token_pos, |
10030 const char* format, ...) { | 10062 const char* format, ...) { |
10031 va_list args; | 10063 va_list args; |
10032 va_start(args, format); | 10064 va_start(args, format); |
10033 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10065 Report::LongJumpV(prev_error, script, token_pos, format, args); |
10034 va_end(args); | 10066 va_end(args); |
10035 UNREACHABLE(); | 10067 UNREACHABLE(); |
10036 } | 10068 } |
10037 | 10069 |
10038 | 10070 |
10039 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const { | 10071 void Parser::ReportError(TokenPosition token_pos, |
| 10072 const char* format, ...) const { |
10040 va_list args; | 10073 va_list args; |
10041 va_start(args, format); | 10074 va_start(args, format); |
10042 Report::MessageV(Report::kError, | 10075 Report::MessageV(Report::kError, |
10043 script_, token_pos, Report::AtLocation, format, args); | 10076 script_, token_pos, Report::AtLocation, format, args); |
10044 va_end(args); | 10077 va_end(args); |
10045 UNREACHABLE(); | 10078 UNREACHABLE(); |
10046 } | 10079 } |
10047 | 10080 |
10048 | 10081 |
10049 void Parser::ReportErrorBefore(const char* format, ...) { | 10082 void Parser::ReportErrorBefore(const char* format, ...) { |
(...skipping 10 matching lines...) Expand all Loading... |
10060 void Parser::ReportError(const char* format, ...) const { | 10093 void Parser::ReportError(const char* format, ...) const { |
10061 va_list args; | 10094 va_list args; |
10062 va_start(args, format); | 10095 va_start(args, format); |
10063 Report::MessageV(Report::kError, | 10096 Report::MessageV(Report::kError, |
10064 script_, TokenPos(), Report::AtLocation, format, args); | 10097 script_, TokenPos(), Report::AtLocation, format, args); |
10065 va_end(args); | 10098 va_end(args); |
10066 UNREACHABLE(); | 10099 UNREACHABLE(); |
10067 } | 10100 } |
10068 | 10101 |
10069 | 10102 |
10070 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const { | 10103 void Parser::ReportWarning(TokenPosition token_pos, |
| 10104 const char* format, ...) const { |
10071 va_list args; | 10105 va_list args; |
10072 va_start(args, format); | 10106 va_start(args, format); |
10073 Report::MessageV(Report::kWarning, | 10107 Report::MessageV(Report::kWarning, |
10074 script_, token_pos, Report::AtLocation, format, args); | 10108 script_, token_pos, Report::AtLocation, format, args); |
10075 va_end(args); | 10109 va_end(args); |
10076 } | 10110 } |
10077 | 10111 |
10078 | 10112 |
10079 void Parser::ReportWarning(const char* format, ...) const { | 10113 void Parser::ReportWarning(const char* format, ...) const { |
10080 va_list args; | 10114 va_list args; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10160 } | 10194 } |
10161 | 10195 |
10162 | 10196 |
10163 static bool IsPrefixOperator(Token::Kind token) { | 10197 static bool IsPrefixOperator(Token::Kind token) { |
10164 return (token == Token::kSUB) || | 10198 return (token == Token::kSUB) || |
10165 (token == Token::kNOT) || | 10199 (token == Token::kNOT) || |
10166 (token == Token::kBIT_NOT); | 10200 (token == Token::kBIT_NOT); |
10167 } | 10201 } |
10168 | 10202 |
10169 | 10203 |
10170 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos, | 10204 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, |
10171 AstNode* node, | 10205 AstNode* node, |
10172 LocalScope* scope) { | 10206 LocalScope* scope) { |
10173 if ((node == NULL) || !node->IsSequenceNode()) { | 10207 if ((node == NULL) || !node->IsSequenceNode()) { |
10174 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); | 10208 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); |
10175 if (node != NULL) { | 10209 if (node != NULL) { |
10176 sequence->Add(node); | 10210 sequence->Add(node); |
10177 } | 10211 } |
10178 return sequence; | 10212 return sequence; |
10179 } | 10213 } |
10180 return node->AsSequenceNode(); | 10214 return node->AsSequenceNode(); |
10181 } | 10215 } |
10182 | 10216 |
10183 | 10217 |
10184 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10218 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
10185 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type, | 10219 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, |
| 10220 const AbstractType& type, |
10186 LibraryPrefix* prefix) { | 10221 LibraryPrefix* prefix) { |
10187 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); | 10222 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); |
10188 | 10223 |
10189 String& method_name = String::Handle(Z); | 10224 String& method_name = String::Handle(Z); |
10190 if (prefix == NULL) { | 10225 if (prefix == NULL) { |
10191 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10226 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
10192 } else { | 10227 } else { |
10193 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); | 10228 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); |
10194 method_name = Library::PrivateCoreLibName( | 10229 method_name = Library::PrivateCoreLibName( |
10195 Symbols::ThrowNewIfNotLoaded()).raw(); | 10230 Symbols::ThrowNewIfNotLoaded()).raw(); |
10196 } | 10231 } |
10197 // Location argument. | 10232 // Location argument. |
10198 arguments->Add(new(Z) LiteralNode( | 10233 arguments->Add(new(Z) LiteralNode( |
10199 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos)))); | 10234 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos.value())))); |
10200 // Src value argument. | 10235 // Src value argument. |
10201 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); | 10236 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); |
10202 // Dst type name argument. | 10237 // Dst type name argument. |
10203 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); | 10238 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); |
10204 // Dst name argument. | 10239 // Dst name argument. |
10205 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); | 10240 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); |
10206 // Malformed type error or malbounded type error. | 10241 // Malformed type error or malbounded type error. |
10207 const Error& error = Error::Handle(Z, type.error()); | 10242 const Error& error = Error::Handle(Z, type.error()); |
10208 ASSERT(!error.IsNull()); | 10243 ASSERT(!error.IsNull()); |
10209 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, | 10244 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, |
10210 Symbols::New(error.ToErrorCString())))); | 10245 Symbols::New(error.ToErrorCString())))); |
10211 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); | 10246 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); |
10212 } | 10247 } |
10213 | 10248 |
10214 | 10249 |
10215 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10250 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
10216 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 10251 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, |
10217 const Class& cls, | 10252 const Class& cls, |
10218 const String& function_name, | 10253 const String& function_name, |
10219 ArgumentListNode* function_arguments, | 10254 ArgumentListNode* function_arguments, |
10220 InvocationMirror::Call im_call, | 10255 InvocationMirror::Call im_call, |
10221 InvocationMirror::Type im_type, | 10256 InvocationMirror::Type im_type, |
10222 const Function* func, | 10257 const Function* func, |
10223 const LibraryPrefix* prefix) { | 10258 const LibraryPrefix* prefix) { |
10224 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); | 10259 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); |
10225 | 10260 |
10226 String& method_name = String::Handle(Z); | 10261 String& method_name = String::Handle(Z); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10312 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10347 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
10313 AstNode* left_operand = ParseUnaryExpr(); | 10348 AstNode* left_operand = ParseUnaryExpr(); |
10314 if (left_operand->IsPrimaryNode() && | 10349 if (left_operand->IsPrimaryNode() && |
10315 (left_operand->AsPrimaryNode()->IsSuper())) { | 10350 (left_operand->AsPrimaryNode()->IsSuper())) { |
10316 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10351 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
10317 } | 10352 } |
10318 int current_preced = Token::Precedence(CurrentToken()); | 10353 int current_preced = Token::Precedence(CurrentToken()); |
10319 while (current_preced >= min_preced) { | 10354 while (current_preced >= min_preced) { |
10320 while (Token::Precedence(CurrentToken()) == current_preced) { | 10355 while (Token::Precedence(CurrentToken()) == current_preced) { |
10321 Token::Kind op_kind = CurrentToken(); | 10356 Token::Kind op_kind = CurrentToken(); |
10322 const intptr_t op_pos = TokenPos(); | 10357 const TokenPosition op_pos = TokenPos(); |
10323 ConsumeToken(); | 10358 ConsumeToken(); |
10324 AstNode* right_operand = NULL; | 10359 AstNode* right_operand = NULL; |
10325 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 10360 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
10326 right_operand = ParseBinaryExpr(current_preced + 1); | 10361 right_operand = ParseBinaryExpr(current_preced + 1); |
10327 } else { | 10362 } else { |
10328 // For 'is' and 'as' we expect the right operand to be a type. | 10363 // For 'is' and 'as' we expect the right operand to be a type. |
10329 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 10364 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
10330 ConsumeToken(); | 10365 ConsumeToken(); |
10331 op_kind = Token::kISNOT; | 10366 op_kind = Token::kISNOT; |
10332 } | 10367 } |
10333 const intptr_t type_pos = TokenPos(); | 10368 const TokenPosition type_pos = TokenPos(); |
10334 const AbstractType& type = AbstractType::ZoneHandle(Z, | 10369 const AbstractType& type = AbstractType::ZoneHandle(Z, |
10335 ParseType(ClassFinalizer::kCanonicalize)); | 10370 ParseType(ClassFinalizer::kCanonicalize)); |
10336 if (!type.IsInstantiated() && | 10371 if (!type.IsInstantiated() && |
10337 (current_block_->scope->function_level() > 0)) { | 10372 (current_block_->scope->function_level() > 0)) { |
10338 // Make sure that the instantiator is captured. | 10373 // Make sure that the instantiator is captured. |
10339 CaptureInstantiator(); | 10374 CaptureInstantiator(); |
10340 } | 10375 } |
10341 right_operand = new(Z) TypeNode(type_pos, type); | 10376 right_operand = new(Z) TypeNode(type_pos, type); |
10342 // In production mode, the type may be malformed. | 10377 // In production mode, the type may be malformed. |
10343 // In checked mode, the type may be malformed or malbounded. | 10378 // In checked mode, the type may be malformed or malbounded. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10401 return expressions; | 10436 return expressions; |
10402 } | 10437 } |
10403 | 10438 |
10404 | 10439 |
10405 void Parser::EnsureExpressionTemp() { | 10440 void Parser::EnsureExpressionTemp() { |
10406 // Temporary used later by the flow_graph_builder. | 10441 // Temporary used later by the flow_graph_builder. |
10407 parsed_function()->EnsureExpressionTemp(); | 10442 parsed_function()->EnsureExpressionTemp(); |
10408 } | 10443 } |
10409 | 10444 |
10410 | 10445 |
10411 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 10446 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, |
10412 const char* s) { | 10447 const char* s) { |
10413 char name[64]; | 10448 char name[64]; |
10414 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); | 10449 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); |
10415 LocalVariable* temp = new(Z) LocalVariable( | 10450 LocalVariable* temp = new(Z) LocalVariable( |
10416 token_pos, | 10451 token_pos, |
10417 String::ZoneHandle(Z, Symbols::New(name)), | 10452 String::ZoneHandle(Z, Symbols::New(name)), |
10418 Object::dynamic_type()); | 10453 Object::dynamic_type()); |
10419 temp->set_is_final(); | 10454 temp->set_is_final(); |
10420 current_block_->scope->AddVariable(temp); | 10455 current_block_->scope->AddVariable(temp); |
10421 return temp; | 10456 return temp; |
10422 } | 10457 } |
10423 | 10458 |
10424 | 10459 |
10425 // TODO(srdjan): Implement other optimizations. | 10460 // TODO(srdjan): Implement other optimizations. |
10426 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 10461 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, |
10427 Token::Kind binary_op, | 10462 Token::Kind binary_op, |
10428 AstNode* lhs, | 10463 AstNode* lhs, |
10429 AstNode* rhs) { | 10464 AstNode* rhs) { |
10430 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 10465 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
10431 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 10466 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
10432 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 10467 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
10433 if (lhs_literal->literal().IsDouble() && | 10468 if (lhs_literal->literal().IsDouble() && |
10434 rhs_literal->literal().IsDouble()) { | 10469 rhs_literal->literal().IsDouble()) { |
10435 double left_double = Double::Cast(lhs_literal->literal()).value(); | 10470 double left_double = Double::Cast(lhs_literal->literal()).value(); |
10436 double right_double = Double::Cast(rhs_literal->literal()).value(); | 10471 double right_double = Double::Cast(rhs_literal->literal()).value(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10474 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); | 10509 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); |
10475 } | 10510 } |
10476 CacheConstantValue(op_pos, expr_value); | 10511 CacheConstantValue(op_pos, expr_value); |
10477 } | 10512 } |
10478 return new(Z) LiteralNode(op_pos, expr_value); | 10513 return new(Z) LiteralNode(op_pos, expr_value); |
10479 } | 10514 } |
10480 | 10515 |
10481 LetNode* result = new(Z) LetNode(op_pos); | 10516 LetNode* result = new(Z) LetNode(op_pos); |
10482 LocalVariable* left_temp = result->AddInitializer(lhs); | 10517 LocalVariable* left_temp = result->AddInitializer(lhs); |
10483 left_temp->set_is_final(); | 10518 left_temp->set_is_final(); |
10484 const intptr_t no_pos = Token::kNoSourcePos; | 10519 const TokenPosition no_pos = TokenPosition::kNoSource; |
10485 LiteralNode* null_operand = | 10520 LiteralNode* null_operand = |
10486 new(Z) LiteralNode(no_pos, Object::null_instance()); | 10521 new(Z) LiteralNode(no_pos, Object::null_instance()); |
10487 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); | 10522 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); |
10488 ComparisonNode* null_compare = | 10523 ComparisonNode* null_compare = |
10489 new(Z) ComparisonNode(no_pos, | 10524 new(Z) ComparisonNode(no_pos, |
10490 Token::kNE_STRICT, | 10525 Token::kNE_STRICT, |
10491 load_left_temp, | 10526 load_left_temp, |
10492 null_operand); | 10527 null_operand); |
10493 result->AddNode(new(Z) ConditionalExprNode(op_pos, | 10528 result->AddNode(new(Z) ConditionalExprNode(op_pos, |
10494 null_compare, | 10529 null_compare, |
10495 load_left_temp, | 10530 load_left_temp, |
10496 rhs)); | 10531 rhs)); |
10497 return result; | 10532 return result; |
10498 } | 10533 } |
10499 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 10534 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
10500 } | 10535 } |
10501 | 10536 |
10502 | 10537 |
10503 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 10538 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, |
10504 Token::Kind assignment_op, | 10539 Token::Kind assignment_op, |
10505 AstNode* lhs, | 10540 AstNode* lhs, |
10506 AstNode* rhs) { | 10541 AstNode* rhs) { |
10507 TRACE_PARSER("ExpandAssignableOp"); | 10542 TRACE_PARSER("ExpandAssignableOp"); |
10508 switch (assignment_op) { | 10543 switch (assignment_op) { |
10509 case Token::kASSIGN: | 10544 case Token::kASSIGN: |
10510 return rhs; | 10545 return rhs; |
10511 case Token::kASSIGN_ADD: | 10546 case Token::kASSIGN_ADD: |
10512 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 10547 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
10513 case Token::kASSIGN_SUB: | 10548 case Token::kASSIGN_SUB: |
(...skipping 23 matching lines...) Expand all Loading... |
10537 "internal error: ExpandAssignableOp '%s' unimplemented", | 10572 "internal error: ExpandAssignableOp '%s' unimplemented", |
10538 Token::Name(assignment_op)); | 10573 Token::Name(assignment_op)); |
10539 UNIMPLEMENTED(); | 10574 UNIMPLEMENTED(); |
10540 return NULL; | 10575 return NULL; |
10541 } | 10576 } |
10542 } | 10577 } |
10543 | 10578 |
10544 | 10579 |
10545 // Evaluates the value of the compile time constant expression | 10580 // Evaluates the value of the compile time constant expression |
10546 // and returns a literal node for the value. | 10581 // and returns a literal node for the value. |
10547 LiteralNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 10582 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { |
10548 if (expr->IsLiteralNode()) { | 10583 if (expr->IsLiteralNode()) { |
10549 return expr->AsLiteralNode(); | 10584 return expr->AsLiteralNode(); |
10550 } | 10585 } |
10551 if (expr->EvalConstExpr() == NULL) { | 10586 if (expr->EvalConstExpr() == NULL) { |
10552 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 10587 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
10553 } | 10588 } |
10554 return new(Z) LiteralNode( | 10589 return new(Z) LiteralNode( |
10555 expr_pos, EvaluateConstExpr(expr_pos, expr)); | 10590 expr_pos, EvaluateConstExpr(expr_pos, expr)); |
10556 } | 10591 } |
10557 | 10592 |
10558 | 10593 |
10559 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 10594 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
10560 AstNode* node = *expr; | 10595 AstNode* node = *expr; |
10561 intptr_t token_pos = node->token_pos(); | 10596 TokenPosition token_pos = node->token_pos(); |
10562 LetNode* result = new(Z) LetNode(token_pos); | 10597 LetNode* result = new(Z) LetNode(token_pos); |
10563 if (node->IsLoadIndexedNode()) { | 10598 if (node->IsLoadIndexedNode()) { |
10564 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 10599 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
10565 AstNode* array = load_indexed->array(); | 10600 AstNode* array = load_indexed->array(); |
10566 AstNode* index = load_indexed->index_expr(); | 10601 AstNode* index = load_indexed->index_expr(); |
10567 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 10602 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
10568 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 10603 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
10569 array = new(Z) LoadLocalNode(token_pos, t0); | 10604 array = new(Z) LoadLocalNode(token_pos, t0); |
10570 } | 10605 } |
10571 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { | 10606 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { |
(...skipping 23 matching lines...) Expand all Loading... |
10595 | 10630 |
10596 | 10631 |
10597 // Check whether the syntax of expression expr is a grammatically legal | 10632 // Check whether the syntax of expression expr is a grammatically legal |
10598 // assignable expression. This check is used to detect situations where | 10633 // assignable expression. This check is used to detect situations where |
10599 // the expression itself is assignable, but the source is grammatically | 10634 // the expression itself is assignable, but the source is grammatically |
10600 // wrong. The AST representation of an expression cannot distinguish | 10635 // wrong. The AST representation of an expression cannot distinguish |
10601 // between x = 0 and (x) = 0. The latter is illegal. | 10636 // between x = 0 and (x) = 0. The latter is illegal. |
10602 // A syntactically legal assignable expression always ends with an | 10637 // A syntactically legal assignable expression always ends with an |
10603 // identifier token or a ] token. We rewind the token iterator and | 10638 // identifier token or a ] token. We rewind the token iterator and |
10604 // check whether the token before end_pos is an identifier or ]. | 10639 // check whether the token before end_pos is an identifier or ]. |
10605 bool Parser::IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos) { | 10640 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos) { |
10606 ASSERT(expr->token_pos() >= 0); | 10641 ASSERT(expr->token_pos().IsReal()); |
10607 ASSERT(expr->token_pos() < end_pos); | 10642 ASSERT(expr->token_pos() < end_pos); |
10608 SetPosition(expr->token_pos()); | 10643 SetPosition(expr->token_pos()); |
10609 Token::Kind token = Token::kILLEGAL; | 10644 Token::Kind token = Token::kILLEGAL; |
10610 while (TokenPos() < end_pos) { | 10645 while (TokenPos() < end_pos) { |
10611 token = CurrentToken(); | 10646 token = CurrentToken(); |
10612 ConsumeToken(); | 10647 ConsumeToken(); |
10613 } | 10648 } |
10614 ASSERT(TokenPos() == end_pos); | 10649 ASSERT(TokenPos() == end_pos); |
10615 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 10650 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
10616 } | 10651 } |
10617 | 10652 |
10618 | 10653 |
10619 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 10654 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
10620 AstNode* rhs, | 10655 AstNode* rhs, |
10621 const String* left_ident, | 10656 const String* left_ident, |
10622 intptr_t left_pos, | 10657 TokenPosition left_pos, |
10623 bool is_compound /* = false */) { | 10658 bool is_compound /* = false */) { |
10624 AstNode* result = original->MakeAssignmentNode(rhs); | 10659 AstNode* result = original->MakeAssignmentNode(rhs); |
10625 if (result == NULL) { | 10660 if (result == NULL) { |
10626 String& name = String::ZoneHandle(Z); | 10661 String& name = String::ZoneHandle(Z); |
10627 const Class* target_cls = ¤t_class(); | 10662 const Class* target_cls = ¤t_class(); |
10628 if (original->IsTypeNode()) { | 10663 if (original->IsTypeNode()) { |
10629 name = Symbols::New(original->AsTypeNode()->TypeName()); | 10664 name = Symbols::New(original->AsTypeNode()->TypeName()); |
10630 } else if (original->IsLoadStaticFieldNode()) { | 10665 } else if (original->IsLoadStaticFieldNode()) { |
10631 name = original->AsLoadStaticFieldNode()->field().name(); | 10666 name = original->AsLoadStaticFieldNode()->field().name(); |
10632 target_cls = &Class::Handle(Z, | 10667 target_cls = &Class::Handle(Z, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10670 result = OptimizeBinaryOpNode(ifnull->token_pos(), | 10705 result = OptimizeBinaryOpNode(ifnull->token_pos(), |
10671 ifnull->kind(), | 10706 ifnull->kind(), |
10672 ifnull->left(), | 10707 ifnull->left(), |
10673 modified_assign); | 10708 modified_assign); |
10674 } | 10709 } |
10675 return result; | 10710 return result; |
10676 } | 10711 } |
10677 | 10712 |
10678 | 10713 |
10679 AstNode* Parser::ParseCascades(AstNode* expr) { | 10714 AstNode* Parser::ParseCascades(AstNode* expr) { |
10680 intptr_t cascade_pos = TokenPos(); | 10715 TokenPosition cascade_pos = TokenPos(); |
10681 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10716 LetNode* cascade = new(Z) LetNode(cascade_pos); |
10682 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10717 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
10683 while (CurrentToken() == Token::kCASCADE) { | 10718 while (CurrentToken() == Token::kCASCADE) { |
10684 cascade_pos = TokenPos(); | 10719 cascade_pos = TokenPos(); |
10685 LoadLocalNode* load_cascade_receiver = | 10720 LoadLocalNode* load_cascade_receiver = |
10686 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); | 10721 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
10687 if (Token::IsIdentifier(LookaheadToken(1))) { | 10722 if (Token::IsIdentifier(LookaheadToken(1))) { |
10688 // Replace .. with . for ParseSelectors(). | 10723 // Replace .. with . for ParseSelectors(). |
10689 token_kind_ = Token::kPERIOD; | 10724 token_kind_ = Token::kPERIOD; |
10690 } else if (LookaheadToken(1) == Token::kLBRACK) { | 10725 } else if (LookaheadToken(1) == Token::kLBRACK) { |
10691 ConsumeToken(); | 10726 ConsumeToken(); |
10692 } else { | 10727 } else { |
10693 ReportError("identifier or [ expected after .."); | 10728 ReportError("identifier or [ expected after .."); |
10694 } | 10729 } |
10695 String* expr_ident = | 10730 String* expr_ident = |
10696 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10731 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10697 const intptr_t expr_pos = TokenPos(); | 10732 const TokenPosition expr_pos = TokenPos(); |
10698 expr = ParseSelectors(load_cascade_receiver, true); | 10733 expr = ParseSelectors(load_cascade_receiver, true); |
10699 | 10734 |
10700 // Assignments after a cascade are part of the cascade. The | 10735 // Assignments after a cascade are part of the cascade. The |
10701 // assigned expression must not contain cascades. | 10736 // assigned expression must not contain cascades. |
10702 if (Token::IsAssignmentOperator(CurrentToken())) { | 10737 if (Token::IsAssignmentOperator(CurrentToken())) { |
10703 Token::Kind assignment_op = CurrentToken(); | 10738 Token::Kind assignment_op = CurrentToken(); |
10704 const intptr_t assignment_pos = TokenPos(); | 10739 const TokenPosition assignment_pos = TokenPos(); |
10705 ConsumeToken(); | 10740 ConsumeToken(); |
10706 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); | 10741 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
10707 if (assignment_op != Token::kASSIGN) { | 10742 if (assignment_op != Token::kASSIGN) { |
10708 // Compound assignment: store inputs with side effects into | 10743 // Compound assignment: store inputs with side effects into |
10709 // temporary locals. | 10744 // temporary locals. |
10710 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10745 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
10711 right_expr = | 10746 right_expr = |
10712 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10747 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
10713 AstNode* assign_expr = | 10748 AstNode* assign_expr = |
10714 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); | 10749 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10774 } | 10809 } |
10775 return expr; | 10810 return expr; |
10776 } | 10811 } |
10777 | 10812 |
10778 | 10813 |
10779 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 10814 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
10780 bool consume_cascades) { | 10815 bool consume_cascades) { |
10781 TRACE_PARSER("ParseExpr"); | 10816 TRACE_PARSER("ParseExpr"); |
10782 String* expr_ident = | 10817 String* expr_ident = |
10783 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10818 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10784 const intptr_t expr_pos = TokenPos(); | 10819 const TokenPosition expr_pos = TokenPos(); |
10785 | 10820 |
10786 RecursionChecker rc(this); | 10821 RecursionChecker rc(this); |
10787 | 10822 |
10788 if (CurrentToken() == Token::kTHROW) { | 10823 if (CurrentToken() == Token::kTHROW) { |
10789 if (require_compiletime_const) { | 10824 if (require_compiletime_const) { |
10790 ReportError("'throw expr' is not a valid compile-time constant"); | 10825 ReportError("'throw expr' is not a valid compile-time constant"); |
10791 } | 10826 } |
10792 ConsumeToken(); | 10827 ConsumeToken(); |
10793 if (CurrentToken() == Token::kSEMICOLON) { | 10828 if (CurrentToken() == Token::kSEMICOLON) { |
10794 ReportError("expression expected after throw"); | 10829 ReportError("expression expected after throw"); |
(...skipping 25 matching lines...) Expand all Loading... |
10820 } else { | 10855 } else { |
10821 expr = LiteralIfStaticConst(Z, expr); | 10856 expr = LiteralIfStaticConst(Z, expr); |
10822 } | 10857 } |
10823 return expr; | 10858 return expr; |
10824 } | 10859 } |
10825 // Assignment expressions. | 10860 // Assignment expressions. |
10826 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 10861 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
10827 ReportError(expr_pos, "expression is not assignable"); | 10862 ReportError(expr_pos, "expression is not assignable"); |
10828 } | 10863 } |
10829 const Token::Kind assignment_op = CurrentToken(); | 10864 const Token::Kind assignment_op = CurrentToken(); |
10830 const intptr_t assignment_pos = TokenPos(); | 10865 const TokenPosition assignment_pos = TokenPos(); |
10831 ConsumeToken(); | 10866 ConsumeToken(); |
10832 const intptr_t right_expr_pos = TokenPos(); | 10867 const TokenPosition right_expr_pos = TokenPos(); |
10833 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 10868 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
10834 ReportError(right_expr_pos, | 10869 ReportError(right_expr_pos, |
10835 "expression is not a valid compile-time constant"); | 10870 "expression is not a valid compile-time constant"); |
10836 } | 10871 } |
10837 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 10872 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
10838 if (assignment_op != Token::kASSIGN) { | 10873 if (assignment_op != Token::kASSIGN) { |
10839 // Compound assignment: store inputs with side effects into temp. locals. | 10874 // Compound assignment: store inputs with side effects into temp. locals. |
10840 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10875 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
10841 AstNode* assigned_value = | 10876 AstNode* assigned_value = |
10842 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10877 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
10843 AstNode* assign_expr = | 10878 AstNode* assign_expr = |
10844 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); | 10879 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); |
10845 ASSERT(assign_expr != NULL); | 10880 ASSERT(assign_expr != NULL); |
10846 let_expr->AddNode(assign_expr); | 10881 let_expr->AddNode(assign_expr); |
10847 return let_expr; | 10882 return let_expr; |
10848 } else { | 10883 } else { |
10849 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 10884 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
10850 AstNode* assign_expr = | 10885 AstNode* assign_expr = |
10851 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10886 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
10852 ASSERT(assign_expr != NULL); | 10887 ASSERT(assign_expr != NULL); |
10853 return assign_expr; | 10888 return assign_expr; |
10854 } | 10889 } |
10855 } | 10890 } |
10856 | 10891 |
10857 | 10892 |
10858 LiteralNode* Parser::ParseConstExpr() { | 10893 LiteralNode* Parser::ParseConstExpr() { |
10859 TRACE_PARSER("ParseConstExpr"); | 10894 TRACE_PARSER("ParseConstExpr"); |
10860 intptr_t expr_pos = TokenPos(); | 10895 TokenPosition expr_pos = TokenPos(); |
10861 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 10896 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
10862 if (!expr->IsLiteralNode()) { | 10897 if (!expr->IsLiteralNode()) { |
10863 ReportError(expr_pos, "expression must be a compile-time constant"); | 10898 ReportError(expr_pos, "expression must be a compile-time constant"); |
10864 } | 10899 } |
10865 return expr->AsLiteralNode(); | 10900 return expr->AsLiteralNode(); |
10866 } | 10901 } |
10867 | 10902 |
10868 | 10903 |
10869 AstNode* Parser::ParseConditionalExpr() { | 10904 AstNode* Parser::ParseConditionalExpr() { |
10870 TRACE_PARSER("ParseConditionalExpr"); | 10905 TRACE_PARSER("ParseConditionalExpr"); |
10871 const intptr_t expr_pos = TokenPos(); | 10906 const TokenPosition expr_pos = TokenPos(); |
10872 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); | 10907 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
10873 if (CurrentToken() == Token::kCONDITIONAL) { | 10908 if (CurrentToken() == Token::kCONDITIONAL) { |
10874 EnsureExpressionTemp(); | 10909 EnsureExpressionTemp(); |
10875 ConsumeToken(); | 10910 ConsumeToken(); |
10876 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 10911 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
10877 ExpectToken(Token::kCOLON); | 10912 ExpectToken(Token::kCOLON); |
10878 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 10913 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
10879 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 10914 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
10880 } | 10915 } |
10881 return expr; | 10916 return expr; |
10882 } | 10917 } |
10883 | 10918 |
10884 | 10919 |
10885 AstNode* Parser::ParseUnaryExpr() { | 10920 AstNode* Parser::ParseUnaryExpr() { |
10886 TRACE_PARSER("ParseUnaryExpr"); | 10921 TRACE_PARSER("ParseUnaryExpr"); |
10887 AstNode* expr = NULL; | 10922 AstNode* expr = NULL; |
10888 const intptr_t op_pos = TokenPos(); | 10923 const TokenPosition op_pos = TokenPos(); |
10889 if (IsAwaitKeyword()) { | 10924 if (IsAwaitKeyword()) { |
10890 TRACE_PARSER("ParseAwaitExpr"); | 10925 TRACE_PARSER("ParseAwaitExpr"); |
10891 if (!innermost_function().IsAsyncFunction() && | 10926 if (!innermost_function().IsAsyncFunction() && |
10892 !innermost_function().IsAsyncClosure() && | 10927 !innermost_function().IsAsyncClosure() && |
10893 !innermost_function().IsAsyncGenerator() && | 10928 !innermost_function().IsAsyncGenerator() && |
10894 !innermost_function().IsAsyncGenClosure()) { | 10929 !innermost_function().IsAsyncGenClosure()) { |
10895 ReportError("await operator is only allowed in an asynchronous function"); | 10930 ReportError("await operator is only allowed in an asynchronous function"); |
10896 } | 10931 } |
10897 ConsumeToken(); | 10932 ConsumeToken(); |
10898 parsed_function()->record_await(); | 10933 parsed_function()->record_await(); |
(...skipping 23 matching lines...) Expand all Loading... |
10922 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { | 10957 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
10923 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); | 10958 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
10924 } else { | 10959 } else { |
10925 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 10960 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
10926 } | 10961 } |
10927 } else if (IsIncrementOperator(CurrentToken())) { | 10962 } else if (IsIncrementOperator(CurrentToken())) { |
10928 Token::Kind incr_op = CurrentToken(); | 10963 Token::Kind incr_op = CurrentToken(); |
10929 ConsumeToken(); | 10964 ConsumeToken(); |
10930 String* expr_ident = | 10965 String* expr_ident = |
10931 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10966 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10932 const intptr_t expr_pos = TokenPos(); | 10967 const TokenPosition expr_pos = TokenPos(); |
10933 expr = ParseUnaryExpr(); | 10968 expr = ParseUnaryExpr(); |
10934 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 10969 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
10935 ReportError(expr_pos, "expression is not assignable"); | 10970 ReportError(expr_pos, "expression is not assignable"); |
10936 } | 10971 } |
10937 // Is prefix. | 10972 // Is prefix. |
10938 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10973 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
10939 Token::Kind binary_op = | 10974 Token::Kind binary_op = |
10940 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 10975 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
10941 BinaryOpNode* add = new(Z) BinaryOpNode( | 10976 BinaryOpNode* add = new(Z) BinaryOpNode( |
10942 op_pos, | 10977 op_pos, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11003 SetAllowFunctionLiterals(saved_mode); | 11038 SetAllowFunctionLiterals(saved_mode); |
11004 if (named_argument_seen) { | 11039 if (named_argument_seen) { |
11005 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); | 11040 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); |
11006 } | 11041 } |
11007 return arguments; | 11042 return arguments; |
11008 } | 11043 } |
11009 | 11044 |
11010 | 11045 |
11011 AstNode* Parser::ParseStaticCall(const Class& cls, | 11046 AstNode* Parser::ParseStaticCall(const Class& cls, |
11012 const String& func_name, | 11047 const String& func_name, |
11013 intptr_t ident_pos) { | 11048 TokenPosition ident_pos) { |
11014 TRACE_PARSER("ParseStaticCall"); | 11049 TRACE_PARSER("ParseStaticCall"); |
11015 const intptr_t call_pos = TokenPos(); | 11050 const TokenPosition call_pos = TokenPos(); |
11016 ASSERT(CurrentToken() == Token::kLPAREN); | 11051 ASSERT(CurrentToken() == Token::kLPAREN); |
11017 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11052 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11018 const int num_arguments = arguments->length(); | 11053 const int num_arguments = arguments->length(); |
11019 const Function& func = Function::ZoneHandle(Z, | 11054 const Function& func = Function::ZoneHandle(Z, |
11020 Resolver::ResolveStatic(cls, | 11055 Resolver::ResolveStatic(cls, |
11021 func_name, | 11056 func_name, |
11022 num_arguments, | 11057 num_arguments, |
11023 arguments->names())); | 11058 arguments->names())); |
11024 if (func.IsNull()) { | 11059 if (func.IsNull()) { |
11025 // Check if there is a static field of the same name, it could be a closure | 11060 // Check if there is a static field of the same name, it could be a closure |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11091 arguments->NodeAt(0), | 11126 arguments->NodeAt(0), |
11092 arguments->NodeAt(1)); | 11127 arguments->NodeAt(1)); |
11093 } | 11128 } |
11094 } | 11129 } |
11095 return new(Z) StaticCallNode(ident_pos, func, arguments); | 11130 return new(Z) StaticCallNode(ident_pos, func, arguments); |
11096 } | 11131 } |
11097 | 11132 |
11098 | 11133 |
11099 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 11134 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
11100 const String& func_name, | 11135 const String& func_name, |
11101 intptr_t ident_pos, | 11136 TokenPosition ident_pos, |
11102 bool is_conditional) { | 11137 bool is_conditional) { |
11103 TRACE_PARSER("ParseInstanceCall"); | 11138 TRACE_PARSER("ParseInstanceCall"); |
11104 CheckToken(Token::kLPAREN); | 11139 CheckToken(Token::kLPAREN); |
11105 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11140 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11106 return new(Z) InstanceCallNode(ident_pos, | 11141 return new(Z) InstanceCallNode(ident_pos, |
11107 receiver, | 11142 receiver, |
11108 func_name, | 11143 func_name, |
11109 arguments, | 11144 arguments, |
11110 is_conditional); | 11145 is_conditional); |
11111 } | 11146 } |
11112 | 11147 |
11113 | 11148 |
11114 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 11149 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
11115 TRACE_PARSER("ParseClosureCall"); | 11150 TRACE_PARSER("ParseClosureCall"); |
11116 const intptr_t call_pos = TokenPos(); | 11151 const TokenPosition call_pos = TokenPos(); |
11117 ASSERT(CurrentToken() == Token::kLPAREN); | 11152 ASSERT(CurrentToken() == Token::kLPAREN); |
11118 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11153 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11119 return BuildClosureCall(call_pos, closure, arguments); | 11154 return BuildClosureCall(call_pos, closure, arguments); |
11120 } | 11155 } |
11121 | 11156 |
11122 | 11157 |
11123 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 11158 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
11124 intptr_t ident_pos) { | 11159 TokenPosition ident_pos) { |
11125 // If the static field has an initializer, initialize the field at compile | 11160 // If the static field has an initializer, initialize the field at compile |
11126 // time, which is only possible if the field is const. | 11161 // time, which is only possible if the field is const. |
11127 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11162 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
11128 if (initializing_getter != NULL) { | 11163 if (initializing_getter != NULL) { |
11129 // The field is not yet initialized and could not be initialized at compile | 11164 // The field is not yet initialized and could not be initialized at compile |
11130 // time. The getter will initialize the field. | 11165 // time. The getter will initialize the field. |
11131 return initializing_getter; | 11166 return initializing_getter; |
11132 } | 11167 } |
11133 // The field is initialized. | 11168 // The field is initialized. |
11134 ASSERT(field.is_static()); | 11169 ASSERT(field.is_static()); |
(...skipping 13 matching lines...) Expand all Loading... |
11148 NULL, // Receiver. | 11183 NULL, // Receiver. |
11149 field_owner, | 11184 field_owner, |
11150 field_name); | 11185 field_name); |
11151 } | 11186 } |
11152 } | 11187 } |
11153 | 11188 |
11154 | 11189 |
11155 // Reference to 'field_name' with explicit class as primary. | 11190 // Reference to 'field_name' with explicit class as primary. |
11156 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, | 11191 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, |
11157 const String& field_name, | 11192 const String& field_name, |
11158 intptr_t ident_pos) { | 11193 TokenPosition ident_pos) { |
11159 AstNode* access = NULL; | 11194 AstNode* access = NULL; |
11160 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); | 11195 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
11161 Function& func = Function::ZoneHandle(Z); | 11196 Function& func = Function::ZoneHandle(Z); |
11162 if (field.IsNull()) { | 11197 if (field.IsNull()) { |
11163 // No field, check if we have an explicit getter function. | 11198 // No field, check if we have an explicit getter function. |
11164 func = cls.LookupGetterFunction(field_name); | 11199 func = cls.LookupGetterFunction(field_name); |
11165 if (func.IsNull() || func.IsDynamicFunction()) { | 11200 if (func.IsNull() || func.IsDynamicFunction()) { |
11166 // We might be referring to an implicit closure, check to see if | 11201 // We might be referring to an implicit closure, check to see if |
11167 // there is a function of the same name. | 11202 // there is a function of the same name. |
11168 func = cls.LookupStaticFunction(field_name); | 11203 func = cls.LookupStaticFunction(field_name); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11255 AstNode* left = primary; | 11290 AstNode* left = primary; |
11256 while (true) { | 11291 while (true) { |
11257 AstNode* selector = NULL; | 11292 AstNode* selector = NULL; |
11258 if ((CurrentToken() == Token::kPERIOD) || | 11293 if ((CurrentToken() == Token::kPERIOD) || |
11259 (CurrentToken() == Token::kQM_PERIOD)) { | 11294 (CurrentToken() == Token::kQM_PERIOD)) { |
11260 // Unconditional or conditional property extraction or method call. | 11295 // Unconditional or conditional property extraction or method call. |
11261 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | 11296 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; |
11262 ConsumeToken(); | 11297 ConsumeToken(); |
11263 if (left->IsPrimaryNode()) { | 11298 if (left->IsPrimaryNode()) { |
11264 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11299 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11265 const intptr_t primary_pos = primary_node->token_pos(); | 11300 const TokenPosition primary_pos = primary_node->token_pos(); |
11266 if (primary_node->primary().IsFunction()) { | 11301 if (primary_node->primary().IsFunction()) { |
11267 left = LoadClosure(primary_node); | 11302 left = LoadClosure(primary_node); |
11268 } else if (primary_node->primary().IsTypeParameter()) { | 11303 } else if (primary_node->primary().IsTypeParameter()) { |
11269 if (ParsingStaticMember()) { | 11304 if (ParsingStaticMember()) { |
11270 const String& name = String::Handle(Z, | 11305 const String& name = String::Handle(Z, |
11271 TypeParameter::Cast(primary_node->primary()).name()); | 11306 TypeParameter::Cast(primary_node->primary()).name()); |
11272 ReportError(primary_pos, | 11307 ReportError(primary_pos, |
11273 "cannot access type parameter '%s' " | 11308 "cannot access type parameter '%s' " |
11274 "from static function", | 11309 "from static function", |
11275 name.ToCString()); | 11310 name.ToCString()); |
11276 } | 11311 } |
11277 if (current_block_->scope->function_level() > 0) { | 11312 if (current_block_->scope->function_level() > 0) { |
11278 // Make sure that the instantiator is captured. | 11313 // Make sure that the instantiator is captured. |
11279 CaptureInstantiator(); | 11314 CaptureInstantiator(); |
11280 } | 11315 } |
11281 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11316 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
11282 type_parameter ^= ClassFinalizer::FinalizeType( | 11317 type_parameter ^= ClassFinalizer::FinalizeType( |
11283 current_class(), | 11318 current_class(), |
11284 TypeParameter::Cast(primary_node->primary()), | 11319 TypeParameter::Cast(primary_node->primary()), |
11285 ClassFinalizer::kCanonicalize); | 11320 ClassFinalizer::kCanonicalize); |
11286 ASSERT(!type_parameter.IsMalformed()); | 11321 ASSERT(!type_parameter.IsMalformed()); |
11287 left = new(Z) TypeNode(primary->token_pos(), type_parameter); | 11322 left = new(Z) TypeNode(primary->token_pos(), type_parameter); |
11288 } else { | 11323 } else { |
11289 // Super field access handled in ParseSuperFieldAccess(), | 11324 // Super field access handled in ParseSuperFieldAccess(), |
11290 // super calls handled in ParseSuperCall(). | 11325 // super calls handled in ParseSuperCall(). |
11291 ASSERT(!primary_node->IsSuper()); | 11326 ASSERT(!primary_node->IsSuper()); |
11292 left = LoadFieldIfUnresolved(left); | 11327 left = LoadFieldIfUnresolved(left); |
11293 } | 11328 } |
11294 } | 11329 } |
11295 const intptr_t ident_pos = TokenPos(); | 11330 const TokenPosition ident_pos = TokenPos(); |
11296 String* ident = ExpectIdentifier("identifier expected"); | 11331 String* ident = ExpectIdentifier("identifier expected"); |
11297 if (CurrentToken() == Token::kLPAREN) { | 11332 if (CurrentToken() == Token::kLPAREN) { |
11298 // Identifier followed by a opening paren: method call. | 11333 // Identifier followed by a opening paren: method call. |
11299 if (left->IsPrimaryNode() && | 11334 if (left->IsPrimaryNode() && |
11300 left->AsPrimaryNode()->primary().IsClass()) { | 11335 left->AsPrimaryNode()->primary().IsClass()) { |
11301 // Static method call prefixed with class name. | 11336 // Static method call prefixed with class name. |
11302 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 11337 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
11303 selector = ParseStaticCall(cls, *ident, ident_pos); | 11338 selector = ParseStaticCall(cls, *ident, ident_pos); |
11304 } else { | 11339 } else { |
11305 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); | 11340 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); |
(...skipping 25 matching lines...) Expand all Loading... |
11331 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 11366 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
11332 } else if (selector->IsStaticGetterNode()) { | 11367 } else if (selector->IsStaticGetterNode()) { |
11333 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); | 11368 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); |
11334 } | 11369 } |
11335 } | 11370 } |
11336 } | 11371 } |
11337 } else if (CurrentToken() == Token::kLBRACK) { | 11372 } else if (CurrentToken() == Token::kLBRACK) { |
11338 // Super index operator handled in ParseSuperOperator(). | 11373 // Super index operator handled in ParseSuperOperator(). |
11339 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); | 11374 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); |
11340 | 11375 |
11341 const intptr_t bracket_pos = TokenPos(); | 11376 const TokenPosition bracket_pos = TokenPos(); |
11342 ConsumeToken(); | 11377 ConsumeToken(); |
11343 left = LoadFieldIfUnresolved(left); | 11378 left = LoadFieldIfUnresolved(left); |
11344 const bool saved_mode = SetAllowFunctionLiterals(true); | 11379 const bool saved_mode = SetAllowFunctionLiterals(true); |
11345 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); | 11380 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); |
11346 SetAllowFunctionLiterals(saved_mode); | 11381 SetAllowFunctionLiterals(saved_mode); |
11347 ExpectToken(Token::kRBRACK); | 11382 ExpectToken(Token::kRBRACK); |
11348 AstNode* array = left; | 11383 AstNode* array = left; |
11349 if (left->IsPrimaryNode()) { | 11384 if (left->IsPrimaryNode()) { |
11350 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11385 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11351 const intptr_t primary_pos = primary_node->token_pos(); | 11386 const TokenPosition primary_pos = primary_node->token_pos(); |
11352 if (primary_node->primary().IsFunction()) { | 11387 if (primary_node->primary().IsFunction()) { |
11353 array = LoadClosure(primary_node); | 11388 array = LoadClosure(primary_node); |
11354 } else if (primary_node->primary().IsClass()) { | 11389 } else if (primary_node->primary().IsClass()) { |
11355 const Class& type_class = Class::Cast(primary_node->primary()); | 11390 const Class& type_class = Class::Cast(primary_node->primary()); |
11356 AbstractType& type = Type::ZoneHandle(Z, | 11391 AbstractType& type = Type::ZoneHandle(Z, |
11357 Type::New(type_class, TypeArguments::Handle(Z), | 11392 Type::New(type_class, TypeArguments::Handle(Z), |
11358 primary_pos, Heap::kOld)); | 11393 primary_pos, Heap::kOld)); |
11359 type ^= ClassFinalizer::FinalizeType( | 11394 type ^= ClassFinalizer::FinalizeType( |
11360 current_class(), type, ClassFinalizer::kCanonicalize); | 11395 current_class(), type, ClassFinalizer::kCanonicalize); |
11361 // Type may be malbounded, but not malformed. | 11396 // Type may be malbounded, but not malformed. |
(...skipping 21 matching lines...) Expand all Loading... |
11383 array = new(Z) TypeNode(primary_pos, type_parameter); | 11418 array = new(Z) TypeNode(primary_pos, type_parameter); |
11384 } else { | 11419 } else { |
11385 UNREACHABLE(); // Internal parser error. | 11420 UNREACHABLE(); // Internal parser error. |
11386 } | 11421 } |
11387 } | 11422 } |
11388 selector = new(Z) LoadIndexedNode( | 11423 selector = new(Z) LoadIndexedNode( |
11389 bracket_pos, array, index, Class::ZoneHandle(Z)); | 11424 bracket_pos, array, index, Class::ZoneHandle(Z)); |
11390 } else if (CurrentToken() == Token::kLPAREN) { | 11425 } else if (CurrentToken() == Token::kLPAREN) { |
11391 if (left->IsPrimaryNode()) { | 11426 if (left->IsPrimaryNode()) { |
11392 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11427 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11393 const intptr_t primary_pos = primary_node->token_pos(); | 11428 const TokenPosition primary_pos = primary_node->token_pos(); |
11394 if (primary_node->primary().IsFunction()) { | 11429 if (primary_node->primary().IsFunction()) { |
11395 const Function& func = Function::Cast(primary_node->primary()); | 11430 const Function& func = Function::Cast(primary_node->primary()); |
11396 const String& func_name = String::ZoneHandle(Z, func.name()); | 11431 const String& func_name = String::ZoneHandle(Z, func.name()); |
11397 if (func.is_static()) { | 11432 if (func.is_static()) { |
11398 // Parse static function call. | 11433 // Parse static function call. |
11399 Class& cls = Class::Handle(Z, func.Owner()); | 11434 Class& cls = Class::Handle(Z, func.Owner()); |
11400 selector = ParseStaticCall(cls, func_name, primary_pos); | 11435 selector = ParseStaticCall(cls, func_name, primary_pos); |
11401 } else { | 11436 } else { |
11402 // Dynamic function call on implicit "this" parameter. | 11437 // Dynamic function call on implicit "this" parameter. |
11403 if (current_function().is_static()) { | 11438 if (current_function().is_static()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11459 } else { | 11494 } else { |
11460 // Left is not a primary node; this must be a closure call. | 11495 // Left is not a primary node; this must be a closure call. |
11461 AstNode* closure = left; | 11496 AstNode* closure = left; |
11462 selector = ParseClosureCall(closure); | 11497 selector = ParseClosureCall(closure); |
11463 } | 11498 } |
11464 } else { | 11499 } else { |
11465 // No (more) selectors to parse. | 11500 // No (more) selectors to parse. |
11466 left = LoadFieldIfUnresolved(left); | 11501 left = LoadFieldIfUnresolved(left); |
11467 if (left->IsPrimaryNode()) { | 11502 if (left->IsPrimaryNode()) { |
11468 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11503 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11469 const intptr_t primary_pos = primary->token_pos(); | 11504 const TokenPosition primary_pos = primary->token_pos(); |
11470 if (primary_node->primary().IsFunction()) { | 11505 if (primary_node->primary().IsFunction()) { |
11471 // Treat as implicit closure. | 11506 // Treat as implicit closure. |
11472 left = LoadClosure(primary_node); | 11507 left = LoadClosure(primary_node); |
11473 } else if (primary_node->primary().IsClass()) { | 11508 } else if (primary_node->primary().IsClass()) { |
11474 const Class& type_class = Class::Cast(primary_node->primary()); | 11509 const Class& type_class = Class::Cast(primary_node->primary()); |
11475 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 11510 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
11476 type_class, TypeArguments::Handle(Z), primary_pos)); | 11511 type_class, TypeArguments::Handle(Z), primary_pos)); |
11477 type = ClassFinalizer::FinalizeType( | 11512 type = ClassFinalizer::FinalizeType( |
11478 current_class(), type, ClassFinalizer::kCanonicalize); | 11513 current_class(), type, ClassFinalizer::kCanonicalize); |
11479 // Type may be malbounded, but not malformed. | 11514 // Type may be malbounded, but not malformed. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11512 } | 11547 } |
11513 ASSERT(selector != NULL); | 11548 ASSERT(selector != NULL); |
11514 left = selector; | 11549 left = selector; |
11515 } | 11550 } |
11516 } | 11551 } |
11517 | 11552 |
11518 | 11553 |
11519 // Closurization e#m of getter, setter, method or operator. | 11554 // Closurization e#m of getter, setter, method or operator. |
11520 AstNode* Parser::ParseClosurization(AstNode* primary) { | 11555 AstNode* Parser::ParseClosurization(AstNode* primary) { |
11521 ExpectToken(Token::kHASH); | 11556 ExpectToken(Token::kHASH); |
11522 intptr_t property_pos = TokenPos(); | 11557 TokenPosition property_pos = TokenPos(); |
11523 bool is_setter_name = false; | 11558 bool is_setter_name = false; |
11524 | 11559 |
11525 String& extractor_name = String::ZoneHandle(Z); | 11560 String& extractor_name = String::ZoneHandle(Z); |
11526 if (IsIdentifier()) { | 11561 if (IsIdentifier()) { |
11527 extractor_name = CurrentLiteral()->raw(); | 11562 extractor_name = CurrentLiteral()->raw(); |
11528 ConsumeToken(); | 11563 ConsumeToken(); |
11529 if (CurrentToken() == Token::kASSIGN) { | 11564 if (CurrentToken() == Token::kASSIGN) { |
11530 ConsumeToken(); | 11565 ConsumeToken(); |
11531 is_setter_name = true; | 11566 is_setter_name = true; |
11532 } | 11567 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11653 pieces.Add(extractor_name); | 11688 pieces.Add(extractor_name); |
11654 extractor_name = Symbols::FromConcatAll(pieces); | 11689 extractor_name = Symbols::FromConcatAll(pieces); |
11655 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); | 11690 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); |
11656 } | 11691 } |
11657 | 11692 |
11658 | 11693 |
11659 AstNode* Parser::ParsePostfixExpr() { | 11694 AstNode* Parser::ParsePostfixExpr() { |
11660 TRACE_PARSER("ParsePostfixExpr"); | 11695 TRACE_PARSER("ParsePostfixExpr"); |
11661 String* expr_ident = | 11696 String* expr_ident = |
11662 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11697 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11663 const intptr_t expr_pos = TokenPos(); | 11698 const TokenPosition expr_pos = TokenPos(); |
11664 AstNode* expr = ParsePrimary(); | 11699 AstNode* expr = ParsePrimary(); |
11665 if (CurrentToken() == Token::kHASH) { | 11700 if (CurrentToken() == Token::kHASH) { |
11666 expr = LoadFieldIfUnresolved(expr); | 11701 expr = LoadFieldIfUnresolved(expr); |
11667 expr = ParseClosurization(expr); | 11702 expr = ParseClosurization(expr); |
11668 } else { | 11703 } else { |
11669 expr = ParseSelectors(expr, false); | 11704 expr = ParseSelectors(expr, false); |
11670 } | 11705 } |
11671 if (IsIncrementOperator(CurrentToken())) { | 11706 if (IsIncrementOperator(CurrentToken())) { |
11672 TRACE_PARSER("IncrementOperator"); | 11707 TRACE_PARSER("IncrementOperator"); |
11673 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11708 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
11674 ReportError(expr_pos, "expression is not assignable"); | 11709 ReportError(expr_pos, "expression is not assignable"); |
11675 } | 11710 } |
11676 Token::Kind incr_op = CurrentToken(); | 11711 Token::Kind incr_op = CurrentToken(); |
11677 const intptr_t op_pos = TokenPos(); | 11712 const TokenPosition op_pos = TokenPos(); |
11678 ConsumeToken(); | 11713 ConsumeToken(); |
11679 // Not prefix. | 11714 // Not prefix. |
11680 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11715 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
11681 LocalVariable* temp = let_expr->AddInitializer(expr); | 11716 LocalVariable* temp = let_expr->AddInitializer(expr); |
11682 Token::Kind binary_op = | 11717 Token::Kind binary_op = |
11683 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11718 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
11684 BinaryOpNode* add = new(Z) BinaryOpNode( | 11719 BinaryOpNode* add = new(Z) BinaryOpNode( |
11685 op_pos, | 11720 op_pos, |
11686 binary_op, | 11721 binary_op, |
11687 new(Z) LoadLocalNode(op_pos, temp), | 11722 new(Z) LoadLocalNode(op_pos, temp), |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11800 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 11835 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
11801 if (current_block_ == NULL) { | 11836 if (current_block_ == NULL) { |
11802 return NULL; | 11837 return NULL; |
11803 } | 11838 } |
11804 // A found name is treated as accessed and possibly marked as captured. | 11839 // A found name is treated as accessed and possibly marked as captured. |
11805 const bool kTestOnly = false; | 11840 const bool kTestOnly = false; |
11806 return current_block_->scope->LookupVariable(ident, kTestOnly); | 11841 return current_block_->scope->LookupVariable(ident, kTestOnly); |
11807 } | 11842 } |
11808 | 11843 |
11809 | 11844 |
11810 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 11845 void Parser::CheckInstanceFieldAccess(TokenPosition field_pos, |
11811 const String& field_name) { | 11846 const String& field_name) { |
11812 // Fields are not accessible from a static function, except from a | 11847 // Fields are not accessible from a static function, except from a |
11813 // constructor, which is considered as non-static by the compiler. | 11848 // constructor, which is considered as non-static by the compiler. |
11814 if (current_function().is_static()) { | 11849 if (current_function().is_static()) { |
11815 ReportError(field_pos, | 11850 ReportError(field_pos, |
11816 "cannot access instance field '%s' from a static function", | 11851 "cannot access instance field '%s' from a static function", |
11817 field_name.ToCString()); | 11852 field_name.ToCString()); |
11818 } | 11853 } |
11819 } | 11854 } |
11820 | 11855 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11863 // We cache computed compile-time constants in a map so we can look them | 11898 // We cache computed compile-time constants in a map so we can look them |
11864 // up when the same code gets compiled again. The map key is a pair | 11899 // up when the same code gets compiled again. The map key is a pair |
11865 // (script url, token position) which is encoded in an array with 2 | 11900 // (script url, token position) which is encoded in an array with 2 |
11866 // elements: | 11901 // elements: |
11867 // - key[0] contains the canonicalized url of the script. | 11902 // - key[0] contains the canonicalized url of the script. |
11868 // - key[1] contains the token position of the constant in the script. | 11903 // - key[1] contains the token position of the constant in the script. |
11869 | 11904 |
11870 // ConstantPosKey allows us to look up a constant in the map without | 11905 // ConstantPosKey allows us to look up a constant in the map without |
11871 // allocating a key pair (array). | 11906 // allocating a key pair (array). |
11872 struct ConstantPosKey : ValueObject { | 11907 struct ConstantPosKey : ValueObject { |
11873 ConstantPosKey(const String& url, intptr_t pos) | 11908 ConstantPosKey(const String& url, TokenPosition pos) |
11874 : script_url(url), token_pos(pos) { } | 11909 : script_url(url), token_pos(pos) { } |
11875 const String& script_url; | 11910 const String& script_url; |
11876 intptr_t token_pos; | 11911 TokenPosition token_pos; |
11877 }; | 11912 }; |
11878 | 11913 |
11879 | 11914 |
11880 class ConstMapKeyEqualsTraits { | 11915 class ConstMapKeyEqualsTraits { |
11881 public: | 11916 public: |
11882 static bool IsMatch(const Object& a, const Object& b) { | 11917 static bool IsMatch(const Object& a, const Object& b) { |
11883 const Array& key1 = Array::Cast(a); | 11918 const Array& key1 = Array::Cast(a); |
11884 const Array& key2 = Array::Cast(b); | 11919 const Array& key2 = Array::Cast(b); |
11885 // Compare raw strings of script url symbol and raw smi of token positon. | 11920 // Compare raw strings of script url symbol and raw smi of token positon. |
11886 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); | 11921 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); |
11887 } | 11922 } |
11888 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { | 11923 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { |
11889 const Array& key2 = Array::Cast(b); | 11924 const Array& key2 = Array::Cast(b); |
11890 // Compare raw strings of script url symbol and token positon. | 11925 // Compare raw strings of script url symbol and token positon. |
11891 return (key1.script_url.raw() == key2.At(0)) | 11926 return (key1.script_url.raw() == key2.At(0)) |
11892 && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1)))); | 11927 && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1)))); |
11893 } | 11928 } |
11894 static uword Hash(const Object& obj) { | 11929 static uword Hash(const Object& obj) { |
11895 const Array& key = Array::Cast(obj); | 11930 const Array& key = Array::Cast(obj); |
11896 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); | 11931 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); |
11897 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); | 11932 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); |
11898 return HashValue(url_hash, pos); | 11933 return HashValue(url_hash, pos); |
11899 } | 11934 } |
11900 static uword Hash(const ConstantPosKey& key) { | 11935 static uword Hash(const ConstantPosKey& key) { |
11901 return HashValue(String::HashRawSymbol(key.script_url.raw()), | 11936 return HashValue(String::HashRawSymbol(key.script_url.raw()), |
11902 key.token_pos); | 11937 key.token_pos.value()); |
11903 } | 11938 } |
11904 // Used by CachConstantValue if a new constant is added to the map. | 11939 // Used by CachConstantValue if a new constant is added to the map. |
11905 static RawObject* NewKey(const ConstantPosKey& key) { | 11940 static RawObject* NewKey(const ConstantPosKey& key) { |
11906 const Array& key_obj = Array::Handle(Array::New(2)); | 11941 const Array& key_obj = Array::Handle(Array::New(2)); |
11907 key_obj.SetAt(0, key.script_url); | 11942 key_obj.SetAt(0, key.script_url); |
11908 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos))); | 11943 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value()))); |
11909 return key_obj.raw();; | 11944 return key_obj.raw();; |
11910 } | 11945 } |
11911 | 11946 |
11912 private: | 11947 private: |
11913 static uword HashValue(intptr_t url_hash, intptr_t pos) { | 11948 static uword HashValue(intptr_t url_hash, intptr_t pos) { |
11914 return url_hash * pos % (Smi::kMaxValue - 13); | 11949 return url_hash * pos % (Smi::kMaxValue - 13); |
11915 } | 11950 } |
11916 }; | 11951 }; |
11917 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; | 11952 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
11918 | 11953 |
11919 | 11954 |
11920 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) { | 11955 void Parser::CacheConstantValue(TokenPosition token_pos, |
| 11956 const Instance& value) { |
11921 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); | 11957 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
11922 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11958 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
11923 const intptr_t kInitialConstMapSize = 16; | 11959 const intptr_t kInitialConstMapSize = 16; |
11924 isolate()->object_store()->set_compile_time_constants( | 11960 isolate()->object_store()->set_compile_time_constants( |
11925 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, | 11961 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, |
11926 Heap::kNew))); | 11962 Heap::kNew))); |
11927 } | 11963 } |
11928 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11964 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
11929 constants.InsertNewOrGetValue(key, value); | 11965 constants.InsertNewOrGetValue(key, value); |
11930 if (FLAG_compiler_stats) { | 11966 if (FLAG_compiler_stats) { |
11931 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); | 11967 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); |
11932 } | 11968 } |
11933 isolate()->object_store()->set_compile_time_constants(constants.Release()); | 11969 isolate()->object_store()->set_compile_time_constants(constants.Release()); |
11934 } | 11970 } |
11935 | 11971 |
11936 | 11972 |
11937 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { | 11973 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) { |
11938 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11974 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
11939 return false; | 11975 return false; |
11940 } | 11976 } |
11941 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); | 11977 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
11942 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11978 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
11943 bool is_present = false; | 11979 bool is_present = false; |
11944 *value ^= constants.GetOrNull(key, &is_present); | 11980 *value ^= constants.GetOrNull(key, &is_present); |
11945 // Mutator compiler thread may add constants while background compiler | 11981 // Mutator compiler thread may add constants while background compiler |
11946 // is running , and thus change the value of 'compile_time_constants'; | 11982 // is running , and thus change the value of 'compile_time_constants'; |
11947 // do not assert that 'compile_time_constants' has not changed. | 11983 // do not assert that 'compile_time_constants' has not changed. |
11948 constants.Release(); | 11984 constants.Release(); |
11949 if (FLAG_compiler_stats && is_present) { | 11985 if (FLAG_compiler_stats && is_present) { |
11950 isolate_->compiler_stats()->num_const_cache_hits++; | 11986 isolate_->compiler_stats()->num_const_cache_hits++; |
11951 } | 11987 } |
11952 return is_present; | 11988 return is_present; |
11953 } | 11989 } |
11954 | 11990 |
11955 | 11991 |
11956 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 11992 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
11957 intptr_t token_pos) { | 11993 TokenPosition token_pos) { |
11958 if (instance.IsNull()) { | 11994 if (instance.IsNull()) { |
11959 return instance.raw(); | 11995 return instance.raw(); |
11960 } | 11996 } |
11961 const char* error_str = NULL; | 11997 const char* error_str = NULL; |
11962 Instance& result = | 11998 Instance& result = |
11963 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); | 11999 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); |
11964 if (result.IsNull()) { | 12000 if (result.IsNull()) { |
11965 ReportError(token_pos, "Invalid const object %s", error_str); | 12001 ReportError(token_pos, "Invalid const object %s", error_str); |
11966 } | 12002 } |
11967 return result.raw(); | 12003 return result.raw(); |
11968 } | 12004 } |
11969 | 12005 |
11970 | 12006 |
11971 // If the field is already initialized, return no ast (NULL). | 12007 // If the field is already initialized, return no ast (NULL). |
11972 // Otherwise, if the field is constant, initialize the field and return no ast. | 12008 // Otherwise, if the field is constant, initialize the field and return no ast. |
11973 // If the field is not initialized and not const, return the ast for the getter. | 12009 // If the field is not initialized and not const, return the ast for the getter. |
11974 StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field, | 12010 StaticGetterNode* Parser::RunStaticFieldInitializer( |
11975 intptr_t field_ref_pos) { | 12011 const Field& field, TokenPosition field_ref_pos) { |
11976 ASSERT(field.is_static()); | 12012 ASSERT(field.is_static()); |
11977 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); | 12013 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); |
11978 const String& field_name = String::ZoneHandle(Z, field.name()); | 12014 const String& field_name = String::ZoneHandle(Z, field.name()); |
11979 const String& getter_name = | 12015 const String& getter_name = |
11980 String::Handle(Z, Field::GetterSymbol(field_name)); | 12016 String::Handle(Z, Field::GetterSymbol(field_name)); |
11981 const Function& getter = Function::Handle(Z, | 12017 const Function& getter = Function::Handle(Z, |
11982 field_owner.LookupStaticFunction(getter_name)); | 12018 field_owner.LookupStaticFunction(getter_name)); |
11983 const Instance& value = Instance::Handle(Z, field.StaticValue()); | 12019 const Instance& value = Instance::Handle(Z, field.StaticValue()); |
11984 if (value.raw() == Object::transition_sentinel().raw()) { | 12020 if (value.raw() == Object::transition_sentinel().raw()) { |
11985 if (field.is_const()) { | 12021 if (field.is_const()) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12102 instance ^= result.raw(); | 12138 instance ^= result.raw(); |
12103 } | 12139 } |
12104 return TryCanonicalize(instance, TokenPos()); | 12140 return TryCanonicalize(instance, TokenPos()); |
12105 } | 12141 } |
12106 } | 12142 } |
12107 | 12143 |
12108 | 12144 |
12109 // Do a lookup for the identifier in the block scope and the class scope | 12145 // Do a lookup for the identifier in the block scope and the class scope |
12110 // return true if the identifier is found, false otherwise. | 12146 // return true if the identifier is found, false otherwise. |
12111 // If node is non NULL return an AST node corresponding to the identifier. | 12147 // If node is non NULL return an AST node corresponding to the identifier. |
12112 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 12148 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, |
12113 const String &ident, | 12149 const String &ident, |
12114 AstNode** node) { | 12150 AstNode** node) { |
12115 TRACE_PARSER("ResolveIdentInLocalScope"); | 12151 TRACE_PARSER("ResolveIdentInLocalScope"); |
12116 // First try to find the identifier in the nested local scopes. | 12152 // First try to find the identifier in the nested local scopes. |
12117 LocalVariable* local = LookupLocalScope(ident); | 12153 LocalVariable* local = LookupLocalScope(ident); |
12118 if (current_block_ != NULL) { | 12154 if (current_block_ != NULL) { |
12119 current_block_->scope->AddReferencedName(ident_pos, ident); | 12155 current_block_->scope->AddReferencedName(ident_pos, ident); |
12120 } | 12156 } |
12121 if (local != NULL) { | 12157 if (local != NULL) { |
12122 if (node != NULL) { | 12158 if (node != NULL) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12207 if (node != NULL) { | 12243 if (node != NULL) { |
12208 *node = NULL; | 12244 *node = NULL; |
12209 } | 12245 } |
12210 return false; | 12246 return false; |
12211 } | 12247 } |
12212 | 12248 |
12213 | 12249 |
12214 // Resolve an identifier by checking the global scope of the current | 12250 // Resolve an identifier by checking the global scope of the current |
12215 // library. If not found in the current library, then look in the scopes | 12251 // library. If not found in the current library, then look in the scopes |
12216 // of all libraries that are imported without a library prefix. | 12252 // of all libraries that are imported without a library prefix. |
12217 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 12253 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, |
12218 const String& ident) { | 12254 const String& ident) { |
12219 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 12255 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
12220 HANDLESCOPE(thread()); | 12256 HANDLESCOPE(thread()); |
12221 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); | 12257 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
12222 if (obj.IsClass()) { | 12258 if (obj.IsClass()) { |
12223 const Class& cls = Class::Cast(obj); | 12259 const Class& cls = Class::Cast(obj); |
12224 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 12260 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
12225 } else if (obj.IsField()) { | 12261 } else if (obj.IsField()) { |
12226 const Field& field = Field::Cast(obj); | 12262 const Field& field = Field::Cast(obj); |
12227 ASSERT(field.is_static()); | 12263 ASSERT(field.is_static()); |
(...skipping 25 matching lines...) Expand all Loading... |
12253 ASSERT(obj.IsNull()); | 12289 ASSERT(obj.IsNull()); |
12254 } | 12290 } |
12255 // Lexically unresolved primary identifiers are referenced by their name. | 12291 // Lexically unresolved primary identifiers are referenced by their name. |
12256 return new(Z) PrimaryNode(ident_pos, ident); | 12292 return new(Z) PrimaryNode(ident_pos, ident); |
12257 } | 12293 } |
12258 | 12294 |
12259 | 12295 |
12260 // Do a lookup for the identifier in the scope of the specified | 12296 // Do a lookup for the identifier in the scope of the specified |
12261 // library prefix. This means trying to resolve it locally in all of the | 12297 // library prefix. This means trying to resolve it locally in all of the |
12262 // libraries present in the library prefix. | 12298 // libraries present in the library prefix. |
12263 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 12299 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, |
12264 const LibraryPrefix& prefix, | 12300 const LibraryPrefix& prefix, |
12265 const String& ident) { | 12301 const String& ident) { |
12266 TRACE_PARSER("ResolveIdentInPrefixScope"); | 12302 TRACE_PARSER("ResolveIdentInPrefixScope"); |
12267 HANDLESCOPE(thread()); | 12303 HANDLESCOPE(thread()); |
12268 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 12304 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
12269 // Private names are not exported by libraries. The name mangling | 12305 // Private names are not exported by libraries. The name mangling |
12270 // of private names with a library-specific suffix usually ensures | 12306 // of private names with a library-specific suffix usually ensures |
12271 // that _x in library A is not found when looked up from library B. | 12307 // that _x in library A is not found when looked up from library B. |
12272 // In the pathological case where a library imports itself with | 12308 // In the pathological case where a library imports itself with |
12273 // a prefix, the name mangling would not help in hiding the private | 12309 // a prefix, the name mangling would not help in hiding the private |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12332 UNREACHABLE(); | 12368 UNREACHABLE(); |
12333 return NULL; | 12369 return NULL; |
12334 } | 12370 } |
12335 | 12371 |
12336 | 12372 |
12337 // Resolve identifier. Issue an error message if | 12373 // Resolve identifier. Issue an error message if |
12338 // the ident refers to a method and allow_closure_names is false. | 12374 // the ident refers to a method and allow_closure_names is false. |
12339 // If the name cannot be resolved, turn it into an instance field access | 12375 // If the name cannot be resolved, turn it into an instance field access |
12340 // if we're compiling an instance method, or generate | 12376 // if we're compiling an instance method, or generate |
12341 // throw NoSuchMethodError if we're compiling a static method. | 12377 // throw NoSuchMethodError if we're compiling a static method. |
12342 AstNode* Parser::ResolveIdent(intptr_t ident_pos, | 12378 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, |
12343 const String& ident, | 12379 const String& ident, |
12344 bool allow_closure_names) { | 12380 bool allow_closure_names) { |
12345 TRACE_PARSER("ResolveIdent"); | 12381 TRACE_PARSER("ResolveIdent"); |
12346 // First try to find the variable in the local scope (block scope or | 12382 // First try to find the variable in the local scope (block scope or |
12347 // class scope). | 12383 // class scope). |
12348 AstNode* resolved = NULL; | 12384 AstNode* resolved = NULL; |
12349 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 12385 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
12350 if (resolved == NULL) { | 12386 if (resolved == NULL) { |
12351 // Check whether the identifier is a type parameter. | 12387 // Check whether the identifier is a type parameter. |
12352 if (!current_class().IsNull()) { | 12388 if (!current_class().IsNull()) { |
(...skipping 10 matching lines...) Expand all Loading... |
12363 return new(Z) TypeNode(ident_pos, type_parameter); | 12399 return new(Z) TypeNode(ident_pos, type_parameter); |
12364 } | 12400 } |
12365 } | 12401 } |
12366 // Not found in the local scope, and the name is not a type parameter. | 12402 // Not found in the local scope, and the name is not a type parameter. |
12367 // Try finding the variable in the library scope (current library | 12403 // Try finding the variable in the library scope (current library |
12368 // and all libraries imported by it without a library prefix). | 12404 // and all libraries imported by it without a library prefix). |
12369 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 12405 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
12370 } | 12406 } |
12371 if (resolved->IsPrimaryNode()) { | 12407 if (resolved->IsPrimaryNode()) { |
12372 PrimaryNode* primary = resolved->AsPrimaryNode(); | 12408 PrimaryNode* primary = resolved->AsPrimaryNode(); |
12373 const intptr_t primary_pos = primary->token_pos(); | 12409 const TokenPosition primary_pos = primary->token_pos(); |
12374 if (primary->primary().IsString()) { | 12410 if (primary->primary().IsString()) { |
12375 // We got an unresolved name. If we are compiling a static | 12411 // We got an unresolved name. If we are compiling a static |
12376 // method, evaluation of an unresolved identifier causes a | 12412 // method, evaluation of an unresolved identifier causes a |
12377 // NoSuchMethodError to be thrown. In an instance method, we convert | 12413 // NoSuchMethodError to be thrown. In an instance method, we convert |
12378 // the unresolved name to an instance field access, since a | 12414 // the unresolved name to an instance field access, since a |
12379 // subclass might define a field with this name. | 12415 // subclass might define a field with this name. |
12380 if (current_function().is_static()) { | 12416 if (current_function().is_static()) { |
12381 resolved = ThrowNoSuchMethodError(ident_pos, | 12417 resolved = ThrowNoSuchMethodError(ident_pos, |
12382 current_class(), | 12418 current_class(), |
12383 ident, | 12419 ident, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12422 | 12458 |
12423 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 12459 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
12424 // finalize it according to the given type finalization mode. Returns prefix. | 12460 // finalize it according to the given type finalization mode. Returns prefix. |
12425 RawAbstractType* Parser::ParseType( | 12461 RawAbstractType* Parser::ParseType( |
12426 ClassFinalizer::FinalizationKind finalization, | 12462 ClassFinalizer::FinalizationKind finalization, |
12427 bool allow_deferred_type, | 12463 bool allow_deferred_type, |
12428 bool consume_unresolved_prefix, | 12464 bool consume_unresolved_prefix, |
12429 LibraryPrefix* prefix) { | 12465 LibraryPrefix* prefix) { |
12430 TRACE_PARSER("ParseType"); | 12466 TRACE_PARSER("ParseType"); |
12431 CheckToken(Token::kIDENT, "type name expected"); | 12467 CheckToken(Token::kIDENT, "type name expected"); |
12432 intptr_t ident_pos = TokenPos(); | 12468 TokenPosition ident_pos = TokenPos(); |
12433 String& type_name = String::Handle(Z); | 12469 String& type_name = String::Handle(Z); |
12434 | 12470 |
12435 if (finalization == ClassFinalizer::kIgnore) { | 12471 if (finalization == ClassFinalizer::kIgnore) { |
12436 if (!is_top_level_ && (current_block_ != NULL)) { | 12472 if (!is_top_level_ && (current_block_ != NULL)) { |
12437 // Add the library prefix or type class name to the list of referenced | 12473 // Add the library prefix or type class name to the list of referenced |
12438 // names of this scope, even if the type is ignored. | 12474 // names of this scope, even if the type is ignored. |
12439 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 12475 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
12440 } | 12476 } |
12441 SkipQualIdent(); | 12477 SkipQualIdent(); |
12442 } else { | 12478 } else { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12535 ResolveTypeFromClass(current_class(), finalization, &type); | 12571 ResolveTypeFromClass(current_class(), finalization, &type); |
12536 if (finalization >= ClassFinalizer::kCanonicalize) { | 12572 if (finalization >= ClassFinalizer::kCanonicalize) { |
12537 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 12573 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
12538 } | 12574 } |
12539 } | 12575 } |
12540 return type.raw(); | 12576 return type.raw(); |
12541 } | 12577 } |
12542 | 12578 |
12543 | 12579 |
12544 void Parser::CheckConstructorCallTypeArguments( | 12580 void Parser::CheckConstructorCallTypeArguments( |
12545 intptr_t pos, const Function& constructor, | 12581 TokenPosition pos, const Function& constructor, |
12546 const TypeArguments& type_arguments) { | 12582 const TypeArguments& type_arguments) { |
12547 if (!type_arguments.IsNull()) { | 12583 if (!type_arguments.IsNull()) { |
12548 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); | 12584 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
12549 ASSERT(!constructor_class.IsNull()); | 12585 ASSERT(!constructor_class.IsNull()); |
12550 ASSERT(constructor_class.is_finalized()); | 12586 ASSERT(constructor_class.is_finalized()); |
12551 ASSERT(type_arguments.IsCanonical()); | 12587 ASSERT(type_arguments.IsCanonical()); |
12552 // Do not report the expected vs. actual number of type arguments, because | 12588 // Do not report the expected vs. actual number of type arguments, because |
12553 // the type argument vector is flattened and raw types are allowed. | 12589 // the type argument vector is flattened and raw types are allowed. |
12554 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 12590 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
12555 ReportError(pos, "wrong number of type arguments passed to constructor"); | 12591 ReportError(pos, "wrong number of type arguments passed to constructor"); |
12556 } | 12592 } |
12557 } | 12593 } |
12558 } | 12594 } |
12559 | 12595 |
12560 | 12596 |
12561 // Parse "[" [ expr { "," expr } ["," ] "]". | 12597 // Parse "[" [ expr { "," expr } ["," ] "]". |
12562 // Note: if the list literal is empty and the brackets have no whitespace | 12598 // Note: if the list literal is empty and the brackets have no whitespace |
12563 // between them, the scanner recognizes the opening and closing bracket | 12599 // between them, the scanner recognizes the opening and closing bracket |
12564 // as one token of type Token::kINDEX. | 12600 // as one token of type Token::kINDEX. |
12565 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 12601 AstNode* Parser::ParseListLiteral(TokenPosition type_pos, |
12566 bool is_const, | 12602 bool is_const, |
12567 const TypeArguments& type_arguments) { | 12603 const TypeArguments& type_arguments) { |
12568 TRACE_PARSER("ParseListLiteral"); | 12604 TRACE_PARSER("ParseListLiteral"); |
12569 ASSERT(type_pos >= 0); | 12605 ASSERT(type_pos.IsReal()); |
12570 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 12606 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
12571 const intptr_t literal_pos = TokenPos(); | 12607 const TokenPosition literal_pos = TokenPos(); |
12572 | 12608 |
12573 if (is_const) { | 12609 if (is_const) { |
12574 Instance& existing_const = Instance::ZoneHandle(Z); | 12610 Instance& existing_const = Instance::ZoneHandle(Z); |
12575 if (GetCachedConstant(literal_pos, &existing_const)) { | 12611 if (GetCachedConstant(literal_pos, &existing_const)) { |
12576 SkipListLiteral(); | 12612 SkipListLiteral(); |
12577 return new(Z) LiteralNode(literal_pos, existing_const); | 12613 return new(Z) LiteralNode(literal_pos, existing_const); |
12578 } | 12614 } |
12579 } | 12615 } |
12580 | 12616 |
12581 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 12617 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12615 Type& type = Type::ZoneHandle(Z, | 12651 Type& type = Type::ZoneHandle(Z, |
12616 Type::New(array_class, list_type_arguments, type_pos)); | 12652 Type::New(array_class, list_type_arguments, type_pos)); |
12617 type ^= ClassFinalizer::FinalizeType( | 12653 type ^= ClassFinalizer::FinalizeType( |
12618 current_class(), type, ClassFinalizer::kCanonicalize); | 12654 current_class(), type, ClassFinalizer::kCanonicalize); |
12619 GrowableArray<AstNode*> element_list; | 12655 GrowableArray<AstNode*> element_list; |
12620 // Parse the list elements. Note: there may be an optional extra | 12656 // Parse the list elements. Note: there may be an optional extra |
12621 // comma after the last element. | 12657 // comma after the last element. |
12622 if (!is_empty_literal) { | 12658 if (!is_empty_literal) { |
12623 const bool saved_mode = SetAllowFunctionLiterals(true); | 12659 const bool saved_mode = SetAllowFunctionLiterals(true); |
12624 while (CurrentToken() != Token::kRBRACK) { | 12660 while (CurrentToken() != Token::kRBRACK) { |
12625 const intptr_t element_pos = TokenPos(); | 12661 const TokenPosition element_pos = TokenPos(); |
12626 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 12662 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
12627 if (I->flags().type_checks() && | 12663 if (I->flags().type_checks() && |
12628 !is_const && | 12664 !is_const && |
12629 !element_type.IsDynamicType()) { | 12665 !element_type.IsDynamicType()) { |
12630 element = new(Z) AssignableNode(element_pos, | 12666 element = new(Z) AssignableNode(element_pos, |
12631 element, | 12667 element, |
12632 element_type, | 12668 element_type, |
12633 Symbols::ListLiteralElement()); | 12669 Symbols::ListLiteralElement()); |
12634 } | 12670 } |
12635 element_list.Add(element); | 12671 element_list.Add(element); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12721 } | 12757 } |
12722 return CreateConstructorCallNode(literal_pos, | 12758 return CreateConstructorCallNode(literal_pos, |
12723 factory_type_args, | 12759 factory_type_args, |
12724 factory_method, | 12760 factory_method, |
12725 factory_param); | 12761 factory_param); |
12726 } | 12762 } |
12727 } | 12763 } |
12728 | 12764 |
12729 | 12765 |
12730 ConstructorCallNode* Parser::CreateConstructorCallNode( | 12766 ConstructorCallNode* Parser::CreateConstructorCallNode( |
12731 intptr_t token_pos, | 12767 TokenPosition token_pos, |
12732 const TypeArguments& type_arguments, | 12768 const TypeArguments& type_arguments, |
12733 const Function& constructor, | 12769 const Function& constructor, |
12734 ArgumentListNode* arguments) { | 12770 ArgumentListNode* arguments) { |
12735 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 12771 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
12736 EnsureExpressionTemp(); | 12772 EnsureExpressionTemp(); |
12737 } | 12773 } |
12738 return new(Z) ConstructorCallNode( | 12774 return new(Z) ConstructorCallNode( |
12739 token_pos, type_arguments, constructor, arguments); | 12775 token_pos, type_arguments, constructor, arguments); |
12740 } | 12776 } |
12741 | 12777 |
(...skipping 16 matching lines...) Expand all Loading... |
12758 (*pairs)[i + 1] = value; | 12794 (*pairs)[i + 1] = value; |
12759 return; | 12795 return; |
12760 } | 12796 } |
12761 } | 12797 } |
12762 } | 12798 } |
12763 pairs->Add(key); | 12799 pairs->Add(key); |
12764 pairs->Add(value); | 12800 pairs->Add(value); |
12765 } | 12801 } |
12766 | 12802 |
12767 | 12803 |
12768 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 12804 AstNode* Parser::ParseMapLiteral(TokenPosition type_pos, |
12769 bool is_const, | 12805 bool is_const, |
12770 const TypeArguments& type_arguments) { | 12806 const TypeArguments& type_arguments) { |
12771 TRACE_PARSER("ParseMapLiteral"); | 12807 TRACE_PARSER("ParseMapLiteral"); |
12772 ASSERT(type_pos >= 0); | 12808 ASSERT(type_pos.IsReal()); |
12773 ASSERT(CurrentToken() == Token::kLBRACE); | 12809 ASSERT(CurrentToken() == Token::kLBRACE); |
12774 const intptr_t literal_pos = TokenPos(); | 12810 const TokenPosition literal_pos = TokenPos(); |
12775 | 12811 |
12776 if (is_const) { | 12812 if (is_const) { |
12777 Instance& existing_const = Instance::ZoneHandle(Z); | 12813 Instance& existing_const = Instance::ZoneHandle(Z); |
12778 if (GetCachedConstant(literal_pos, &existing_const)) { | 12814 if (GetCachedConstant(literal_pos, &existing_const)) { |
12779 SkipMapLiteral(); | 12815 SkipMapLiteral(); |
12780 return new(Z) LiteralNode(literal_pos, existing_const); | 12816 return new(Z) LiteralNode(literal_pos, existing_const); |
12781 } | 12817 } |
12782 } | 12818 } |
12783 | 12819 |
12784 ConsumeToken(); // Opening brace. | 12820 ConsumeToken(); // Opening brace. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12817 } | 12853 } |
12818 } | 12854 } |
12819 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 12855 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
12820 map_type_arguments ^= map_type_arguments.Canonicalize(); | 12856 map_type_arguments ^= map_type_arguments.Canonicalize(); |
12821 | 12857 |
12822 GrowableArray<AstNode*> kv_pairs_list; | 12858 GrowableArray<AstNode*> kv_pairs_list; |
12823 // Parse the map entries. Note: there may be an optional extra | 12859 // Parse the map entries. Note: there may be an optional extra |
12824 // comma after the last entry. | 12860 // comma after the last entry. |
12825 while (CurrentToken() != Token::kRBRACE) { | 12861 while (CurrentToken() != Token::kRBRACE) { |
12826 const bool saved_mode = SetAllowFunctionLiterals(true); | 12862 const bool saved_mode = SetAllowFunctionLiterals(true); |
12827 const intptr_t key_pos = TokenPos(); | 12863 const TokenPosition key_pos = TokenPos(); |
12828 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 12864 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
12829 if (I->flags().type_checks() && | 12865 if (I->flags().type_checks() && |
12830 !is_const && | 12866 !is_const && |
12831 !key_type.IsDynamicType()) { | 12867 !key_type.IsDynamicType()) { |
12832 key = new(Z) AssignableNode( | 12868 key = new(Z) AssignableNode( |
12833 key_pos, key, key_type, Symbols::ListLiteralElement()); | 12869 key_pos, key, key_type, Symbols::ListLiteralElement()); |
12834 } | 12870 } |
12835 if (is_const) { | 12871 if (is_const) { |
12836 ASSERT(key->IsLiteralNode()); | 12872 ASSERT(key->IsLiteralNode()); |
12837 const Instance& key_value = key->AsLiteralNode()->literal(); | 12873 const Instance& key_value = key->AsLiteralNode()->literal(); |
12838 if (key_value.IsDouble()) { | 12874 if (key_value.IsDouble()) { |
12839 ReportError(key_pos, "key value must not be of type double"); | 12875 ReportError(key_pos, "key value must not be of type double"); |
12840 } | 12876 } |
12841 if (!key_value.IsInteger() && | 12877 if (!key_value.IsInteger() && |
12842 !key_value.IsString() && | 12878 !key_value.IsString() && |
12843 (key_value.clazz() != I->object_store()->symbol_class()) && | 12879 (key_value.clazz() != I->object_store()->symbol_class()) && |
12844 ImplementsEqualOperator(key_value)) { | 12880 ImplementsEqualOperator(key_value)) { |
12845 ReportError(key_pos, "key value must not implement operator =="); | 12881 ReportError(key_pos, "key value must not implement operator =="); |
12846 } | 12882 } |
12847 } | 12883 } |
12848 ExpectToken(Token::kCOLON); | 12884 ExpectToken(Token::kCOLON); |
12849 const intptr_t value_pos = TokenPos(); | 12885 const TokenPosition value_pos = TokenPos(); |
12850 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 12886 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
12851 SetAllowFunctionLiterals(saved_mode); | 12887 SetAllowFunctionLiterals(saved_mode); |
12852 if (I->flags().type_checks() && | 12888 if (I->flags().type_checks() && |
12853 !is_const && | 12889 !is_const && |
12854 !value_type.IsDynamicType()) { | 12890 !value_type.IsDynamicType()) { |
12855 value = new(Z) AssignableNode( | 12891 value = new(Z) AssignableNode( |
12856 value_pos, value, value_type, Symbols::ListLiteralElement()); | 12892 value_pos, value, value_type, Symbols::ListLiteralElement()); |
12857 } | 12893 } |
12858 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 12894 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
12859 | 12895 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12989 } | 13025 } |
12990 | 13026 |
12991 | 13027 |
12992 AstNode* Parser::ParseCompoundLiteral() { | 13028 AstNode* Parser::ParseCompoundLiteral() { |
12993 TRACE_PARSER("ParseCompoundLiteral"); | 13029 TRACE_PARSER("ParseCompoundLiteral"); |
12994 bool is_const = false; | 13030 bool is_const = false; |
12995 if (CurrentToken() == Token::kCONST) { | 13031 if (CurrentToken() == Token::kCONST) { |
12996 is_const = true; | 13032 is_const = true; |
12997 ConsumeToken(); | 13033 ConsumeToken(); |
12998 } | 13034 } |
12999 const intptr_t type_pos = TokenPos(); | 13035 const TokenPosition type_pos = TokenPos(); |
13000 TypeArguments& type_arguments = TypeArguments::Handle(Z, | 13036 TypeArguments& type_arguments = TypeArguments::Handle(Z, |
13001 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 13037 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
13002 // Malformed type arguments are mapped to dynamic, so we will not encounter | 13038 // Malformed type arguments are mapped to dynamic, so we will not encounter |
13003 // them here. | 13039 // them here. |
13004 // Map and List interfaces do not declare bounds on their type parameters, so | 13040 // Map and List interfaces do not declare bounds on their type parameters, so |
13005 // we will not see malbounded type arguments here. | 13041 // we will not see malbounded type arguments here. |
13006 AstNode* primary = NULL; | 13042 AstNode* primary = NULL; |
13007 if ((CurrentToken() == Token::kLBRACK) || | 13043 if ((CurrentToken() == Token::kLBRACK) || |
13008 (CurrentToken() == Token::kINDEX)) { | 13044 (CurrentToken() == Token::kINDEX)) { |
13009 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 13045 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
13010 } else if (CurrentToken() == Token::kLBRACE) { | 13046 } else if (CurrentToken() == Token::kLBRACE) { |
13011 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 13047 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
13012 } else { | 13048 } else { |
13013 UnexpectedToken(); | 13049 UnexpectedToken(); |
13014 } | 13050 } |
13015 return primary; | 13051 return primary; |
13016 } | 13052 } |
13017 | 13053 |
13018 | 13054 |
13019 AstNode* Parser::ParseSymbolLiteral() { | 13055 AstNode* Parser::ParseSymbolLiteral() { |
13020 ASSERT(CurrentToken() == Token::kHASH); | 13056 ASSERT(CurrentToken() == Token::kHASH); |
13021 ConsumeToken(); | 13057 ConsumeToken(); |
13022 intptr_t symbol_pos = TokenPos(); | 13058 TokenPosition symbol_pos = TokenPos(); |
13023 String& symbol = String::ZoneHandle(Z); | 13059 String& symbol = String::ZoneHandle(Z); |
13024 if (IsIdentifier()) { | 13060 if (IsIdentifier()) { |
13025 symbol = CurrentLiteral()->raw(); | 13061 symbol = CurrentLiteral()->raw(); |
13026 ConsumeToken(); | 13062 ConsumeToken(); |
13027 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13063 GrowableHandlePtrArray<const String> pieces(Z, 3); |
13028 pieces.Add(symbol); | 13064 pieces.Add(symbol); |
13029 while (CurrentToken() == Token::kPERIOD) { | 13065 while (CurrentToken() == Token::kPERIOD) { |
13030 pieces.Add(Symbols::Dot()); | 13066 pieces.Add(Symbols::Dot()); |
13031 ConsumeToken(); | 13067 ConsumeToken(); |
13032 pieces.Add(*ExpectIdentifier("identifier expected")); | 13068 pieces.Add(*ExpectIdentifier("identifier expected")); |
(...skipping 29 matching lines...) Expand all Loading... |
13062 ReportErrors(Error::Cast(result), | 13098 ReportErrors(Error::Cast(result), |
13063 script_, symbol_pos, | 13099 script_, symbol_pos, |
13064 "error executing const Symbol constructor"); | 13100 "error executing const Symbol constructor"); |
13065 } | 13101 } |
13066 symbol_instance ^= result.raw(); | 13102 symbol_instance ^= result.raw(); |
13067 CacheConstantValue(symbol_pos, symbol_instance); | 13103 CacheConstantValue(symbol_pos, symbol_instance); |
13068 return new(Z) LiteralNode(symbol_pos, symbol_instance); | 13104 return new(Z) LiteralNode(symbol_pos, symbol_instance); |
13069 } | 13105 } |
13070 | 13106 |
13071 | 13107 |
13072 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, | 13108 RawFunction* Parser::BuildConstructorClosureFunction( |
13073 intptr_t token_pos) { | 13109 const Function& ctr, TokenPosition token_pos) { |
13074 ASSERT(ctr.kind() == RawFunction::kConstructor); | 13110 ASSERT(ctr.kind() == RawFunction::kConstructor); |
13075 Function& closure = Function::Handle(Z); | 13111 Function& closure = Function::Handle(Z); |
13076 closure = I->LookupClosureFunction(innermost_function(), token_pos); | 13112 closure = I->LookupClosureFunction(innermost_function(), token_pos); |
13077 if (!closure.IsNull()) { | 13113 if (!closure.IsNull()) { |
13078 ASSERT(closure.IsConstructorClosureFunction()); | 13114 ASSERT(closure.IsConstructorClosureFunction()); |
13079 return closure.raw(); | 13115 return closure.raw(); |
13080 } | 13116 } |
13081 | 13117 |
13082 String& closure_name = String::Handle(Z, ctr.name()); | 13118 String& closure_name = String::Handle(Z, ctr.name()); |
13083 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(), | 13119 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(), |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13180 } | 13216 } |
13181 *type_arguments = type.arguments(); | 13217 *type_arguments = type.arguments(); |
13182 *constructor = constructor->RedirectionTarget(); | 13218 *constructor = constructor->RedirectionTarget(); |
13183 } | 13219 } |
13184 } | 13220 } |
13185 } | 13221 } |
13186 | 13222 |
13187 | 13223 |
13188 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13224 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
13189 TRACE_PARSER("ParseNewOperator"); | 13225 TRACE_PARSER("ParseNewOperator"); |
13190 const intptr_t new_pos = TokenPos(); | 13226 const TokenPosition new_pos = TokenPos(); |
13191 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13227 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
13192 bool is_const = (op_kind == Token::kCONST); | 13228 bool is_const = (op_kind == Token::kCONST); |
13193 if (!IsIdentifier()) { | 13229 if (!IsIdentifier()) { |
13194 ReportError("type name expected"); | 13230 ReportError("type name expected"); |
13195 } | 13231 } |
13196 intptr_t type_pos = TokenPos(); | 13232 TokenPosition type_pos = TokenPos(); |
13197 // Can't allocate const objects of a deferred type. | 13233 // Can't allocate const objects of a deferred type. |
13198 const bool allow_deferred_type = !is_const; | 13234 const bool allow_deferred_type = !is_const; |
13199 const Token::Kind la3 = LookaheadToken(3); | 13235 const Token::Kind la3 = LookaheadToken(3); |
13200 const bool consume_unresolved_prefix = | 13236 const bool consume_unresolved_prefix = |
13201 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | 13237 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
13202 | 13238 |
13203 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 13239 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
13204 AbstractType& type = AbstractType::Handle(Z, | 13240 AbstractType& type = AbstractType::Handle(Z, |
13205 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 13241 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
13206 allow_deferred_type, | 13242 allow_deferred_type, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13257 ConsumeToken(); | 13293 ConsumeToken(); |
13258 if (IsIdentifier()) { | 13294 if (IsIdentifier()) { |
13259 named_constructor = ExpectIdentifier("name of constructor expected"); | 13295 named_constructor = ExpectIdentifier("name of constructor expected"); |
13260 } | 13296 } |
13261 } else if (CurrentToken() == Token::kPERIOD) { | 13297 } else if (CurrentToken() == Token::kPERIOD) { |
13262 ConsumeToken(); | 13298 ConsumeToken(); |
13263 named_constructor = ExpectIdentifier("name of constructor expected"); | 13299 named_constructor = ExpectIdentifier("name of constructor expected"); |
13264 } | 13300 } |
13265 | 13301 |
13266 // Parse constructor parameters. | 13302 // Parse constructor parameters. |
13267 intptr_t call_pos = TokenPos(); | 13303 TokenPosition call_pos = TokenPos(); |
13268 ArgumentListNode* arguments = NULL; | 13304 ArgumentListNode* arguments = NULL; |
13269 if (!is_tearoff_expression) { | 13305 if (!is_tearoff_expression) { |
13270 CheckToken(Token::kLPAREN); | 13306 CheckToken(Token::kLPAREN); |
13271 call_pos = TokenPos(); | 13307 call_pos = TokenPos(); |
13272 arguments = ParseActualParameters(NULL, is_const); | 13308 arguments = ParseActualParameters(NULL, is_const); |
13273 } else { | 13309 } else { |
13274 // Allocate dummy node with no arguments so we don't have to deal | 13310 // Allocate dummy node with no arguments so we don't have to deal |
13275 // with the NULL corner case below. | 13311 // with the NULL corner case below. |
13276 arguments = new(Z) ArgumentListNode(TokenPos()); | 13312 arguments = new(Z) ArgumentListNode(TokenPos()); |
13277 } | 13313 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13397 // It is ok to call a factory method of an abstract class, but it is | 13433 // It is ok to call a factory method of an abstract class, but it is |
13398 // a dynamic error to instantiate an abstract class. | 13434 // a dynamic error to instantiate an abstract class. |
13399 if (type_class.is_abstract() && !constructor.IsFactory()) { | 13435 if (type_class.is_abstract() && !constructor.IsFactory()) { |
13400 // Evaluate arguments before throwing. | 13436 // Evaluate arguments before throwing. |
13401 LetNode* result = new(Z) LetNode(call_pos); | 13437 LetNode* result = new(Z) LetNode(call_pos); |
13402 for (intptr_t i = 0; i < arguments->length(); ++i) { | 13438 for (intptr_t i = 0; i < arguments->length(); ++i) { |
13403 result->AddNode(arguments->NodeAt(i)); | 13439 result->AddNode(arguments->NodeAt(i)); |
13404 } | 13440 } |
13405 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); | 13441 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); |
13406 error_arguments->Add(new(Z) LiteralNode( | 13442 error_arguments->Add(new(Z) LiteralNode( |
13407 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos)))); | 13443 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos.value())))); |
13408 error_arguments->Add(new(Z) LiteralNode( | 13444 error_arguments->Add(new(Z) LiteralNode( |
13409 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); | 13445 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); |
13410 result->AddNode( | 13446 result->AddNode( |
13411 MakeStaticCall(Symbols::AbstractClassInstantiationError(), | 13447 MakeStaticCall(Symbols::AbstractClassInstantiationError(), |
13412 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 13448 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
13413 error_arguments)); | 13449 error_arguments)); |
13414 return result; | 13450 return result; |
13415 } | 13451 } |
13416 | 13452 |
13417 type_arguments ^= type_arguments.Canonicalize(); | 13453 type_arguments ^= type_arguments.Canonicalize(); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13575 | 13611 |
13576 // A string literal consists of the concatenation of the next n tokens | 13612 // A string literal consists of the concatenation of the next n tokens |
13577 // that satisfy the EBNF grammar: | 13613 // that satisfy the EBNF grammar: |
13578 // literal = kSTRING {{ interpol } kSTRING } | 13614 // literal = kSTRING {{ interpol } kSTRING } |
13579 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 13615 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
13580 // In other words, the scanner breaks down interpolated strings so that | 13616 // In other words, the scanner breaks down interpolated strings so that |
13581 // a string literal always begins and ends with a kSTRING token. | 13617 // a string literal always begins and ends with a kSTRING token. |
13582 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 13618 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
13583 TRACE_PARSER("ParseStringLiteral"); | 13619 TRACE_PARSER("ParseStringLiteral"); |
13584 AstNode* primary = NULL; | 13620 AstNode* primary = NULL; |
13585 const intptr_t literal_start = TokenPos(); | 13621 const TokenPosition literal_start = TokenPos(); |
13586 ASSERT(CurrentToken() == Token::kSTRING); | 13622 ASSERT(CurrentToken() == Token::kSTRING); |
13587 Token::Kind l1_token = LookaheadToken(1); | 13623 Token::Kind l1_token = LookaheadToken(1); |
13588 if ((l1_token != Token::kSTRING) && | 13624 if ((l1_token != Token::kSTRING) && |
13589 (l1_token != Token::kINTERPOL_VAR) && | 13625 (l1_token != Token::kINTERPOL_VAR) && |
13590 (l1_token != Token::kINTERPOL_START)) { | 13626 (l1_token != Token::kINTERPOL_START)) { |
13591 // Common case: no interpolation. | 13627 // Common case: no interpolation. |
13592 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); | 13628 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); |
13593 ConsumeToken(); | 13629 ConsumeToken(); |
13594 return primary; | 13630 return primary; |
13595 } | 13631 } |
(...skipping 18 matching lines...) Expand all Loading... |
13614 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); | 13650 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); |
13615 } | 13651 } |
13616 ConsumeToken(); | 13652 ConsumeToken(); |
13617 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 13653 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
13618 (CurrentToken() == Token::kINTERPOL_START)) { | 13654 (CurrentToken() == Token::kINTERPOL_START)) { |
13619 if (!allow_interpolation) { | 13655 if (!allow_interpolation) { |
13620 ReportError("string interpolation not allowed in this context"); | 13656 ReportError("string interpolation not allowed in this context"); |
13621 } | 13657 } |
13622 has_interpolation = true; | 13658 has_interpolation = true; |
13623 AstNode* expr = NULL; | 13659 AstNode* expr = NULL; |
13624 const intptr_t expr_pos = TokenPos(); | 13660 const TokenPosition expr_pos = TokenPos(); |
13625 if (CurrentToken() == Token::kINTERPOL_VAR) { | 13661 if (CurrentToken() == Token::kINTERPOL_VAR) { |
13626 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); | 13662 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
13627 ConsumeToken(); | 13663 ConsumeToken(); |
13628 } else { | 13664 } else { |
13629 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 13665 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
13630 ConsumeToken(); | 13666 ConsumeToken(); |
13631 const bool saved_mode = SetAllowFunctionLiterals(true); | 13667 const bool saved_mode = SetAllowFunctionLiterals(true); |
13632 expr = ParseExpr(kAllowConst, kConsumeCascades); | 13668 expr = ParseExpr(kAllowConst, kConsumeCascades); |
13633 SetAllowFunctionLiterals(saved_mode); | 13669 SetAllowFunctionLiterals(saved_mode); |
13634 ExpectToken(Token::kINTERPOL_END); | 13670 ExpectToken(Token::kINTERPOL_END); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13687 ASSERT(!is_top_level_); | 13723 ASSERT(!is_top_level_); |
13688 AstNode* primary = NULL; | 13724 AstNode* primary = NULL; |
13689 const Token::Kind token = CurrentToken(); | 13725 const Token::Kind token = CurrentToken(); |
13690 if (IsFunctionLiteral()) { | 13726 if (IsFunctionLiteral()) { |
13691 // The name of a literal function is visible from inside the function, but | 13727 // The name of a literal function is visible from inside the function, but |
13692 // must not collide with names in the scope declaring the literal. | 13728 // must not collide with names in the scope declaring the literal. |
13693 OpenBlock(); | 13729 OpenBlock(); |
13694 primary = ParseFunctionStatement(true); | 13730 primary = ParseFunctionStatement(true); |
13695 CloseBlock(); | 13731 CloseBlock(); |
13696 } else if (IsIdentifier()) { | 13732 } else if (IsIdentifier()) { |
13697 intptr_t qual_ident_pos = TokenPos(); | 13733 TokenPosition qual_ident_pos = TokenPos(); |
13698 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13734 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
13699 if (!prefix.IsNull()) { | 13735 if (!prefix.IsNull()) { |
13700 if (CurrentToken() == Token::kHASH) { | 13736 if (CurrentToken() == Token::kHASH) { |
13701 // Closurization of top-level entity in prefix scope. | 13737 // Closurization of top-level entity in prefix scope. |
13702 return new(Z) LiteralNode(qual_ident_pos, prefix); | 13738 return new(Z) LiteralNode(qual_ident_pos, prefix); |
13703 } else { | 13739 } else { |
13704 ExpectToken(Token::kPERIOD); | 13740 ExpectToken(Token::kPERIOD); |
13705 } | 13741 } |
13706 } | 13742 } |
13707 String& ident = *CurrentLiteral(); | 13743 String& ident = *CurrentLiteral(); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13846 } else if (token == Token::kHASH) { | 13882 } else if (token == Token::kHASH) { |
13847 primary = ParseSymbolLiteral(); | 13883 primary = ParseSymbolLiteral(); |
13848 } else if (token == Token::kSUPER) { | 13884 } else if (token == Token::kSUPER) { |
13849 if (current_function().is_static()) { | 13885 if (current_function().is_static()) { |
13850 ReportError("cannot access superclass from static method"); | 13886 ReportError("cannot access superclass from static method"); |
13851 } | 13887 } |
13852 if (current_class().SuperClass() == Class::null()) { | 13888 if (current_class().SuperClass() == Class::null()) { |
13853 ReportError("class '%s' does not have a superclass", | 13889 ReportError("class '%s' does not have a superclass", |
13854 String::Handle(Z, current_class().Name()).ToCString()); | 13890 String::Handle(Z, current_class().Name()).ToCString()); |
13855 } | 13891 } |
13856 const intptr_t super_pos = TokenPos(); | 13892 const TokenPosition super_pos = TokenPos(); |
13857 ConsumeToken(); | 13893 ConsumeToken(); |
13858 if (CurrentToken() == Token::kPERIOD) { | 13894 if (CurrentToken() == Token::kPERIOD) { |
13859 ConsumeToken(); | 13895 ConsumeToken(); |
13860 const intptr_t ident_pos = TokenPos(); | 13896 const TokenPosition ident_pos = TokenPos(); |
13861 const String& ident = *ExpectIdentifier("identifier expected"); | 13897 const String& ident = *ExpectIdentifier("identifier expected"); |
13862 if (CurrentToken() == Token::kLPAREN) { | 13898 if (CurrentToken() == Token::kLPAREN) { |
13863 primary = ParseSuperCall(ident); | 13899 primary = ParseSuperCall(ident); |
13864 } else { | 13900 } else { |
13865 primary = ParseSuperFieldAccess(ident, ident_pos); | 13901 primary = ParseSuperFieldAccess(ident, ident_pos); |
13866 } | 13902 } |
13867 } else if ((CurrentToken() == Token::kLBRACK) || | 13903 } else if ((CurrentToken() == Token::kLBRACK) || |
13868 Token::CanBeOverloaded(CurrentToken()) || | 13904 Token::CanBeOverloaded(CurrentToken()) || |
13869 (CurrentToken() == Token::kNE)) { | 13905 (CurrentToken() == Token::kNE)) { |
13870 primary = ParseSuperOperator(); | 13906 primary = ParseSuperOperator(); |
13871 } else if (CurrentToken() == Token::kQM_PERIOD) { | 13907 } else if (CurrentToken() == Token::kQM_PERIOD) { |
13872 ReportError("super call or super getter may not use ?."); | 13908 ReportError("super call or super getter may not use ?."); |
13873 } else { | 13909 } else { |
13874 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); | 13910 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); |
13875 } | 13911 } |
13876 } else { | 13912 } else { |
13877 UnexpectedToken(); | 13913 UnexpectedToken(); |
13878 } | 13914 } |
13879 return primary; | 13915 return primary; |
13880 } | 13916 } |
13881 | 13917 |
13882 | 13918 |
13883 // Evaluate expression in expr and return the value. The expression must | 13919 // Evaluate expression in expr and return the value. The expression must |
13884 // be a compile time constant. | 13920 // be a compile time constant. |
13885 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { | 13921 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, |
| 13922 AstNode* expr) { |
13886 if (expr->IsLiteralNode()) { | 13923 if (expr->IsLiteralNode()) { |
13887 return expr->AsLiteralNode()->literal(); | 13924 return expr->AsLiteralNode()->literal(); |
13888 } else if (expr->IsLoadLocalNode() && | 13925 } else if (expr->IsLoadLocalNode() && |
13889 expr->AsLoadLocalNode()->local().IsConst()) { | 13926 expr->AsLoadLocalNode()->local().IsConst()) { |
13890 return *expr->AsLoadLocalNode()->local().ConstValue(); | 13927 return *expr->AsLoadLocalNode()->local().ConstValue(); |
13891 } else if (expr->IsLoadStaticFieldNode()) { | 13928 } else if (expr->IsLoadStaticFieldNode()) { |
13892 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 13929 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
13893 // We already checked that this field is const and has been | 13930 // We already checked that this field is const and has been |
13894 // initialized. | 13931 // initialized. |
13895 ASSERT(field.is_const()); | 13932 ASSERT(field.is_const()); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14347 } | 14384 } |
14348 | 14385 |
14349 | 14386 |
14350 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 14387 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
14351 UNREACHABLE(); | 14388 UNREACHABLE(); |
14352 return NULL; | 14389 return NULL; |
14353 } | 14390 } |
14354 | 14391 |
14355 | 14392 |
14356 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 14393 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
14357 intptr_t call_pos, | 14394 TokenPosition call_pos, |
14358 const String& function_name, | 14395 const String& function_name, |
14359 const ArgumentListNode& function_args, | 14396 const ArgumentListNode& function_args, |
14360 const LocalVariable* temp_for_last_arg, | 14397 const LocalVariable* temp_for_last_arg, |
14361 bool is_super_invocation) { | 14398 bool is_super_invocation) { |
14362 UNREACHABLE(); | 14399 UNREACHABLE(); |
14363 return NULL; | 14400 return NULL; |
14364 } | 14401 } |
14365 | 14402 |
14366 } // namespace dart | 14403 } // namespace dart |
14367 | 14404 |
14368 #endif // DART_PRECOMPILED_RUNTIME | 14405 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |