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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 DECLARE_FLAG(bool, profile_vm); | 60 DECLARE_FLAG(bool, profile_vm); |
61 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 61 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
62 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 62 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
63 | 63 |
64 // Quick access to the current thread, isolate and zone. | 64 // Quick access to the current thread, isolate and zone. |
65 #define T (thread()) | 65 #define T (thread()) |
66 #define I (isolate()) | 66 #define I (isolate()) |
67 #define Z (zone()) | 67 #define Z (zone()) |
68 | 68 |
69 // Quick synthetic token position. | 69 // Quick synthetic token position. |
70 #define ST(token_pos) Token::ToSynthetic(token_pos) | 70 #define ST(token_pos) TokenDescriptor::ToSynthetic(token_pos) |
71 | 71 |
72 #if defined(DEBUG) | 72 #if defined(DEBUG) |
73 class TraceParser : public ValueObject { | 73 class TraceParser : public ValueObject { |
74 public: | 74 public: |
75 TraceParser(intptr_t token_pos, | 75 TraceParser(TokenDescriptor token_pos, |
76 const Script& script, | 76 const Script& script, |
77 intptr_t* trace_indent, | 77 intptr_t* trace_indent, |
78 const char* msg) { | 78 const char* msg) { |
79 indent_ = trace_indent; | 79 indent_ = trace_indent; |
80 if (FLAG_trace_parser) { | 80 if (FLAG_trace_parser) { |
81 // Skips tracing of bootstrap libraries. | 81 // Skips tracing of bootstrap libraries. |
82 if (script.HasSource()) { | 82 if (script.HasSource()) { |
83 intptr_t line, column; | 83 intptr_t line, column; |
84 script.GetTokenLocation(token_pos, &line, &column); | 84 script.GetTokenLocation(token_pos, &line, &column); |
85 PrintIndent(); | 85 PrintIndent(); |
86 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", | 86 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", |
87 msg, line, column, token_pos); | 87 msg, line, column, token_pos.value()); |
88 } | 88 } |
89 (*indent_)++; | 89 (*indent_)++; |
90 } | 90 } |
91 } | 91 } |
92 ~TraceParser() { | 92 ~TraceParser() { |
93 if (FLAG_trace_parser) { | 93 if (FLAG_trace_parser) { |
94 (*indent_)--; | 94 (*indent_)--; |
95 ASSERT(*indent_ >= 0); | 95 ASSERT(*indent_ >= 0); |
96 } | 96 } |
97 } | 97 } |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 &found_captured_variables); | 255 &found_captured_variables); |
256 | 256 |
257 // Frame indices are relative to the frame pointer and are decreasing. | 257 // Frame indices are relative to the frame pointer and are decreasing. |
258 ASSERT(next_free_frame_index <= first_stack_local_index_); | 258 ASSERT(next_free_frame_index <= first_stack_local_index_); |
259 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 259 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
260 } | 260 } |
261 | 261 |
262 | 262 |
263 struct CatchParamDesc { | 263 struct CatchParamDesc { |
264 CatchParamDesc() | 264 CatchParamDesc() |
265 : token_pos(Token::kNoSourcePos), type(NULL), name(NULL), var(NULL) { } | 265 : token_pos(TokenDescriptor::kNoSource), |
266 intptr_t token_pos; | 266 type(NULL), |
| 267 name(NULL), |
| 268 var(NULL) { } |
| 269 TokenDescriptor token_pos; |
267 const AbstractType* type; | 270 const AbstractType* type; |
268 const String* name; | 271 const String* name; |
269 LocalVariable* var; | 272 LocalVariable* var; |
270 }; | 273 }; |
271 | 274 |
272 | 275 |
273 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 276 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
274 ASSERT(function().IsIrregexpFunction()); | 277 ASSERT(function().IsIrregexpFunction()); |
275 ASSERT(function().NumOptionalParameters() == 0); | 278 ASSERT(function().NumOptionalParameters() == 0); |
276 const intptr_t num_params = function().num_fixed_parameters(); | 279 const intptr_t num_params = function().num_fixed_parameters(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 DISALLOW_COPY_AND_ASSIGN(TryStack); | 345 DISALLOW_COPY_AND_ASSIGN(TryStack); |
343 }; | 346 }; |
344 | 347 |
345 | 348 |
346 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { | 349 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { |
347 inlined_finally_nodes_.Add(node); | 350 inlined_finally_nodes_.Add(node); |
348 } | 351 } |
349 | 352 |
350 | 353 |
351 // For parsing a compilation unit. | 354 // For parsing a compilation unit. |
352 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 355 Parser::Parser(const Script& script, |
| 356 const Library& library, |
| 357 TokenDescriptor token_pos) |
353 : isolate_(Thread::Current()->isolate()), | 358 : isolate_(Thread::Current()->isolate()), |
354 thread_(Thread::Current()), | 359 thread_(Thread::Current()), |
355 script_(Script::Handle(zone(), script.raw())), | 360 script_(Script::Handle(zone(), script.raw())), |
356 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), | 361 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
357 token_pos), | 362 token_pos), |
358 token_kind_(Token::kILLEGAL), | 363 token_kind_(Token::kILLEGAL), |
359 current_block_(NULL), | 364 current_block_(NULL), |
360 is_top_level_(false), | 365 is_top_level_(false), |
361 await_is_keyword_(false), | 366 await_is_keyword_(false), |
362 current_member_(NULL), | 367 current_member_(NULL), |
(...skipping 10 matching lines...) Expand all Loading... |
373 trace_indent_(0), | 378 trace_indent_(0), |
374 recursion_counter_(0) { | 379 recursion_counter_(0) { |
375 ASSERT(tokens_iterator_.IsValid()); | 380 ASSERT(tokens_iterator_.IsValid()); |
376 ASSERT(!library.IsNull()); | 381 ASSERT(!library.IsNull()); |
377 } | 382 } |
378 | 383 |
379 | 384 |
380 // For parsing a function. | 385 // For parsing a function. |
381 Parser::Parser(const Script& script, | 386 Parser::Parser(const Script& script, |
382 ParsedFunction* parsed_function, | 387 ParsedFunction* parsed_function, |
383 intptr_t token_position) | 388 TokenDescriptor token_pos) |
384 : isolate_(Thread::Current()->isolate()), | 389 : isolate_(Thread::Current()->isolate()), |
385 thread_(Thread::Current()), | 390 thread_(Thread::Current()), |
386 script_(Script::Handle(zone(), script.raw())), | 391 script_(Script::Handle(zone(), script.raw())), |
387 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), | 392 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
388 token_position), | 393 token_pos), |
389 token_kind_(Token::kILLEGAL), | 394 token_kind_(Token::kILLEGAL), |
390 current_block_(NULL), | 395 current_block_(NULL), |
391 is_top_level_(false), | 396 is_top_level_(false), |
392 await_is_keyword_(false), | 397 await_is_keyword_(false), |
393 current_member_(NULL), | 398 current_member_(NULL), |
394 allow_function_literals_(true), | 399 allow_function_literals_(true), |
395 parsed_function_(parsed_function), | 400 parsed_function_(parsed_function), |
396 innermost_function_(Function::Handle(zone(), | 401 innermost_function_(Function::Handle(zone(), |
397 parsed_function->function().raw())), | 402 parsed_function->function().raw())), |
398 literal_token_(LiteralToken::Handle(zone())), | 403 literal_token_(LiteralToken::Handle(zone())), |
(...skipping 29 matching lines...) Expand all Loading... |
428 // Each try in this function gets its own try index. | 433 // Each try in this function gets its own try index. |
429 // See definition of RawPcDescriptors::PcDescriptor. | 434 // See definition of RawPcDescriptors::PcDescriptor. |
430 int16_t Parser::AllocateTryIndex() { | 435 int16_t Parser::AllocateTryIndex() { |
431 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 436 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
432 ReportError("too many nested try statements"); | 437 ReportError("too many nested try statements"); |
433 } | 438 } |
434 return last_used_try_index_++; | 439 return last_used_try_index_++; |
435 } | 440 } |
436 | 441 |
437 | 442 |
438 void Parser::SetScript(const Script& script, intptr_t token_pos) { | 443 void Parser::SetScript(const Script& script, TokenDescriptor token_pos) { |
439 script_ = script.raw(); | 444 script_ = script.raw(); |
440 tokens_iterator_.SetStream( | 445 tokens_iterator_.SetStream( |
441 TokenStream::Handle(Z, script.tokens()), token_pos); | 446 TokenStream::Handle(Z, script.tokens()), token_pos); |
442 token_kind_ = Token::kILLEGAL; | 447 token_kind_ = Token::kILLEGAL; |
443 } | 448 } |
444 | 449 |
445 | 450 |
446 bool Parser::SetAllowFunctionLiterals(bool value) { | 451 bool Parser::SetAllowFunctionLiterals(bool value) { |
447 bool current_value = allow_function_literals_; | 452 bool current_value = allow_function_literals_; |
448 allow_function_literals_ = value; | 453 allow_function_literals_ = value; |
(...skipping 18 matching lines...) Expand all Loading... |
467 | 472 |
468 | 473 |
469 void Parser::set_current_class(const Class& value) { | 474 void Parser::set_current_class(const Class& value) { |
470 current_class_ = value.raw(); | 475 current_class_ = value.raw(); |
471 } | 476 } |
472 | 477 |
473 | 478 |
474 void Parser::SetPosition(intptr_t position) { | 479 void Parser::SetPosition(intptr_t position) { |
475 tokens_iterator_.SetCurrentPosition(position); | 480 tokens_iterator_.SetCurrentPosition(position); |
476 token_kind_ = Token::kILLEGAL; | 481 token_kind_ = Token::kILLEGAL; |
| 482 prev_token_pos_ = TokenDescriptor(position); |
| 483 } |
| 484 |
| 485 |
| 486 void Parser::SetPosition(TokenDescriptor position) { |
| 487 tokens_iterator_.SetCurrentPosition(position.value()); |
| 488 token_kind_ = Token::kILLEGAL; |
477 prev_token_pos_ = position; | 489 prev_token_pos_ = position; |
478 } | 490 } |
479 | 491 |
480 | 492 |
481 void Parser::ParseCompilationUnit(const Library& library, | 493 void Parser::ParseCompilationUnit(const Library& library, |
482 const Script& script) { | 494 const Script& script) { |
483 Thread* thread = Thread::Current(); | 495 Thread* thread = Thread::Current(); |
484 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 496 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
485 CSTAT_TIMER_SCOPE(thread, parser_timer); | 497 CSTAT_TIMER_SCOPE(thread, parser_timer); |
486 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 498 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
487 TimelineDurationScope tds(thread, | 499 TimelineDurationScope tds(thread, |
488 thread->isolate()->GetCompilerStream(), | 500 thread->isolate()->GetCompilerStream(), |
489 "CompileTopLevel"); | 501 "CompileTopLevel"); |
490 if (tds.enabled()) { | 502 if (tds.enabled()) { |
491 tds.SetNumArguments(1); | 503 tds.SetNumArguments(1); |
492 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); | 504 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); |
493 } | 505 } |
494 | 506 |
495 Parser parser(script, library, 0); | 507 Parser parser(script, library, TokenDescriptor::kMinSource); |
496 parser.ParseTopLevel(); | 508 parser.ParseTopLevel(); |
497 } | 509 } |
498 | 510 |
499 | 511 |
500 void Parser::ComputeCurrentToken() { | 512 void Parser::ComputeCurrentToken() { |
501 ASSERT(token_kind_ == Token::kILLEGAL); | 513 ASSERT(token_kind_ == Token::kILLEGAL); |
502 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 514 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
503 if (token_kind_ == Token::kERROR) { | 515 if (token_kind_ == Token::kERROR) { |
504 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 516 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
505 } | 517 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 i.ToCString()); | 549 i.ToCString()); |
538 } | 550 } |
539 } | 551 } |
540 return ri; | 552 return ri; |
541 } | 553 } |
542 | 554 |
543 | 555 |
544 struct ParamDesc { | 556 struct ParamDesc { |
545 ParamDesc() | 557 ParamDesc() |
546 : type(NULL), | 558 : type(NULL), |
547 name_pos(Token::kNoSourcePos), | 559 name_pos(TokenDescriptor::kNoSource), |
548 name(NULL), | 560 name(NULL), |
549 default_value(NULL), | 561 default_value(NULL), |
550 metadata(NULL), | 562 metadata(NULL), |
551 var(NULL), | 563 var(NULL), |
552 is_final(false), | 564 is_final(false), |
553 is_field_initializer(false), | 565 is_field_initializer(false), |
554 has_explicit_type(false) { } | 566 has_explicit_type(false) { } |
555 const AbstractType* type; | 567 const AbstractType* type; |
556 intptr_t name_pos; | 568 TokenDescriptor name_pos; |
557 const String* name; | 569 const String* name; |
558 const Instance* default_value; // NULL if not an optional parameter. | 570 const Instance* default_value; // NULL if not an optional parameter. |
559 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 571 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
560 LocalVariable* var; // Scope variable allocated for this parameter. | 572 LocalVariable* var; // Scope variable allocated for this parameter. |
561 bool is_final; | 573 bool is_final; |
562 bool is_field_initializer; | 574 bool is_field_initializer; |
563 bool has_explicit_type; | 575 bool has_explicit_type; |
564 }; | 576 }; |
565 | 577 |
566 | 578 |
567 struct ParamList { | 579 struct ParamList { |
568 ParamList() { | 580 ParamList() { |
569 Clear(); | 581 Clear(); |
570 } | 582 } |
571 | 583 |
572 void Clear() { | 584 void Clear() { |
573 num_fixed_parameters = 0; | 585 num_fixed_parameters = 0; |
574 num_optional_parameters = 0; | 586 num_optional_parameters = 0; |
575 has_optional_positional_parameters = false; | 587 has_optional_positional_parameters = false; |
576 has_optional_named_parameters = false; | 588 has_optional_named_parameters = false; |
577 has_explicit_default_values = false; | 589 has_explicit_default_values = false; |
578 has_field_initializer = false; | 590 has_field_initializer = false; |
579 implicitly_final = false; | 591 implicitly_final = false; |
580 skipped = false; | 592 skipped = false; |
581 this->parameters = new ZoneGrowableArray<ParamDesc>(); | 593 this->parameters = new ZoneGrowableArray<ParamDesc>(); |
582 } | 594 } |
583 | 595 |
584 void AddFinalParameter(intptr_t name_pos, | 596 void AddFinalParameter(TokenDescriptor name_pos, |
585 const String* name, | 597 const String* name, |
586 const AbstractType* type) { | 598 const AbstractType* type) { |
587 this->num_fixed_parameters++; | 599 this->num_fixed_parameters++; |
588 ParamDesc param; | 600 ParamDesc param; |
589 param.name_pos = name_pos; | 601 param.name_pos = name_pos; |
590 param.name = name; | 602 param.name = name; |
591 param.is_final = true; | 603 param.is_final = true; |
592 param.type = type; | 604 param.type = type; |
593 this->parameters->Add(param); | 605 this->parameters->Add(param); |
594 } | 606 } |
595 | 607 |
596 void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) { | 608 void AddReceiver(const AbstractType* receiver_type, |
| 609 TokenDescriptor token_pos) { |
597 ASSERT(this->parameters->is_empty()); | 610 ASSERT(this->parameters->is_empty()); |
598 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); | 611 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); |
599 } | 612 } |
600 | 613 |
601 void EraseParameterTypes() { | 614 void EraseParameterTypes() { |
602 const int num_parameters = parameters->length(); | 615 const int num_parameters = parameters->length(); |
603 for (int i = 0; i < num_parameters; i++) { | 616 for (int i = 0; i < num_parameters; i++) { |
604 (*parameters)[i].type = &Object::dynamic_type(); | 617 (*parameters)[i].type = &Object::dynamic_type(); |
605 } | 618 } |
606 } | 619 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 void Clear() { | 655 void Clear() { |
643 has_abstract = false; | 656 has_abstract = false; |
644 has_external = false; | 657 has_external = false; |
645 has_final = false; | 658 has_final = false; |
646 has_const = false; | 659 has_const = false; |
647 has_static = false; | 660 has_static = false; |
648 has_var = false; | 661 has_var = false; |
649 has_factory = false; | 662 has_factory = false; |
650 has_operator = false; | 663 has_operator = false; |
651 has_native = false; | 664 has_native = false; |
652 metadata_pos = Token::kNoSourcePos; | 665 metadata_pos = TokenDescriptor::kNoSource; |
653 operator_token = Token::kILLEGAL; | 666 operator_token = Token::kILLEGAL; |
654 type = NULL; | 667 type = NULL; |
655 name_pos = Token::kNoSourcePos; | 668 name_pos = TokenDescriptor::kNoSource; |
656 name = NULL; | 669 name = NULL; |
657 redirect_name = NULL; | 670 redirect_name = NULL; |
658 dict_name = NULL; | 671 dict_name = NULL; |
659 params.Clear(); | 672 params.Clear(); |
660 kind = RawFunction::kRegularFunction; | 673 kind = RawFunction::kRegularFunction; |
661 field_ = NULL; | 674 field_ = NULL; |
662 } | 675 } |
663 | 676 |
664 bool IsConstructor() const { | 677 bool IsConstructor() const { |
665 return (kind == RawFunction::kConstructor) && !has_static; | 678 return (kind == RawFunction::kConstructor) && !has_static; |
(...skipping 29 matching lines...) Expand all Loading... |
695 } | 708 } |
696 bool has_abstract; | 709 bool has_abstract; |
697 bool has_external; | 710 bool has_external; |
698 bool has_final; | 711 bool has_final; |
699 bool has_const; | 712 bool has_const; |
700 bool has_static; | 713 bool has_static; |
701 bool has_var; | 714 bool has_var; |
702 bool has_factory; | 715 bool has_factory; |
703 bool has_operator; | 716 bool has_operator; |
704 bool has_native; | 717 bool has_native; |
705 intptr_t metadata_pos; | 718 TokenDescriptor metadata_pos; |
706 Token::Kind operator_token; | 719 Token::Kind operator_token; |
707 const AbstractType* type; | 720 const AbstractType* type; |
708 intptr_t name_pos; | 721 TokenDescriptor name_pos; |
709 intptr_t decl_begin_pos; | 722 TokenDescriptor decl_begin_pos; |
710 String* name; | 723 String* name; |
711 // For constructors: NULL or name of redirected to constructor. | 724 // For constructors: NULL or name of redirected to constructor. |
712 String* redirect_name; | 725 String* redirect_name; |
713 // dict_name is the name used for the class namespace, if it | 726 // dict_name is the name used for the class namespace, if it |
714 // differs from 'name'. | 727 // differs from 'name'. |
715 // For constructors: NULL for unnamed constructor, | 728 // For constructors: NULL for unnamed constructor, |
716 // identifier after classname for named constructors. | 729 // identifier after classname for named constructors. |
717 // For getters and setters: unmangled name. | 730 // For getters and setters: unmangled name. |
718 String* dict_name; | 731 String* dict_name; |
719 ParamList params; | 732 ParamList params; |
720 RawFunction::Kind kind; | 733 RawFunction::Kind kind; |
721 // NULL for functions, field object for static or instance fields. | 734 // NULL for functions, field object for static or instance fields. |
722 Field* field_; | 735 Field* field_; |
723 }; | 736 }; |
724 | 737 |
725 | 738 |
726 class ClassDesc : public ValueObject { | 739 class ClassDesc : public ValueObject { |
727 public: | 740 public: |
728 ClassDesc(Zone* zone, | 741 ClassDesc(Zone* zone, |
729 const Class& cls, | 742 const Class& cls, |
730 const String& cls_name, | 743 const String& cls_name, |
731 bool is_interface, | 744 bool is_interface, |
732 intptr_t token_pos) | 745 TokenDescriptor token_pos) |
733 : zone_(zone), | 746 : zone_(zone), |
734 clazz_(cls), | 747 clazz_(cls), |
735 class_name_(cls_name), | 748 class_name_(cls_name), |
736 token_pos_(token_pos), | 749 token_pos_(token_pos), |
737 functions_(zone, 4), | 750 functions_(zone, 4), |
738 fields_(zone, 4) { | 751 fields_(zone, 4) { |
739 } | 752 } |
740 | 753 |
741 void AddFunction(const Function& function) { | 754 void AddFunction(const Function& function) { |
742 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 755 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
(...skipping 22 matching lines...) Expand all Loading... |
765 bool has_constructor() const { | 778 bool has_constructor() const { |
766 for (int i = 0; i < functions_.length(); i++) { | 779 for (int i = 0; i < functions_.length(); i++) { |
767 const Function* func = functions_.At(i); | 780 const Function* func = functions_.At(i); |
768 if (func->kind() == RawFunction::kConstructor) { | 781 if (func->kind() == RawFunction::kConstructor) { |
769 return true; | 782 return true; |
770 } | 783 } |
771 } | 784 } |
772 return false; | 785 return false; |
773 } | 786 } |
774 | 787 |
775 intptr_t token_pos() const { | 788 TokenDescriptor token_pos() const { |
776 return token_pos_; | 789 return token_pos_; |
777 } | 790 } |
778 | 791 |
779 void AddMember(const MemberDesc& member) { | 792 void AddMember(const MemberDesc& member) { |
780 members_.Add(member); | 793 members_.Add(member); |
781 } | 794 } |
782 | 795 |
783 const GrowableArray<MemberDesc>& members() const { | 796 const GrowableArray<MemberDesc>& members() const { |
784 return members_; | 797 return members_; |
785 } | 798 } |
(...skipping 13 matching lines...) Expand all Loading... |
799 for (intptr_t i = 0; i < len; i++) { | 812 for (intptr_t i = 0; i < len; i++) { |
800 res.SetAt(i, *functions_[i]); | 813 res.SetAt(i, *functions_[i]); |
801 } | 814 } |
802 return res.raw(); | 815 return res.raw(); |
803 } | 816 } |
804 | 817 |
805 private: | 818 private: |
806 Zone* zone_; | 819 Zone* zone_; |
807 const Class& clazz_; | 820 const Class& clazz_; |
808 const String& class_name_; | 821 const String& class_name_; |
809 intptr_t token_pos_; // Token index of "class" keyword. | 822 TokenDescriptor token_pos_; // Token index of "class" keyword. |
810 GrowableArray<const Function*> functions_; | 823 GrowableArray<const Function*> functions_; |
811 GrowableArray<const Field*> fields_; | 824 GrowableArray<const Field*> fields_; |
812 GrowableArray<MemberDesc> members_; | 825 GrowableArray<MemberDesc> members_; |
813 }; | 826 }; |
814 | 827 |
815 | 828 |
816 class TopLevel : public ValueObject { | 829 class TopLevel : public ValueObject { |
817 public: | 830 public: |
818 explicit TopLevel(Zone* zone) : | 831 explicit TopLevel(Zone* zone) : |
819 zone_(zone), | 832 zone_(zone), |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 | 1074 |
1062 | 1075 |
1063 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 1076 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
1064 LongJumpScope jump; | 1077 LongJumpScope jump; |
1065 if (setjmp(*jump.Set()) == 0) { | 1078 if (setjmp(*jump.Set()) == 0) { |
1066 Thread* thread = Thread::Current(); | 1079 Thread* thread = Thread::Current(); |
1067 StackZone stack_zone(thread); | 1080 StackZone stack_zone(thread); |
1068 Zone* zone = stack_zone.GetZone(); | 1081 Zone* zone = stack_zone.GetZone(); |
1069 const Class& owner_class = Class::Handle(zone, meta_data.owner()); | 1082 const Class& owner_class = Class::Handle(zone, meta_data.owner()); |
1070 const Script& script = Script::Handle(zone, meta_data.script()); | 1083 const Script& script = Script::Handle(zone, meta_data.script()); |
1071 const intptr_t token_pos = meta_data.token_pos(); | 1084 const TokenDescriptor token_pos = meta_data.token_pos(); |
1072 // Parsing metadata can involve following paths in the parser that are | 1085 // Parsing metadata can involve following paths in the parser that are |
1073 // normally used for expressions and assume current_function is non-null, | 1086 // normally used for expressions and assume current_function is non-null, |
1074 // so we create a fake function to use as the current_function rather than | 1087 // so we create a fake function to use as the current_function rather than |
1075 // scattering special cases throughout the parser. | 1088 // scattering special cases throughout the parser. |
1076 const Function& fake_function = Function::ZoneHandle(zone, Function::New( | 1089 const Function& fake_function = Function::ZoneHandle(zone, Function::New( |
1077 Symbols::At(), | 1090 Symbols::At(), |
1078 RawFunction::kRegularFunction, | 1091 RawFunction::kRegularFunction, |
1079 true, // is_static | 1092 true, // is_static |
1080 false, // is_const | 1093 false, // is_const |
1081 false, // is_abstract | 1094 false, // is_abstract |
(...skipping 24 matching lines...) Expand all Loading... |
1106 return Object::null(); | 1119 return Object::null(); |
1107 } | 1120 } |
1108 | 1121 |
1109 | 1122 |
1110 RawArray* Parser::EvaluateMetadata() { | 1123 RawArray* Parser::EvaluateMetadata() { |
1111 CheckToken(Token::kAT, "Metadata character '@' expected"); | 1124 CheckToken(Token::kAT, "Metadata character '@' expected"); |
1112 GrowableObjectArray& meta_values = | 1125 GrowableObjectArray& meta_values = |
1113 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 1126 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
1114 while (CurrentToken() == Token::kAT) { | 1127 while (CurrentToken() == Token::kAT) { |
1115 ConsumeToken(); | 1128 ConsumeToken(); |
1116 intptr_t expr_pos = TokenPos(); | 1129 TokenDescriptor expr_pos = TokenPos(); |
1117 if (!IsIdentifier()) { | 1130 if (!IsIdentifier()) { |
1118 ExpectIdentifier("identifier expected"); | 1131 ExpectIdentifier("identifier expected"); |
1119 } | 1132 } |
1120 // Reject expressions with deferred library prefix eagerly. | 1133 // Reject expressions with deferred library prefix eagerly. |
1121 Object& obj = | 1134 Object& obj = |
1122 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); | 1135 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); |
1123 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 1136 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
1124 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 1137 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
1125 ReportError("Metadata must be compile-time constant"); | 1138 ReportError("Metadata must be compile-time constant"); |
1126 } | 1139 } |
(...skipping 23 matching lines...) Expand all Loading... |
1150 } | 1163 } |
1151 } | 1164 } |
1152 if (CurrentToken() == Token::kPERIOD) { | 1165 if (CurrentToken() == Token::kPERIOD) { |
1153 // C.x or L.C.X. | 1166 // C.x or L.C.X. |
1154 if (cls.IsNull()) { | 1167 if (cls.IsNull()) { |
1155 ReportError(expr_pos, | 1168 ReportError(expr_pos, |
1156 "Metadata expressions must refer to a const field " | 1169 "Metadata expressions must refer to a const field " |
1157 "or constructor"); | 1170 "or constructor"); |
1158 } | 1171 } |
1159 ConsumeToken(); | 1172 ConsumeToken(); |
1160 const intptr_t ident_pos = TokenPos(); | 1173 const TokenDescriptor ident_pos = TokenPos(); |
1161 String* ident = ExpectIdentifier("identifier expected"); | 1174 String* ident = ExpectIdentifier("identifier expected"); |
1162 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); | 1175 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); |
1163 if (field.IsNull()) { | 1176 if (field.IsNull()) { |
1164 ReportError(ident_pos, | 1177 ReportError(ident_pos, |
1165 "Class '%s' has no field '%s'", | 1178 "Class '%s' has no field '%s'", |
1166 cls.ToCString(), | 1179 cls.ToCString(), |
1167 ident->ToCString()); | 1180 ident->ToCString()); |
1168 } | 1181 } |
1169 if (!field.is_const()) { | 1182 if (!field.is_const()) { |
1170 ReportError(ident_pos, | 1183 ReportError(ident_pos, |
(...skipping 12 matching lines...) Expand all Loading... |
1183 } | 1196 } |
1184 return Array::MakeArray(meta_values); | 1197 return Array::MakeArray(meta_values); |
1185 } | 1198 } |
1186 | 1199 |
1187 | 1200 |
1188 SequenceNode* Parser::ParseStaticInitializer() { | 1201 SequenceNode* Parser::ParseStaticInitializer() { |
1189 ExpectIdentifier("field name expected"); | 1202 ExpectIdentifier("field name expected"); |
1190 CheckToken(Token::kASSIGN, "field initialier expected"); | 1203 CheckToken(Token::kASSIGN, "field initialier expected"); |
1191 ConsumeToken(); | 1204 ConsumeToken(); |
1192 OpenFunctionBlock(parsed_function()->function()); | 1205 OpenFunctionBlock(parsed_function()->function()); |
1193 intptr_t expr_pos = TokenPos(); | 1206 TokenDescriptor expr_pos = TokenPos(); |
1194 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1207 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1195 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); | 1208 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); |
1196 current_block_->statements->Add(ret); | 1209 current_block_->statements->Add(ret); |
1197 return CloseBlock(); | 1210 return CloseBlock(); |
1198 } | 1211 } |
1199 | 1212 |
1200 | 1213 |
1201 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1214 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
1202 ASSERT(field.is_static()); | 1215 ASSERT(field.is_static()); |
1203 Thread* thread = Thread::Current(); | 1216 Thread* thread = Thread::Current(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 TRACE_PARSER("ParseStaticFinalGetter"); | 1270 TRACE_PARSER("ParseStaticFinalGetter"); |
1258 ParamList params; | 1271 ParamList params; |
1259 ASSERT(func.num_fixed_parameters() == 0); // static. | 1272 ASSERT(func.num_fixed_parameters() == 0); // static. |
1260 ASSERT(!func.HasOptionalParameters()); | 1273 ASSERT(!func.HasOptionalParameters()); |
1261 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1274 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
1262 | 1275 |
1263 // Build local scope for function and populate with the formal parameters. | 1276 // Build local scope for function and populate with the formal parameters. |
1264 OpenFunctionBlock(func); | 1277 OpenFunctionBlock(func); |
1265 AddFormalParamsToScope(¶ms, current_block_->scope); | 1278 AddFormalParamsToScope(¶ms, current_block_->scope); |
1266 | 1279 |
1267 intptr_t ident_pos = TokenPos(); | 1280 TokenDescriptor ident_pos = TokenPos(); |
1268 const String& field_name = *ExpectIdentifier("field name expected"); | 1281 const String& field_name = *ExpectIdentifier("field name expected"); |
1269 const Class& field_class = Class::Handle(Z, func.Owner()); | 1282 const Class& field_class = Class::Handle(Z, func.Owner()); |
1270 const Field& field = | 1283 const Field& field = |
1271 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); | 1284 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); |
1272 ASSERT(!field.IsNull()); | 1285 ASSERT(!field.IsNull()); |
1273 | 1286 |
1274 // Static final fields must have an initializer. | 1287 // Static final fields must have an initializer. |
1275 ExpectToken(Token::kASSIGN); | 1288 ExpectToken(Token::kASSIGN); |
1276 | 1289 |
1277 const intptr_t expr_pos = TokenPos(); | 1290 const TokenDescriptor expr_pos = TokenPos(); |
1278 if (field.is_const()) { | 1291 if (field.is_const()) { |
1279 // We don't want to use ParseConstExpr() here because we don't want | 1292 // We don't want to use ParseConstExpr() here because we don't want |
1280 // the constant folding code to create, compile and execute a code | 1293 // the constant folding code to create, compile and execute a code |
1281 // fragment to evaluate the expression. Instead, we just make sure | 1294 // fragment to evaluate the expression. Instead, we just make sure |
1282 // the static const field initializer is a constant expression and | 1295 // the static const field initializer is a constant expression and |
1283 // leave the evaluation to the getter function. | 1296 // leave the evaluation to the getter function. |
1284 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1297 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
1285 // This getter will only be called once at compile time. | 1298 // This getter will only be called once at compile time. |
1286 if (expr->EvalConstExpr() == NULL) { | 1299 if (expr->EvalConstExpr() == NULL) { |
1287 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1300 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
(...skipping 17 matching lines...) Expand all Loading... |
1305 | 1318 |
1306 | 1319 |
1307 // Create AstNodes for an implicit instance getter method: | 1320 // Create AstNodes for an implicit instance getter method: |
1308 // LoadLocalNode 0 ('this'); | 1321 // LoadLocalNode 0 ('this'); |
1309 // LoadInstanceFieldNode (field_name); | 1322 // LoadInstanceFieldNode (field_name); |
1310 // ReturnNode (field's value); | 1323 // ReturnNode (field's value); |
1311 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1324 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
1312 TRACE_PARSER("ParseInstanceGetter"); | 1325 TRACE_PARSER("ParseInstanceGetter"); |
1313 ParamList params; | 1326 ParamList params; |
1314 // func.token_pos() points to the name of the field. | 1327 // func.token_pos() points to the name of the field. |
1315 const intptr_t ident_pos = func.token_pos(); | 1328 const TokenDescriptor ident_pos = func.token_pos(); |
1316 ASSERT(current_class().raw() == func.Owner()); | 1329 ASSERT(current_class().raw() == func.Owner()); |
1317 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1330 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1318 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 1331 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
1319 ASSERT(!func.HasOptionalParameters()); | 1332 ASSERT(!func.HasOptionalParameters()); |
1320 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1333 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
1321 | 1334 |
1322 // Build local scope for function and populate with the formal parameters. | 1335 // Build local scope for function and populate with the formal parameters. |
1323 OpenFunctionBlock(func); | 1336 OpenFunctionBlock(func); |
1324 AddFormalParamsToScope(¶ms, current_block_->scope); | 1337 AddFormalParamsToScope(¶ms, current_block_->scope); |
1325 | 1338 |
(...skipping 18 matching lines...) Expand all Loading... |
1344 | 1357 |
1345 | 1358 |
1346 // Create AstNodes for an implicit instance setter method: | 1359 // Create AstNodes for an implicit instance setter method: |
1347 // LoadLocalNode 0 ('this') | 1360 // LoadLocalNode 0 ('this') |
1348 // LoadLocalNode 1 ('value') | 1361 // LoadLocalNode 1 ('value') |
1349 // SetInstanceField (field_name); | 1362 // SetInstanceField (field_name); |
1350 // ReturnNode (void); | 1363 // ReturnNode (void); |
1351 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1364 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
1352 TRACE_PARSER("ParseInstanceSetter"); | 1365 TRACE_PARSER("ParseInstanceSetter"); |
1353 // func.token_pos() points to the name of the field. | 1366 // func.token_pos() points to the name of the field. |
1354 const intptr_t ident_pos = func.token_pos(); | 1367 const TokenDescriptor ident_pos = func.token_pos(); |
1355 const String& field_name = *CurrentLiteral(); | 1368 const String& field_name = *CurrentLiteral(); |
1356 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); | 1369 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); |
1357 const Field& field = | 1370 const Field& field = |
1358 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1371 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
1359 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1372 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
1360 | 1373 |
1361 ParamList params; | 1374 ParamList params; |
1362 ASSERT(current_class().raw() == func.Owner()); | 1375 ASSERT(current_class().raw() == func.Owner()); |
1363 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1376 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1364 params.AddFinalParameter(ident_pos, | 1377 params.AddFinalParameter(ident_pos, |
(...skipping 16 matching lines...) Expand all Loading... |
1381 StoreInstanceFieldNode* store_field = | 1394 StoreInstanceFieldNode* store_field = |
1382 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1395 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
1383 current_block_->statements->Add(store_field); | 1396 current_block_->statements->Add(store_field); |
1384 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); | 1397 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); |
1385 return CloseBlock(); | 1398 return CloseBlock(); |
1386 } | 1399 } |
1387 | 1400 |
1388 | 1401 |
1389 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1402 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
1390 TRACE_PARSER("ParseConstructorClosure"); | 1403 TRACE_PARSER("ParseConstructorClosure"); |
1391 const intptr_t token_pos = func.token_pos(); | 1404 const TokenDescriptor token_pos = func.token_pos(); |
1392 | 1405 |
1393 Function& constructor = Function::ZoneHandle(Z); | 1406 Function& constructor = Function::ZoneHandle(Z); |
1394 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1407 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
1395 ParseConstructorClosurization(&constructor, &type_args); | 1408 ParseConstructorClosurization(&constructor, &type_args); |
1396 ASSERT(!constructor.IsNull()); | 1409 ASSERT(!constructor.IsNull()); |
1397 | 1410 |
1398 ParamList params; | 1411 ParamList params; |
1399 // The first parameter of the closure function is the | 1412 // The first parameter of the closure function is the |
1400 // implicit closure argument. | 1413 // implicit closure argument. |
1401 params.AddFinalParameter(token_pos, | 1414 params.AddFinalParameter(token_pos, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 AstNode* new_object = | 1448 AstNode* new_object = |
1436 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); | 1449 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); |
1437 ReturnNode* return_node = new ReturnNode(token_pos, new_object); | 1450 ReturnNode* return_node = new ReturnNode(token_pos, new_object); |
1438 current_block_->statements->Add(return_node); | 1451 current_block_->statements->Add(return_node); |
1439 return CloseBlock(); | 1452 return CloseBlock(); |
1440 } | 1453 } |
1441 | 1454 |
1442 | 1455 |
1443 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { | 1456 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { |
1444 TRACE_PARSER("ParseImplicitClosure"); | 1457 TRACE_PARSER("ParseImplicitClosure"); |
1445 intptr_t token_pos = func.token_pos(); | 1458 TokenDescriptor token_pos = func.token_pos(); |
1446 | 1459 |
1447 OpenFunctionBlock(func); | 1460 OpenFunctionBlock(func); |
1448 | 1461 |
1449 ParamList params; | 1462 ParamList params; |
1450 params.AddFinalParameter( | 1463 params.AddFinalParameter( |
1451 token_pos, | 1464 token_pos, |
1452 &Symbols::ClosureParameter(), | 1465 &Symbols::ClosureParameter(), |
1453 &Object::dynamic_type()); | 1466 &Object::dynamic_type()); |
1454 | 1467 |
1455 const Function& parent = Function::ZoneHandle(func.parent_function()); | 1468 const Function& parent = Function::ZoneHandle(func.parent_function()); |
1456 if (parent.IsImplicitSetterFunction()) { | 1469 if (parent.IsImplicitSetterFunction()) { |
1457 const intptr_t ident_pos = func.token_pos(); | 1470 const TokenDescriptor ident_pos = func.token_pos(); |
1458 ASSERT(IsIdentifier()); | 1471 ASSERT(IsIdentifier()); |
1459 const String& field_name = *CurrentLiteral(); | 1472 const String& field_name = *CurrentLiteral(); |
1460 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); | 1473 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); |
1461 const Field& field = | 1474 const Field& field = |
1462 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1475 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
1463 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1476 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
1464 params.AddFinalParameter(ident_pos, | 1477 params.AddFinalParameter(ident_pos, |
1465 &Symbols::Value(), | 1478 &Symbols::Value(), |
1466 &field_type); | 1479 &field_type); |
1467 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | 1480 ASSERT(func.num_fixed_parameters() == 2); // closure, value. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 current_block_->statements->Add(return_node); | 1514 current_block_->statements->Add(return_node); |
1502 return CloseBlock(); | 1515 return CloseBlock(); |
1503 } | 1516 } |
1504 | 1517 |
1505 | 1518 |
1506 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1519 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
1507 TRACE_PARSER("ParseMethodExtractor"); | 1520 TRACE_PARSER("ParseMethodExtractor"); |
1508 | 1521 |
1509 ParamList params; | 1522 ParamList params; |
1510 | 1523 |
1511 const intptr_t ident_pos = func.token_pos(); | 1524 const TokenDescriptor ident_pos = func.token_pos(); |
1512 ASSERT(func.token_pos() == ClassifyingTokenPositions::kMethodExtractor); | 1525 ASSERT(func.token_pos() == TokenDescriptor::kMethodExtractor); |
1513 ASSERT(current_class().raw() == func.Owner()); | 1526 ASSERT(current_class().raw() == func.Owner()); |
1514 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1527 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
1515 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1528 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
1516 ASSERT(!func.HasOptionalParameters()); | 1529 ASSERT(!func.HasOptionalParameters()); |
1517 | 1530 |
1518 // Build local scope for function and populate with the formal parameters. | 1531 // Build local scope for function and populate with the formal parameters. |
1519 OpenFunctionBlock(func); | 1532 OpenFunctionBlock(func); |
1520 AddFormalParamsToScope(¶ms, current_block_->scope); | 1533 AddFormalParamsToScope(¶ms, current_block_->scope); |
1521 | 1534 |
1522 // Receiver is local 0. | 1535 // Receiver is local 0. |
1523 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1536 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1524 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1537 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
1525 | 1538 |
1526 ClosureNode* closure = new ClosureNode( | 1539 ClosureNode* closure = new ClosureNode( |
1527 ident_pos, | 1540 ident_pos, |
1528 Function::ZoneHandle(Z, func.extracted_method_closure()), | 1541 Function::ZoneHandle(Z, func.extracted_method_closure()), |
1529 load_receiver, | 1542 load_receiver, |
1530 NULL); | 1543 NULL); |
1531 | 1544 |
1532 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1545 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
1533 current_block_->statements->Add(return_node); | 1546 current_block_->statements->Add(return_node); |
1534 return CloseBlock(); | 1547 return CloseBlock(); |
1535 } | 1548 } |
1536 | 1549 |
1537 | 1550 |
1538 void Parser::BuildDispatcherScope(const Function& func, | 1551 void Parser::BuildDispatcherScope(const Function& func, |
1539 const ArgumentsDescriptor& desc) { | 1552 const ArgumentsDescriptor& desc) { |
1540 ParamList params; | 1553 ParamList params; |
1541 // Receiver first. | 1554 // Receiver first. |
1542 intptr_t token_pos = func.token_pos(); | 1555 TokenDescriptor token_pos = func.token_pos(); |
1543 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1556 params.AddReceiver(ReceiverType(current_class()), token_pos); |
1544 // Remaining positional parameters. | 1557 // Remaining positional parameters. |
1545 intptr_t i = 1; | 1558 intptr_t i = 1; |
1546 for (; i < desc.PositionalCount(); ++i) { | 1559 for (; i < desc.PositionalCount(); ++i) { |
1547 ParamDesc p; | 1560 ParamDesc p; |
1548 char name[64]; | 1561 char name[64]; |
1549 OS::SNPrint(name, 64, ":p%" Pd, i); | 1562 OS::SNPrint(name, 64, ":p%" Pd, i); |
1550 p.name = &String::ZoneHandle(Z, Symbols::New(name)); | 1563 p.name = &String::ZoneHandle(Z, Symbols::New(name)); |
1551 p.type = &Object::dynamic_type(); | 1564 p.type = &Object::dynamic_type(); |
1552 params.parameters->Add(p); | 1565 params.parameters->Add(p); |
(...skipping 19 matching lines...) Expand all Loading... |
1572 // Build local scope for function and populate with the formal parameters. | 1585 // Build local scope for function and populate with the formal parameters. |
1573 OpenFunctionBlock(func); | 1586 OpenFunctionBlock(func); |
1574 AddFormalParamsToScope(¶ms, current_block_->scope); | 1587 AddFormalParamsToScope(¶ms, current_block_->scope); |
1575 } | 1588 } |
1576 | 1589 |
1577 | 1590 |
1578 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { | 1591 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { |
1579 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1592 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
1580 ASSERT(FLAG_lazy_dispatchers); | 1593 ASSERT(FLAG_lazy_dispatchers); |
1581 ASSERT(func.IsNoSuchMethodDispatcher()); | 1594 ASSERT(func.IsNoSuchMethodDispatcher()); |
1582 intptr_t token_pos = func.token_pos(); | 1595 TokenDescriptor token_pos = func.token_pos(); |
1583 ASSERT(func.token_pos() == 0); | 1596 ASSERT(func.token_pos() == TokenDescriptor::kMinSource); |
1584 ASSERT(current_class().raw() == func.Owner()); | 1597 ASSERT(current_class().raw() == func.Owner()); |
1585 | 1598 |
1586 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); | 1599 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); |
1587 ASSERT(desc.Count() > 0); | 1600 ASSERT(desc.Count() > 0); |
1588 | 1601 |
1589 // Set up scope for this function. | 1602 // Set up scope for this function. |
1590 BuildDispatcherScope(func, desc); | 1603 BuildDispatcherScope(func, desc); |
1591 | 1604 |
1592 // Receiver is local 0. | 1605 // Receiver is local 0. |
1593 LocalScope* scope = current_block_->scope; | 1606 LocalScope* scope = current_block_->scope; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 | 1640 |
1628 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1641 ReturnNode* return_node = new ReturnNode(token_pos, call); |
1629 current_block_->statements->Add(return_node); | 1642 current_block_->statements->Add(return_node); |
1630 return CloseBlock(); | 1643 return CloseBlock(); |
1631 } | 1644 } |
1632 | 1645 |
1633 | 1646 |
1634 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { | 1647 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
1635 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1648 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
1636 ASSERT(func.IsInvokeFieldDispatcher()); | 1649 ASSERT(func.IsInvokeFieldDispatcher()); |
1637 intptr_t token_pos = func.token_pos(); | 1650 TokenDescriptor token_pos = func.token_pos(); |
1638 ASSERT(func.token_pos() == 0); | 1651 ASSERT(func.token_pos() == TokenDescriptor::kMinSource); |
1639 ASSERT(current_class().raw() == func.Owner()); | 1652 ASSERT(current_class().raw() == func.Owner()); |
1640 | 1653 |
1641 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); | 1654 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
1642 ArgumentsDescriptor desc(args_desc); | 1655 ArgumentsDescriptor desc(args_desc); |
1643 ASSERT(desc.Count() > 0); | 1656 ASSERT(desc.Count() > 0); |
1644 | 1657 |
1645 // Set up scope for this function. | 1658 // Set up scope for this function. |
1646 BuildDispatcherScope(func, desc); | 1659 BuildDispatcherScope(func, desc); |
1647 | 1660 |
1648 // Receiver is local 0. | 1661 // Receiver is local 0. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 } else { | 1702 } else { |
1690 result = BuildClosureCall(token_pos, function_object, args); | 1703 result = BuildClosureCall(token_pos, function_object, args); |
1691 } | 1704 } |
1692 | 1705 |
1693 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1706 ReturnNode* return_node = new ReturnNode(token_pos, result); |
1694 current_block_->statements->Add(return_node); | 1707 current_block_->statements->Add(return_node); |
1695 return CloseBlock(); | 1708 return CloseBlock(); |
1696 } | 1709 } |
1697 | 1710 |
1698 | 1711 |
1699 AstNode* Parser::BuildClosureCall(intptr_t token_pos, | 1712 AstNode* Parser::BuildClosureCall(TokenDescriptor token_pos, |
1700 AstNode* closure, | 1713 AstNode* closure, |
1701 ArgumentListNode* arguments) { | 1714 ArgumentListNode* arguments) { |
1702 return new InstanceCallNode(token_pos, | 1715 return new InstanceCallNode(token_pos, |
1703 closure, | 1716 closure, |
1704 Symbols::Call(), | 1717 Symbols::Call(), |
1705 arguments); | 1718 arguments); |
1706 } | 1719 } |
1707 | 1720 |
1708 | 1721 |
1709 void Parser::SkipToMatching() { | 1722 void Parser::SkipToMatching() { |
1710 Token::Kind opening_token = CurrentToken(); | 1723 Token::Kind opening_token = CurrentToken(); |
1711 ASSERT((opening_token == Token::kLBRACE) || | 1724 ASSERT((opening_token == Token::kLBRACE) || |
1712 (opening_token == Token::kLPAREN)); | 1725 (opening_token == Token::kLPAREN)); |
1713 GrowableArray<Token::Kind> token_stack(8); | 1726 GrowableArray<Token::Kind> token_stack(8); |
1714 GrowableArray<intptr_t> token_pos_stack(8); | 1727 GrowableArray<TokenDescriptor> token_pos_stack(8); |
1715 // Adding the first opening brace here, because it will be consumed | 1728 // Adding the first opening brace here, because it will be consumed |
1716 // in the loop right away. | 1729 // in the loop right away. |
1717 token_stack.Add(opening_token); | 1730 token_stack.Add(opening_token); |
1718 const intptr_t start_pos = TokenPos(); | 1731 const TokenDescriptor start_pos = TokenPos(); |
1719 intptr_t opening_pos = start_pos; | 1732 TokenDescriptor opening_pos = start_pos; |
1720 token_pos_stack.Add(start_pos); | 1733 token_pos_stack.Add(start_pos); |
1721 bool is_match = true; | 1734 bool is_match = true; |
1722 bool unexpected_token_found = false; | 1735 bool unexpected_token_found = false; |
1723 Token::Kind token = opening_token; | 1736 Token::Kind token = opening_token; |
1724 intptr_t token_pos; | 1737 TokenDescriptor token_pos; |
1725 do { | 1738 do { |
1726 ConsumeToken(); | 1739 ConsumeToken(); |
1727 token = CurrentToken(); | 1740 token = CurrentToken(); |
1728 token_pos = TokenPos(); | 1741 token_pos = TokenPos(); |
1729 switch (token) { | 1742 switch (token) { |
1730 case Token::kLBRACE: | 1743 case Token::kLBRACE: |
1731 case Token::kLPAREN: | 1744 case Token::kLPAREN: |
1732 case Token::kLBRACK: | 1745 case Token::kLBRACK: |
1733 token_stack.Add(token); | 1746 token_stack.Add(token); |
1734 token_pos_stack.Add(token_pos); | 1747 token_pos_stack.Add(token_pos); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1905 const bool no_explicit_default_values = false; | 1918 const bool no_explicit_default_values = false; |
1906 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 1919 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
1907 | 1920 |
1908 // In top-level and mixin functions, the source may be in a different | 1921 // In top-level and mixin functions, the source may be in a different |
1909 // script than the script of the current class. However, we never reparse | 1922 // script than the script of the current class. However, we never reparse |
1910 // signature functions (except typedef signature functions), therefore | 1923 // signature functions (except typedef signature functions), therefore |
1911 // we do not need to keep the correct script via a patch class. Use the | 1924 // we do not need to keep the correct script via a patch class. Use the |
1912 // actual current class as owner of the signature function. | 1925 // actual current class as owner of the signature function. |
1913 const Function& signature_function = Function::Handle(Z, | 1926 const Function& signature_function = Function::Handle(Z, |
1914 Function::NewSignatureFunction(current_class(), | 1927 Function::NewSignatureFunction(current_class(), |
1915 Token::kNoSourcePos)); | 1928 TokenDescriptor::kNoSource)); |
1916 signature_function.set_result_type(result_type); | 1929 signature_function.set_result_type(result_type); |
1917 AddFormalParamsToFunction(&func_params, signature_function); | 1930 AddFormalParamsToFunction(&func_params, signature_function); |
1918 FunctionType& signature_type = | 1931 FunctionType& signature_type = |
1919 FunctionType::ZoneHandle(Z, signature_function.SignatureType()); | 1932 FunctionType::ZoneHandle(Z, signature_function.SignatureType()); |
1920 if (!is_top_level_) { | 1933 if (!is_top_level_) { |
1921 signature_type ^= ClassFinalizer::FinalizeType( | 1934 signature_type ^= ClassFinalizer::FinalizeType( |
1922 current_class(), signature_type, ClassFinalizer::kCanonicalize); | 1935 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
1923 signature_function.SetSignatureType(signature_type); | 1936 signature_function.SetSignatureType(signature_type); |
1924 } | 1937 } |
1925 ASSERT(is_top_level_ || signature_type.IsFinalized()); | 1938 ASSERT(is_top_level_ || signature_type.IsFinalized()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 String& native_name = *CurrentLiteral(); | 2059 String& native_name = *CurrentLiteral(); |
2047 ConsumeToken(); | 2060 ConsumeToken(); |
2048 return native_name; | 2061 return native_name; |
2049 } | 2062 } |
2050 | 2063 |
2051 | 2064 |
2052 // Resolve and return the dynamic function of the given name in the superclass. | 2065 // Resolve and return the dynamic function of the given name in the superclass. |
2053 // If it is not found, and resolve_getter is true, try to resolve a getter of | 2066 // If it is not found, and resolve_getter is true, try to resolve a getter of |
2054 // the same name. If it is still not found, return noSuchMethod and | 2067 // the same name. If it is still not found, return noSuchMethod and |
2055 // set is_no_such_method to true.. | 2068 // set is_no_such_method to true.. |
2056 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 2069 RawFunction* Parser::GetSuperFunction(TokenDescriptor token_pos, |
2057 const String& name, | 2070 const String& name, |
2058 ArgumentListNode* arguments, | 2071 ArgumentListNode* arguments, |
2059 bool resolve_getter, | 2072 bool resolve_getter, |
2060 bool* is_no_such_method) { | 2073 bool* is_no_such_method) { |
2061 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); | 2074 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
2062 if (super_class.IsNull()) { | 2075 if (super_class.IsNull()) { |
2063 ReportError(token_pos, "class '%s' does not have a superclass", | 2076 ReportError(token_pos, "class '%s' does not have a superclass", |
2064 String::Handle(Z, current_class().Name()).ToCString()); | 2077 String::Handle(Z, current_class().Name()).ToCString()); |
2065 } | 2078 } |
2066 Function& super_func = Function::Handle(Z, | 2079 Function& super_func = Function::Handle(Z, |
(...skipping 15 matching lines...) Expand all Loading... |
2082 ASSERT(!super_func.IsNull()); | 2095 ASSERT(!super_func.IsNull()); |
2083 *is_no_such_method = true; | 2096 *is_no_such_method = true; |
2084 } else { | 2097 } else { |
2085 *is_no_such_method = false; | 2098 *is_no_such_method = false; |
2086 } | 2099 } |
2087 return super_func.raw(); | 2100 return super_func.raw(); |
2088 } | 2101 } |
2089 | 2102 |
2090 | 2103 |
2091 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 2104 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
2092 intptr_t call_pos, | 2105 TokenDescriptor call_pos, |
2093 const String& function_name, | 2106 const String& function_name, |
2094 const ArgumentListNode& function_args, | 2107 const ArgumentListNode& function_args, |
2095 const LocalVariable* temp_for_last_arg, | 2108 const LocalVariable* temp_for_last_arg, |
2096 bool is_super_invocation) { | 2109 bool is_super_invocation) { |
2097 const intptr_t args_pos = function_args.token_pos(); | 2110 const TokenDescriptor args_pos = function_args.token_pos(); |
2098 // Build arguments to the call to the static | 2111 // Build arguments to the call to the static |
2099 // InvocationMirror._allocateInvocationMirror method. | 2112 // InvocationMirror._allocateInvocationMirror method. |
2100 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2113 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2101 // The first argument is the original function name. | 2114 // The first argument is the original function name. |
2102 arguments->Add(new LiteralNode(args_pos, function_name)); | 2115 arguments->Add(new LiteralNode(args_pos, function_name)); |
2103 // The second argument is the arguments descriptor of the original function. | 2116 // The second argument is the arguments descriptor of the original function. |
2104 const Array& args_descriptor = | 2117 const Array& args_descriptor = |
2105 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 2118 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), |
2106 function_args.names())); | 2119 function_args.names())); |
2107 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 2120 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
(...skipping 23 matching lines...) Expand all Loading... |
2131 ASSERT(!mirror_class.IsNull()); | 2144 ASSERT(!mirror_class.IsNull()); |
2132 const Function& allocation_function = Function::ZoneHandle( | 2145 const Function& allocation_function = Function::ZoneHandle( |
2133 mirror_class.LookupStaticFunction( | 2146 mirror_class.LookupStaticFunction( |
2134 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 2147 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
2135 ASSERT(!allocation_function.IsNull()); | 2148 ASSERT(!allocation_function.IsNull()); |
2136 return new StaticCallNode(call_pos, allocation_function, arguments); | 2149 return new StaticCallNode(call_pos, allocation_function, arguments); |
2137 } | 2150 } |
2138 | 2151 |
2139 | 2152 |
2140 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 2153 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
2141 intptr_t call_pos, | 2154 TokenDescriptor call_pos, |
2142 const String& function_name, | 2155 const String& function_name, |
2143 const ArgumentListNode& function_args, | 2156 const ArgumentListNode& function_args, |
2144 const LocalVariable* temp_for_last_arg, | 2157 const LocalVariable* temp_for_last_arg, |
2145 bool is_super_invocation) { | 2158 bool is_super_invocation) { |
2146 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 2159 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
2147 const intptr_t args_pos = function_args.token_pos(); | 2160 const TokenDescriptor args_pos = function_args.token_pos(); |
2148 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2161 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
2149 arguments->Add(function_args.NodeAt(0)); | 2162 arguments->Add(function_args.NodeAt(0)); |
2150 // The second argument is the invocation mirror. | 2163 // The second argument is the invocation mirror. |
2151 arguments->Add(BuildInvocationMirrorAllocation(call_pos, | 2164 arguments->Add(BuildInvocationMirrorAllocation(call_pos, |
2152 function_name, | 2165 function_name, |
2153 function_args, | 2166 function_args, |
2154 temp_for_last_arg, | 2167 temp_for_last_arg, |
2155 is_super_invocation)); | 2168 is_super_invocation)); |
2156 return arguments; | 2169 return arguments; |
2157 } | 2170 } |
2158 | 2171 |
2159 | 2172 |
2160 AstNode* Parser::ParseSuperCall(const String& function_name) { | 2173 AstNode* Parser::ParseSuperCall(const String& function_name) { |
2161 TRACE_PARSER("ParseSuperCall"); | 2174 TRACE_PARSER("ParseSuperCall"); |
2162 ASSERT(CurrentToken() == Token::kLPAREN); | 2175 ASSERT(CurrentToken() == Token::kLPAREN); |
2163 const intptr_t supercall_pos = TokenPos(); | 2176 const TokenDescriptor supercall_pos = TokenPos(); |
2164 | 2177 |
2165 // 'this' parameter is the first argument to super call. | 2178 // 'this' parameter is the first argument to super call. |
2166 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2179 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
2167 AstNode* receiver = LoadReceiver(supercall_pos); | 2180 AstNode* receiver = LoadReceiver(supercall_pos); |
2168 arguments->Add(receiver); | 2181 arguments->Add(receiver); |
2169 ParseActualParameters(arguments, kAllowConst); | 2182 ParseActualParameters(arguments, kAllowConst); |
2170 | 2183 |
2171 const bool kResolveGetter = true; | 2184 const bool kResolveGetter = true; |
2172 bool is_no_such_method = false; | 2185 bool is_no_such_method = false; |
2173 const Function& super_function = Function::ZoneHandle(Z, | 2186 const Function& super_function = Function::ZoneHandle(Z, |
(...skipping 27 matching lines...) Expand all Loading... |
2201 | 2214 |
2202 // Simple test if a node is side effect free. | 2215 // Simple test if a node is side effect free. |
2203 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 2216 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
2204 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 2217 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
2205 } | 2218 } |
2206 | 2219 |
2207 | 2220 |
2208 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 2221 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
2209 ASSERT(super->IsSuper()); | 2222 ASSERT(super->IsSuper()); |
2210 AstNode* super_op = NULL; | 2223 AstNode* super_op = NULL; |
2211 const intptr_t super_pos = super->token_pos(); | 2224 const TokenDescriptor super_pos = super->token_pos(); |
2212 if ((op == Token::kNEGATE) || | 2225 if ((op == Token::kNEGATE) || |
2213 (op == Token::kBIT_NOT)) { | 2226 (op == Token::kBIT_NOT)) { |
2214 // Resolve the operator function in the superclass. | 2227 // Resolve the operator function in the superclass. |
2215 const String& operator_function_name = | 2228 const String& operator_function_name = |
2216 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); | 2229 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); |
2217 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 2230 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
2218 AstNode* receiver = LoadReceiver(super_pos); | 2231 AstNode* receiver = LoadReceiver(super_pos); |
2219 op_arguments->Add(receiver); | 2232 op_arguments->Add(receiver); |
2220 const bool kResolveGetter = false; | 2233 const bool kResolveGetter = false; |
2221 bool is_no_such_method = false; | 2234 bool is_no_such_method = false; |
(...skipping 11 matching lines...) Expand all Loading... |
2233 } else { | 2246 } else { |
2234 ReportError(super_pos, "illegal super operator call"); | 2247 ReportError(super_pos, "illegal super operator call"); |
2235 } | 2248 } |
2236 return super_op; | 2249 return super_op; |
2237 } | 2250 } |
2238 | 2251 |
2239 | 2252 |
2240 AstNode* Parser::ParseSuperOperator() { | 2253 AstNode* Parser::ParseSuperOperator() { |
2241 TRACE_PARSER("ParseSuperOperator"); | 2254 TRACE_PARSER("ParseSuperOperator"); |
2242 AstNode* super_op = NULL; | 2255 AstNode* super_op = NULL; |
2243 const intptr_t operator_pos = TokenPos(); | 2256 const TokenDescriptor operator_pos = TokenPos(); |
2244 | 2257 |
2245 if (CurrentToken() == Token::kLBRACK) { | 2258 if (CurrentToken() == Token::kLBRACK) { |
2246 ConsumeToken(); | 2259 ConsumeToken(); |
2247 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2260 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2248 ExpectToken(Token::kRBRACK); | 2261 ExpectToken(Token::kRBRACK); |
2249 AstNode* receiver = LoadReceiver(operator_pos); | 2262 AstNode* receiver = LoadReceiver(operator_pos); |
2250 const Class& super_class = | 2263 const Class& super_class = |
2251 Class::ZoneHandle(Z, current_class().SuperClass()); | 2264 Class::ZoneHandle(Z, current_class().SuperClass()); |
2252 ASSERT(!super_class.IsNull()); | 2265 ASSERT(!super_class.IsNull()); |
2253 super_op = | 2266 super_op = |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2290 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2303 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
2291 if (negate_result) { | 2304 if (negate_result) { |
2292 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2305 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
2293 } | 2306 } |
2294 } | 2307 } |
2295 return super_op; | 2308 return super_op; |
2296 } | 2309 } |
2297 | 2310 |
2298 | 2311 |
2299 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2312 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
2300 intptr_t token_pos, | 2313 TokenDescriptor token_pos, |
2301 AstNode* receiver) { | 2314 AstNode* receiver) { |
2302 Function& implicit_closure_function = | 2315 Function& implicit_closure_function = |
2303 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); | 2316 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); |
2304 if (receiver != NULL) { | 2317 if (receiver != NULL) { |
2305 // If we create an implicit instance closure from inside a closure of a | 2318 // If we create an implicit instance closure from inside a closure of a |
2306 // parameterized class, make sure that the receiver is captured as | 2319 // parameterized class, make sure that the receiver is captured as |
2307 // instantiator. | 2320 // instantiator. |
2308 if (current_block_->scope->function_level() > 0) { | 2321 if (current_block_->scope->function_level() > 0) { |
2309 const FunctionType& signature_type = FunctionType::Handle(Z, | 2322 const FunctionType& signature_type = FunctionType::Handle(Z, |
2310 implicit_closure_function.SignatureType()); | 2323 implicit_closure_function.SignatureType()); |
2311 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); | 2324 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); |
2312 if (scope_class.IsGeneric()) { | 2325 if (scope_class.IsGeneric()) { |
2313 CaptureInstantiator(); | 2326 CaptureInstantiator(); |
2314 } | 2327 } |
2315 } | 2328 } |
2316 } | 2329 } |
2317 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2330 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
2318 } | 2331 } |
2319 | 2332 |
2320 | 2333 |
2321 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2334 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
2322 intptr_t field_pos) { | 2335 TokenDescriptor field_pos) { |
2323 TRACE_PARSER("ParseSuperFieldAccess"); | 2336 TRACE_PARSER("ParseSuperFieldAccess"); |
2324 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); | 2337 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); |
2325 if (super_class.IsNull()) { | 2338 if (super_class.IsNull()) { |
2326 ReportError("class '%s' does not have a superclass", | 2339 ReportError("class '%s' does not have a superclass", |
2327 String::Handle(Z, current_class().Name()).ToCString()); | 2340 String::Handle(Z, current_class().Name()).ToCString()); |
2328 } | 2341 } |
2329 AstNode* implicit_argument = LoadReceiver(field_pos); | 2342 AstNode* implicit_argument = LoadReceiver(field_pos); |
2330 | 2343 |
2331 const String& getter_name = | 2344 const String& getter_name = |
2332 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); | 2345 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); |
(...skipping 26 matching lines...) Expand all Loading... |
2359 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2372 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
2360 } | 2373 } |
2361 } | 2374 } |
2362 return new(Z) StaticGetterNode( | 2375 return new(Z) StaticGetterNode( |
2363 field_pos, implicit_argument, super_class, field_name); | 2376 field_pos, implicit_argument, super_class, field_name); |
2364 } | 2377 } |
2365 | 2378 |
2366 | 2379 |
2367 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2380 StaticCallNode* Parser::GenerateSuperConstructorCall( |
2368 const Class& cls, | 2381 const Class& cls, |
2369 intptr_t supercall_pos, | 2382 TokenDescriptor supercall_pos, |
2370 LocalVariable* receiver, | 2383 LocalVariable* receiver, |
2371 ArgumentListNode* forwarding_args) { | 2384 ArgumentListNode* forwarding_args) { |
2372 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2385 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2373 // Omit the implicit super() if there is no super class (i.e. | 2386 // Omit the implicit super() if there is no super class (i.e. |
2374 // we're not compiling class Object), or if the super class is an | 2387 // we're not compiling class Object), or if the super class is an |
2375 // artificially generated "wrapper class" that has no constructor. | 2388 // artificially generated "wrapper class" that has no constructor. |
2376 if (super_class.IsNull() || | 2389 if (super_class.IsNull() || |
2377 (super_class.num_native_fields() > 0 && | 2390 (super_class.num_native_fields() > 0 && |
2378 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { | 2391 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { |
2379 return NULL; | 2392 return NULL; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2426 error_message.ToCString()); | 2439 error_message.ToCString()); |
2427 } | 2440 } |
2428 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2441 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2429 } | 2442 } |
2430 | 2443 |
2431 | 2444 |
2432 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, | 2445 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, |
2433 LocalVariable* receiver) { | 2446 LocalVariable* receiver) { |
2434 TRACE_PARSER("ParseSuperInitializer"); | 2447 TRACE_PARSER("ParseSuperInitializer"); |
2435 ASSERT(CurrentToken() == Token::kSUPER); | 2448 ASSERT(CurrentToken() == Token::kSUPER); |
2436 const intptr_t supercall_pos = TokenPos(); | 2449 const TokenDescriptor supercall_pos = TokenPos(); |
2437 ConsumeToken(); | 2450 ConsumeToken(); |
2438 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2451 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
2439 ASSERT(!super_class.IsNull()); | 2452 ASSERT(!super_class.IsNull()); |
2440 String& ctor_name = String::Handle(Z, super_class.Name()); | 2453 String& ctor_name = String::Handle(Z, super_class.Name()); |
2441 ctor_name = Symbols::FromConcat(ctor_name, Symbols::Dot()); | 2454 ctor_name = Symbols::FromConcat(ctor_name, Symbols::Dot()); |
2442 if (CurrentToken() == Token::kPERIOD) { | 2455 if (CurrentToken() == Token::kPERIOD) { |
2443 ConsumeToken(); | 2456 ConsumeToken(); |
2444 ctor_name = Symbols::FromConcat( | 2457 ctor_name = Symbols::FromConcat( |
2445 ctor_name, *ExpectIdentifier("constructor name expected")); | 2458 ctor_name, *ExpectIdentifier("constructor name expected")); |
2446 } | 2459 } |
(...skipping 30 matching lines...) Expand all Loading... |
2477 error_message.ToCString()); | 2490 error_message.ToCString()); |
2478 } | 2491 } |
2479 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2492 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
2480 } | 2493 } |
2481 | 2494 |
2482 | 2495 |
2483 AstNode* Parser::ParseInitializer(const Class& cls, | 2496 AstNode* Parser::ParseInitializer(const Class& cls, |
2484 LocalVariable* receiver, | 2497 LocalVariable* receiver, |
2485 GrowableArray<Field*>* initialized_fields) { | 2498 GrowableArray<Field*>* initialized_fields) { |
2486 TRACE_PARSER("ParseInitializer"); | 2499 TRACE_PARSER("ParseInitializer"); |
2487 const intptr_t field_pos = TokenPos(); | 2500 const TokenDescriptor field_pos = TokenPos(); |
2488 if (CurrentToken() == Token::kTHIS) { | 2501 if (CurrentToken() == Token::kTHIS) { |
2489 ConsumeToken(); | 2502 ConsumeToken(); |
2490 ExpectToken(Token::kPERIOD); | 2503 ExpectToken(Token::kPERIOD); |
2491 } | 2504 } |
2492 const String& field_name = *ExpectIdentifier("field name expected"); | 2505 const String& field_name = *ExpectIdentifier("field name expected"); |
2493 ExpectToken(Token::kASSIGN); | 2506 ExpectToken(Token::kASSIGN); |
2494 | 2507 |
2495 const bool saved_mode = SetAllowFunctionLiterals(false); | 2508 const bool saved_mode = SetAllowFunctionLiterals(false); |
2496 // "this" must not be accessible in initializer expressions. | 2509 // "this" must not be accessible in initializer expressions. |
2497 receiver->set_invisible(true); | 2510 receiver->set_invisible(true); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2553 | 2566 |
2554 | 2567 |
2555 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2568 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
2556 // Only use this function if the initialized field originates | 2569 // Only use this function if the initialized field originates |
2557 // from a different class. We need to save and restore current | 2570 // from a different class. We need to save and restore current |
2558 // class, library, and token stream (script). | 2571 // class, library, and token stream (script). |
2559 ASSERT(current_class().raw() != field.origin()); | 2572 ASSERT(current_class().raw() != field.origin()); |
2560 const Class& saved_class = Class::Handle(Z, current_class().raw()); | 2573 const Class& saved_class = Class::Handle(Z, current_class().raw()); |
2561 const Library& saved_library = Library::Handle(Z, library().raw()); | 2574 const Library& saved_library = Library::Handle(Z, library().raw()); |
2562 const Script& saved_script = Script::Handle(Z, script().raw()); | 2575 const Script& saved_script = Script::Handle(Z, script().raw()); |
2563 const intptr_t saved_token_pos = TokenPos(); | 2576 const TokenDescriptor saved_token_pos = TokenPos(); |
2564 | 2577 |
2565 set_current_class(Class::Handle(Z, field.origin())); | 2578 set_current_class(Class::Handle(Z, field.origin())); |
2566 set_library(Library::Handle(Z, current_class().library())); | 2579 set_library(Library::Handle(Z, current_class().library())); |
2567 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); | 2580 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); |
2568 | 2581 |
2569 ASSERT(IsIdentifier()); | 2582 ASSERT(IsIdentifier()); |
2570 ConsumeToken(); | 2583 ConsumeToken(); |
2571 ExpectToken(Token::kASSIGN); | 2584 ExpectToken(Token::kASSIGN); |
2572 AstNode* init_expr = NULL; | 2585 AstNode* init_expr = NULL; |
2573 intptr_t expr_pos = TokenPos(); | 2586 TokenDescriptor expr_pos = TokenPos(); |
2574 if (field.is_const()) { | 2587 if (field.is_const()) { |
2575 init_expr = ParseConstExpr(); | 2588 init_expr = ParseConstExpr(); |
2576 } else { | 2589 } else { |
2577 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2590 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2578 if (init_expr->EvalConstExpr() != NULL) { | 2591 if (init_expr->EvalConstExpr() != NULL) { |
2579 Instance& expr_value = Instance::ZoneHandle(Z); | 2592 Instance& expr_value = Instance::ZoneHandle(Z); |
2580 if (!GetCachedConstant(expr_pos, &expr_value)) { | 2593 if (!GetCachedConstant(expr_pos, &expr_value)) { |
2581 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); | 2594 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); |
2582 CacheConstantValue(expr_pos, expr_value); | 2595 CacheConstantValue(expr_pos, expr_value); |
2583 } | 2596 } |
2584 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); | 2597 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); |
2585 } | 2598 } |
2586 } | 2599 } |
2587 set_current_class(saved_class); | 2600 set_current_class(saved_class); |
2588 set_library(saved_library); | 2601 set_library(saved_library); |
2589 SetScript(saved_script, saved_token_pos); | 2602 SetScript(saved_script, saved_token_pos); |
2590 return init_expr; | 2603 return init_expr; |
2591 } | 2604 } |
2592 | 2605 |
2593 | 2606 |
2594 void Parser::ParseInitializedInstanceFields(const Class& cls, | 2607 void Parser::ParseInitializedInstanceFields(const Class& cls, |
2595 LocalVariable* receiver, | 2608 LocalVariable* receiver, |
2596 GrowableArray<Field*>* initialized_fields) { | 2609 GrowableArray<Field*>* initialized_fields) { |
2597 TRACE_PARSER("ParseInitializedInstanceFields"); | 2610 TRACE_PARSER("ParseInitializedInstanceFields"); |
2598 const Array& fields = Array::Handle(Z, cls.fields()); | 2611 const Array& fields = Array::Handle(Z, cls.fields()); |
2599 Field& f = Field::Handle(Z); | 2612 Field& f = Field::Handle(Z); |
2600 const intptr_t saved_pos = TokenPos(); | 2613 const TokenDescriptor saved_pos = TokenPos(); |
2601 for (int i = 0; i < fields.Length(); i++) { | 2614 for (int i = 0; i < fields.Length(); i++) { |
2602 f ^= fields.At(i); | 2615 f ^= fields.At(i); |
2603 if (!f.is_static() && f.has_initializer()) { | 2616 if (!f.is_static() && f.has_initializer()) { |
2604 Field& field = Field::ZoneHandle(Z); | 2617 Field& field = Field::ZoneHandle(Z); |
2605 field ^= fields.At(i); | 2618 field ^= fields.At(i); |
2606 if (field.is_final()) { | 2619 if (field.is_final()) { |
2607 // Final fields with initializer expression may not be initialized | 2620 // Final fields with initializer expression may not be initialized |
2608 // again by constructors. Remember that this field is already | 2621 // again by constructors. Remember that this field is already |
2609 // initialized. | 2622 // initialized. |
2610 initialized_fields->Add(&field); | 2623 initialized_fields->Add(&field); |
2611 } | 2624 } |
2612 AstNode* init_expr = NULL; | 2625 AstNode* init_expr = NULL; |
2613 if (current_class().raw() != field.origin()) { | 2626 if (current_class().raw() != field.origin()) { |
2614 init_expr = ParseExternalInitializedField(field); | 2627 init_expr = ParseExternalInitializedField(field); |
2615 } else { | 2628 } else { |
2616 SetPosition(field.token_pos()); | 2629 SetPosition(field.token_pos().value()); |
2617 ASSERT(IsIdentifier()); | 2630 ASSERT(IsIdentifier()); |
2618 ConsumeToken(); | 2631 ConsumeToken(); |
2619 ExpectToken(Token::kASSIGN); | 2632 ExpectToken(Token::kASSIGN); |
2620 if (current_class().is_const()) { | 2633 if (current_class().is_const()) { |
2621 // If the class has a const contructor, the initializer | 2634 // If the class has a const contructor, the initializer |
2622 // expression must be a compile-time constant. | 2635 // expression must be a compile-time constant. |
2623 init_expr = ParseConstExpr(); | 2636 init_expr = ParseConstExpr(); |
2624 } else { | 2637 } else { |
2625 intptr_t expr_pos = TokenPos(); | 2638 TokenDescriptor expr_pos = TokenPos(); |
2626 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2639 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
2627 if (init_expr->EvalConstExpr() != NULL) { | 2640 if (init_expr->EvalConstExpr() != NULL) { |
2628 Instance& expr_value = Instance::ZoneHandle(Z); | 2641 Instance& expr_value = Instance::ZoneHandle(Z); |
2629 if (!GetCachedConstant(expr_pos, &expr_value)) { | 2642 if (!GetCachedConstant(expr_pos, &expr_value)) { |
2630 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); | 2643 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); |
2631 CacheConstantValue(expr_pos, expr_value); | 2644 CacheConstantValue(expr_pos, expr_value); |
2632 } | 2645 } |
2633 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); | 2646 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); |
2634 } | 2647 } |
2635 } | 2648 } |
2636 } | 2649 } |
2637 ASSERT(init_expr != NULL); | 2650 ASSERT(init_expr != NULL); |
2638 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); | 2651 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
2639 EnsureExpressionTemp(); | 2652 EnsureExpressionTemp(); |
2640 AstNode* field_init = | 2653 AstNode* field_init = |
2641 new StoreInstanceFieldNode(field.token_pos(), | 2654 new StoreInstanceFieldNode(field.token_pos(), |
2642 instance, | 2655 instance, |
2643 field, | 2656 field, |
2644 init_expr); | 2657 init_expr); |
2645 current_block_->statements->Add(field_init); | 2658 current_block_->statements->Add(field_init); |
2646 } | 2659 } |
2647 } | 2660 } |
2648 initialized_fields->Add(NULL); // End of inline initializers. | 2661 initialized_fields->Add(NULL); // End of inline initializers. |
2649 SetPosition(saved_pos); | 2662 SetPosition(saved_pos); |
2650 } | 2663 } |
2651 | 2664 |
2652 | 2665 |
2653 AstNode* Parser::CheckDuplicateFieldInit( | 2666 AstNode* Parser::CheckDuplicateFieldInit( |
2654 intptr_t init_pos, | 2667 TokenDescriptor init_pos, |
2655 GrowableArray<Field*>* initialized_fields, | 2668 GrowableArray<Field*>* initialized_fields, |
2656 AstNode* instance, | 2669 AstNode* instance, |
2657 Field* field, | 2670 Field* field, |
2658 AstNode* init_value) { | 2671 AstNode* init_value) { |
2659 ASSERT(!field->is_static()); | 2672 ASSERT(!field->is_static()); |
2660 AstNode* result = NULL; | 2673 AstNode* result = NULL; |
2661 | 2674 |
2662 // The initializer_list is divided into two sections. The sections | 2675 // The initializer_list is divided into two sections. The sections |
2663 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] | 2676 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] |
2664 // The first fields f0 .. fn are final fields of the class that | 2677 // 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... |
2817 } | 2830 } |
2818 CheckFieldsInitialized(cls); | 2831 CheckFieldsInitialized(cls); |
2819 } | 2832 } |
2820 | 2833 |
2821 | 2834 |
2822 void Parser::ParseConstructorRedirection(const Class& cls, | 2835 void Parser::ParseConstructorRedirection(const Class& cls, |
2823 LocalVariable* receiver) { | 2836 LocalVariable* receiver) { |
2824 TRACE_PARSER("ParseConstructorRedirection"); | 2837 TRACE_PARSER("ParseConstructorRedirection"); |
2825 ExpectToken(Token::kCOLON); | 2838 ExpectToken(Token::kCOLON); |
2826 ASSERT(CurrentToken() == Token::kTHIS); | 2839 ASSERT(CurrentToken() == Token::kTHIS); |
2827 const intptr_t call_pos = TokenPos(); | 2840 const TokenDescriptor call_pos = TokenPos(); |
2828 ConsumeToken(); | 2841 ConsumeToken(); |
2829 String& ctor_name = String::Handle(Z, cls.Name()); | 2842 String& ctor_name = String::Handle(Z, cls.Name()); |
2830 GrowableHandlePtrArray<const String> pieces(Z, 3); | 2843 GrowableHandlePtrArray<const String> pieces(Z, 3); |
2831 pieces.Add(ctor_name); | 2844 pieces.Add(ctor_name); |
2832 pieces.Add(Symbols::Dot()); | 2845 pieces.Add(Symbols::Dot()); |
2833 if (CurrentToken() == Token::kPERIOD) { | 2846 if (CurrentToken() == Token::kPERIOD) { |
2834 ConsumeToken(); | 2847 ConsumeToken(); |
2835 pieces.Add(*ExpectIdentifier("constructor name expected")); | 2848 pieces.Add(*ExpectIdentifier("constructor name expected")); |
2836 } | 2849 } |
2837 ctor_name = Symbols::FromConcatAll(pieces); | 2850 ctor_name = Symbols::FromConcatAll(pieces); |
(...skipping 23 matching lines...) Expand all Loading... |
2861 error_message.ToCString()); | 2874 error_message.ToCString()); |
2862 } | 2875 } |
2863 current_block_->statements->Add( | 2876 current_block_->statements->Add( |
2864 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2877 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
2865 } | 2878 } |
2866 | 2879 |
2867 | 2880 |
2868 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2881 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
2869 ASSERT(func.IsGenerativeConstructor()); | 2882 ASSERT(func.IsGenerativeConstructor()); |
2870 ASSERT(func.Owner() == current_class().raw()); | 2883 ASSERT(func.Owner() == current_class().raw()); |
2871 const intptr_t ctor_pos = TokenPos(); | 2884 const TokenDescriptor ctor_pos = TokenPos(); |
2872 OpenFunctionBlock(func); | 2885 OpenFunctionBlock(func); |
2873 | 2886 |
2874 LocalVariable* receiver = new LocalVariable( | 2887 LocalVariable* receiver = new LocalVariable( |
2875 Token::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); | 2888 TokenDescriptor::kNoSource, |
| 2889 Symbols::This(), |
| 2890 *ReceiverType(current_class())); |
2876 current_block_->scope->InsertParameterAt(0, receiver); | 2891 current_block_->scope->InsertParameterAt(0, receiver); |
2877 | 2892 |
2878 // Parse expressions of instance fields that have an explicit | 2893 // Parse expressions of instance fields that have an explicit |
2879 // initializer expression. | 2894 // initializer expression. |
2880 // The receiver must not be visible to field initializer expressions. | 2895 // The receiver must not be visible to field initializer expressions. |
2881 receiver->set_invisible(true); | 2896 receiver->set_invisible(true); |
2882 GrowableArray<Field*> initialized_fields; | 2897 GrowableArray<Field*> initialized_fields; |
2883 ParseInitializedInstanceFields( | 2898 ParseInitializedInstanceFields( |
2884 current_class(), receiver, &initialized_fields); | 2899 current_class(), receiver, &initialized_fields); |
2885 receiver->set_invisible(false); | 2900 receiver->set_invisible(false); |
(...skipping 25 matching lines...) Expand all Loading... |
2911 "optional parameters and invoke it via super from a " | 2926 "optional parameters and invoke it via super from a " |
2912 "constructor of the class extending the mixin application", | 2927 "constructor of the class extending the mixin application", |
2913 String::Handle(Z, super_class.Name()).ToCString()); | 2928 String::Handle(Z, super_class.Name()).ToCString()); |
2914 } | 2929 } |
2915 | 2930 |
2916 // Prepare user-defined arguments to be forwarded to super call. | 2931 // Prepare user-defined arguments to be forwarded to super call. |
2917 // The first user-defined argument is at position 1. | 2932 // The first user-defined argument is at position 1. |
2918 forwarding_args = new ArgumentListNode(ST(ctor_pos)); | 2933 forwarding_args = new ArgumentListNode(ST(ctor_pos)); |
2919 for (int i = 1; i < func.NumParameters(); i++) { | 2934 for (int i = 1; i < func.NumParameters(); i++) { |
2920 LocalVariable* param = new LocalVariable( | 2935 LocalVariable* param = new LocalVariable( |
2921 Token::kNoSourcePos, | 2936 TokenDescriptor::kNoSource, |
2922 String::ZoneHandle(Z, func.ParameterNameAt(i)), | 2937 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
2923 Object::dynamic_type()); | 2938 Object::dynamic_type()); |
2924 current_block_->scope->InsertParameterAt(i, param); | 2939 current_block_->scope->InsertParameterAt(i, param); |
2925 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); | 2940 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); |
2926 } | 2941 } |
2927 } | 2942 } |
2928 | 2943 |
2929 AstNode* super_call = GenerateSuperConstructorCall( | 2944 AstNode* super_call = GenerateSuperConstructorCall( |
2930 current_class(), | 2945 current_class(), |
2931 ctor_pos, | 2946 ctor_pos, |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3268 if (IsInstantiatorRequired()) { | 3283 if (IsInstantiatorRequired()) { |
3269 // Make sure that the receiver of the enclosing instance function | 3284 // Make sure that the receiver of the enclosing instance function |
3270 // (or implicit first parameter of an enclosing factory) is marked as | 3285 // (or implicit first parameter of an enclosing factory) is marked as |
3271 // captured if type checks are enabled, because they may access it to | 3286 // captured if type checks are enabled, because they may access it to |
3272 // instantiate types. | 3287 // instantiate types. |
3273 CaptureInstantiator(); | 3288 CaptureInstantiator(); |
3274 } | 3289 } |
3275 } | 3290 } |
3276 } | 3291 } |
3277 | 3292 |
3278 const intptr_t modifier_pos = TokenPos(); | 3293 const TokenDescriptor modifier_pos = TokenPos(); |
3279 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3294 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
3280 if (!func.is_generated_body()) { | 3295 if (!func.is_generated_body()) { |
3281 // Don't add a modifier to the closure representing the body of | 3296 // Don't add a modifier to the closure representing the body of |
3282 // the asynchronous function or generator. | 3297 // the asynchronous function or generator. |
3283 func.set_modifier(func_modifier); | 3298 func.set_modifier(func_modifier); |
3284 } | 3299 } |
3285 | 3300 |
3286 OpenBlock(); // Open a nested scope for the outermost function block. | 3301 OpenBlock(); // Open a nested scope for the outermost function block. |
3287 | 3302 |
3288 Function& generated_body_closure = Function::ZoneHandle(Z); | 3303 Function& generated_body_closure = Function::ZoneHandle(Z); |
(...skipping 18 matching lines...) Expand all Loading... |
3307 func.set_is_debuggable(false); | 3322 func.set_is_debuggable(false); |
3308 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); | 3323 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); |
3309 } else if (func.IsAsyncGenClosure()) { | 3324 } else if (func.IsAsyncGenClosure()) { |
3310 // The closure containing the body of an async* function is debuggable. | 3325 // The closure containing the body of an async* function is debuggable. |
3311 ASSERT(func.is_debuggable()); | 3326 ASSERT(func.is_debuggable()); |
3312 OpenAsyncGeneratorClosure(); | 3327 OpenAsyncGeneratorClosure(); |
3313 } | 3328 } |
3314 | 3329 |
3315 BoolScope allow_await(&this->await_is_keyword_, | 3330 BoolScope allow_await(&this->await_is_keyword_, |
3316 func.IsAsyncOrGenerator() || func.is_generated_body()); | 3331 func.IsAsyncOrGenerator() || func.is_generated_body()); |
3317 intptr_t end_token_pos = Token::kNoSourcePos; | 3332 TokenDescriptor end_token_pos = TokenDescriptor::kNoSource; |
3318 if (CurrentToken() == Token::kLBRACE) { | 3333 if (CurrentToken() == Token::kLBRACE) { |
3319 ConsumeToken(); | 3334 ConsumeToken(); |
3320 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { | 3335 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
3321 const Class& owner = Class::Handle(Z, func.Owner()); | 3336 const Class& owner = Class::Handle(Z, func.Owner()); |
3322 if (!owner.IsObjectClass()) { | 3337 if (!owner.IsObjectClass()) { |
3323 AddEqualityNullCheck(); | 3338 AddEqualityNullCheck(); |
3324 } | 3339 } |
3325 } | 3340 } |
3326 ParseStatementSequence(); | 3341 ParseStatementSequence(); |
3327 end_token_pos = TokenPos(); | 3342 end_token_pos = TokenPos(); |
3328 ExpectToken(Token::kRBRACE); | 3343 ExpectToken(Token::kRBRACE); |
3329 } else if (CurrentToken() == Token::kARROW) { | 3344 } else if (CurrentToken() == Token::kARROW) { |
3330 if (func.IsGenerator()) { | 3345 if (func.IsGenerator()) { |
3331 ReportError(modifier_pos, | 3346 ReportError(modifier_pos, |
3332 "=> style function may not be sync* or async* generator"); | 3347 "=> style function may not be sync* or async* generator"); |
3333 } | 3348 } |
3334 ConsumeToken(); | 3349 ConsumeToken(); |
3335 if (String::Handle(Z, func.name()).Equals( | 3350 if (String::Handle(Z, func.name()).Equals( |
3336 Symbols::EqualOperator())) { | 3351 Symbols::EqualOperator())) { |
3337 const Class& owner = Class::Handle(Z, func.Owner()); | 3352 const Class& owner = Class::Handle(Z, func.Owner()); |
3338 if (!owner.IsObjectClass()) { | 3353 if (!owner.IsObjectClass()) { |
3339 AddEqualityNullCheck(); | 3354 AddEqualityNullCheck(); |
3340 } | 3355 } |
3341 } | 3356 } |
3342 const intptr_t expr_pos = TokenPos(); | 3357 const TokenDescriptor expr_pos = TokenPos(); |
3343 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3358 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
3344 ASSERT(expr != NULL); | 3359 ASSERT(expr != NULL); |
3345 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3360 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
3346 end_token_pos = TokenPos(); | 3361 end_token_pos = TokenPos(); |
3347 if (check_semicolon) { | 3362 if (check_semicolon) { |
3348 ExpectSemicolon(); | 3363 ExpectSemicolon(); |
3349 } | 3364 } |
3350 } else if (IsSymbol(Symbols::Native())) { | 3365 } else if (IsSymbol(Symbols::Native())) { |
3351 if (String::Handle(Z, func.name()).Equals( | 3366 if (String::Handle(Z, func.name()).Equals( |
3352 Symbols::EqualOperator())) { | 3367 Symbols::EqualOperator())) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3400 current_block_->statements->Add(body); | 3415 current_block_->statements->Add(body); |
3401 innermost_function_ = saved_innermost_function.raw(); | 3416 innermost_function_ = saved_innermost_function.raw(); |
3402 last_used_try_index_ = saved_try_index; | 3417 last_used_try_index_ = saved_try_index; |
3403 async_temp_scope_ = saved_async_temp_scope; | 3418 async_temp_scope_ = saved_async_temp_scope; |
3404 return CloseBlock(); | 3419 return CloseBlock(); |
3405 } | 3420 } |
3406 | 3421 |
3407 | 3422 |
3408 void Parser::AddEqualityNullCheck() { | 3423 void Parser::AddEqualityNullCheck() { |
3409 AstNode* argument = | 3424 AstNode* argument = |
3410 new LoadLocalNode(Token::kNoSourcePos, | 3425 new LoadLocalNode(TokenDescriptor::kNoSource, |
3411 current_block_->scope->parent()->VariableAt(1)); | 3426 current_block_->scope->parent()->VariableAt(1)); |
3412 LiteralNode* null_operand = | 3427 LiteralNode* null_operand = |
3413 new LiteralNode(Token::kNoSourcePos, Instance::ZoneHandle(Z)); | 3428 new LiteralNode(TokenDescriptor::kNoSource, Instance::ZoneHandle(Z)); |
3414 ComparisonNode* check_arg = | 3429 ComparisonNode* check_arg = |
3415 new ComparisonNode(Token::kNoSourcePos, | 3430 new ComparisonNode(TokenDescriptor::kNoSource, |
3416 Token::kEQ_STRICT, | 3431 Token::kEQ_STRICT, |
3417 argument, | 3432 argument, |
3418 null_operand); | 3433 null_operand); |
3419 ComparisonNode* result = | 3434 ComparisonNode* result = |
3420 new ComparisonNode(Token::kNoSourcePos, | 3435 new ComparisonNode(TokenDescriptor::kNoSource, |
3421 Token::kEQ_STRICT, | 3436 Token::kEQ_STRICT, |
3422 LoadReceiver(Token::kNoSourcePos), | 3437 LoadReceiver(TokenDescriptor::kNoSource), |
3423 null_operand); | 3438 null_operand); |
3424 SequenceNode* arg_is_null = new SequenceNode(Token::kNoSourcePos, | 3439 SequenceNode* arg_is_null = new SequenceNode(TokenDescriptor::kNoSource, |
3425 current_block_->scope); | 3440 current_block_->scope); |
3426 arg_is_null->Add(new ReturnNode(Token::kNoSourcePos, result)); | 3441 arg_is_null->Add(new ReturnNode(TokenDescriptor::kNoSource, result)); |
3427 IfNode* if_arg_null = new IfNode(Token::kNoSourcePos, | 3442 IfNode* if_arg_null = new IfNode(TokenDescriptor::kNoSource, |
3428 check_arg, | 3443 check_arg, |
3429 arg_is_null, | 3444 arg_is_null, |
3430 NULL); | 3445 NULL); |
3431 current_block_->statements->Add(if_arg_null); | 3446 current_block_->statements->Add(if_arg_null); |
3432 } | 3447 } |
3433 | 3448 |
3434 | 3449 |
3435 void Parser::SkipIf(Token::Kind token) { | 3450 void Parser::SkipIf(Token::Kind token) { |
3436 if (CurrentToken() == token) { | 3451 if (CurrentToken() == token) { |
3437 ConsumeToken(); | 3452 ConsumeToken(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3529 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 3544 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
3530 ReportError(method->name_pos, "constructor cannot be abstract"); | 3545 ReportError(method->name_pos, "constructor cannot be abstract"); |
3531 } | 3546 } |
3532 if (method->has_const && method->IsConstructor()) { | 3547 if (method->has_const && method->IsConstructor()) { |
3533 current_class().set_is_const(); | 3548 current_class().set_is_const(); |
3534 } | 3549 } |
3535 | 3550 |
3536 // Parse the formal parameters. | 3551 // Parse the formal parameters. |
3537 const bool are_implicitly_final = method->has_const; | 3552 const bool are_implicitly_final = method->has_const; |
3538 const bool allow_explicit_default_values = true; | 3553 const bool allow_explicit_default_values = true; |
3539 const intptr_t formal_param_pos = TokenPos(); | 3554 const TokenDescriptor formal_param_pos = TokenPos(); |
3540 method->params.Clear(); | 3555 method->params.Clear(); |
3541 // Static functions do not have a receiver. | 3556 // Static functions do not have a receiver. |
3542 // The first parameter of a factory is the TypeArguments vector of | 3557 // The first parameter of a factory is the TypeArguments vector of |
3543 // the type of the instance to be allocated. | 3558 // the type of the instance to be allocated. |
3544 if (!method->has_static || method->IsConstructor()) { | 3559 if (!method->has_static || method->IsConstructor()) { |
3545 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); | 3560 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); |
3546 } else if (method->IsFactory()) { | 3561 } else if (method->IsFactory()) { |
3547 method->params.AddFinalParameter( | 3562 method->params.AddFinalParameter( |
3548 formal_param_pos, | 3563 formal_param_pos, |
3549 &Symbols::TypeArgumentsParameter(), | 3564 &Symbols::TypeArgumentsParameter(), |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3603 ReportError("redirecting factory '%s' may not specify default values " | 3618 ReportError("redirecting factory '%s' may not specify default values " |
3604 "for optional parameters", | 3619 "for optional parameters", |
3605 method->name->ToCString()); | 3620 method->name->ToCString()); |
3606 } | 3621 } |
3607 if (method->has_external) { | 3622 if (method->has_external) { |
3608 ReportError(TokenPos(), | 3623 ReportError(TokenPos(), |
3609 "external factory constructor '%s' may not have redirection", | 3624 "external factory constructor '%s' may not have redirection", |
3610 method->name->ToCString()); | 3625 method->name->ToCString()); |
3611 } | 3626 } |
3612 ConsumeToken(); | 3627 ConsumeToken(); |
3613 const intptr_t type_pos = TokenPos(); | 3628 const TokenDescriptor type_pos = TokenPos(); |
3614 is_redirecting = true; | 3629 is_redirecting = true; |
3615 const bool consume_unresolved_prefix = | 3630 const bool consume_unresolved_prefix = |
3616 (LookaheadToken(3) == Token::kLT) || | 3631 (LookaheadToken(3) == Token::kLT) || |
3617 (LookaheadToken(3) == Token::kPERIOD); | 3632 (LookaheadToken(3) == Token::kPERIOD); |
3618 const AbstractType& type = AbstractType::Handle(Z, | 3633 const AbstractType& type = AbstractType::Handle(Z, |
3619 ParseType(ClassFinalizer::kResolveTypeParameters, | 3634 ParseType(ClassFinalizer::kResolveTypeParameters, |
3620 true, | 3635 true, |
3621 consume_unresolved_prefix)); | 3636 consume_unresolved_prefix)); |
3622 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3637 if (!type.IsMalformed() && type.IsTypeParameter()) { |
3623 // Replace the type with a malformed type and compile a throw when called. | 3638 // 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... |
3682 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3697 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
3683 | 3698 |
3684 if (method->IsConstructor() && | 3699 if (method->IsConstructor() && |
3685 method->has_external && | 3700 method->has_external && |
3686 method->params.has_field_initializer) { | 3701 method->params.has_field_initializer) { |
3687 ReportError(method->name_pos, | 3702 ReportError(method->name_pos, |
3688 "external constructor '%s' may not have field initializers", | 3703 "external constructor '%s' may not have field initializers", |
3689 method->name->ToCString()); | 3704 method->name->ToCString()); |
3690 } | 3705 } |
3691 | 3706 |
3692 const intptr_t modifier_pos = TokenPos(); | 3707 const TokenDescriptor modifier_pos = TokenPos(); |
3693 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 3708 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
3694 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && | 3709 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && |
3695 (async_modifier != RawFunction::kNoModifier)) { | 3710 (async_modifier != RawFunction::kNoModifier)) { |
3696 ReportError(modifier_pos, | 3711 ReportError(modifier_pos, |
3697 "%s '%s' may not be async, async* or sync*", | 3712 "%s '%s' may not be async, async* or sync*", |
3698 (method->IsSetter()) ? "setter" : "constructor", | 3713 (method->IsSetter()) ? "setter" : "constructor", |
3699 method->name->ToCString()); | 3714 method->name->ToCString()); |
3700 } | 3715 } |
3701 | 3716 |
3702 intptr_t method_end_pos = TokenPos(); | 3717 TokenDescriptor method_end_pos = TokenPos(); |
3703 String* native_name = NULL; | 3718 String* native_name = NULL; |
3704 if ((CurrentToken() == Token::kLBRACE) || | 3719 if ((CurrentToken() == Token::kLBRACE) || |
3705 (CurrentToken() == Token::kARROW)) { | 3720 (CurrentToken() == Token::kARROW)) { |
3706 if (method->has_abstract) { | 3721 if (method->has_abstract) { |
3707 ReportError(TokenPos(), | 3722 ReportError(TokenPos(), |
3708 "abstract method '%s' may not have a function body", | 3723 "abstract method '%s' may not have a function body", |
3709 method->name->ToCString()); | 3724 method->name->ToCString()); |
3710 } else if (method->has_external) { | 3725 } else if (method->has_external) { |
3711 ReportError(TokenPos(), | 3726 ReportError(TokenPos(), |
3712 "external %s '%s' may not have a function body", | 3727 "external %s '%s' may not have a function body", |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3824 method->has_native, | 3839 method->has_native, |
3825 current_class(), | 3840 current_class(), |
3826 method->decl_begin_pos)); | 3841 method->decl_begin_pos)); |
3827 func.set_result_type(*method->type); | 3842 func.set_result_type(*method->type); |
3828 func.set_end_token_pos(method_end_pos); | 3843 func.set_end_token_pos(method_end_pos); |
3829 func.set_is_redirecting(is_redirecting); | 3844 func.set_is_redirecting(is_redirecting); |
3830 func.set_modifier(async_modifier); | 3845 func.set_modifier(async_modifier); |
3831 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { | 3846 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { |
3832 func.set_is_reflectable(false); | 3847 func.set_is_reflectable(false); |
3833 } | 3848 } |
3834 if (FLAG_enable_mirrors && (method->metadata_pos >= 0)) { | 3849 if (FLAG_enable_mirrors && (method->metadata_pos.IsReal())) { |
3835 library_.AddFunctionMetadata(func, method->metadata_pos); | 3850 library_.AddFunctionMetadata(func, method->metadata_pos); |
3836 } | 3851 } |
3837 if (method->has_native) { | 3852 if (method->has_native) { |
3838 func.set_native_name(*native_name); | 3853 func.set_native_name(*native_name); |
3839 } | 3854 } |
3840 | 3855 |
3841 // If this method is a redirecting factory, set the redirection information. | 3856 // If this method is a redirecting factory, set the redirection information. |
3842 if (!redirection_type.IsNull()) { | 3857 if (!redirection_type.IsNull()) { |
3843 ASSERT(func.IsFactory()); | 3858 ASSERT(func.IsFactory()); |
3844 func.SetRedirectionType(redirection_type); | 3859 func.SetRedirectionType(redirection_type); |
(...skipping 10 matching lines...) Expand all Loading... |
3855 | 3870 |
3856 | 3871 |
3857 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 3872 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
3858 TRACE_PARSER("ParseFieldDefinition"); | 3873 TRACE_PARSER("ParseFieldDefinition"); |
3859 // The parser has read the first field name and is now at the token | 3874 // The parser has read the first field name and is now at the token |
3860 // after the field name. | 3875 // after the field name. |
3861 ASSERT(CurrentToken() == Token::kSEMICOLON || | 3876 ASSERT(CurrentToken() == Token::kSEMICOLON || |
3862 CurrentToken() == Token::kCOMMA || | 3877 CurrentToken() == Token::kCOMMA || |
3863 CurrentToken() == Token::kASSIGN); | 3878 CurrentToken() == Token::kASSIGN); |
3864 ASSERT(field->type != NULL); | 3879 ASSERT(field->type != NULL); |
3865 ASSERT(field->name_pos >= 0); | 3880 ASSERT(field->name_pos.IsReal()); |
3866 ASSERT(current_member_ == field); | 3881 ASSERT(current_member_ == field); |
3867 // All const fields are also final. | 3882 // All const fields are also final. |
3868 ASSERT(!field->has_const || field->has_final); | 3883 ASSERT(!field->has_const || field->has_final); |
3869 | 3884 |
3870 if (field->has_abstract) { | 3885 if (field->has_abstract) { |
3871 ReportError("keyword 'abstract' not allowed in field declaration"); | 3886 ReportError("keyword 'abstract' not allowed in field declaration"); |
3872 } | 3887 } |
3873 if (field->has_external) { | 3888 if (field->has_external) { |
3874 ReportError("keyword 'external' not allowed in field declaration"); | 3889 ReportError("keyword 'external' not allowed in field declaration"); |
3875 } | 3890 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3924 field->has_static, | 3939 field->has_static, |
3925 field->has_final, | 3940 field->has_final, |
3926 field->has_const, | 3941 field->has_const, |
3927 is_reflectable, | 3942 is_reflectable, |
3928 current_class(), | 3943 current_class(), |
3929 *field->type, | 3944 *field->type, |
3930 field->name_pos); | 3945 field->name_pos); |
3931 class_field.set_has_initializer(has_initializer); | 3946 class_field.set_has_initializer(has_initializer); |
3932 members->AddField(class_field); | 3947 members->AddField(class_field); |
3933 field->field_ = &class_field; | 3948 field->field_ = &class_field; |
3934 if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) { | 3949 if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) { |
3935 library_.AddFieldMetadata(class_field, field->metadata_pos); | 3950 library_.AddFieldMetadata(class_field, field->metadata_pos); |
3936 } | 3951 } |
3937 | 3952 |
3938 // Start tracking types for fields with simple initializers in their | 3953 // Start tracking types for fields with simple initializers in their |
3939 // definition. This avoids some of the overhead to track this at runtime | 3954 // definition. This avoids some of the overhead to track this at runtime |
3940 // and rules out many fields from being unnecessary unboxing candidates. | 3955 // and rules out many fields from being unnecessary unboxing candidates. |
3941 if (!field->has_static && has_initializer && has_simple_literal) { | 3956 if (!field->has_static && has_initializer && has_simple_literal) { |
3942 class_field.RecordStore(init_value); | 3957 class_field.RecordStore(init_value); |
3943 if (!init_value.IsNull() && init_value.IsDouble()) { | 3958 if (!init_value.IsNull() && init_value.IsDouble()) { |
3944 class_field.set_is_double_initialized(true); | 3959 class_field.set_is_double_initialized(true); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 "%s '%s' conflicts with previously declared %s", | 4086 "%s '%s' conflicts with previously declared %s", |
4072 member->ToCString(), | 4087 member->ToCString(), |
4073 name.ToCString(), | 4088 name.ToCString(), |
4074 existing_member->ToCString()); | 4089 existing_member->ToCString()); |
4075 } | 4090 } |
4076 } | 4091 } |
4077 } | 4092 } |
4078 | 4093 |
4079 | 4094 |
4080 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4095 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
4081 intptr_t metadata_pos) { | 4096 TokenDescriptor metadata_pos) { |
4082 TRACE_PARSER("ParseClassMemberDefinition"); | 4097 TRACE_PARSER("ParseClassMemberDefinition"); |
4083 MemberDesc member; | 4098 MemberDesc member; |
4084 current_member_ = &member; | 4099 current_member_ = &member; |
4085 member.metadata_pos = metadata_pos; | 4100 member.metadata_pos = metadata_pos; |
4086 member.decl_begin_pos = TokenPos(); | 4101 member.decl_begin_pos = TokenPos(); |
4087 if ((CurrentToken() == Token::kEXTERNAL) && | 4102 if ((CurrentToken() == Token::kEXTERNAL) && |
4088 (LookaheadToken(1) != Token::kLPAREN)) { | 4103 (LookaheadToken(1) != Token::kLPAREN)) { |
4089 ConsumeToken(); | 4104 ConsumeToken(); |
4090 member.has_external = true; | 4105 member.has_external = true; |
4091 } | 4106 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4282 UnexpectedToken(); | 4297 UnexpectedToken(); |
4283 } | 4298 } |
4284 current_member_ = NULL; | 4299 current_member_ = NULL; |
4285 CheckMemberNameConflict(members, &member); | 4300 CheckMemberNameConflict(members, &member); |
4286 members->AddMember(member); | 4301 members->AddMember(member); |
4287 } | 4302 } |
4288 | 4303 |
4289 | 4304 |
4290 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, | 4305 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
4291 const Object& tl_owner, | 4306 const Object& tl_owner, |
4292 intptr_t metadata_pos) { | 4307 TokenDescriptor metadata_pos) { |
4293 TRACE_PARSER("ParseEnumDeclaration"); | 4308 TRACE_PARSER("ParseEnumDeclaration"); |
4294 const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos | 4309 const TokenDescriptor declaration_pos = |
4295 : TokenPos(); | 4310 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); |
4296 ConsumeToken(); | 4311 ConsumeToken(); |
4297 const intptr_t name_pos = TokenPos(); | 4312 const TokenDescriptor name_pos = TokenPos(); |
4298 String* enum_name = | 4313 String* enum_name = |
4299 ExpectUserDefinedTypeIdentifier("enum type name expected"); | 4314 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
4300 if (FLAG_trace_parser) { | 4315 if (FLAG_trace_parser) { |
4301 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); | 4316 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); |
4302 } | 4317 } |
4303 ExpectToken(Token::kLBRACE); | 4318 ExpectToken(Token::kLBRACE); |
4304 if (!IsIdentifier()) { | 4319 if (!IsIdentifier()) { |
4305 ReportError("Enumeration must have at least one name"); | 4320 ReportError("Enumeration must have at least one name"); |
4306 } | 4321 } |
4307 while (IsIdentifier()) { | 4322 while (IsIdentifier()) { |
(...skipping 14 matching lines...) Expand all Loading... |
4322 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); | 4337 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); |
4323 if (!obj.IsNull()) { | 4338 if (!obj.IsNull()) { |
4324 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); | 4339 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); |
4325 } | 4340 } |
4326 Class& cls = Class::Handle(Z); | 4341 Class& cls = Class::Handle(Z); |
4327 cls = Class::New(*enum_name, script_, declaration_pos); | 4342 cls = Class::New(*enum_name, script_, declaration_pos); |
4328 cls.set_library(library_); | 4343 cls.set_library(library_); |
4329 library_.AddClass(cls); | 4344 library_.AddClass(cls); |
4330 cls.set_is_synthesized_class(); | 4345 cls.set_is_synthesized_class(); |
4331 cls.set_is_enum_class(); | 4346 cls.set_is_enum_class(); |
4332 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4347 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { |
4333 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4348 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
4334 } | 4349 } |
4335 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); | 4350 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
4336 pending_classes.Add(cls, Heap::kOld); | 4351 pending_classes.Add(cls, Heap::kOld); |
4337 } | 4352 } |
4338 | 4353 |
4339 | 4354 |
4340 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4355 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
4341 const Object& tl_owner, | 4356 const Object& tl_owner, |
4342 intptr_t metadata_pos) { | 4357 TokenDescriptor metadata_pos) { |
4343 TRACE_PARSER("ParseClassDeclaration"); | 4358 TRACE_PARSER("ParseClassDeclaration"); |
4344 bool is_patch = false; | 4359 bool is_patch = false; |
4345 bool is_abstract = false; | 4360 bool is_abstract = false; |
4346 intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos(); | 4361 TokenDescriptor declaration_pos = |
| 4362 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
4347 if (is_patch_source() && | 4363 if (is_patch_source() && |
4348 (CurrentToken() == Token::kIDENT) && | 4364 (CurrentToken() == Token::kIDENT) && |
4349 CurrentLiteral()->Equals("patch")) { | 4365 CurrentLiteral()->Equals("patch")) { |
4350 ConsumeToken(); | 4366 ConsumeToken(); |
4351 is_patch = true; | 4367 is_patch = true; |
4352 } else if (CurrentToken() == Token::kABSTRACT) { | 4368 } else if (CurrentToken() == Token::kABSTRACT) { |
4353 is_abstract = true; | 4369 is_abstract = true; |
4354 ConsumeToken(); | 4370 ConsumeToken(); |
4355 } | 4371 } |
4356 ExpectToken(Token::kCLASS); | 4372 ExpectToken(Token::kCLASS); |
4357 const intptr_t classname_pos = TokenPos(); | 4373 const TokenDescriptor classname_pos = TokenPos(); |
4358 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4374 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
4359 if (FLAG_trace_parser) { | 4375 if (FLAG_trace_parser) { |
4360 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 4376 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
4361 } | 4377 } |
4362 Class& cls = Class::Handle(Z); | 4378 Class& cls = Class::Handle(Z); |
4363 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); | 4379 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); |
4364 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4380 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
4365 if (obj.IsNull()) { | 4381 if (obj.IsNull()) { |
4366 if (is_patch) { | 4382 if (is_patch) { |
4367 ReportError(classname_pos, "missing class '%s' cannot be patched", | 4383 ReportError(classname_pos, "missing class '%s' cannot be patched", |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4441 class_name.ToCString(), | 4457 class_name.ToCString(), |
4442 String::Handle(orig_bound.UserVisibleName()).ToCString()); | 4458 String::Handle(orig_bound.UserVisibleName()).ToCString()); |
4443 } | 4459 } |
4444 } | 4460 } |
4445 cls.set_type_parameters(orig_type_parameters); | 4461 cls.set_type_parameters(orig_type_parameters); |
4446 } | 4462 } |
4447 | 4463 |
4448 if (is_abstract) { | 4464 if (is_abstract) { |
4449 cls.set_is_abstract(); | 4465 cls.set_is_abstract(); |
4450 } | 4466 } |
4451 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4467 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
4452 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4468 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
4453 } | 4469 } |
4454 | 4470 |
4455 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 4471 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
4456 if (is_mixin_declaration && is_patch) { | 4472 if (is_mixin_declaration && is_patch) { |
4457 ReportError(classname_pos, | 4473 ReportError(classname_pos, |
4458 "mixin application '%s' may not be a patch class", | 4474 "mixin application '%s' may not be a patch class", |
4459 class_name.ToCString()); | 4475 class_name.ToCString()); |
4460 } | 4476 } |
4461 | 4477 |
4462 AbstractType& super_type = Type::Handle(Z); | 4478 AbstractType& super_type = Type::Handle(Z); |
4463 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4479 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
4464 ConsumeToken(); // extends or = | 4480 ConsumeToken(); // extends or = |
4465 const intptr_t type_pos = TokenPos(); | 4481 const TokenDescriptor type_pos = TokenPos(); |
4466 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4482 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
4467 if (super_type.IsMalformedOrMalbounded()) { | 4483 if (super_type.IsMalformedOrMalbounded()) { |
4468 ReportError(Error::Handle(Z, super_type.error())); | 4484 ReportError(Error::Handle(Z, super_type.error())); |
4469 } | 4485 } |
4470 if (super_type.IsDynamicType()) { | 4486 if (super_type.IsDynamicType()) { |
4471 // Unlikely here, since super type is not resolved yet. | 4487 // Unlikely here, since super type is not resolved yet. |
4472 ReportError(type_pos, | 4488 ReportError(type_pos, |
4473 "class '%s' may not extend 'dynamic'", | 4489 "class '%s' may not extend 'dynamic'", |
4474 class_name.ToCString()); | 4490 class_name.ToCString()); |
4475 } | 4491 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4532 String& class_name = String::Handle(Z, cls.Name()); | 4548 String& class_name = String::Handle(Z, cls.Name()); |
4533 SkipMetadata(); | 4549 SkipMetadata(); |
4534 if (is_patch_source() && | 4550 if (is_patch_source() && |
4535 (CurrentToken() == Token::kIDENT) && | 4551 (CurrentToken() == Token::kIDENT) && |
4536 CurrentLiteral()->Equals("patch")) { | 4552 CurrentLiteral()->Equals("patch")) { |
4537 ConsumeToken(); | 4553 ConsumeToken(); |
4538 } else if (CurrentToken() == Token::kABSTRACT) { | 4554 } else if (CurrentToken() == Token::kABSTRACT) { |
4539 ConsumeToken(); | 4555 ConsumeToken(); |
4540 } | 4556 } |
4541 ExpectToken(Token::kCLASS); | 4557 ExpectToken(Token::kCLASS); |
4542 const intptr_t class_pos = TokenPos(); | 4558 const TokenDescriptor class_pos = TokenPos(); |
4543 ClassDesc members(Z, cls, class_name, false, class_pos); | 4559 ClassDesc members(Z, cls, class_name, false, class_pos); |
4544 while (CurrentToken() != Token::kLBRACE) { | 4560 while (CurrentToken() != Token::kLBRACE) { |
4545 ConsumeToken(); | 4561 ConsumeToken(); |
4546 } | 4562 } |
4547 ExpectToken(Token::kLBRACE); | 4563 ExpectToken(Token::kLBRACE); |
4548 while (CurrentToken() != Token::kRBRACE) { | 4564 while (CurrentToken() != Token::kRBRACE) { |
4549 intptr_t metadata_pos = SkipMetadata(); | 4565 TokenDescriptor metadata_pos = SkipMetadata(); |
4550 ParseClassMemberDefinition(&members, metadata_pos); | 4566 ParseClassMemberDefinition(&members, metadata_pos); |
4551 } | 4567 } |
4552 ExpectToken(Token::kRBRACE); | 4568 ExpectToken(Token::kRBRACE); |
4553 | 4569 |
4554 CheckConstructors(&members); | 4570 CheckConstructors(&members); |
4555 | 4571 |
4556 // Need to compute this here since MakeArray() will clear the | 4572 // Need to compute this here since MakeArray() will clear the |
4557 // functions array in members. | 4573 // functions array in members. |
4558 const bool need_implicit_constructor = | 4574 const bool need_implicit_constructor = |
4559 !members.has_constructor() && !cls.is_patch(); | 4575 !members.has_constructor() && !cls.is_patch(); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4818 ctors.Add(member); | 4834 ctors.Add(member); |
4819 member = class_desc->LookupMember(*member->redirect_name); | 4835 member = class_desc->LookupMember(*member->redirect_name); |
4820 } | 4836 } |
4821 } | 4837 } |
4822 } | 4838 } |
4823 | 4839 |
4824 | 4840 |
4825 void Parser::ParseMixinAppAlias( | 4841 void Parser::ParseMixinAppAlias( |
4826 const GrowableObjectArray& pending_classes, | 4842 const GrowableObjectArray& pending_classes, |
4827 const Object& tl_owner, | 4843 const Object& tl_owner, |
4828 intptr_t metadata_pos) { | 4844 TokenDescriptor metadata_pos) { |
4829 TRACE_PARSER("ParseMixinAppAlias"); | 4845 TRACE_PARSER("ParseMixinAppAlias"); |
4830 const intptr_t classname_pos = TokenPos(); | 4846 const TokenDescriptor classname_pos = TokenPos(); |
4831 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4847 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
4832 if (FLAG_trace_parser) { | 4848 if (FLAG_trace_parser) { |
4833 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4849 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
4834 class_name.ToCString()); | 4850 class_name.ToCString()); |
4835 } | 4851 } |
4836 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4852 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
4837 if (!obj.IsNull()) { | 4853 if (!obj.IsNull()) { |
4838 ReportError(classname_pos, "'%s' is already defined", | 4854 ReportError(classname_pos, "'%s' is already defined", |
4839 class_name.ToCString()); | 4855 class_name.ToCString()); |
4840 } | 4856 } |
4841 const Class& mixin_application = | 4857 const Class& mixin_application = |
4842 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); | 4858 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); |
4843 mixin_application.set_is_mixin_app_alias(); | 4859 mixin_application.set_is_mixin_app_alias(); |
4844 library_.AddClass(mixin_application); | 4860 library_.AddClass(mixin_application); |
4845 set_current_class(mixin_application); | 4861 set_current_class(mixin_application); |
4846 ParseTypeParameters(mixin_application); | 4862 ParseTypeParameters(mixin_application); |
4847 | 4863 |
4848 ExpectToken(Token::kASSIGN); | 4864 ExpectToken(Token::kASSIGN); |
4849 | 4865 |
4850 if (CurrentToken() == Token::kABSTRACT) { | 4866 if (CurrentToken() == Token::kABSTRACT) { |
4851 mixin_application.set_is_abstract(); | 4867 mixin_application.set_is_abstract(); |
4852 ConsumeToken(); | 4868 ConsumeToken(); |
4853 } | 4869 } |
4854 | 4870 |
4855 const intptr_t type_pos = TokenPos(); | 4871 const TokenDescriptor type_pos = TokenPos(); |
4856 AbstractType& type = | 4872 AbstractType& type = |
4857 AbstractType::Handle(Z, | 4873 AbstractType::Handle(Z, |
4858 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4874 ParseType(ClassFinalizer::kResolveTypeParameters)); |
4859 if (type.IsTypeParameter()) { | 4875 if (type.IsTypeParameter()) { |
4860 ReportError(type_pos, | 4876 ReportError(type_pos, |
4861 "class '%s' may not extend type parameter '%s'", | 4877 "class '%s' may not extend type parameter '%s'", |
4862 class_name.ToCString(), | 4878 class_name.ToCString(), |
4863 String::Handle(Z, type.UserVisibleName()).ToCString()); | 4879 String::Handle(Z, type.UserVisibleName()).ToCString()); |
4864 } | 4880 } |
4865 | 4881 |
4866 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4882 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
4867 type = ParseMixins(type); | 4883 type = ParseMixins(type); |
4868 | 4884 |
4869 mixin_application.set_super_type(type); | 4885 mixin_application.set_super_type(type); |
4870 mixin_application.set_is_synthesized_class(); | 4886 mixin_application.set_is_synthesized_class(); |
4871 | 4887 |
4872 // This mixin application alias needs an implicit constructor, but it is | 4888 // This mixin application alias needs an implicit constructor, but it is |
4873 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4889 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
4874 // because this class should be lazily compiled. | 4890 // because this class should be lazily compiled. |
4875 if (CurrentToken() == Token::kIMPLEMENTS) { | 4891 if (CurrentToken() == Token::kIMPLEMENTS) { |
4876 ParseInterfaceList(mixin_application); | 4892 ParseInterfaceList(mixin_application); |
4877 } | 4893 } |
4878 ExpectSemicolon(); | 4894 ExpectSemicolon(); |
4879 pending_classes.Add(mixin_application, Heap::kOld); | 4895 pending_classes.Add(mixin_application, Heap::kOld); |
4880 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4896 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
4881 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); | 4897 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); |
4882 } | 4898 } |
4883 } | 4899 } |
4884 | 4900 |
4885 | 4901 |
4886 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 4902 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
4887 // We need this lookahead to distinguish between the optional return type | 4903 // We need this lookahead to distinguish between the optional return type |
4888 // and the alias name of a function type alias. | 4904 // and the alias name of a function type alias. |
4889 // Token position remains unchanged. | 4905 // Token position remains unchanged. |
4890 bool Parser::IsFunctionTypeAliasName() { | 4906 bool Parser::IsFunctionTypeAliasName() { |
4891 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4907 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
4892 return true; | 4908 return true; |
4893 } | 4909 } |
4894 const intptr_t saved_pos = TokenPos(); | 4910 const TokenDescriptor saved_pos = TokenPos(); |
4895 bool is_alias_name = false; | 4911 bool is_alias_name = false; |
4896 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4912 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
4897 ConsumeToken(); | 4913 ConsumeToken(); |
4898 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { | 4914 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { |
4899 is_alias_name = true; | 4915 is_alias_name = true; |
4900 } | 4916 } |
4901 } | 4917 } |
4902 SetPosition(saved_pos); | 4918 SetPosition(saved_pos); |
4903 return is_alias_name; | 4919 return is_alias_name; |
4904 } | 4920 } |
4905 | 4921 |
4906 | 4922 |
4907 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". | 4923 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". |
4908 // Token position remains unchanged. | 4924 // Token position remains unchanged. |
4909 bool Parser::IsMixinAppAlias() { | 4925 bool Parser::IsMixinAppAlias() { |
4910 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { | 4926 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { |
4911 return true; | 4927 return true; |
4912 } | 4928 } |
4913 const intptr_t saved_pos = TokenPos(); | 4929 const TokenDescriptor saved_pos = TokenPos(); |
4914 bool is_mixin_def = false; | 4930 bool is_mixin_def = false; |
4915 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4931 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
4916 ConsumeToken(); | 4932 ConsumeToken(); |
4917 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { | 4933 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { |
4918 is_mixin_def = true; | 4934 is_mixin_def = true; |
4919 } | 4935 } |
4920 } | 4936 } |
4921 SetPosition(saved_pos); | 4937 SetPosition(saved_pos); |
4922 return is_mixin_def; | 4938 return is_mixin_def; |
4923 } | 4939 } |
4924 | 4940 |
4925 | 4941 |
4926 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4942 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
4927 const Object& tl_owner, | 4943 const Object& tl_owner, |
4928 intptr_t metadata_pos) { | 4944 TokenDescriptor metadata_pos) { |
4929 TRACE_PARSER("ParseTypedef"); | 4945 TRACE_PARSER("ParseTypedef"); |
4930 intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos(); | 4946 TokenDescriptor declaration_pos = |
| 4947 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
4931 ExpectToken(Token::kTYPEDEF); | 4948 ExpectToken(Token::kTYPEDEF); |
4932 | 4949 |
4933 if (IsMixinAppAlias()) { | 4950 if (IsMixinAppAlias()) { |
4934 if (FLAG_warn_mixin_typedef) { | 4951 if (FLAG_warn_mixin_typedef) { |
4935 ReportWarning(TokenPos(), "deprecated mixin application typedef"); | 4952 ReportWarning(TokenPos(), "deprecated mixin application typedef"); |
4936 } | 4953 } |
4937 ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos); | 4954 ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos); |
4938 return; | 4955 return; |
4939 } | 4956 } |
4940 | 4957 |
4941 // Parse the result type of the function type. | 4958 // Parse the result type of the function type. |
4942 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 4959 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
4943 if (CurrentToken() == Token::kVOID) { | 4960 if (CurrentToken() == Token::kVOID) { |
4944 ConsumeToken(); | 4961 ConsumeToken(); |
4945 result_type = Type::VoidType(); | 4962 result_type = Type::VoidType(); |
4946 } else if (!IsFunctionTypeAliasName()) { | 4963 } else if (!IsFunctionTypeAliasName()) { |
4947 // Type annotations in typedef are never ignored, even in production mode. | 4964 // Type annotations in typedef are never ignored, even in production mode. |
4948 // Wait until we have an owner class before resolving the result type. | 4965 // Wait until we have an owner class before resolving the result type. |
4949 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4966 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
4950 } | 4967 } |
4951 | 4968 |
4952 const intptr_t alias_name_pos = TokenPos(); | 4969 const TokenDescriptor alias_name_pos = TokenPos(); |
4953 const String* alias_name = | 4970 const String* alias_name = |
4954 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4971 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
4955 | 4972 |
4956 // Lookup alias name and report an error if it is already defined in | 4973 // Lookup alias name and report an error if it is already defined in |
4957 // the library scope. | 4974 // the library scope. |
4958 const Object& obj = | 4975 const Object& obj = |
4959 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); | 4976 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); |
4960 if (!obj.IsNull()) { | 4977 if (!obj.IsNull()) { |
4961 ReportError(alias_name_pos, | 4978 ReportError(alias_name_pos, |
4962 "'%s' is already defined", alias_name->ToCString()); | 4979 "'%s' is already defined", alias_name->ToCString()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5005 function_type_alias.set_signature_function(signature_function); | 5022 function_type_alias.set_signature_function(signature_function); |
5006 | 5023 |
5007 if (FLAG_trace_parser) { | 5024 if (FLAG_trace_parser) { |
5008 OS::Print("TopLevel parsing function type alias '%s'\n", | 5025 OS::Print("TopLevel parsing function type alias '%s'\n", |
5009 String::Handle(Z, signature_function.Signature()).ToCString()); | 5026 String::Handle(Z, signature_function.Signature()).ToCString()); |
5010 } | 5027 } |
5011 // The alias should not be marked as finalized yet, since it needs to be | 5028 // The alias should not be marked as finalized yet, since it needs to be |
5012 // checked in the class finalizer for illegal self references. | 5029 // checked in the class finalizer for illegal self references. |
5013 ASSERT(!function_type_alias.is_finalized()); | 5030 ASSERT(!function_type_alias.is_finalized()); |
5014 pending_classes.Add(function_type_alias, Heap::kOld); | 5031 pending_classes.Add(function_type_alias, Heap::kOld); |
5015 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5032 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5016 library_.AddClassMetadata(function_type_alias, | 5033 library_.AddClassMetadata(function_type_alias, |
5017 tl_owner, | 5034 tl_owner, |
5018 metadata_pos); | 5035 metadata_pos); |
5019 } | 5036 } |
5020 } | 5037 } |
5021 | 5038 |
5022 | 5039 |
5023 // Consumes exactly one right angle bracket. If the current token is a single | 5040 // Consumes exactly one right angle bracket. If the current token is a single |
5024 // bracket token, it is consumed normally. However, if it is a double or triple | 5041 // bracket token, it is consumed normally. However, if it is a double or triple |
5025 // bracket, it is replaced by a single or double bracket token without | 5042 // bracket, it is replaced by a single or double bracket token without |
5026 // incrementing the token index. | 5043 // incrementing the token index. |
5027 void Parser::ConsumeRightAngleBracket() { | 5044 void Parser::ConsumeRightAngleBracket() { |
5028 if (token_kind_ == Token::kGT) { | 5045 if (token_kind_ == Token::kGT) { |
5029 ConsumeToken(); | 5046 ConsumeToken(); |
5030 } else if (token_kind_ == Token::kSHR) { | 5047 } else if (token_kind_ == Token::kSHR) { |
5031 token_kind_ = Token::kGT; | 5048 token_kind_ = Token::kGT; |
5032 } else { | 5049 } else { |
5033 UNREACHABLE(); | 5050 UNREACHABLE(); |
5034 } | 5051 } |
5035 } | 5052 } |
5036 | 5053 |
5037 | 5054 |
5038 intptr_t Parser::SkipMetadata() { | 5055 TokenDescriptor Parser::SkipMetadata() { |
5039 if (CurrentToken() != Token::kAT) { | 5056 if (CurrentToken() != Token::kAT) { |
5040 return Token::kNoSourcePos; | 5057 return TokenDescriptor::kNoSource; |
5041 } | 5058 } |
5042 intptr_t metadata_pos = TokenPos(); | 5059 TokenDescriptor metadata_pos = TokenPos(); |
5043 while (CurrentToken() == Token::kAT) { | 5060 while (CurrentToken() == Token::kAT) { |
5044 ConsumeToken(); | 5061 ConsumeToken(); |
5045 ExpectIdentifier("identifier expected"); | 5062 ExpectIdentifier("identifier expected"); |
5046 if (CurrentToken() == Token::kPERIOD) { | 5063 if (CurrentToken() == Token::kPERIOD) { |
5047 ConsumeToken(); | 5064 ConsumeToken(); |
5048 ExpectIdentifier("identifier expected"); | 5065 ExpectIdentifier("identifier expected"); |
5049 if (CurrentToken() == Token::kPERIOD) { | 5066 if (CurrentToken() == Token::kPERIOD) { |
5050 ConsumeToken(); | 5067 ConsumeToken(); |
5051 ExpectIdentifier("identifier expected"); | 5068 ExpectIdentifier("identifier expected"); |
5052 } | 5069 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5096 TRACE_PARSER("ParseTypeParameters"); | 5113 TRACE_PARSER("ParseTypeParameters"); |
5097 if (CurrentToken() == Token::kLT) { | 5114 if (CurrentToken() == Token::kLT) { |
5098 GrowableArray<AbstractType*> type_parameters_array(Z, 2); | 5115 GrowableArray<AbstractType*> type_parameters_array(Z, 2); |
5099 intptr_t index = 0; | 5116 intptr_t index = 0; |
5100 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5117 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
5101 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5118 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
5102 String& existing_type_parameter_name = String::Handle(Z); | 5119 String& existing_type_parameter_name = String::Handle(Z); |
5103 AbstractType& type_parameter_bound = Type::Handle(Z); | 5120 AbstractType& type_parameter_bound = Type::Handle(Z); |
5104 do { | 5121 do { |
5105 ConsumeToken(); | 5122 ConsumeToken(); |
5106 const intptr_t metadata_pos = SkipMetadata(); | 5123 const TokenDescriptor metadata_pos = SkipMetadata(); |
5107 const intptr_t type_parameter_pos = TokenPos(); | 5124 const TokenDescriptor type_parameter_pos = TokenPos(); |
5108 const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos | 5125 const TokenDescriptor declaration_pos = |
5109 : type_parameter_pos; | 5126 metadata_pos.IsReal() ? metadata_pos : type_parameter_pos; |
5110 String& type_parameter_name = | 5127 String& type_parameter_name = |
5111 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 5128 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
5112 // Check for duplicate type parameters. | 5129 // Check for duplicate type parameters. |
5113 for (intptr_t i = 0; i < index; i++) { | 5130 for (intptr_t i = 0; i < index; i++) { |
5114 existing_type_parameter ^= type_parameters_array.At(i)->raw(); | 5131 existing_type_parameter ^= type_parameters_array.At(i)->raw(); |
5115 existing_type_parameter_name = existing_type_parameter.name(); | 5132 existing_type_parameter_name = existing_type_parameter.name(); |
5116 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 5133 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
5117 ReportError(type_parameter_pos, "duplicate type parameter '%s'", | 5134 ReportError(type_parameter_pos, "duplicate type parameter '%s'", |
5118 type_parameter_name.ToCString()); | 5135 type_parameter_name.ToCString()); |
5119 } | 5136 } |
5120 } | 5137 } |
5121 if (CurrentToken() == Token::kEXTENDS) { | 5138 if (CurrentToken() == Token::kEXTENDS) { |
5122 ConsumeToken(); | 5139 ConsumeToken(); |
5123 // A bound may refer to the owner of the type parameter it applies to, | 5140 // A bound may refer to the owner of the type parameter it applies to, |
5124 // i.e. to the class or interface currently being parsed. | 5141 // i.e. to the class or interface currently being parsed. |
5125 // Postpone resolution in order to avoid resolving the class and its | 5142 // Postpone resolution in order to avoid resolving the class and its |
5126 // type parameters, as they are not fully parsed yet. | 5143 // type parameters, as they are not fully parsed yet. |
5127 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 5144 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
5128 } else { | 5145 } else { |
5129 type_parameter_bound = I->object_store()->object_type(); | 5146 type_parameter_bound = I->object_store()->object_type(); |
5130 } | 5147 } |
5131 type_parameter = TypeParameter::New(cls, | 5148 type_parameter = TypeParameter::New(cls, |
5132 index, | 5149 index, |
5133 type_parameter_name, | 5150 type_parameter_name, |
5134 type_parameter_bound, | 5151 type_parameter_bound, |
5135 declaration_pos); | 5152 declaration_pos); |
5136 type_parameters_array.Add( | 5153 type_parameters_array.Add( |
5137 &AbstractType::ZoneHandle(Z, type_parameter.raw())); | 5154 &AbstractType::ZoneHandle(Z, type_parameter.raw())); |
5138 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5155 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5139 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 5156 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
5140 } | 5157 } |
5141 index++; | 5158 index++; |
5142 } while (CurrentToken() == Token::kCOMMA); | 5159 } while (CurrentToken() == Token::kCOMMA); |
5143 Token::Kind token = CurrentToken(); | 5160 Token::Kind token = CurrentToken(); |
5144 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5161 if ((token == Token::kGT) || (token == Token::kSHR)) { |
5145 ConsumeRightAngleBracket(); | 5162 ConsumeRightAngleBracket(); |
5146 } else { | 5163 } else { |
5147 ReportError("right angle bracket expected"); | 5164 ReportError("right angle bracket expected"); |
5148 } | 5165 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5203 AbstractType& interface = AbstractType::Handle(Z); | 5220 AbstractType& interface = AbstractType::Handle(Z); |
5204 // First get all the interfaces already implemented by class. | 5221 // First get all the interfaces already implemented by class. |
5205 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); | 5222 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); |
5206 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 5223 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
5207 interface ^= cls_interfaces.At(i); | 5224 interface ^= cls_interfaces.At(i); |
5208 all_interfaces.Add(interface); | 5225 all_interfaces.Add(interface); |
5209 } | 5226 } |
5210 // Now parse and add the new interfaces. | 5227 // Now parse and add the new interfaces. |
5211 do { | 5228 do { |
5212 ConsumeToken(); | 5229 ConsumeToken(); |
5213 intptr_t interface_pos = TokenPos(); | 5230 TokenDescriptor interface_pos = TokenPos(); |
5214 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 5231 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
5215 if (interface.IsTypeParameter()) { | 5232 if (interface.IsTypeParameter()) { |
5216 ReportError(interface_pos, | 5233 ReportError(interface_pos, |
5217 "type parameter '%s' may not be used in interface list", | 5234 "type parameter '%s' may not be used in interface list", |
5218 String::Handle(Z, interface.UserVisibleName()).ToCString()); | 5235 String::Handle(Z, interface.UserVisibleName()).ToCString()); |
5219 } | 5236 } |
5220 all_interfaces.Add(interface); | 5237 all_interfaces.Add(interface); |
5221 } while (CurrentToken() == Token::kCOMMA); | 5238 } while (CurrentToken() == Token::kCOMMA); |
5222 cls_interfaces = Array::MakeArray(all_interfaces); | 5239 cls_interfaces = Array::MakeArray(all_interfaces); |
5223 cls.set_interfaces(cls_interfaces); | 5240 cls.set_interfaces(cls_interfaces); |
(...skipping 21 matching lines...) Expand all Loading... |
5245 } | 5262 } |
5246 mixin_types.Add(mixin_type); | 5263 mixin_types.Add(mixin_type); |
5247 } while (CurrentToken() == Token::kCOMMA); | 5264 } while (CurrentToken() == Token::kCOMMA); |
5248 return MixinAppType::New(super_type, | 5265 return MixinAppType::New(super_type, |
5249 Array::Handle(Z, Array::MakeArray(mixin_types))); | 5266 Array::Handle(Z, Array::MakeArray(mixin_types))); |
5250 } | 5267 } |
5251 | 5268 |
5252 | 5269 |
5253 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5270 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
5254 const Object& owner, | 5271 const Object& owner, |
5255 intptr_t metadata_pos) { | 5272 TokenDescriptor metadata_pos) { |
5256 TRACE_PARSER("ParseTopLevelVariable"); | 5273 TRACE_PARSER("ParseTopLevelVariable"); |
5257 const bool is_const = (CurrentToken() == Token::kCONST); | 5274 const bool is_const = (CurrentToken() == Token::kCONST); |
5258 // Const fields are implicitly final. | 5275 // Const fields are implicitly final. |
5259 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5276 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
5260 const bool is_static = true; | 5277 const bool is_static = true; |
5261 const AbstractType& type = AbstractType::ZoneHandle(Z, | 5278 const AbstractType& type = AbstractType::ZoneHandle(Z, |
5262 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5279 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
5263 Field& field = Field::Handle(Z); | 5280 Field& field = Field::Handle(Z); |
5264 Function& getter = Function::Handle(Z); | 5281 Function& getter = Function::Handle(Z); |
5265 while (true) { | 5282 while (true) { |
5266 const intptr_t name_pos = TokenPos(); | 5283 const TokenDescriptor name_pos = TokenPos(); |
5267 String& var_name = *ExpectIdentifier("variable name expected"); | 5284 String& var_name = *ExpectIdentifier("variable name expected"); |
5268 | 5285 |
5269 if (library_.LookupLocalObject(var_name) != Object::null()) { | 5286 if (library_.LookupLocalObject(var_name) != Object::null()) { |
5270 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); | 5287 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); |
5271 } | 5288 } |
5272 | 5289 |
5273 // Check whether a getter or setter for this name exists. A const | 5290 // Check whether a getter or setter for this name exists. A const |
5274 // or final field implies a setter which throws a NoSuchMethodError, | 5291 // or final field implies a setter which throws a NoSuchMethodError, |
5275 // thus we need to check for conflicts with existing setters and | 5292 // thus we need to check for conflicts with existing setters and |
5276 // getters. | 5293 // getters. |
(...skipping 10 matching lines...) Expand all Loading... |
5287 | 5304 |
5288 const bool is_reflectable = | 5305 const bool is_reflectable = |
5289 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); | 5306 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); |
5290 | 5307 |
5291 field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos); | 5308 field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos); |
5292 field.SetFieldType(type); | 5309 field.SetFieldType(type); |
5293 field.set_is_reflectable(is_reflectable); | 5310 field.set_is_reflectable(is_reflectable); |
5294 field.SetStaticValue(Object::null_instance(), true); | 5311 field.SetStaticValue(Object::null_instance(), true); |
5295 top_level->AddField(field); | 5312 top_level->AddField(field); |
5296 library_.AddObject(field, var_name); | 5313 library_.AddObject(field, var_name); |
5297 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5314 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5298 library_.AddFieldMetadata(field, metadata_pos); | 5315 library_.AddFieldMetadata(field, metadata_pos); |
5299 } | 5316 } |
5300 if (CurrentToken() == Token::kASSIGN) { | 5317 if (CurrentToken() == Token::kASSIGN) { |
5301 ConsumeToken(); | 5318 ConsumeToken(); |
5302 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); | 5319 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); |
5303 bool has_simple_literal = false; | 5320 bool has_simple_literal = false; |
5304 if (LookaheadToken(1) == Token::kSEMICOLON) { | 5321 if (LookaheadToken(1) == Token::kSEMICOLON) { |
5305 has_simple_literal = IsSimpleLiteral(type, &field_value); | 5322 has_simple_literal = IsSimpleLiteral(type, &field_value); |
5306 } | 5323 } |
5307 SkipExpr(); | 5324 SkipExpr(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5363 ConsumeToken(); | 5380 ConsumeToken(); |
5364 ConsumeToken(); | 5381 ConsumeToken(); |
5365 return RawFunction::kSyncGen; | 5382 return RawFunction::kSyncGen; |
5366 } | 5383 } |
5367 return RawFunction::kNoModifier; | 5384 return RawFunction::kNoModifier; |
5368 } | 5385 } |
5369 | 5386 |
5370 | 5387 |
5371 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5388 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
5372 const Object& owner, | 5389 const Object& owner, |
5373 intptr_t metadata_pos) { | 5390 TokenDescriptor metadata_pos) { |
5374 TRACE_PARSER("ParseTopLevelFunction"); | 5391 TRACE_PARSER("ParseTopLevelFunction"); |
5375 const intptr_t decl_begin_pos = TokenPos(); | 5392 const TokenDescriptor decl_begin_pos = TokenPos(); |
5376 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5393 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
5377 const bool is_static = true; | 5394 const bool is_static = true; |
5378 bool is_external = false; | 5395 bool is_external = false; |
5379 bool is_patch = false; | 5396 bool is_patch = false; |
5380 if (is_patch_source() && | 5397 if (is_patch_source() && |
5381 (CurrentToken() == Token::kIDENT) && | 5398 (CurrentToken() == Token::kIDENT) && |
5382 CurrentLiteral()->Equals("patch") && | 5399 CurrentLiteral()->Equals("patch") && |
5383 (LookaheadToken(1) != Token::kLPAREN)) { | 5400 (LookaheadToken(1) != Token::kLPAREN)) { |
5384 ConsumeToken(); | 5401 ConsumeToken(); |
5385 is_patch = true; | 5402 is_patch = true; |
5386 } else if (CurrentToken() == Token::kEXTERNAL) { | 5403 } else if (CurrentToken() == Token::kEXTERNAL) { |
5387 ConsumeToken(); | 5404 ConsumeToken(); |
5388 is_external = true; | 5405 is_external = true; |
5389 } | 5406 } |
5390 if (CurrentToken() == Token::kVOID) { | 5407 if (CurrentToken() == Token::kVOID) { |
5391 ConsumeToken(); | 5408 ConsumeToken(); |
5392 result_type = Type::VoidType(); | 5409 result_type = Type::VoidType(); |
5393 } else { | 5410 } else { |
5394 // Parse optional type. | 5411 // Parse optional type. |
5395 if ((CurrentToken() == Token::kIDENT) && | 5412 if ((CurrentToken() == Token::kIDENT) && |
5396 (LookaheadToken(1) != Token::kLPAREN)) { | 5413 (LookaheadToken(1) != Token::kLPAREN)) { |
5397 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5414 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
5398 } | 5415 } |
5399 } | 5416 } |
5400 const intptr_t name_pos = TokenPos(); | 5417 const TokenDescriptor name_pos = TokenPos(); |
5401 const String& func_name = *ExpectIdentifier("function name expected"); | 5418 const String& func_name = *ExpectIdentifier("function name expected"); |
5402 | 5419 |
5403 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 5420 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
5404 if (found && !is_patch) { | 5421 if (found && !is_patch) { |
5405 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); | 5422 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); |
5406 } else if (!found && is_patch) { | 5423 } else if (!found && is_patch) { |
5407 ReportError(name_pos, "missing '%s' cannot be patched", | 5424 ReportError(name_pos, "missing '%s' cannot be patched", |
5408 func_name.ToCString()); | 5425 func_name.ToCString()); |
5409 } | 5426 } |
5410 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); | 5427 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); |
5411 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5428 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
5412 ReportError(name_pos, "'%s' is already defined as getter", | 5429 ReportError(name_pos, "'%s' is already defined as getter", |
5413 func_name.ToCString()); | 5430 func_name.ToCString()); |
5414 } | 5431 } |
5415 // A setter named x= may co-exist with a function named x, thus we do | 5432 // A setter named x= may co-exist with a function named x, thus we do |
5416 // not need to check setters. | 5433 // not need to check setters. |
5417 | 5434 |
5418 CheckToken(Token::kLPAREN); | 5435 CheckToken(Token::kLPAREN); |
5419 const intptr_t function_pos = TokenPos(); | 5436 const TokenDescriptor function_pos = TokenPos(); |
5420 ParamList params; | 5437 ParamList params; |
5421 const bool allow_explicit_default_values = true; | 5438 const bool allow_explicit_default_values = true; |
5422 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5439 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
5423 | 5440 |
5424 const intptr_t modifier_pos = TokenPos(); | 5441 const TokenDescriptor modifier_pos = TokenPos(); |
5425 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5442 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
5426 | 5443 |
5427 intptr_t function_end_pos = function_pos; | 5444 TokenDescriptor function_end_pos = function_pos; |
5428 bool is_native = false; | 5445 bool is_native = false; |
5429 String* native_name = NULL; | 5446 String* native_name = NULL; |
5430 if (is_external) { | 5447 if (is_external) { |
5431 function_end_pos = TokenPos(); | 5448 function_end_pos = TokenPos(); |
5432 ExpectSemicolon(); | 5449 ExpectSemicolon(); |
5433 } else if (CurrentToken() == Token::kLBRACE) { | 5450 } else if (CurrentToken() == Token::kLBRACE) { |
5434 SkipBlock(); | 5451 SkipBlock(); |
5435 function_end_pos = TokenPos(); | 5452 function_end_pos = TokenPos(); |
5436 ExpectToken(Token::kRBRACE); | 5453 ExpectToken(Token::kRBRACE); |
5437 } else if (CurrentToken() == Token::kARROW) { | 5454 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5478 library_.AddObject(func, func_name); | 5495 library_.AddObject(func, func_name); |
5479 } else { | 5496 } else { |
5480 // Need to remove the previously added function that is being patched. | 5497 // Need to remove the previously added function that is being patched. |
5481 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); | 5498 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); |
5482 const Function& replaced_func = | 5499 const Function& replaced_func = |
5483 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); | 5500 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); |
5484 ASSERT(!replaced_func.IsNull()); | 5501 ASSERT(!replaced_func.IsNull()); |
5485 toplevel_cls.RemoveFunction(replaced_func); | 5502 toplevel_cls.RemoveFunction(replaced_func); |
5486 library_.ReplaceObject(func, func_name); | 5503 library_.ReplaceObject(func, func_name); |
5487 } | 5504 } |
5488 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5505 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5489 library_.AddFunctionMetadata(func, metadata_pos); | 5506 library_.AddFunctionMetadata(func, metadata_pos); |
5490 } | 5507 } |
5491 } | 5508 } |
5492 | 5509 |
5493 | 5510 |
5494 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 5511 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
5495 const Object& owner, | 5512 const Object& owner, |
5496 intptr_t metadata_pos) { | 5513 TokenDescriptor metadata_pos) { |
5497 TRACE_PARSER("ParseTopLevelAccessor"); | 5514 TRACE_PARSER("ParseTopLevelAccessor"); |
5498 const intptr_t decl_begin_pos = TokenPos(); | 5515 const TokenDescriptor decl_begin_pos = TokenPos(); |
5499 const bool is_static = true; | 5516 const bool is_static = true; |
5500 bool is_external = false; | 5517 bool is_external = false; |
5501 bool is_patch = false; | 5518 bool is_patch = false; |
5502 AbstractType& result_type = AbstractType::Handle(Z); | 5519 AbstractType& result_type = AbstractType::Handle(Z); |
5503 if (is_patch_source() && | 5520 if (is_patch_source() && |
5504 (CurrentToken() == Token::kIDENT) && | 5521 (CurrentToken() == Token::kIDENT) && |
5505 CurrentLiteral()->Equals("patch")) { | 5522 CurrentLiteral()->Equals("patch")) { |
5506 ConsumeToken(); | 5523 ConsumeToken(); |
5507 is_patch = true; | 5524 is_patch = true; |
5508 } else if (CurrentToken() == Token::kEXTERNAL) { | 5525 } else if (CurrentToken() == Token::kEXTERNAL) { |
(...skipping 12 matching lines...) Expand all Loading... |
5521 } else { | 5538 } else { |
5522 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5539 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
5523 } | 5540 } |
5524 is_getter = (CurrentToken() == Token::kGET); | 5541 is_getter = (CurrentToken() == Token::kGET); |
5525 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 5542 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
5526 ConsumeToken(); | 5543 ConsumeToken(); |
5527 } else { | 5544 } else { |
5528 UnexpectedToken(); | 5545 UnexpectedToken(); |
5529 } | 5546 } |
5530 } | 5547 } |
5531 const intptr_t name_pos = TokenPos(); | 5548 const TokenDescriptor name_pos = TokenPos(); |
5532 const String* field_name = ExpectIdentifier("accessor name expected"); | 5549 const String* field_name = ExpectIdentifier("accessor name expected"); |
5533 | 5550 |
5534 const intptr_t accessor_pos = TokenPos(); | 5551 const TokenDescriptor accessor_pos = TokenPos(); |
5535 ParamList params; | 5552 ParamList params; |
5536 | 5553 |
5537 if (!is_getter) { | 5554 if (!is_getter) { |
5538 const bool allow_explicit_default_values = true; | 5555 const bool allow_explicit_default_values = true; |
5539 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5556 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
5540 } | 5557 } |
5541 String& accessor_name = String::ZoneHandle(Z); | 5558 String& accessor_name = String::ZoneHandle(Z); |
5542 int expected_num_parameters = -1; | 5559 int expected_num_parameters = -1; |
5543 if (is_getter) { | 5560 if (is_getter) { |
5544 expected_num_parameters = 0; | 5561 expected_num_parameters = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
5571 if (found && !is_patch) { | 5588 if (found && !is_patch) { |
5572 ReportError(name_pos, "%s for '%s' is already defined", | 5589 ReportError(name_pos, "%s for '%s' is already defined", |
5573 is_getter ? "getter" : "setter", | 5590 is_getter ? "getter" : "setter", |
5574 field_name->ToCString()); | 5591 field_name->ToCString()); |
5575 } else if (!found && is_patch) { | 5592 } else if (!found && is_patch) { |
5576 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5593 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
5577 is_getter ? "getter" : "setter", | 5594 is_getter ? "getter" : "setter", |
5578 field_name->ToCString()); | 5595 field_name->ToCString()); |
5579 } | 5596 } |
5580 | 5597 |
5581 const intptr_t modifier_pos = TokenPos(); | 5598 const TokenDescriptor modifier_pos = TokenPos(); |
5582 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5599 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
5583 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { | 5600 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { |
5584 ReportError(modifier_pos, | 5601 ReportError(modifier_pos, |
5585 "setter function cannot be async, async* or sync*"); | 5602 "setter function cannot be async, async* or sync*"); |
5586 } | 5603 } |
5587 | 5604 |
5588 intptr_t accessor_end_pos = accessor_pos; | 5605 TokenDescriptor accessor_end_pos = accessor_pos; |
5589 bool is_native = false; | 5606 bool is_native = false; |
5590 String* native_name = NULL; | 5607 String* native_name = NULL; |
5591 if (is_external) { | 5608 if (is_external) { |
5592 accessor_end_pos = TokenPos(); | 5609 accessor_end_pos = TokenPos(); |
5593 ExpectSemicolon(); | 5610 ExpectSemicolon(); |
5594 } else if (CurrentToken() == Token::kLBRACE) { | 5611 } else if (CurrentToken() == Token::kLBRACE) { |
5595 SkipBlock(); | 5612 SkipBlock(); |
5596 accessor_end_pos = TokenPos(); | 5613 accessor_end_pos = TokenPos(); |
5597 ExpectToken(Token::kRBRACE); | 5614 ExpectToken(Token::kRBRACE); |
5598 } else if (CurrentToken() == Token::kARROW) { | 5615 } else if (CurrentToken() == Token::kARROW) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5643 // Need to remove the previously added accessor that is being patched. | 5660 // Need to remove the previously added accessor that is being patched. |
5644 const Class& toplevel_cls = Class::Handle(Z, | 5661 const Class& toplevel_cls = Class::Handle(Z, |
5645 owner.IsClass() ? Class::Cast(owner).raw() | 5662 owner.IsClass() ? Class::Cast(owner).raw() |
5646 : PatchClass::Cast(owner).patched_class()); | 5663 : PatchClass::Cast(owner).patched_class()); |
5647 const Function& replaced_func = | 5664 const Function& replaced_func = |
5648 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); | 5665 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); |
5649 ASSERT(!replaced_func.IsNull()); | 5666 ASSERT(!replaced_func.IsNull()); |
5650 toplevel_cls.RemoveFunction(replaced_func); | 5667 toplevel_cls.RemoveFunction(replaced_func); |
5651 library_.ReplaceObject(func, accessor_name); | 5668 library_.ReplaceObject(func, accessor_name); |
5652 } | 5669 } |
5653 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5670 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5654 library_.AddFunctionMetadata(func, metadata_pos); | 5671 library_.AddFunctionMetadata(func, metadata_pos); |
5655 } | 5672 } |
5656 } | 5673 } |
5657 | 5674 |
5658 | 5675 |
5659 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, | 5676 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, |
5660 intptr_t token_pos, | 5677 TokenDescriptor token_pos, |
5661 const String& url) { | 5678 const String& url) { |
5662 Dart_LibraryTagHandler handler = I->library_tag_handler(); | 5679 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
5663 if (handler == NULL) { | 5680 if (handler == NULL) { |
5664 if (url.StartsWith(Symbols::DartScheme())) { | 5681 if (url.StartsWith(Symbols::DartScheme())) { |
5665 if (tag == Dart_kCanonicalizeUrl) { | 5682 if (tag == Dart_kCanonicalizeUrl) { |
5666 return url.raw(); | 5683 return url.raw(); |
5667 } | 5684 } |
5668 return Object::null(); | 5685 return Object::null(); |
5669 } | 5686 } |
5670 ReportError(token_pos, "no library handler registered"); | 5687 ReportError(token_pos, "no library handler registered"); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5721 ConsumeToken(); // Identifier. | 5738 ConsumeToken(); // Identifier. |
5722 if (CurrentToken() != Token::kCOMMA) { | 5739 if (CurrentToken() != Token::kCOMMA) { |
5723 return; | 5740 return; |
5724 } | 5741 } |
5725 ConsumeToken(); // Comma. | 5742 ConsumeToken(); // Comma. |
5726 } | 5743 } |
5727 } | 5744 } |
5728 | 5745 |
5729 | 5746 |
5730 void Parser::ParseLibraryImportExport(const Object& tl_owner, | 5747 void Parser::ParseLibraryImportExport(const Object& tl_owner, |
5731 intptr_t metadata_pos) { | 5748 TokenDescriptor metadata_pos) { |
5732 bool is_import = (CurrentToken() == Token::kIMPORT); | 5749 bool is_import = (CurrentToken() == Token::kIMPORT); |
5733 bool is_export = (CurrentToken() == Token::kEXPORT); | 5750 bool is_export = (CurrentToken() == Token::kEXPORT); |
5734 ASSERT(is_import || is_export); | 5751 ASSERT(is_import || is_export); |
5735 const intptr_t import_pos = TokenPos(); | 5752 const TokenDescriptor import_pos = TokenPos(); |
5736 ConsumeToken(); | 5753 ConsumeToken(); |
5737 CheckToken(Token::kSTRING, "library url expected"); | 5754 CheckToken(Token::kSTRING, "library url expected"); |
5738 AstNode* url_literal = ParseStringLiteral(false); | 5755 AstNode* url_literal = ParseStringLiteral(false); |
5739 if (FLAG_conditional_directives) { | 5756 if (FLAG_conditional_directives) { |
5740 bool condition_triggered = false; | 5757 bool condition_triggered = false; |
5741 while (CurrentToken() == Token::kIF) { | 5758 while (CurrentToken() == Token::kIF) { |
5742 // Conditional import: if (env == val) uri. | 5759 // Conditional import: if (env == val) uri. |
5743 ConsumeToken(); | 5760 ConsumeToken(); |
5744 ExpectToken(Token::kLPAREN); | 5761 ExpectToken(Token::kLPAREN); |
5745 // Parse dotted name. | 5762 // Parse dotted name. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5789 if (url.Length() == 0) { | 5806 if (url.Length() == 0) { |
5790 ReportError("library url expected"); | 5807 ReportError("library url expected"); |
5791 } | 5808 } |
5792 bool is_deferred_import = false; | 5809 bool is_deferred_import = false; |
5793 if (is_import && (IsSymbol(Symbols::Deferred()))) { | 5810 if (is_import && (IsSymbol(Symbols::Deferred()))) { |
5794 is_deferred_import = true; | 5811 is_deferred_import = true; |
5795 ConsumeToken(); | 5812 ConsumeToken(); |
5796 CheckToken(Token::kAS, "'as' expected"); | 5813 CheckToken(Token::kAS, "'as' expected"); |
5797 } | 5814 } |
5798 String& prefix = String::Handle(Z); | 5815 String& prefix = String::Handle(Z); |
5799 intptr_t prefix_pos = Token::kNoSourcePos; | 5816 TokenDescriptor prefix_pos = TokenDescriptor::kNoSource; |
5800 if (is_import && (CurrentToken() == Token::kAS)) { | 5817 if (is_import && (CurrentToken() == Token::kAS)) { |
5801 ConsumeToken(); | 5818 ConsumeToken(); |
5802 prefix_pos = TokenPos(); | 5819 prefix_pos = TokenPos(); |
5803 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5820 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
5804 } | 5821 } |
5805 | 5822 |
5806 Array& show_names = Array::Handle(Z); | 5823 Array& show_names = Array::Handle(Z); |
5807 Array& hide_names = Array::Handle(Z); | 5824 Array& hide_names = Array::Handle(Z); |
5808 if (is_deferred_import || | 5825 if (is_deferred_import || |
5809 IsSymbol(Symbols::Show()) || | 5826 IsSymbol(Symbols::Show()) || |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5852 // library import, call the library tag handler to request loading | 5869 // library import, call the library tag handler to request loading |
5853 // the library. | 5870 // the library. |
5854 if (library.LoadNotStarted() && | 5871 if (library.LoadNotStarted() && |
5855 (!is_deferred_import || FLAG_load_deferred_eagerly)) { | 5872 (!is_deferred_import || FLAG_load_deferred_eagerly)) { |
5856 library.SetLoadRequested(); | 5873 library.SetLoadRequested(); |
5857 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 5874 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
5858 } | 5875 } |
5859 | 5876 |
5860 Namespace& ns = Namespace::Handle(Z, | 5877 Namespace& ns = Namespace::Handle(Z, |
5861 Namespace::New(library, show_names, hide_names)); | 5878 Namespace::New(library, show_names, hide_names)); |
5862 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5879 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5863 ns.AddMetadata(tl_owner, metadata_pos); | 5880 ns.AddMetadata(tl_owner, metadata_pos); |
5864 } | 5881 } |
5865 | 5882 |
5866 // Ensure that private dart:_ libraries are only imported into dart: | 5883 // Ensure that private dart:_ libraries are only imported into dart: |
5867 // libraries, including indirectly through exports. | 5884 // libraries, including indirectly through exports. |
5868 const String& lib_url = String::Handle(Z, library_.url()); | 5885 const String& lib_url = String::Handle(Z, library_.url()); |
5869 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5886 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
5870 !lib_url.StartsWith(Symbols::DartScheme())) { | 5887 !lib_url.StartsWith(Symbols::DartScheme())) { |
5871 ReportError(import_pos, "private library is not accessible"); | 5888 ReportError(import_pos, "private library is not accessible"); |
5872 } | 5889 } |
(...skipping 29 matching lines...) Expand all Loading... |
5902 } | 5919 } |
5903 } | 5920 } |
5904 } else { | 5921 } else { |
5905 ASSERT(is_export); | 5922 ASSERT(is_export); |
5906 library_.AddExport(ns); | 5923 library_.AddExport(ns); |
5907 } | 5924 } |
5908 } | 5925 } |
5909 | 5926 |
5910 | 5927 |
5911 void Parser::ParseLibraryPart() { | 5928 void Parser::ParseLibraryPart() { |
5912 const intptr_t source_pos = TokenPos(); | 5929 const TokenDescriptor source_pos = TokenPos(); |
5913 ConsumeToken(); // Consume "part". | 5930 ConsumeToken(); // Consume "part". |
5914 CheckToken(Token::kSTRING, "url expected"); | 5931 CheckToken(Token::kSTRING, "url expected"); |
5915 AstNode* url_literal = ParseStringLiteral(false); | 5932 AstNode* url_literal = ParseStringLiteral(false); |
5916 ASSERT(url_literal->IsLiteralNode()); | 5933 ASSERT(url_literal->IsLiteralNode()); |
5917 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 5934 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
5918 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 5935 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
5919 ExpectSemicolon(); | 5936 ExpectSemicolon(); |
5920 const String& canon_url = String::CheckedHandle( | 5937 const String& canon_url = String::CheckedHandle( |
5921 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); | 5938 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); |
5922 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); | 5939 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); |
5923 } | 5940 } |
5924 | 5941 |
5925 | 5942 |
5926 void Parser::ParseLibraryDefinition(const Object& tl_owner) { | 5943 void Parser::ParseLibraryDefinition(const Object& tl_owner) { |
5927 TRACE_PARSER("ParseLibraryDefinition"); | 5944 TRACE_PARSER("ParseLibraryDefinition"); |
5928 | 5945 |
5929 // Handle the script tag. | 5946 // Handle the script tag. |
5930 if (CurrentToken() == Token::kSCRIPTTAG) { | 5947 if (CurrentToken() == Token::kSCRIPTTAG) { |
5931 // Nothing to do for script tags except to skip them. | 5948 // Nothing to do for script tags except to skip them. |
5932 ConsumeToken(); | 5949 ConsumeToken(); |
5933 } | 5950 } |
5934 | 5951 |
5935 ASSERT(script_.kind() != RawScript::kSourceTag); | 5952 ASSERT(script_.kind() != RawScript::kSourceTag); |
5936 | 5953 |
5937 // We may read metadata tokens that are part of the toplevel | 5954 // We may read metadata tokens that are part of the toplevel |
5938 // declaration that follows the library definitions. Therefore, we | 5955 // declaration that follows the library definitions. Therefore, we |
5939 // need to remember the position of the last token that was | 5956 // need to remember the position of the last token that was |
5940 // successfully consumed. | 5957 // successfully consumed. |
5941 intptr_t rewind_pos = TokenPos(); | 5958 TokenDescriptor rewind_pos = TokenPos(); |
5942 intptr_t metadata_pos = SkipMetadata(); | 5959 TokenDescriptor metadata_pos = SkipMetadata(); |
5943 if (CurrentToken() == Token::kLIBRARY) { | 5960 if (CurrentToken() == Token::kLIBRARY) { |
5944 if (is_patch_source()) { | 5961 if (is_patch_source()) { |
5945 ReportError("patch cannot override library name"); | 5962 ReportError("patch cannot override library name"); |
5946 } | 5963 } |
5947 ParseLibraryName(); | 5964 ParseLibraryName(); |
5948 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5965 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5949 library_.AddLibraryMetadata(tl_owner, metadata_pos); | 5966 library_.AddLibraryMetadata(tl_owner, metadata_pos); |
5950 } | 5967 } |
5951 rewind_pos = TokenPos(); | 5968 rewind_pos = TokenPos(); |
5952 metadata_pos = SkipMetadata(); | 5969 metadata_pos = SkipMetadata(); |
5953 } | 5970 } |
5954 while ((CurrentToken() == Token::kIMPORT) || | 5971 while ((CurrentToken() == Token::kIMPORT) || |
5955 (CurrentToken() == Token::kEXPORT)) { | 5972 (CurrentToken() == Token::kEXPORT)) { |
5956 ParseLibraryImportExport(tl_owner, metadata_pos); | 5973 ParseLibraryImportExport(tl_owner, metadata_pos); |
5957 rewind_pos = TokenPos(); | 5974 rewind_pos = TokenPos(); |
5958 metadata_pos = SkipMetadata(); | 5975 metadata_pos = SkipMetadata(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6020 if (is_library_source() || is_patch_source()) { | 6037 if (is_library_source() || is_patch_source()) { |
6021 set_current_class(toplevel_class); | 6038 set_current_class(toplevel_class); |
6022 ParseLibraryDefinition(tl_owner); | 6039 ParseLibraryDefinition(tl_owner); |
6023 } else if (is_part_source()) { | 6040 } else if (is_part_source()) { |
6024 ParsePartHeader(); | 6041 ParsePartHeader(); |
6025 } | 6042 } |
6026 | 6043 |
6027 const Class& cls = Class::Handle(Z); | 6044 const Class& cls = Class::Handle(Z); |
6028 while (true) { | 6045 while (true) { |
6029 set_current_class(cls); // No current class. | 6046 set_current_class(cls); // No current class. |
6030 intptr_t metadata_pos = SkipMetadata(); | 6047 TokenDescriptor metadata_pos = SkipMetadata(); |
6031 if (CurrentToken() == Token::kCLASS) { | 6048 if (CurrentToken() == Token::kCLASS) { |
6032 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); | 6049 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); |
6033 } else if (CurrentToken() == Token::kENUM) { | 6050 } else if (CurrentToken() == Token::kENUM) { |
6034 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); | 6051 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); |
6035 } else if ((CurrentToken() == Token::kTYPEDEF) && | 6052 } else if ((CurrentToken() == Token::kTYPEDEF) && |
6036 (LookaheadToken(1) != Token::kLPAREN)) { | 6053 (LookaheadToken(1) != Token::kLPAREN)) { |
6037 set_current_class(toplevel_class); | 6054 set_current_class(toplevel_class); |
6038 ParseTypedef(pending_classes, tl_owner, metadata_pos); | 6055 ParseTypedef(pending_classes, tl_owner, metadata_pos); |
6039 } else if ((CurrentToken() == Token::kABSTRACT) && | 6056 } else if ((CurrentToken() == Token::kABSTRACT) && |
6040 (LookaheadToken(1) == Token::kCLASS)) { | 6057 (LookaheadToken(1) == Token::kCLASS)) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6145 | 6162 |
6146 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { | 6163 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { |
6147 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); | 6164 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); |
6148 // The generated try-catch-finally that wraps the async generator function | 6165 // The generated try-catch-finally that wraps the async generator function |
6149 // body is the outermost try statement. | 6166 // body is the outermost try statement. |
6150 ASSERT(try_stack_ != NULL); | 6167 ASSERT(try_stack_ != NULL); |
6151 ASSERT(try_stack_->outer_try() == NULL); | 6168 ASSERT(try_stack_->outer_try() == NULL); |
6152 // We only get here when parsing an async generator body. | 6169 // We only get here when parsing an async generator body. |
6153 ASSERT(innermost_function().IsAsyncGenClosure()); | 6170 ASSERT(innermost_function().IsAsyncGenClosure()); |
6154 | 6171 |
6155 const intptr_t try_end_pos = innermost_function().end_token_pos(); | 6172 const TokenDescriptor try_end_pos = innermost_function().end_token_pos(); |
6156 | 6173 |
6157 // The try-block (closure body code) has been parsed. We are now | 6174 // The try-block (closure body code) has been parsed. We are now |
6158 // generating the code for the catch block. | 6175 // generating the code for the catch block. |
6159 LocalScope* try_scope = current_block_->scope; | 6176 LocalScope* try_scope = current_block_->scope; |
6160 try_stack_->enter_catch(); | 6177 try_stack_->enter_catch(); |
6161 OpenBlock(); // Catch handler list. | 6178 OpenBlock(); // Catch handler list. |
6162 OpenBlock(); // Catch block. | 6179 OpenBlock(); // Catch block. |
6163 | 6180 |
6164 // Add the exception and stack trace parameters to the scope. | 6181 // Add the exception and stack trace parameters to the scope. |
6165 CatchParamDesc exception_param; | 6182 CatchParamDesc exception_param; |
6166 CatchParamDesc stack_trace_param; | 6183 CatchParamDesc stack_trace_param; |
6167 exception_param.token_pos = Token::kNoSourcePos; | 6184 exception_param.token_pos = TokenDescriptor::kNoSource; |
6168 exception_param.type = &Object::dynamic_type(); | 6185 exception_param.type = &Object::dynamic_type(); |
6169 exception_param.name = &Symbols::ExceptionParameter(); | 6186 exception_param.name = &Symbols::ExceptionParameter(); |
6170 stack_trace_param.token_pos = Token::kNoSourcePos; | 6187 stack_trace_param.token_pos = TokenDescriptor::kNoSource; |
6171 stack_trace_param.type = &Object::dynamic_type(); | 6188 stack_trace_param.type = &Object::dynamic_type(); |
6172 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6189 stack_trace_param.name = &Symbols::StackTraceParameter(); |
6173 | 6190 |
6174 AddCatchParamsToScope( | 6191 AddCatchParamsToScope( |
6175 &exception_param, &stack_trace_param, current_block_->scope); | 6192 &exception_param, &stack_trace_param, current_block_->scope); |
6176 | 6193 |
6177 // Generate code to save the exception object and stack trace | 6194 // Generate code to save the exception object and stack trace |
6178 // in local variables. | 6195 // in local variables. |
6179 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6196 LocalVariable* context_var = try_scope->LocalLookupVariable( |
6180 Symbols::SavedTryContextVar()); | 6197 Symbols::SavedTryContextVar()); |
6181 ASSERT(context_var != NULL); | 6198 ASSERT(context_var != NULL); |
6182 | 6199 |
6183 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6200 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
6184 Symbols::ExceptionVar()); | 6201 Symbols::ExceptionVar()); |
6185 ASSERT(exception_var != NULL); | 6202 ASSERT(exception_var != NULL); |
6186 if (exception_param.var != NULL) { | 6203 if (exception_param.var != NULL) { |
6187 // Generate code to load the exception object (:exception_var) into | 6204 // Generate code to load the exception object (:exception_var) into |
6188 // the exception variable specified in this block. | 6205 // the exception variable specified in this block. |
6189 current_block_->statements->Add(new(Z) StoreLocalNode( | 6206 current_block_->statements->Add(new(Z) StoreLocalNode( |
6190 Token::kNoSourcePos, | 6207 TokenDescriptor::kNoSource, |
6191 exception_param.var, | 6208 exception_param.var, |
6192 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 6209 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_var))); |
6193 } | 6210 } |
6194 | 6211 |
6195 LocalVariable* stack_trace_var = | 6212 LocalVariable* stack_trace_var = |
6196 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6213 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
6197 ASSERT(stack_trace_var != NULL); | 6214 ASSERT(stack_trace_var != NULL); |
6198 if (stack_trace_param.var != NULL) { | 6215 if (stack_trace_param.var != NULL) { |
6199 // A stack trace variable is specified in this block, so generate code | 6216 // A stack trace variable is specified in this block, so generate code |
6200 // to load the stack trace object (:stack_trace_var) into the stack | 6217 // to load the stack trace object (:stack_trace_var) into the stack |
6201 // trace variable specified in this block. | 6218 // trace variable specified in this block. |
6202 current_block_->statements->Add(new(Z) StoreLocalNode( | 6219 current_block_->statements->Add(new(Z) StoreLocalNode( |
6203 Token::kNoSourcePos, | 6220 TokenDescriptor::kNoSource, |
6204 stack_trace_param.var, | 6221 stack_trace_param.var, |
6205 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 6222 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, stack_trace_var))); |
6206 } | 6223 } |
6207 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6224 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
6208 Symbols::SavedExceptionVar()); | 6225 Symbols::SavedExceptionVar()); |
6209 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6226 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
6210 Symbols::SavedStackTraceVar()); | 6227 Symbols::SavedStackTraceVar()); |
6211 SaveExceptionAndStacktrace(current_block_->statements, | 6228 SaveExceptionAndStacktrace(current_block_->statements, |
6212 exception_var, | 6229 exception_var, |
6213 stack_trace_var, | 6230 stack_trace_var, |
6214 saved_exception_var, | 6231 saved_exception_var, |
6215 saved_stack_trace_var); | 6232 saved_stack_trace_var); |
6216 | 6233 |
6217 // Catch block: add the error to the stream. | 6234 // Catch block: add the error to the stream. |
6218 // :controller.AddError(:exception, :stack_trace); | 6235 // :controller.AddError(:exception, :stack_trace); |
6219 // return; // The finally block will close the stream. | 6236 // return; // The finally block will close the stream. |
6220 LocalVariable* controller = | 6237 LocalVariable* controller = |
6221 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6238 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
6222 ASSERT(controller != NULL); | 6239 ASSERT(controller != NULL); |
6223 ArgumentListNode* args = | 6240 ArgumentListNode* args = |
6224 new(Z) ArgumentListNode(Token::kNoSourcePos); | 6241 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
6225 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); | 6242 args->Add(new(Z) LoadLocalNode( |
6226 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); | 6243 TokenDescriptor::kNoSource, exception_param.var)); |
| 6244 args->Add(new(Z) LoadLocalNode( |
| 6245 TokenDescriptor::kNoSource, stack_trace_param.var)); |
6227 current_block_->statements->Add( | 6246 current_block_->statements->Add( |
6228 new(Z) InstanceCallNode(try_end_pos, | 6247 new(Z) InstanceCallNode(try_end_pos, |
6229 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), | 6248 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, controller), |
6230 Symbols::AddError(), | 6249 Symbols::AddError(), |
6231 args)); | 6250 args)); |
6232 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos); | 6251 ReturnNode* return_node = new(Z) ReturnNode(TokenDescriptor::kNoSource); |
6233 AddNodeForFinallyInlining(return_node); | 6252 AddNodeForFinallyInlining(return_node); |
6234 current_block_->statements->Add(return_node); | 6253 current_block_->statements->Add(return_node); |
6235 AstNode* catch_block = CloseBlock(); | 6254 AstNode* catch_block = CloseBlock(); |
6236 current_block_->statements->Add(catch_block); | 6255 current_block_->statements->Add(catch_block); |
6237 SequenceNode* catch_handler_list = CloseBlock(); | 6256 SequenceNode* catch_handler_list = CloseBlock(); |
6238 | 6257 |
6239 TryStack* try_statement = PopTry(); | 6258 TryStack* try_statement = PopTry(); |
6240 ASSERT(try_stack_ == NULL); // We popped the outermost try block. | 6259 ASSERT(try_stack_ == NULL); // We popped the outermost try block. |
6241 | 6260 |
6242 // Finally block: closing the stream and returning. Instead of simply | 6261 // Finally block: closing the stream and returning. Instead of simply |
6243 // returning, create an await state and suspend. There may be outstanding | 6262 // returning, create an await state and suspend. There may be outstanding |
6244 // calls to schedule the generator body. This suspension ensures that we | 6263 // calls to schedule the generator body. This suspension ensures that we |
6245 // do not repeat any code of the generator body. | 6264 // do not repeat any code of the generator body. |
6246 // :controller.close(); | 6265 // :controller.close(); |
6247 // suspend; | 6266 // suspend; |
6248 // We need to inline this code in all recorded exit points. | 6267 // We need to inline this code in all recorded exit points. |
6249 intptr_t node_index = 0; | 6268 intptr_t node_index = 0; |
6250 SequenceNode* finally_clause = NULL; | 6269 SequenceNode* finally_clause = NULL; |
6251 if (try_stack_ != NULL) { | 6270 if (try_stack_ != NULL) { |
6252 try_stack_->enter_finally(); | 6271 try_stack_->enter_finally(); |
6253 } | 6272 } |
6254 do { | 6273 do { |
6255 OpenBlock(); | 6274 OpenBlock(); |
6256 ArgumentListNode* no_args = | 6275 ArgumentListNode* no_args = |
6257 new(Z) ArgumentListNode(Token::kNoSourcePos); | 6276 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
6258 current_block_->statements->Add( | 6277 current_block_->statements->Add( |
6259 new(Z) InstanceCallNode(try_end_pos, | 6278 new(Z) InstanceCallNode(try_end_pos, |
6260 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), | 6279 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, controller), |
6261 Symbols::Close(), | 6280 Symbols::Close(), |
6262 no_args)); | 6281 no_args)); |
6263 | 6282 |
6264 // Suspend after the close. | 6283 // Suspend after the close. |
6265 AwaitMarkerNode* await_marker = | 6284 AwaitMarkerNode* await_marker = |
6266 new(Z) AwaitMarkerNode(async_temp_scope_, | 6285 new(Z) AwaitMarkerNode(async_temp_scope_, |
6267 current_block_->scope, | 6286 current_block_->scope, |
6268 Token::kNoSourcePos); | 6287 TokenDescriptor::kNoSource); |
6269 current_block_->statements->Add(await_marker); | 6288 current_block_->statements->Add(await_marker); |
6270 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); | 6289 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); |
6271 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); | 6290 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); |
6272 current_block_->statements->Add(continuation_ret); | 6291 current_block_->statements->Add(continuation_ret); |
6273 | 6292 |
6274 finally_clause = CloseBlock(); | 6293 finally_clause = CloseBlock(); |
6275 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 6294 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
6276 if (node_to_inline != NULL) { | 6295 if (node_to_inline != NULL) { |
6277 InlinedFinallyNode* node = | 6296 InlinedFinallyNode* node = |
6278 new(Z) InlinedFinallyNode(try_end_pos, | 6297 new(Z) InlinedFinallyNode(try_end_pos, |
(...skipping 10 matching lines...) Expand all Loading... |
6289 if (try_stack_ != NULL) { | 6308 if (try_stack_ != NULL) { |
6290 try_stack_->exit_finally(); | 6309 try_stack_->exit_finally(); |
6291 } | 6310 } |
6292 | 6311 |
6293 const GrowableObjectArray& handler_types = | 6312 const GrowableObjectArray& handler_types = |
6294 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6313 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
6295 // Catch block handles all exceptions. | 6314 // Catch block handles all exceptions. |
6296 handler_types.Add(Object::dynamic_type()); | 6315 handler_types.Add(Object::dynamic_type()); |
6297 | 6316 |
6298 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 6317 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
6299 Token::kNoSourcePos, | 6318 TokenDescriptor::kNoSource, |
6300 catch_handler_list, | 6319 catch_handler_list, |
6301 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6320 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
6302 context_var, | 6321 context_var, |
6303 exception_var, | 6322 exception_var, |
6304 stack_trace_var, | 6323 stack_trace_var, |
6305 saved_exception_var, | 6324 saved_exception_var, |
6306 saved_stack_trace_var, | 6325 saved_stack_trace_var, |
6307 AllocateTryIndex(), | 6326 AllocateTryIndex(), |
6308 true); | 6327 true); |
6309 | 6328 |
6310 const intptr_t try_index = try_statement->try_index(); | 6329 const intptr_t try_index = try_statement->try_index(); |
6311 | 6330 |
6312 AstNode* try_catch_node = | 6331 AstNode* try_catch_node = |
6313 new(Z) TryCatchNode(Token::kNoSourcePos, | 6332 new(Z) TryCatchNode(TokenDescriptor::kNoSource, |
6314 body, | 6333 body, |
6315 context_var, | 6334 context_var, |
6316 catch_clause, | 6335 catch_clause, |
6317 finally_clause, | 6336 finally_clause, |
6318 try_index, | 6337 try_index, |
6319 finally_clause); | 6338 finally_clause); |
6320 current_block_->statements->Add(try_catch_node); | 6339 current_block_->statements->Add(try_catch_node); |
6321 return CloseBlock(); | 6340 return CloseBlock(); |
6322 } | 6341 } |
6323 | 6342 |
6324 | 6343 |
6325 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 6344 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { |
6326 // This is the outermost try-catch of the function. | 6345 // This is the outermost try-catch of the function. |
6327 ASSERT(try_stack_ != NULL); | 6346 ASSERT(try_stack_ != NULL); |
6328 ASSERT(try_stack_->outer_try() == NULL); | 6347 ASSERT(try_stack_->outer_try() == NULL); |
6329 ASSERT(innermost_function().IsAsyncClosure()); | 6348 ASSERT(innermost_function().IsAsyncClosure()); |
6330 LocalScope* try_scope = current_block_->scope; | 6349 LocalScope* try_scope = current_block_->scope; |
6331 | 6350 |
6332 try_stack_->enter_catch(); | 6351 try_stack_->enter_catch(); |
6333 | 6352 |
6334 OpenBlock(); // Catch handler list. | 6353 OpenBlock(); // Catch handler list. |
6335 OpenBlock(); // Catch block. | 6354 OpenBlock(); // Catch block. |
6336 CatchParamDesc exception_param; | 6355 CatchParamDesc exception_param; |
6337 CatchParamDesc stack_trace_param; | 6356 CatchParamDesc stack_trace_param; |
6338 exception_param.token_pos = Token::kNoSourcePos; | 6357 exception_param.token_pos = TokenDescriptor::kNoSource; |
6339 exception_param.type = &Object::dynamic_type(); | 6358 exception_param.type = &Object::dynamic_type(); |
6340 exception_param.name = &Symbols::ExceptionParameter(); | 6359 exception_param.name = &Symbols::ExceptionParameter(); |
6341 stack_trace_param.token_pos = Token::kNoSourcePos; | 6360 stack_trace_param.token_pos = TokenDescriptor::kNoSource; |
6342 stack_trace_param.type = &Object::dynamic_type(); | 6361 stack_trace_param.type = &Object::dynamic_type(); |
6343 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6362 stack_trace_param.name = &Symbols::StackTraceParameter(); |
6344 | 6363 |
6345 AddCatchParamsToScope( | 6364 AddCatchParamsToScope( |
6346 &exception_param, &stack_trace_param, current_block_->scope); | 6365 &exception_param, &stack_trace_param, current_block_->scope); |
6347 | 6366 |
6348 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6367 LocalVariable* context_var = try_scope->LocalLookupVariable( |
6349 Symbols::SavedTryContextVar()); | 6368 Symbols::SavedTryContextVar()); |
6350 ASSERT(context_var != NULL); | 6369 ASSERT(context_var != NULL); |
6351 | 6370 |
6352 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6371 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
6353 Symbols::ExceptionVar()); | 6372 Symbols::ExceptionVar()); |
6354 if (exception_param.var != NULL) { | 6373 if (exception_param.var != NULL) { |
6355 // Generate code to load the exception object (:exception_var) into | 6374 // Generate code to load the exception object (:exception_var) into |
6356 // the exception variable specified in this block. | 6375 // the exception variable specified in this block. |
6357 ASSERT(exception_var != NULL); | 6376 ASSERT(exception_var != NULL); |
6358 current_block_->statements->Add(new(Z) StoreLocalNode( | 6377 current_block_->statements->Add(new(Z) StoreLocalNode( |
6359 Token::kNoSourcePos, | 6378 TokenDescriptor::kNoSource, |
6360 exception_param.var, | 6379 exception_param.var, |
6361 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 6380 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_var))); |
6362 } | 6381 } |
6363 | 6382 |
6364 LocalVariable* stack_trace_var = | 6383 LocalVariable* stack_trace_var = |
6365 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6384 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
6366 if (stack_trace_param.var != NULL) { | 6385 if (stack_trace_param.var != NULL) { |
6367 // A stack trace variable is specified in this block, so generate code | 6386 // A stack trace variable is specified in this block, so generate code |
6368 // to load the stack trace object (:stack_trace_var) into the stack | 6387 // to load the stack trace object (:stack_trace_var) into the stack |
6369 // trace variable specified in this block. | 6388 // trace variable specified in this block. |
6370 ASSERT(stack_trace_var != NULL); | 6389 ASSERT(stack_trace_var != NULL); |
6371 current_block_->statements->Add(new(Z) StoreLocalNode( | 6390 current_block_->statements->Add(new(Z) StoreLocalNode( |
6372 Token::kNoSourcePos, | 6391 TokenDescriptor::kNoSource, |
6373 stack_trace_param.var, | 6392 stack_trace_param.var, |
6374 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 6393 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, stack_trace_var))); |
6375 } | 6394 } |
6376 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6395 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
6377 Symbols::SavedExceptionVar()); | 6396 Symbols::SavedExceptionVar()); |
6378 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6397 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
6379 Symbols::SavedStackTraceVar()); | 6398 Symbols::SavedStackTraceVar()); |
6380 SaveExceptionAndStacktrace(current_block_->statements, | 6399 SaveExceptionAndStacktrace(current_block_->statements, |
6381 exception_var, | 6400 exception_var, |
6382 stack_trace_var, | 6401 stack_trace_var, |
6383 saved_exception_var, | 6402 saved_exception_var, |
6384 saved_stack_trace_var); | 6403 saved_stack_trace_var); |
6385 | 6404 |
6386 // Complete the async future with an error. This catch block executes | 6405 // Complete the async future with an error. This catch block executes |
6387 // unconditionally, there is no need to generate a type check for. | 6406 // unconditionally, there is no need to generate a type check for. |
6388 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6407 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
6389 Symbols::AsyncCompleter(), false); | 6408 Symbols::AsyncCompleter(), false); |
6390 ASSERT(async_completer != NULL); | 6409 ASSERT(async_completer != NULL); |
6391 ArgumentListNode* completer_args = | 6410 ArgumentListNode* completer_args = |
6392 new (Z) ArgumentListNode(Token::kNoSourcePos); | 6411 new (Z) ArgumentListNode(TokenDescriptor::kNoSource); |
6393 completer_args->Add( | 6412 completer_args->Add( |
6394 new (Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); | 6413 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_param.var)); |
6395 completer_args->Add( | 6414 completer_args->Add( |
6396 new (Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); | 6415 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 6416 stack_trace_param.var)); |
6397 current_block_->statements->Add(new (Z) InstanceCallNode( | 6417 current_block_->statements->Add(new (Z) InstanceCallNode( |
6398 TokenPos(), | 6418 TokenPos(), |
6399 new (Z) LoadLocalNode(Token::kNoSourcePos, async_completer), | 6419 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_completer), |
6400 Symbols::CompleterCompleteError(), | 6420 Symbols::CompleterCompleteError(), |
6401 completer_args)); | 6421 completer_args)); |
6402 ReturnNode* return_node = new (Z) ReturnNode(Token::kNoSourcePos); | 6422 ReturnNode* return_node = new (Z) ReturnNode(TokenDescriptor::kNoSource); |
6403 // Behavior like a continuation return, i.e,. don't call a completer. | 6423 // Behavior like a continuation return, i.e,. don't call a completer. |
6404 return_node->set_return_type(ReturnNode::kContinuation); | 6424 return_node->set_return_type(ReturnNode::kContinuation); |
6405 current_block_->statements->Add(return_node); | 6425 current_block_->statements->Add(return_node); |
6406 AstNode* catch_block = CloseBlock(); | 6426 AstNode* catch_block = CloseBlock(); |
6407 current_block_->statements->Add(catch_block); | 6427 current_block_->statements->Add(catch_block); |
6408 SequenceNode* catch_handler_list = CloseBlock(); | 6428 SequenceNode* catch_handler_list = CloseBlock(); |
6409 | 6429 |
6410 const GrowableObjectArray& handler_types = | 6430 const GrowableObjectArray& handler_types = |
6411 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6431 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
6412 handler_types.SetLength(0); | 6432 handler_types.SetLength(0); |
6413 handler_types.Add(*exception_param.type); | 6433 handler_types.Add(*exception_param.type); |
6414 | 6434 |
6415 TryStack* try_statement = PopTry(); | 6435 TryStack* try_statement = PopTry(); |
6416 const intptr_t try_index = try_statement->try_index(); | 6436 const intptr_t try_index = try_statement->try_index(); |
6417 | 6437 |
6418 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( | 6438 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
6419 Token::kNoSourcePos, | 6439 TokenDescriptor::kNoSource, |
6420 catch_handler_list, | 6440 catch_handler_list, |
6421 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6441 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
6422 context_var, | 6442 context_var, |
6423 exception_var, | 6443 exception_var, |
6424 stack_trace_var, | 6444 stack_trace_var, |
6425 saved_exception_var, | 6445 saved_exception_var, |
6426 saved_stack_trace_var, | 6446 saved_stack_trace_var, |
6427 CatchClauseNode::kInvalidTryIndex, | 6447 CatchClauseNode::kInvalidTryIndex, |
6428 true); | 6448 true); |
6429 AstNode* try_catch_node = new (Z) TryCatchNode( | 6449 AstNode* try_catch_node = new (Z) TryCatchNode( |
6430 Token::kNoSourcePos, | 6450 TokenDescriptor::kNoSource, |
6431 try_block, | 6451 try_block, |
6432 context_var, | 6452 context_var, |
6433 catch_clause, | 6453 catch_clause, |
6434 NULL, // No finally clause. | 6454 NULL, // No finally clause. |
6435 try_index, | 6455 try_index, |
6436 NULL); // No rethrow-finally clause. | 6456 NULL); // No rethrow-finally clause. |
6437 current_block_->statements->Add(try_catch_node); | 6457 current_block_->statements->Add(try_catch_node); |
6438 return CloseBlock(); | 6458 return CloseBlock(); |
6439 } | 6459 } |
6440 | 6460 |
(...skipping 25 matching lines...) Expand all Loading... |
6466 } | 6486 } |
6467 | 6487 |
6468 | 6488 |
6469 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6489 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
6470 // Create the parameter list for the body closure of a sync generator: | 6490 // Create the parameter list for the body closure of a sync generator: |
6471 // 1) Implicit closure parameter; | 6491 // 1) Implicit closure parameter; |
6472 // 2) Iterator | 6492 // 2) Iterator |
6473 // Add implicit closure parameter if not already present. | 6493 // Add implicit closure parameter if not already present. |
6474 if (params->parameters->length() == 0) { | 6494 if (params->parameters->length() == 0) { |
6475 params->AddFinalParameter( | 6495 params->AddFinalParameter( |
6476 0, &Symbols::ClosureParameter(), &Object::dynamic_type()); | 6496 TokenDescriptor::kMinSource, |
| 6497 &Symbols::ClosureParameter(), |
| 6498 &Object::dynamic_type()); |
6477 } | 6499 } |
6478 ParamDesc iterator_param; | 6500 ParamDesc iterator_param; |
6479 iterator_param.name = &Symbols::IteratorParameter(); | 6501 iterator_param.name = &Symbols::IteratorParameter(); |
6480 iterator_param.type = &Object::dynamic_type(); | 6502 iterator_param.type = &Object::dynamic_type(); |
6481 params->parameters->Add(iterator_param); | 6503 params->parameters->Add(iterator_param); |
6482 params->num_fixed_parameters++; | 6504 params->num_fixed_parameters++; |
6483 } | 6505 } |
6484 | 6506 |
6485 | 6507 |
6486 void Parser::AddAsyncGenClosureParameters(ParamList* params) { | 6508 void Parser::AddAsyncGenClosureParameters(ParamList* params) { |
6487 // Create the parameter list for the body closure of an async generator. | 6509 // Create the parameter list for the body closure of an async generator. |
6488 // The closure has the same parameters as an asynchronous non-generator. | 6510 // The closure has the same parameters as an asynchronous non-generator. |
6489 AddAsyncClosureParameters(params); | 6511 AddAsyncClosureParameters(params); |
6490 } | 6512 } |
6491 | 6513 |
6492 | 6514 |
6493 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { | 6515 RawFunction* Parser::OpenSyncGeneratorFunction(TokenDescriptor func_pos) { |
6494 Function& body = Function::Handle(Z); | 6516 Function& body = Function::Handle(Z); |
6495 String& body_closure_name = String::Handle(Z); | 6517 String& body_closure_name = String::Handle(Z); |
6496 bool is_new_closure = false; | 6518 bool is_new_closure = false; |
6497 | 6519 |
6498 AddContinuationVariables(); | 6520 AddContinuationVariables(); |
6499 | 6521 |
6500 // Check whether a function for the body of this generator | 6522 // Check whether a function for the body of this generator |
6501 // function has already been created by a previous | 6523 // function has already been created by a previous |
6502 // compilation. | 6524 // compilation. |
6503 const Function& found_func = Function::Handle( | 6525 const Function& found_func = Function::Handle( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6550 LocalVariable* existing_var = | 6572 LocalVariable* existing_var = |
6551 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 6573 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
6552 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6574 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
6553 existing_var = | 6575 existing_var = |
6554 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 6576 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
6555 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6577 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
6556 | 6578 |
6557 // :await_jump_var = -1; | 6579 // :await_jump_var = -1; |
6558 LocalVariable* jump_var = | 6580 LocalVariable* jump_var = |
6559 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6581 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
6560 LiteralNode* init_value = | 6582 LiteralNode* init_value = new(Z) LiteralNode(TokenDescriptor::kNoSource, |
6561 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6583 Smi::ZoneHandle(Smi::New(-1))); |
6562 current_block_->statements->Add( | 6584 current_block_->statements->Add( |
6563 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); | 6585 new(Z) StoreLocalNode(TokenDescriptor::kNoSource, jump_var, init_value)); |
6564 | 6586 |
6565 // return new SyncIterable(body_closure); | 6587 // return new SyncIterable(body_closure); |
6566 const Class& iterable_class = | 6588 const Class& iterable_class = |
6567 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); | 6589 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); |
6568 ASSERT(!iterable_class.IsNull()); | 6590 ASSERT(!iterable_class.IsNull()); |
6569 const Function& iterable_constructor = Function::ZoneHandle(Z, | 6591 const Function& iterable_constructor = Function::ZoneHandle(Z, |
6570 iterable_class.LookupConstructorAllowPrivate( | 6592 iterable_class.LookupConstructorAllowPrivate( |
6571 Symbols::_SyncIterableConstructor())); | 6593 Symbols::_SyncIterableConstructor())); |
6572 ASSERT(!iterable_constructor.IsNull()); | 6594 ASSERT(!iterable_constructor.IsNull()); |
6573 | 6595 |
6574 const String& closure_name = String::Handle(Z, closure.name()); | 6596 const String& closure_name = String::Handle(Z, closure.name()); |
6575 ASSERT(closure_name.IsSymbol()); | 6597 ASSERT(closure_name.IsSymbol()); |
6576 | 6598 |
6577 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); | 6599 ArgumentListNode* arguments = |
| 6600 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
6578 ClosureNode* closure_obj = new(Z) ClosureNode( | 6601 ClosureNode* closure_obj = new(Z) ClosureNode( |
6579 Token::kNoSourcePos, closure, NULL, closure_body->scope()); | 6602 TokenDescriptor::kNoSource, closure, NULL, closure_body->scope()); |
6580 arguments->Add(closure_obj); | 6603 arguments->Add(closure_obj); |
6581 ConstructorCallNode* new_iterable = | 6604 ConstructorCallNode* new_iterable = |
6582 new(Z) ConstructorCallNode(Token::kNoSourcePos, | 6605 new(Z) ConstructorCallNode(TokenDescriptor::kNoSource, |
6583 TypeArguments::ZoneHandle(Z), | 6606 TypeArguments::ZoneHandle(Z), |
6584 iterable_constructor, | 6607 iterable_constructor, |
6585 arguments); | 6608 arguments); |
6586 ReturnNode* return_node = | 6609 ReturnNode* return_node = |
6587 new (Z) ReturnNode(Token::kNoSourcePos, new_iterable); | 6610 new (Z) ReturnNode(TokenDescriptor::kNoSource, new_iterable); |
6588 current_block_->statements->Add(return_node); | 6611 current_block_->statements->Add(return_node); |
6589 return CloseBlock(); | 6612 return CloseBlock(); |
6590 } | 6613 } |
6591 | 6614 |
6592 | 6615 |
6593 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6616 void Parser::AddAsyncClosureParameters(ParamList* params) { |
6594 // Async closures have three optional parameters: | 6617 // Async closures have three optional parameters: |
6595 // * A continuation result. | 6618 // * A continuation result. |
6596 // * A continuation error. | 6619 // * A continuation error. |
6597 // * A continuation stack trace. | 6620 // * A continuation stack trace. |
6598 ASSERT(params->parameters->length() <= 1); | 6621 ASSERT(params->parameters->length() <= 1); |
6599 // Add implicit closure parameter if not yet present. | 6622 // Add implicit closure parameter if not yet present. |
6600 if (params->parameters->length() == 0) { | 6623 if (params->parameters->length() == 0) { |
6601 params->AddFinalParameter( | 6624 params->AddFinalParameter( |
6602 0, &Symbols::ClosureParameter(), &Object::dynamic_type()); | 6625 TokenDescriptor::kMinSource, |
| 6626 &Symbols::ClosureParameter(), |
| 6627 &Object::dynamic_type()); |
6603 } | 6628 } |
6604 ParamDesc result_param; | 6629 ParamDesc result_param; |
6605 result_param.name = &Symbols::AsyncOperationParam(); | 6630 result_param.name = &Symbols::AsyncOperationParam(); |
6606 result_param.default_value = &Object::null_instance(); | 6631 result_param.default_value = &Object::null_instance(); |
6607 result_param.type = &Object::dynamic_type(); | 6632 result_param.type = &Object::dynamic_type(); |
6608 params->parameters->Add(result_param); | 6633 params->parameters->Add(result_param); |
6609 ParamDesc error_param; | 6634 ParamDesc error_param; |
6610 error_param.name = &Symbols::AsyncOperationErrorParam(); | 6635 error_param.name = &Symbols::AsyncOperationErrorParam(); |
6611 error_param.default_value = &Object::null_instance(); | 6636 error_param.default_value = &Object::null_instance(); |
6612 error_param.type = &Object::dynamic_type(); | 6637 error_param.type = &Object::dynamic_type(); |
6613 params->parameters->Add(error_param); | 6638 params->parameters->Add(error_param); |
6614 ParamDesc stack_trace_param; | 6639 ParamDesc stack_trace_param; |
6615 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | 6640 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); |
6616 stack_trace_param.default_value = &Object::null_instance(); | 6641 stack_trace_param.default_value = &Object::null_instance(); |
6617 stack_trace_param.type = &Object::dynamic_type(); | 6642 stack_trace_param.type = &Object::dynamic_type(); |
6618 params->parameters->Add(stack_trace_param); | 6643 params->parameters->Add(stack_trace_param); |
6619 params->has_optional_positional_parameters = true; | 6644 params->has_optional_positional_parameters = true; |
6620 params->num_optional_parameters += 3; | 6645 params->num_optional_parameters += 3; |
6621 } | 6646 } |
6622 | 6647 |
6623 | 6648 |
6624 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { | 6649 RawFunction* Parser::OpenAsyncFunction(TokenDescriptor async_func_pos) { |
6625 TRACE_PARSER("OpenAsyncFunction"); | 6650 TRACE_PARSER("OpenAsyncFunction"); |
6626 AddContinuationVariables(); | 6651 AddContinuationVariables(); |
6627 AddAsyncClosureVariables(); | 6652 AddAsyncClosureVariables(); |
6628 Function& closure = Function::Handle(Z); | 6653 Function& closure = Function::Handle(Z); |
6629 bool is_new_closure = false; | 6654 bool is_new_closure = false; |
6630 | 6655 |
6631 // Check whether a function for the asynchronous function body of | 6656 // Check whether a function for the asynchronous function body of |
6632 // this async function has already been created by a previous | 6657 // this async function has already been created by a previous |
6633 // compilation of this function. | 6658 // compilation of this function. |
6634 const Function& found_func = Function::Handle( | 6659 const Function& found_func = Function::Handle( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6671 async_temp_scope_ = current_block_->scope; | 6696 async_temp_scope_ = current_block_->scope; |
6672 return closure.raw(); | 6697 return closure.raw(); |
6673 } | 6698 } |
6674 | 6699 |
6675 | 6700 |
6676 void Parser::AddContinuationVariables() { | 6701 void Parser::AddContinuationVariables() { |
6677 // Add to current block's scope: | 6702 // Add to current block's scope: |
6678 // var :await_jump_var; | 6703 // var :await_jump_var; |
6679 // var :await_ctx_var; | 6704 // var :await_ctx_var; |
6680 LocalVariable* await_jump_var = new (Z) LocalVariable( | 6705 LocalVariable* await_jump_var = new (Z) LocalVariable( |
6681 Token::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type()); | 6706 TokenDescriptor::kNoSource, |
| 6707 Symbols::AwaitJumpVar(), |
| 6708 Object::dynamic_type()); |
6682 current_block_->scope->AddVariable(await_jump_var); | 6709 current_block_->scope->AddVariable(await_jump_var); |
6683 LocalVariable* await_ctx_var = new (Z) LocalVariable( | 6710 LocalVariable* await_ctx_var = new (Z) LocalVariable( |
6684 Token::kNoSourcePos, | 6711 TokenDescriptor::kNoSource, |
6685 Symbols::AwaitContextVar(), | 6712 Symbols::AwaitContextVar(), |
6686 Object::dynamic_type()); | 6713 Object::dynamic_type()); |
6687 current_block_->scope->AddVariable(await_ctx_var); | 6714 current_block_->scope->AddVariable(await_ctx_var); |
6688 } | 6715 } |
6689 | 6716 |
6690 | 6717 |
6691 void Parser::AddAsyncClosureVariables() { | 6718 void Parser::AddAsyncClosureVariables() { |
6692 // Add to current block's scope: | 6719 // Add to current block's scope: |
6693 // var :async_op; | 6720 // var :async_op; |
6694 // var :async_then_callback; | 6721 // var :async_then_callback; |
6695 // var :async_catch_error_callback; | 6722 // var :async_catch_error_callback; |
6696 // var :async_completer; | 6723 // var :async_completer; |
6697 LocalVariable* async_op_var = new(Z) LocalVariable( | 6724 LocalVariable* async_op_var = new(Z) LocalVariable( |
6698 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6725 TokenDescriptor::kNoSource, |
| 6726 Symbols::AsyncOperation(), |
| 6727 Object::dynamic_type()); |
6699 current_block_->scope->AddVariable(async_op_var); | 6728 current_block_->scope->AddVariable(async_op_var); |
6700 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6729 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
6701 Token::kNoSourcePos, | 6730 TokenDescriptor::kNoSource, |
6702 Symbols::AsyncThenCallback(), | 6731 Symbols::AsyncThenCallback(), |
6703 Object::dynamic_type()); | 6732 Object::dynamic_type()); |
6704 current_block_->scope->AddVariable(async_then_callback_var); | 6733 current_block_->scope->AddVariable(async_then_callback_var); |
6705 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6734 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
6706 Token::kNoSourcePos, | 6735 TokenDescriptor::kNoSource, |
6707 Symbols::AsyncCatchErrorCallback(), | 6736 Symbols::AsyncCatchErrorCallback(), |
6708 Object::dynamic_type()); | 6737 Object::dynamic_type()); |
6709 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6738 current_block_->scope->AddVariable(async_catch_error_callback_var); |
6710 LocalVariable* async_completer = new(Z) LocalVariable( | 6739 LocalVariable* async_completer = new(Z) LocalVariable( |
6711 Token::kNoSourcePos, | 6740 TokenDescriptor::kNoSource, |
6712 Symbols::AsyncCompleter(), | 6741 Symbols::AsyncCompleter(), |
6713 Object::dynamic_type()); | 6742 Object::dynamic_type()); |
6714 current_block_->scope->AddVariable(async_completer); | 6743 current_block_->scope->AddVariable(async_completer); |
6715 } | 6744 } |
6716 | 6745 |
6717 | 6746 |
6718 void Parser::AddAsyncGeneratorVariables() { | 6747 void Parser::AddAsyncGeneratorVariables() { |
6719 // Add to current block's scope: | 6748 // Add to current block's scope: |
6720 // var :controller; | 6749 // var :controller; |
6721 // The :controller variable is used by the async generator closure to | 6750 // The :controller variable is used by the async generator closure to |
6722 // store the StreamController object to which the yielded expressions | 6751 // store the StreamController object to which the yielded expressions |
6723 // are added. | 6752 // are added. |
6724 // var :async_op; | 6753 // var :async_op; |
6725 // var :async_then_callback; | 6754 // var :async_then_callback; |
6726 // var :async_catch_error_callback; | 6755 // var :async_catch_error_callback; |
6727 // These variables are used to store the async generator closure containing | 6756 // These variables are used to store the async generator closure containing |
6728 // the body of the async* function. They are used by the await operator. | 6757 // the body of the async* function. They are used by the await operator. |
6729 LocalVariable* controller_var = new(Z) LocalVariable( | 6758 LocalVariable* controller_var = new(Z) LocalVariable( |
6730 Token::kNoSourcePos, Symbols::Controller(), Object::dynamic_type()); | 6759 TokenDescriptor::kNoSource, |
| 6760 Symbols::Controller(), |
| 6761 Object::dynamic_type()); |
6731 current_block_->scope->AddVariable(controller_var); | 6762 current_block_->scope->AddVariable(controller_var); |
6732 LocalVariable* async_op_var = new(Z) LocalVariable( | 6763 LocalVariable* async_op_var = new(Z) LocalVariable( |
6733 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6764 TokenDescriptor::kNoSource, |
| 6765 Symbols::AsyncOperation(), |
| 6766 Object::dynamic_type()); |
6734 current_block_->scope->AddVariable(async_op_var); | 6767 current_block_->scope->AddVariable(async_op_var); |
6735 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6768 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
6736 Token::kNoSourcePos, | 6769 TokenDescriptor::kNoSource, |
6737 Symbols::AsyncThenCallback(), | 6770 Symbols::AsyncThenCallback(), |
6738 Object::dynamic_type()); | 6771 Object::dynamic_type()); |
6739 current_block_->scope->AddVariable(async_then_callback_var); | 6772 current_block_->scope->AddVariable(async_then_callback_var); |
6740 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6773 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
6741 Token::kNoSourcePos, | 6774 TokenDescriptor::kNoSource, |
6742 Symbols::AsyncCatchErrorCallback(), | 6775 Symbols::AsyncCatchErrorCallback(), |
6743 Object::dynamic_type()); | 6776 Object::dynamic_type()); |
6744 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6777 current_block_->scope->AddVariable(async_catch_error_callback_var); |
6745 } | 6778 } |
6746 | 6779 |
6747 | 6780 |
6748 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) { | 6781 RawFunction* Parser::OpenAsyncGeneratorFunction( |
| 6782 TokenDescriptor async_func_pos) { |
6749 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 6783 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
6750 AddContinuationVariables(); | 6784 AddContinuationVariables(); |
6751 AddAsyncGeneratorVariables(); | 6785 AddAsyncGeneratorVariables(); |
6752 | 6786 |
6753 Function& closure = Function::Handle(Z); | 6787 Function& closure = Function::Handle(Z); |
6754 bool is_new_closure = false; | 6788 bool is_new_closure = false; |
6755 | 6789 |
6756 // Check whether a function for the asynchronous function body of | 6790 // Check whether a function for the asynchronous function body of |
6757 // this async generator has already been created by a previous | 6791 // this async generator has already been created by a previous |
6758 // compilation of this function. | 6792 // compilation of this function. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6849 async_lib.LookupClassAllowPrivate( | 6883 async_lib.LookupClassAllowPrivate( |
6850 Symbols::_AsyncStarStreamController())); | 6884 Symbols::_AsyncStarStreamController())); |
6851 ASSERT(!controller_class.IsNull()); | 6885 ASSERT(!controller_class.IsNull()); |
6852 const Function& controller_constructor = Function::ZoneHandle(Z, | 6886 const Function& controller_constructor = Function::ZoneHandle(Z, |
6853 controller_class.LookupConstructorAllowPrivate( | 6887 controller_class.LookupConstructorAllowPrivate( |
6854 Symbols::_AsyncStarStreamControllerConstructor())); | 6888 Symbols::_AsyncStarStreamControllerConstructor())); |
6855 | 6889 |
6856 // :await_jump_var = -1; | 6890 // :await_jump_var = -1; |
6857 LocalVariable* jump_var = | 6891 LocalVariable* jump_var = |
6858 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6892 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
6859 LiteralNode* init_value = | 6893 LiteralNode* init_value = new(Z) LiteralNode(TokenDescriptor::kNoSource, |
6860 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6894 Smi::ZoneHandle(Smi::New(-1))); |
6861 current_block_->statements->Add( | 6895 current_block_->statements->Add( |
6862 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); | 6896 new(Z) StoreLocalNode(TokenDescriptor::kNoSource, jump_var, init_value)); |
6863 | 6897 |
6864 // Add to AST: | 6898 // Add to AST: |
6865 // :async_op = <closure>; (containing the original body) | 6899 // :async_op = <closure>; (containing the original body) |
6866 LocalVariable* async_op_var = | 6900 LocalVariable* async_op_var = |
6867 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 6901 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
6868 ClosureNode* closure_obj = new(Z) ClosureNode( | 6902 ClosureNode* closure_obj = new(Z) ClosureNode( |
6869 Token::kNoSourcePos, closure_func, NULL, closure_body->scope()); | 6903 TokenDescriptor::kNoSource, closure_func, NULL, closure_body->scope()); |
6870 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 6904 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
6871 Token::kNoSourcePos, | 6905 TokenDescriptor::kNoSource, |
6872 async_op_var, | 6906 async_op_var, |
6873 closure_obj); | 6907 closure_obj); |
6874 | 6908 |
6875 current_block_->statements->Add(store_async_op); | 6909 current_block_->statements->Add(store_async_op); |
6876 | 6910 |
6877 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 6911 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
6878 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 6912 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
6879 Z, async_lib.LookupFunctionAllowPrivate( | 6913 Z, async_lib.LookupFunctionAllowPrivate( |
6880 Symbols::AsyncThenWrapperHelper())); | 6914 Symbols::AsyncThenWrapperHelper())); |
6881 ASSERT(!async_then_wrapper_helper.IsNull()); | 6915 ASSERT(!async_then_wrapper_helper.IsNull()); |
6882 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 6916 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( |
6883 Token::kNoSourcePos); | 6917 TokenDescriptor::kNoSource); |
6884 async_then_wrapper_helper_args->Add( | 6918 async_then_wrapper_helper_args->Add( |
6885 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6919 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_op_var)); |
6886 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 6920 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( |
6887 Token::kNoSourcePos, | 6921 TokenDescriptor::kNoSource, |
6888 async_then_wrapper_helper, | 6922 async_then_wrapper_helper, |
6889 async_then_wrapper_helper_args); | 6923 async_then_wrapper_helper_args); |
6890 LocalVariable* async_then_callback_var = | 6924 LocalVariable* async_then_callback_var = |
6891 current_block_->scope->LookupVariable( | 6925 current_block_->scope->LookupVariable( |
6892 Symbols::AsyncThenCallback(), false); | 6926 Symbols::AsyncThenCallback(), false); |
6893 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 6927 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( |
6894 Token::kNoSourcePos, | 6928 TokenDescriptor::kNoSource, |
6895 async_then_callback_var, | 6929 async_then_callback_var, |
6896 then_wrapper_call); | 6930 then_wrapper_call); |
6897 | 6931 |
6898 current_block_->statements->Add(store_async_then_callback); | 6932 current_block_->statements->Add(store_async_then_callback); |
6899 | 6933 |
6900 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 6934 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
6901 | 6935 |
6902 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 6936 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
6903 Z, async_lib.LookupFunctionAllowPrivate( | 6937 Z, async_lib.LookupFunctionAllowPrivate( |
6904 Symbols::AsyncErrorWrapperHelper())); | 6938 Symbols::AsyncErrorWrapperHelper())); |
6905 ASSERT(!async_error_wrapper_helper.IsNull()); | 6939 ASSERT(!async_error_wrapper_helper.IsNull()); |
6906 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 6940 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( |
6907 Token::kNoSourcePos); | 6941 TokenDescriptor::kNoSource); |
6908 async_error_wrapper_helper_args->Add( | 6942 async_error_wrapper_helper_args->Add( |
6909 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6943 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_op_var)); |
6910 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 6944 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( |
6911 Token::kNoSourcePos, | 6945 TokenDescriptor::kNoSource, |
6912 async_error_wrapper_helper, | 6946 async_error_wrapper_helper, |
6913 async_error_wrapper_helper_args); | 6947 async_error_wrapper_helper_args); |
6914 LocalVariable* async_catch_error_callback_var = | 6948 LocalVariable* async_catch_error_callback_var = |
6915 current_block_->scope->LookupVariable( | 6949 current_block_->scope->LookupVariable( |
6916 Symbols::AsyncCatchErrorCallback(), false); | 6950 Symbols::AsyncCatchErrorCallback(), false); |
6917 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 6951 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( |
6918 Token::kNoSourcePos, | 6952 TokenDescriptor::kNoSource, |
6919 async_catch_error_callback_var, | 6953 async_catch_error_callback_var, |
6920 error_wrapper_call); | 6954 error_wrapper_call); |
6921 | 6955 |
6922 current_block_->statements->Add(store_async_catch_error_callback); | 6956 current_block_->statements->Add(store_async_catch_error_callback); |
6923 | 6957 |
6924 // :controller = new _AsyncStarStreamController(body_closure); | 6958 // :controller = new _AsyncStarStreamController(body_closure); |
6925 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); | 6959 ArgumentListNode* arguments = |
6926 arguments->Add(new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6960 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 6961 arguments->Add( |
| 6962 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_op_var)); |
6927 ConstructorCallNode* controller_constructor_call = | 6963 ConstructorCallNode* controller_constructor_call = |
6928 new(Z) ConstructorCallNode(Token::kNoSourcePos, | 6964 new(Z) ConstructorCallNode(TokenDescriptor::kNoSource, |
6929 TypeArguments::ZoneHandle(Z), | 6965 TypeArguments::ZoneHandle(Z), |
6930 controller_constructor, | 6966 controller_constructor, |
6931 arguments); | 6967 arguments); |
6932 LocalVariable* controller_var = | 6968 LocalVariable* controller_var = |
6933 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6969 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
6934 StoreLocalNode* store_controller = | 6970 StoreLocalNode* store_controller = |
6935 new(Z) StoreLocalNode(Token::kNoSourcePos, | 6971 new(Z) StoreLocalNode(TokenDescriptor::kNoSource, |
6936 controller_var, | 6972 controller_var, |
6937 controller_constructor_call); | 6973 controller_constructor_call); |
6938 current_block_->statements->Add(store_controller); | 6974 current_block_->statements->Add(store_controller); |
6939 | 6975 |
6940 // return :controller.stream; | 6976 // return :controller.stream; |
6941 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos, | 6977 ReturnNode* return_node = new(Z) ReturnNode(TokenDescriptor::kNoSource, |
6942 new(Z) InstanceGetterNode(Token::kNoSourcePos, | 6978 new(Z) InstanceGetterNode(TokenDescriptor::kNoSource, |
6943 new(Z) LoadLocalNode(Token::kNoSourcePos, | 6979 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, |
6944 controller_var), | 6980 controller_var), |
6945 Symbols::Stream())); | 6981 Symbols::Stream())); |
6946 current_block_->statements->Add(return_node); | 6982 current_block_->statements->Add(return_node); |
6947 return CloseBlock(); | 6983 return CloseBlock(); |
6948 } | 6984 } |
6949 | 6985 |
6950 | 6986 |
6951 void Parser::OpenAsyncGeneratorClosure() { | 6987 void Parser::OpenAsyncGeneratorClosure() { |
6952 async_temp_scope_ = current_block_->scope; | 6988 async_temp_scope_ = current_block_->scope; |
6953 OpenAsyncTryBlock(); | 6989 OpenAsyncTryBlock(); |
6954 } | 6990 } |
6955 | 6991 |
6956 | 6992 |
6957 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { | 6993 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { |
6958 // We need a temporary expression to store intermediate return values. | 6994 // We need a temporary expression to store intermediate return values. |
6959 parsed_function()->EnsureExpressionTemp(); | 6995 parsed_function()->EnsureExpressionTemp(); |
6960 | 6996 |
6961 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); | 6997 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); |
6962 ASSERT(new_body != NULL); | 6998 ASSERT(new_body != NULL); |
6963 ASSERT(new_body->scope() != NULL); | 6999 ASSERT(new_body->scope() != NULL); |
6964 return new_body; | 7000 return new_body; |
6965 } | 7001 } |
6966 | 7002 |
6967 | 7003 |
6968 // Add a return node to the sequence if necessary. | 7004 // Add a return node to the sequence if necessary. |
6969 void Parser::EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos) { | 7005 void Parser::EnsureHasReturnStatement(SequenceNode* seq, |
| 7006 TokenDescriptor return_pos) { |
6970 if ((seq->length() == 0) || | 7007 if ((seq->length() == 0) || |
6971 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { | 7008 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { |
6972 const Function& func = innermost_function(); | 7009 const Function& func = innermost_function(); |
6973 // The implicit return value of synchronous generator closures is false, | 7010 // The implicit return value of synchronous generator closures is false, |
6974 // to indicate that there are no more elements in the iterable. | 7011 // to indicate that there are no more elements in the iterable. |
6975 // In other cases the implicit return value is null. | 7012 // In other cases the implicit return value is null. |
6976 AstNode* return_value = func.IsSyncGenClosure() | 7013 AstNode* return_value = func.IsSyncGenClosure() |
6977 ? new LiteralNode(return_pos, Bool::False()) | 7014 ? new LiteralNode(return_pos, Bool::False()) |
6978 : new LiteralNode(return_pos, Instance::ZoneHandle()); | 7015 : new LiteralNode(return_pos, Instance::ZoneHandle()); |
6979 seq->Add(new ReturnNode(return_pos, return_value)); | 7016 seq->Add(new ReturnNode(return_pos, return_value)); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7027 const Class& completer = | 7064 const Class& completer = |
7028 Class::ZoneHandle(Z, I->object_store()->completer_class()); | 7065 Class::ZoneHandle(Z, I->object_store()->completer_class()); |
7029 ASSERT(!completer.IsNull()); | 7066 ASSERT(!completer.IsNull()); |
7030 const Function& completer_constructor = Function::ZoneHandle(Z, | 7067 const Function& completer_constructor = Function::ZoneHandle(Z, |
7031 completer.LookupFunction(Symbols::CompleterSyncConstructor())); | 7068 completer.LookupFunction(Symbols::CompleterSyncConstructor())); |
7032 ASSERT(!completer_constructor.IsNull()); | 7069 ASSERT(!completer_constructor.IsNull()); |
7033 | 7070 |
7034 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 7071 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
7035 Symbols::AsyncCompleter(), false); | 7072 Symbols::AsyncCompleter(), false); |
7036 | 7073 |
7037 const intptr_t token_pos = ST(closure_body->token_pos()); | 7074 const TokenDescriptor token_pos = ST(closure_body->token_pos()); |
7038 // Add to AST: | 7075 // Add to AST: |
7039 // :async_completer = new Completer.sync(); | 7076 // :async_completer = new Completer.sync(); |
7040 ArgumentListNode* empty_args = | 7077 ArgumentListNode* empty_args = |
7041 new (Z) ArgumentListNode(token_pos); | 7078 new (Z) ArgumentListNode(token_pos); |
7042 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( | 7079 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( |
7043 token_pos, | 7080 token_pos, |
7044 TypeArguments::ZoneHandle(Z), | 7081 TypeArguments::ZoneHandle(Z), |
7045 completer_constructor, | 7082 completer_constructor, |
7046 empty_args); | 7083 empty_args); |
7047 StoreLocalNode* store_completer = new (Z) StoreLocalNode( | 7084 StoreLocalNode* store_completer = new (Z) StoreLocalNode( |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7273 | 7310 |
7274 void Parser::CaptureInstantiator() { | 7311 void Parser::CaptureInstantiator() { |
7275 ASSERT(current_block_->scope->function_level() > 0); | 7312 ASSERT(current_block_->scope->function_level() > 0); |
7276 const String* variable_name = current_function().IsInFactoryScope() ? | 7313 const String* variable_name = current_function().IsInFactoryScope() ? |
7277 &Symbols::TypeArgumentsParameter() : &Symbols::This(); | 7314 &Symbols::TypeArgumentsParameter() : &Symbols::This(); |
7278 current_block_->scope->CaptureVariable( | 7315 current_block_->scope->CaptureVariable( |
7279 current_block_->scope->LookupVariable(*variable_name, true)); | 7316 current_block_->scope->LookupVariable(*variable_name, true)); |
7280 } | 7317 } |
7281 | 7318 |
7282 | 7319 |
7283 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 7320 AstNode* Parser::LoadReceiver(TokenDescriptor token_pos) { |
7284 // A nested function may access 'this', referring to the receiver of the | 7321 // A nested function may access 'this', referring to the receiver of the |
7285 // outermost enclosing function. | 7322 // outermost enclosing function. |
7286 const bool kTestOnly = false; | 7323 const bool kTestOnly = false; |
7287 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7324 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
7288 if (receiver == NULL) { | 7325 if (receiver == NULL) { |
7289 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7326 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
7290 } | 7327 } |
7291 return new(Z) LoadLocalNode(TokenPos(), receiver); | 7328 return new(Z) LoadLocalNode(TokenPos(), receiver); |
7292 } | 7329 } |
7293 | 7330 |
7294 | 7331 |
7295 InstanceGetterNode* Parser::CallGetter(intptr_t token_pos, | 7332 InstanceGetterNode* Parser::CallGetter(TokenDescriptor token_pos, |
7296 AstNode* object, | 7333 AstNode* object, |
7297 const String& name) { | 7334 const String& name) { |
7298 return new(Z) InstanceGetterNode(token_pos, object, name); | 7335 return new(Z) InstanceGetterNode(token_pos, object, name); |
7299 } | 7336 } |
7300 | 7337 |
7301 | 7338 |
7302 // Returns ast nodes of the variable initialization. | 7339 // Returns ast nodes of the variable initialization. |
7303 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7340 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
7304 bool is_final, | 7341 bool is_final, |
7305 bool is_const, | 7342 bool is_const, |
7306 SequenceNode** await_preamble) { | 7343 SequenceNode** await_preamble) { |
7307 TRACE_PARSER("ParseVariableDeclaration"); | 7344 TRACE_PARSER("ParseVariableDeclaration"); |
7308 ASSERT(IsIdentifier()); | 7345 ASSERT(IsIdentifier()); |
7309 const intptr_t ident_pos = TokenPos(); | 7346 const TokenDescriptor ident_pos = TokenPos(); |
7310 const String& ident = *CurrentLiteral(); | 7347 const String& ident = *CurrentLiteral(); |
7311 ConsumeToken(); // Variable identifier. | 7348 ConsumeToken(); // Variable identifier. |
7312 const intptr_t assign_pos = TokenPos(); | 7349 const TokenDescriptor assign_pos = TokenPos(); |
7313 AstNode* initialization = NULL; | 7350 AstNode* initialization = NULL; |
7314 LocalVariable* variable = NULL; | 7351 LocalVariable* variable = NULL; |
7315 if (CurrentToken() == Token::kASSIGN) { | 7352 if (CurrentToken() == Token::kASSIGN) { |
7316 // Variable initialization. | 7353 // Variable initialization. |
7317 ConsumeToken(); | 7354 ConsumeToken(); |
7318 AstNode* expr = ParseAwaitableExpr( | 7355 AstNode* expr = ParseAwaitableExpr( |
7319 is_const, kConsumeCascades, await_preamble); | 7356 is_const, kConsumeCascades, await_preamble); |
7320 const intptr_t expr_end_pos = TokenPos(); | 7357 const TokenDescriptor expr_end_pos = TokenPos(); |
7321 variable = new(Z) LocalVariable( | 7358 variable = new(Z) LocalVariable( |
7322 expr_end_pos, ident, type); | 7359 expr_end_pos, ident, type); |
7323 initialization = new(Z) StoreLocalNode( | 7360 initialization = new(Z) StoreLocalNode( |
7324 assign_pos, variable, expr); | 7361 assign_pos, variable, expr); |
7325 if (is_const) { | 7362 if (is_const) { |
7326 ASSERT(expr->IsLiteralNode()); | 7363 ASSERT(expr->IsLiteralNode()); |
7327 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 7364 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
7328 } | 7365 } |
7329 } else if (is_final || is_const) { | 7366 } else if (is_final || is_const) { |
7330 ReportError(ident_pos, | 7367 ReportError(ident_pos, |
7331 "missing initialization of 'final' or 'const' variable"); | 7368 "missing initialization of 'final' or 'const' variable"); |
7332 } else { | 7369 } else { |
7333 // Initialize variable with null. | 7370 // Initialize variable with null. |
7334 variable = new(Z) LocalVariable( | 7371 variable = new(Z) LocalVariable( |
7335 assign_pos, ident, type); | 7372 assign_pos, ident, type); |
7336 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); | 7373 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); |
7337 initialization = new(Z) StoreLocalNode( | 7374 initialization = new(Z) StoreLocalNode( |
7338 ident_pos, variable, null_expr); | 7375 ident_pos, variable, null_expr); |
7339 } | 7376 } |
7340 | 7377 |
7341 ASSERT(current_block_ != NULL); | 7378 ASSERT(current_block_ != NULL); |
7342 const intptr_t previous_pos = | 7379 const TokenDescriptor previous_pos = |
7343 current_block_->scope->PreviousReferencePos(ident); | 7380 current_block_->scope->PreviousReferencePos(ident); |
7344 if (previous_pos >= 0) { | 7381 if (previous_pos.IsReal()) { |
7345 ASSERT(!script_.IsNull()); | 7382 ASSERT(!script_.IsNull()); |
7346 if (previous_pos > ident_pos) { | 7383 if (previous_pos > ident_pos) { |
7347 ReportError(ident_pos, | 7384 ReportError(ident_pos, |
7348 "initializer of '%s' may not refer to itself", | 7385 "initializer of '%s' may not refer to itself", |
7349 ident.ToCString()); | 7386 ident.ToCString()); |
7350 | 7387 |
7351 } else { | 7388 } else { |
7352 intptr_t line_number; | 7389 intptr_t line_number; |
7353 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7390 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7354 ReportError(ident_pos, | 7391 ReportError(ident_pos, |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7461 | 7498 |
7462 | 7499 |
7463 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7500 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
7464 TRACE_PARSER("ParseFunctionStatement"); | 7501 TRACE_PARSER("ParseFunctionStatement"); |
7465 AbstractType& result_type = AbstractType::Handle(Z); | 7502 AbstractType& result_type = AbstractType::Handle(Z); |
7466 const String* variable_name = NULL; | 7503 const String* variable_name = NULL; |
7467 const String* function_name = NULL; | 7504 const String* function_name = NULL; |
7468 | 7505 |
7469 result_type = Type::DynamicType(); | 7506 result_type = Type::DynamicType(); |
7470 | 7507 |
7471 const intptr_t function_pos = TokenPos(); | 7508 const TokenDescriptor function_pos = TokenPos(); |
7472 intptr_t metadata_pos = Token::kNoSourcePos; | 7509 TokenDescriptor metadata_pos = TokenDescriptor::kNoSource; |
7473 if (is_literal) { | 7510 if (is_literal) { |
7474 ASSERT(CurrentToken() == Token::kLPAREN); | 7511 ASSERT(CurrentToken() == Token::kLPAREN); |
7475 function_name = &Symbols::AnonymousClosure(); | 7512 function_name = &Symbols::AnonymousClosure(); |
7476 } else { | 7513 } else { |
7477 metadata_pos = SkipMetadata(); | 7514 metadata_pos = SkipMetadata(); |
7478 if (CurrentToken() == Token::kVOID) { | 7515 if (CurrentToken() == Token::kVOID) { |
7479 ConsumeToken(); | 7516 ConsumeToken(); |
7480 result_type = Type::VoidType(); | 7517 result_type = Type::VoidType(); |
7481 } else if ((CurrentToken() == Token::kIDENT) && | 7518 } else if ((CurrentToken() == Token::kIDENT) && |
7482 (LookaheadToken(1) != Token::kLPAREN)) { | 7519 (LookaheadToken(1) != Token::kLPAREN)) { |
7483 result_type = ParseType(ClassFinalizer::kCanonicalize); | 7520 result_type = ParseType(ClassFinalizer::kCanonicalize); |
7484 } | 7521 } |
7485 const intptr_t name_pos = TokenPos(); | 7522 const TokenDescriptor name_pos = TokenPos(); |
7486 variable_name = ExpectIdentifier("function name expected"); | 7523 variable_name = ExpectIdentifier("function name expected"); |
7487 function_name = variable_name; | 7524 function_name = variable_name; |
7488 | 7525 |
7489 // Check that the function name has not been referenced | 7526 // Check that the function name has not been referenced |
7490 // before this declaration. | 7527 // before this declaration. |
7491 ASSERT(current_block_ != NULL); | 7528 ASSERT(current_block_ != NULL); |
7492 const intptr_t previous_pos = | 7529 const TokenDescriptor previous_pos = |
7493 current_block_->scope->PreviousReferencePos(*function_name); | 7530 current_block_->scope->PreviousReferencePos(*function_name); |
7494 if (previous_pos >= 0) { | 7531 if (previous_pos.IsReal()) { |
7495 ASSERT(!script_.IsNull()); | 7532 ASSERT(!script_.IsNull()); |
7496 intptr_t line_number; | 7533 intptr_t line_number; |
7497 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7534 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7498 ReportError(name_pos, | 7535 ReportError(name_pos, |
7499 "identifier '%s' previously used in line %" Pd "", | 7536 "identifier '%s' previously used in line %" Pd "", |
7500 function_name->ToCString(), | 7537 function_name->ToCString(), |
7501 line_number); | 7538 line_number); |
7502 } | 7539 } |
7503 } | 7540 } |
7504 CheckToken(Token::kLPAREN); | 7541 CheckToken(Token::kLPAREN); |
7505 | 7542 |
7506 // Check whether we have parsed this closure function before, in a previous | 7543 // Check whether we have parsed this closure function before, in a previous |
7507 // compilation. If so, reuse the function object, else create a new one | 7544 // compilation. If so, reuse the function object, else create a new one |
7508 // and register it in the current class. | 7545 // and register it in the current class. |
7509 // Note that we cannot share the same closure function between the closurized | 7546 // Note that we cannot share the same closure function between the closurized |
7510 // and non-closurized versions of the same parent function. | 7547 // and non-closurized versions of the same parent function. |
7511 Function& function = Function::ZoneHandle(Z); | 7548 Function& function = Function::ZoneHandle(Z); |
7512 // TODO(hausner): There could be two different closures at the given | 7549 // TODO(hausner): There could be two different closures at the given |
7513 // function_pos, one enclosed in a closurized function and one enclosed in the | 7550 // function_pos, one enclosed in a closurized function and one enclosed in the |
7514 // non-closurized version of this same function. | 7551 // non-closurized version of this same function. |
7515 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7552 function = I->LookupClosureFunction(innermost_function(), function_pos); |
7516 if (function.IsNull()) { | 7553 if (function.IsNull()) { |
7517 // The function will be registered in the lookup table by the | 7554 // The function will be registered in the lookup table by the |
7518 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7555 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
7519 // function has been properly setup. | 7556 // function has been properly setup. |
7520 function = Function::NewClosureFunction(*function_name, | 7557 function = Function::NewClosureFunction(*function_name, |
7521 innermost_function(), | 7558 innermost_function(), |
7522 function_pos); | 7559 function_pos); |
7523 function.set_result_type(result_type); | 7560 function.set_result_type(result_type); |
7524 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 7561 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
7525 library_.AddFunctionMetadata(function, metadata_pos); | 7562 library_.AddFunctionMetadata(function, metadata_pos); |
7526 } | 7563 } |
7527 } | 7564 } |
7528 | 7565 |
7529 // The function type needs to be finalized at compile time, since the closure | 7566 // The function type needs to be finalized at compile time, since the closure |
7530 // may be type checked at run time when assigned to a function variable, | 7567 // may be type checked at run time when assigned to a function variable, |
7531 // passed as a function argument, or returned as a function result. | 7568 // passed as a function argument, or returned as a function result. |
7532 | 7569 |
7533 LocalVariable* function_variable = NULL; | 7570 LocalVariable* function_variable = NULL; |
7534 FunctionType& function_type = FunctionType::ZoneHandle(Z); | 7571 FunctionType& function_type = FunctionType::ZoneHandle(Z); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7790 // | const [type] ident (';' | '=' | ',') | 7827 // | const [type] ident (';' | '=' | ',') |
7791 // | type ident (';' | '=' | ',') | 7828 // | type ident (';' | '=' | ',') |
7792 // Token position remains unchanged. | 7829 // Token position remains unchanged. |
7793 bool Parser::IsVariableDeclaration() { | 7830 bool Parser::IsVariableDeclaration() { |
7794 if ((CurrentToken() == Token::kVAR) || | 7831 if ((CurrentToken() == Token::kVAR) || |
7795 (CurrentToken() == Token::kFINAL)) { | 7832 (CurrentToken() == Token::kFINAL)) { |
7796 return true; | 7833 return true; |
7797 } | 7834 } |
7798 // Skip optional metadata. | 7835 // Skip optional metadata. |
7799 if (CurrentToken() == Token::kAT) { | 7836 if (CurrentToken() == Token::kAT) { |
7800 const intptr_t saved_pos = TokenPos(); | 7837 const TokenDescriptor saved_pos = TokenPos(); |
7801 SkipMetadata(); | 7838 SkipMetadata(); |
7802 const bool is_var_decl = IsVariableDeclaration(); | 7839 const bool is_var_decl = IsVariableDeclaration(); |
7803 SetPosition(saved_pos); | 7840 SetPosition(saved_pos); |
7804 return is_var_decl; | 7841 return is_var_decl; |
7805 } | 7842 } |
7806 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { | 7843 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { |
7807 // Not a legal type identifier or const keyword or metadata. | 7844 // Not a legal type identifier or const keyword or metadata. |
7808 return false; | 7845 return false; |
7809 } | 7846 } |
7810 const intptr_t saved_pos = TokenPos(); | 7847 const TokenDescriptor saved_pos = TokenPos(); |
7811 bool is_var_decl = false; | 7848 bool is_var_decl = false; |
7812 bool have_type = false; | 7849 bool have_type = false; |
7813 if (CurrentToken() == Token::kCONST) { | 7850 if (CurrentToken() == Token::kCONST) { |
7814 ConsumeToken(); | 7851 ConsumeToken(); |
7815 have_type = true; // Type is dynamic. | 7852 have_type = true; // Type is dynamic. |
7816 } | 7853 } |
7817 if (IsIdentifier()) { // Type or variable name. | 7854 if (IsIdentifier()) { // Type or variable name. |
7818 Token::Kind follower = LookaheadToken(1); | 7855 Token::Kind follower = LookaheadToken(1); |
7819 if ((follower == Token::kLT) || // Parameterized type. | 7856 if ((follower == Token::kLT) || // Parameterized type. |
7820 (follower == Token::kPERIOD) || // Qualified class name of type. | 7857 (follower == Token::kPERIOD) || // Qualified class name of type. |
7821 Token::IsIdentifier(follower)) { // Variable name following a type. | 7858 Token::IsIdentifier(follower)) { // Variable name following a type. |
7822 // We see the beginning of something that could be a type. | 7859 // We see the beginning of something that could be a type. |
7823 const intptr_t type_pos = TokenPos(); | 7860 const TokenDescriptor type_pos = TokenPos(); |
7824 if (TryParseOptionalType()) { | 7861 if (TryParseOptionalType()) { |
7825 have_type = true; | 7862 have_type = true; |
7826 } else { | 7863 } else { |
7827 SetPosition(type_pos); | 7864 SetPosition(type_pos); |
7828 } | 7865 } |
7829 } | 7866 } |
7830 if (have_type && IsIdentifier()) { | 7867 if (have_type && IsIdentifier()) { |
7831 ConsumeToken(); | 7868 ConsumeToken(); |
7832 if ((CurrentToken() == Token::kSEMICOLON) || | 7869 if ((CurrentToken() == Token::kSEMICOLON) || |
7833 (CurrentToken() == Token::kCOMMA) || | 7870 (CurrentToken() == Token::kCOMMA) || |
7834 (CurrentToken() == Token::kASSIGN)) { | 7871 (CurrentToken() == Token::kASSIGN)) { |
7835 is_var_decl = true; | 7872 is_var_decl = true; |
7836 } | 7873 } |
7837 } | 7874 } |
7838 } | 7875 } |
7839 SetPosition(saved_pos); | 7876 SetPosition(saved_pos); |
7840 return is_var_decl; | 7877 return is_var_decl; |
7841 } | 7878 } |
7842 | 7879 |
7843 | 7880 |
7844 // Look ahead to detect whether the next tokens should be parsed as | 7881 // Look ahead to detect whether the next tokens should be parsed as |
7845 // a function declaration. Token position remains unchanged. | 7882 // a function declaration. Token position remains unchanged. |
7846 bool Parser::IsFunctionDeclaration() { | 7883 bool Parser::IsFunctionDeclaration() { |
7847 const intptr_t saved_pos = TokenPos(); | 7884 const TokenDescriptor saved_pos = TokenPos(); |
7848 bool is_external = false; | 7885 bool is_external = false; |
7849 SkipMetadata(); | 7886 SkipMetadata(); |
7850 if (is_top_level_) { | 7887 if (is_top_level_) { |
7851 if (is_patch_source() && | 7888 if (is_patch_source() && |
7852 (CurrentToken() == Token::kIDENT) && | 7889 (CurrentToken() == Token::kIDENT) && |
7853 CurrentLiteral()->Equals("patch") && | 7890 CurrentLiteral()->Equals("patch") && |
7854 (LookaheadToken(1) != Token::kLPAREN)) { | 7891 (LookaheadToken(1) != Token::kLPAREN)) { |
7855 // Skip over 'patch' for top-level function declarations in patch sources. | 7892 // Skip over 'patch' for top-level function declarations in patch sources. |
7856 ConsumeToken(); | 7893 ConsumeToken(); |
7857 } else if (CurrentToken() == Token::kEXTERNAL) { | 7894 } else if (CurrentToken() == Token::kEXTERNAL) { |
(...skipping 27 matching lines...) Expand all Loading... |
7885 SetPosition(saved_pos); | 7922 SetPosition(saved_pos); |
7886 return true; | 7923 return true; |
7887 } | 7924 } |
7888 } | 7925 } |
7889 SetPosition(saved_pos); | 7926 SetPosition(saved_pos); |
7890 return false; | 7927 return false; |
7891 } | 7928 } |
7892 | 7929 |
7893 | 7930 |
7894 bool Parser::IsTopLevelAccessor() { | 7931 bool Parser::IsTopLevelAccessor() { |
7895 const intptr_t saved_pos = TokenPos(); | 7932 const TokenDescriptor saved_pos = TokenPos(); |
7896 if (is_patch_source() && IsSymbol(Symbols::Patch())) { | 7933 if (is_patch_source() && IsSymbol(Symbols::Patch())) { |
7897 ConsumeToken(); | 7934 ConsumeToken(); |
7898 } else if (CurrentToken() == Token::kEXTERNAL) { | 7935 } else if (CurrentToken() == Token::kEXTERNAL) { |
7899 ConsumeToken(); | 7936 ConsumeToken(); |
7900 } | 7937 } |
7901 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 7938 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
7902 SetPosition(saved_pos); | 7939 SetPosition(saved_pos); |
7903 return true; | 7940 return true; |
7904 } | 7941 } |
7905 if (TryParseReturnType()) { | 7942 if (TryParseReturnType()) { |
7906 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 7943 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
7907 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 7944 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
7908 SetPosition(saved_pos); | 7945 SetPosition(saved_pos); |
7909 return true; | 7946 return true; |
7910 } | 7947 } |
7911 } | 7948 } |
7912 } | 7949 } |
7913 SetPosition(saved_pos); | 7950 SetPosition(saved_pos); |
7914 return false; | 7951 return false; |
7915 } | 7952 } |
7916 | 7953 |
7917 | 7954 |
7918 bool Parser::IsFunctionLiteral() { | 7955 bool Parser::IsFunctionLiteral() { |
7919 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { | 7956 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { |
7920 return false; | 7957 return false; |
7921 } | 7958 } |
7922 const intptr_t saved_pos = TokenPos(); | 7959 const TokenDescriptor saved_pos = TokenPos(); |
7923 bool is_function_literal = false; | 7960 bool is_function_literal = false; |
7924 SkipToMatchingParenthesis(); | 7961 SkipToMatchingParenthesis(); |
7925 ParseFunctionModifier(); | 7962 ParseFunctionModifier(); |
7926 if ((CurrentToken() == Token::kLBRACE) || | 7963 if ((CurrentToken() == Token::kLBRACE) || |
7927 (CurrentToken() == Token::kARROW)) { | 7964 (CurrentToken() == Token::kARROW)) { |
7928 is_function_literal = true; | 7965 is_function_literal = true; |
7929 } | 7966 } |
7930 SetPosition(saved_pos); | 7967 SetPosition(saved_pos); |
7931 return is_function_literal; | 7968 return is_function_literal; |
7932 } | 7969 } |
7933 | 7970 |
7934 | 7971 |
7935 // Current token position is the token after the opening ( of the for | 7972 // Current token position is the token after the opening ( of the for |
7936 // statement. Returns true if we recognize a for ( .. in expr) | 7973 // statement. Returns true if we recognize a for ( .. in expr) |
7937 // statement. | 7974 // statement. |
7938 bool Parser::IsForInStatement() { | 7975 bool Parser::IsForInStatement() { |
7939 const intptr_t saved_pos = TokenPos(); | 7976 const TokenDescriptor saved_pos = TokenPos(); |
7940 bool result = false; | 7977 bool result = false; |
7941 // Allow const modifier as well when recognizing a for-in statement | 7978 // Allow const modifier as well when recognizing a for-in statement |
7942 // pattern. We will get an error later if the loop variable is | 7979 // pattern. We will get an error later if the loop variable is |
7943 // declared with const. | 7980 // declared with const. |
7944 if (CurrentToken() == Token::kVAR || | 7981 if (CurrentToken() == Token::kVAR || |
7945 CurrentToken() == Token::kFINAL || | 7982 CurrentToken() == Token::kFINAL || |
7946 CurrentToken() == Token::kCONST) { | 7983 CurrentToken() == Token::kCONST) { |
7947 ConsumeToken(); | 7984 ConsumeToken(); |
7948 } | 7985 } |
7949 if (IsIdentifier()) { | 7986 if (IsIdentifier()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7981 return false; | 8018 return false; |
7982 } | 8019 } |
7983 | 8020 |
7984 | 8021 |
7985 void Parser::ParseStatementSequence() { | 8022 void Parser::ParseStatementSequence() { |
7986 TRACE_PARSER("ParseStatementSequence"); | 8023 TRACE_PARSER("ParseStatementSequence"); |
7987 const bool dead_code_allowed = true; | 8024 const bool dead_code_allowed = true; |
7988 bool abrupt_completing_seen = false; | 8025 bool abrupt_completing_seen = false; |
7989 RecursionChecker rc(this); | 8026 RecursionChecker rc(this); |
7990 while (CurrentToken() != Token::kRBRACE) { | 8027 while (CurrentToken() != Token::kRBRACE) { |
7991 const intptr_t statement_pos = TokenPos(); | 8028 const TokenDescriptor statement_pos = TokenPos(); |
7992 AstNode* statement = ParseStatement(); | 8029 AstNode* statement = ParseStatement(); |
7993 // Do not add statements with no effect (e.g., LoadLocalNode). | 8030 // Do not add statements with no effect (e.g., LoadLocalNode). |
7994 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 8031 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
7995 // Skip load local. | 8032 // Skip load local. |
7996 continue; | 8033 continue; |
7997 } | 8034 } |
7998 if (statement != NULL) { | 8035 if (statement != NULL) { |
7999 if (!dead_code_allowed && abrupt_completing_seen) { | 8036 if (!dead_code_allowed && abrupt_completing_seen) { |
8000 ReportError(statement_pos, | 8037 ReportError(statement_pos, |
8001 "dead code after abrupt completing statement"); | 8038 "dead code after abrupt completing statement"); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8033 } | 8070 } |
8034 } | 8071 } |
8035 SequenceNode* sequence = CloseBlock(); | 8072 SequenceNode* sequence = CloseBlock(); |
8036 return sequence; | 8073 return sequence; |
8037 } | 8074 } |
8038 | 8075 |
8039 | 8076 |
8040 AstNode* Parser::ParseIfStatement(String* label_name) { | 8077 AstNode* Parser::ParseIfStatement(String* label_name) { |
8041 TRACE_PARSER("ParseIfStatement"); | 8078 TRACE_PARSER("ParseIfStatement"); |
8042 ASSERT(CurrentToken() == Token::kIF); | 8079 ASSERT(CurrentToken() == Token::kIF); |
8043 const intptr_t if_pos = TokenPos(); | 8080 const TokenDescriptor if_pos = TokenPos(); |
8044 SourceLabel* label = NULL; | 8081 SourceLabel* label = NULL; |
8045 if (label_name != NULL) { | 8082 if (label_name != NULL) { |
8046 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 8083 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
8047 OpenBlock(); | 8084 OpenBlock(); |
8048 current_block_->scope->AddLabel(label); | 8085 current_block_->scope->AddLabel(label); |
8049 } | 8086 } |
8050 ConsumeToken(); | 8087 ConsumeToken(); |
8051 ExpectToken(Token::kLPAREN); | 8088 ExpectToken(Token::kLPAREN); |
8052 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8089 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8053 ExpectToken(Token::kRPAREN); | 8090 ExpectToken(Token::kRPAREN); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8088 // of a LiteralNode. | 8125 // of a LiteralNode. |
8089 RawClass* Parser::CheckCaseExpressions( | 8126 RawClass* Parser::CheckCaseExpressions( |
8090 const GrowableArray<LiteralNode*>& values) { | 8127 const GrowableArray<LiteralNode*>& values) { |
8091 const intptr_t num_expressions = values.length(); | 8128 const intptr_t num_expressions = values.length(); |
8092 if (num_expressions == 0) { | 8129 if (num_expressions == 0) { |
8093 return Object::dynamic_class(); | 8130 return Object::dynamic_class(); |
8094 } | 8131 } |
8095 const Instance& first_value = values[0]->literal(); | 8132 const Instance& first_value = values[0]->literal(); |
8096 for (intptr_t i = 0; i < num_expressions; i++) { | 8133 for (intptr_t i = 0; i < num_expressions; i++) { |
8097 const Instance& val = values[i]->literal(); | 8134 const Instance& val = values[i]->literal(); |
8098 const intptr_t val_pos = values[i]->token_pos(); | 8135 const TokenDescriptor val_pos = values[i]->token_pos(); |
8099 if (first_value.IsInteger()) { | 8136 if (first_value.IsInteger()) { |
8100 if (!val.IsInteger()) { | 8137 if (!val.IsInteger()) { |
8101 ReportError(val_pos, "expected case expression of type int"); | 8138 ReportError(val_pos, "expected case expression of type int"); |
8102 } | 8139 } |
8103 continue; | 8140 continue; |
8104 } | 8141 } |
8105 if (first_value.IsString()) { | 8142 if (first_value.IsString()) { |
8106 if (!val.IsString()) { | 8143 if (!val.IsString()) { |
8107 ReportError(val_pos, "expected case expression of type String"); | 8144 ReportError(val_pos, "expected case expression of type String"); |
8108 } | 8145 } |
(...skipping 27 matching lines...) Expand all Loading... |
8136 } | 8173 } |
8137 return first_value.clazz(); | 8174 return first_value.clazz(); |
8138 } | 8175 } |
8139 | 8176 |
8140 | 8177 |
8141 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 8178 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
8142 GrowableArray<LiteralNode*>* case_expr_values, | 8179 GrowableArray<LiteralNode*>* case_expr_values, |
8143 SourceLabel* case_label) { | 8180 SourceLabel* case_label) { |
8144 TRACE_PARSER("ParseCaseClause"); | 8181 TRACE_PARSER("ParseCaseClause"); |
8145 bool default_seen = false; | 8182 bool default_seen = false; |
8146 const intptr_t case_pos = TokenPos(); | 8183 const TokenDescriptor case_pos = TokenPos(); |
8147 // The case expressions node sequence does not own the enclosing scope. | 8184 // The case expressions node sequence does not own the enclosing scope. |
8148 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); | 8185 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); |
8149 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 8186 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
8150 if (CurrentToken() == Token::kCASE) { | 8187 if (CurrentToken() == Token::kCASE) { |
8151 if (default_seen) { | 8188 if (default_seen) { |
8152 ReportError("default clause must be last case"); | 8189 ReportError("default clause must be last case"); |
8153 } | 8190 } |
8154 ConsumeToken(); // Keyword case. | 8191 ConsumeToken(); // Keyword case. |
8155 const intptr_t expr_pos = TokenPos(); | 8192 const TokenDescriptor expr_pos = TokenPos(); |
8156 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 8193 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
8157 ASSERT(expr->IsLiteralNode()); | 8194 ASSERT(expr->IsLiteralNode()); |
8158 case_expr_values->Add(expr->AsLiteralNode()); | 8195 case_expr_values->Add(expr->AsLiteralNode()); |
8159 | 8196 |
8160 AstNode* switch_expr_load = new(Z) LoadLocalNode( | 8197 AstNode* switch_expr_load = new(Z) LoadLocalNode( |
8161 case_pos, switch_expr_value); | 8198 case_pos, switch_expr_value); |
8162 AstNode* case_comparison = new(Z) ComparisonNode( | 8199 AstNode* case_comparison = new(Z) ComparisonNode( |
8163 expr_pos, Token::kEQ, expr, switch_expr_load); | 8200 expr_pos, Token::kEQ, expr, switch_expr_load); |
8164 case_expressions->Add(case_comparison); | 8201 case_expressions->Add(case_comparison); |
8165 } else { | 8202 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
8188 if (next_token == Token::kRBRACE) { | 8225 if (next_token == Token::kRBRACE) { |
8189 // End of switch statement. | 8226 // End of switch statement. |
8190 break; | 8227 break; |
8191 } | 8228 } |
8192 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 8229 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
8193 // End of this case clause. If there is a possible fall-through to | 8230 // End of this case clause. If there is a possible fall-through to |
8194 // the next case clause, throw an implicit FallThroughError. | 8231 // the next case clause, throw an implicit FallThroughError. |
8195 if (!abrupt_completing_seen) { | 8232 if (!abrupt_completing_seen) { |
8196 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); | 8233 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); |
8197 arguments->Add(new(Z) LiteralNode( | 8234 arguments->Add(new(Z) LiteralNode( |
8198 TokenPos(), Integer::ZoneHandle(Z, Integer::New(TokenPos())))); | 8235 TokenPos(), |
| 8236 Integer::ZoneHandle(Z, Integer::New(TokenPos().value())))); |
8199 current_block_->statements->Add( | 8237 current_block_->statements->Add( |
8200 MakeStaticCall(Symbols::FallThroughError(), | 8238 MakeStaticCall(Symbols::FallThroughError(), |
8201 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 8239 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
8202 arguments)); | 8240 arguments)); |
8203 } | 8241 } |
8204 break; | 8242 break; |
8205 } | 8243 } |
8206 // The next statement still belongs to this case. | 8244 // The next statement still belongs to this case. |
8207 AstNode* statement = ParseStatement(); | 8245 AstNode* statement = ParseStatement(); |
8208 if (statement != NULL) { | 8246 if (statement != NULL) { |
8209 current_block_->statements->Add(statement); | 8247 current_block_->statements->Add(statement); |
8210 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8248 abrupt_completing_seen |= IsAbruptCompleting(statement); |
8211 } | 8249 } |
8212 } | 8250 } |
8213 SequenceNode* statements = CloseBlock(); | 8251 SequenceNode* statements = CloseBlock(); |
8214 return new(Z) CaseNode(case_pos, case_label, | 8252 return new(Z) CaseNode(case_pos, case_label, |
8215 case_expressions, default_seen, switch_expr_value, statements); | 8253 case_expressions, default_seen, switch_expr_value, statements); |
8216 } | 8254 } |
8217 | 8255 |
8218 | 8256 |
8219 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 8257 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
8220 TRACE_PARSER("ParseSwitchStatement"); | 8258 TRACE_PARSER("ParseSwitchStatement"); |
8221 ASSERT(CurrentToken() == Token::kSWITCH); | 8259 ASSERT(CurrentToken() == Token::kSWITCH); |
8222 const intptr_t switch_pos = TokenPos(); | 8260 const TokenDescriptor switch_pos = TokenPos(); |
8223 SourceLabel* label = | 8261 SourceLabel* label = |
8224 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 8262 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
8225 ConsumeToken(); | 8263 ConsumeToken(); |
8226 ExpectToken(Token::kLPAREN); | 8264 ExpectToken(Token::kLPAREN); |
8227 const intptr_t expr_pos = TokenPos(); | 8265 const TokenDescriptor expr_pos = TokenPos(); |
8228 AstNode* switch_expr = ParseAwaitableExpr( | 8266 AstNode* switch_expr = ParseAwaitableExpr( |
8229 kAllowConst, kConsumeCascades, NULL); | 8267 kAllowConst, kConsumeCascades, NULL); |
8230 ExpectToken(Token::kRPAREN); | 8268 ExpectToken(Token::kRPAREN); |
8231 ExpectToken(Token::kLBRACE); | 8269 ExpectToken(Token::kLBRACE); |
8232 OpenBlock(); | 8270 OpenBlock(); |
8233 current_block_->scope->AddLabel(label); | 8271 current_block_->scope->AddLabel(label); |
8234 | 8272 |
8235 // Store switch expression in temporary local variable. The type of the | 8273 // Store switch expression in temporary local variable. The type of the |
8236 // variable is set to dynamic. It will later be patched to match the | 8274 // variable is set to dynamic. It will later be patched to match the |
8237 // type of the case clause expressions. Therefore, we have to allocate | 8275 // type of the case clause expressions. Therefore, we have to allocate |
(...skipping 13 matching lines...) Expand all Loading... |
8251 | 8289 |
8252 // Parse case clauses | 8290 // Parse case clauses |
8253 bool default_seen = false; | 8291 bool default_seen = false; |
8254 GrowableArray<LiteralNode*> case_expr_values; | 8292 GrowableArray<LiteralNode*> case_expr_values; |
8255 while (true) { | 8293 while (true) { |
8256 // Check for statement label | 8294 // Check for statement label |
8257 SourceLabel* case_label = NULL; | 8295 SourceLabel* case_label = NULL; |
8258 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 8296 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
8259 // Case statements start with a label. | 8297 // Case statements start with a label. |
8260 String* label_name = CurrentLiteral(); | 8298 String* label_name = CurrentLiteral(); |
8261 const intptr_t label_pos = TokenPos(); | 8299 const TokenDescriptor label_pos = TokenPos(); |
8262 ConsumeToken(); // Consume label identifier. | 8300 ConsumeToken(); // Consume label identifier. |
8263 ConsumeToken(); // Consume colon. | 8301 ConsumeToken(); // Consume colon. |
8264 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 8302 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
8265 if (case_label == NULL) { | 8303 if (case_label == NULL) { |
8266 // Label does not exist yet. Add it to scope of switch statement. | 8304 // Label does not exist yet. Add it to scope of switch statement. |
8267 case_label = new(Z) SourceLabel( | 8305 case_label = new(Z) SourceLabel( |
8268 label_pos, *label_name, SourceLabel::kCase); | 8306 label_pos, *label_name, SourceLabel::kCase); |
8269 current_block_->scope->AddLabel(case_label); | 8307 current_block_->scope->AddLabel(case_label); |
8270 } else if (case_label->kind() == SourceLabel::kForward) { | 8308 } else if (case_label->kind() == SourceLabel::kForward) { |
8271 // We have seen a 'continue' with this label name. Resolve | 8309 // We have seen a 'continue' with this label name. Resolve |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8311 } | 8349 } |
8312 | 8350 |
8313 SequenceNode* switch_body = CloseBlock(); | 8351 SequenceNode* switch_body = CloseBlock(); |
8314 ExpectToken(Token::kRBRACE); | 8352 ExpectToken(Token::kRBRACE); |
8315 return new(Z) SwitchNode(switch_pos, label, switch_body); | 8353 return new(Z) SwitchNode(switch_pos, label, switch_body); |
8316 } | 8354 } |
8317 | 8355 |
8318 | 8356 |
8319 AstNode* Parser::ParseWhileStatement(String* label_name) { | 8357 AstNode* Parser::ParseWhileStatement(String* label_name) { |
8320 TRACE_PARSER("ParseWhileStatement"); | 8358 TRACE_PARSER("ParseWhileStatement"); |
8321 const intptr_t while_pos = TokenPos(); | 8359 const TokenDescriptor while_pos = TokenPos(); |
8322 SourceLabel* label = | 8360 SourceLabel* label = |
8323 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 8361 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
8324 ConsumeToken(); | 8362 ConsumeToken(); |
8325 ExpectToken(Token::kLPAREN); | 8363 ExpectToken(Token::kLPAREN); |
8326 SequenceNode* await_preamble = NULL; | 8364 SequenceNode* await_preamble = NULL; |
8327 AstNode* cond_expr = ParseAwaitableExpr( | 8365 AstNode* cond_expr = ParseAwaitableExpr( |
8328 kAllowConst, kConsumeCascades, &await_preamble); | 8366 kAllowConst, kConsumeCascades, &await_preamble); |
8329 ExpectToken(Token::kRPAREN); | 8367 ExpectToken(Token::kRPAREN); |
8330 const bool parsing_loop_body = true; | 8368 const bool parsing_loop_body = true; |
8331 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 8369 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
8332 WhileNode* while_node = new (Z) WhileNode(while_pos, | 8370 WhileNode* while_node = new (Z) WhileNode(while_pos, |
8333 label, | 8371 label, |
8334 cond_expr, | 8372 cond_expr, |
8335 await_preamble, | 8373 await_preamble, |
8336 while_body); | 8374 while_body); |
8337 return while_node; | 8375 return while_node; |
8338 } | 8376 } |
8339 | 8377 |
8340 | 8378 |
8341 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 8379 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
8342 TRACE_PARSER("ParseDoWhileStatement"); | 8380 TRACE_PARSER("ParseDoWhileStatement"); |
8343 const intptr_t do_pos = TokenPos(); | 8381 const TokenDescriptor do_pos = TokenPos(); |
8344 SourceLabel* label = | 8382 SourceLabel* label = |
8345 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 8383 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
8346 ConsumeToken(); | 8384 ConsumeToken(); |
8347 const bool parsing_loop_body = true; | 8385 const bool parsing_loop_body = true; |
8348 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 8386 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
8349 ExpectToken(Token::kWHILE); | 8387 ExpectToken(Token::kWHILE); |
8350 ExpectToken(Token::kLPAREN); | 8388 ExpectToken(Token::kLPAREN); |
8351 SequenceNode* await_preamble = NULL; | 8389 SequenceNode* await_preamble = NULL; |
8352 intptr_t expr_pos = TokenPos(); | 8390 TokenDescriptor expr_pos = TokenPos(); |
8353 AstNode* cond_expr = | 8391 AstNode* cond_expr = |
8354 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8392 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
8355 if (await_preamble != NULL) { | 8393 if (await_preamble != NULL) { |
8356 // Prepend the preamble to the condition. | 8394 // Prepend the preamble to the condition. |
8357 LetNode* await_cond = new(Z) LetNode(expr_pos); | 8395 LetNode* await_cond = new(Z) LetNode(expr_pos); |
8358 await_cond->AddNode(await_preamble); | 8396 await_cond->AddNode(await_preamble); |
8359 await_cond->AddNode(cond_expr); | 8397 await_cond->AddNode(cond_expr); |
8360 cond_expr = await_cond; | 8398 cond_expr = await_cond; |
8361 } | 8399 } |
8362 ExpectToken(Token::kRPAREN); | 8400 ExpectToken(Token::kRPAREN); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8443 } | 8481 } |
8444 | 8482 |
8445 | 8483 |
8446 // Build an AST node for static call to Dart function print(str). | 8484 // Build an AST node for static call to Dart function print(str). |
8447 // Used during debugging to insert print in generated dart code. | 8485 // Used during debugging to insert print in generated dart code. |
8448 AstNode* Parser::DartPrint(const char* str) { | 8486 AstNode* Parser::DartPrint(const char* str) { |
8449 const Library& lib = Library::Handle(Library::CoreLibrary()); | 8487 const Library& lib = Library::Handle(Library::CoreLibrary()); |
8450 const Function& print_fn = Function::ZoneHandle( | 8488 const Function& print_fn = Function::ZoneHandle( |
8451 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 8489 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
8452 ASSERT(!print_fn.IsNull()); | 8490 ASSERT(!print_fn.IsNull()); |
8453 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Token::kNoSourcePos); | 8491 ArgumentListNode* one_arg = |
| 8492 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
8454 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); | 8493 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); |
8455 one_arg->Add(new(Z) LiteralNode(Token::kNoSourcePos, msg)); | 8494 one_arg->Add(new(Z) LiteralNode(TokenDescriptor::kNoSource, msg)); |
8456 AstNode* print_call = | 8495 AstNode* print_call = |
8457 new(Z) StaticCallNode(Token::kNoSourcePos, print_fn, one_arg); | 8496 new(Z) StaticCallNode(TokenDescriptor::kNoSource, print_fn, one_arg); |
8458 return print_call; | 8497 return print_call; |
8459 } | 8498 } |
8460 | 8499 |
8461 | 8500 |
8462 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 8501 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
8463 TRACE_PARSER("ParseAwaitForStatement"); | 8502 TRACE_PARSER("ParseAwaitForStatement"); |
8464 ASSERT(IsAwaitKeyword()); | 8503 ASSERT(IsAwaitKeyword()); |
8465 const intptr_t await_for_pos = TokenPos(); | 8504 const TokenDescriptor await_for_pos = TokenPos(); |
8466 ConsumeToken(); // await. | 8505 ConsumeToken(); // await. |
8467 ASSERT(CurrentToken() == Token::kFOR); | 8506 ASSERT(CurrentToken() == Token::kFOR); |
8468 ConsumeToken(); // for. | 8507 ConsumeToken(); // for. |
8469 ExpectToken(Token::kLPAREN); | 8508 ExpectToken(Token::kLPAREN); |
8470 | 8509 |
8471 if (!innermost_function().IsAsyncFunction() && | 8510 if (!innermost_function().IsAsyncFunction() && |
8472 !innermost_function().IsAsyncClosure() && | 8511 !innermost_function().IsAsyncClosure() && |
8473 !innermost_function().IsAsyncGenerator() && | 8512 !innermost_function().IsAsyncGenerator() && |
8474 !innermost_function().IsAsyncGenClosure()) { | 8513 !innermost_function().IsAsyncGenClosure()) { |
8475 ReportError(await_for_pos, | 8514 ReportError(await_for_pos, |
8476 "await for loop is only allowed in an asynchronous function"); | 8515 "await for loop is only allowed in an asynchronous function"); |
8477 } | 8516 } |
8478 | 8517 |
8479 // Parse loop variable. | 8518 // Parse loop variable. |
8480 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8519 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
8481 if (CurrentToken() == Token::kCONST) { | 8520 if (CurrentToken() == Token::kCONST) { |
8482 ReportError("Loop variable cannot be 'const'"); | 8521 ReportError("Loop variable cannot be 'const'"); |
8483 } | 8522 } |
8484 bool new_loop_var = false; | 8523 bool new_loop_var = false; |
8485 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8524 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
8486 if (LookaheadToken(1) != Token::kIN) { | 8525 if (LookaheadToken(1) != Token::kIN) { |
8487 // Declaration of a new loop variable. | 8526 // Declaration of a new loop variable. |
8488 // Delay creation of the local variable until we know its actual | 8527 // Delay creation of the local variable until we know its actual |
8489 // position, which is inside the loop body. | 8528 // position, which is inside the loop body. |
8490 new_loop_var = true; | 8529 new_loop_var = true; |
8491 loop_var_type = ParseConstFinalVarOrType( | 8530 loop_var_type = ParseConstFinalVarOrType( |
8492 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8531 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
8493 ClassFinalizer::kIgnore); | 8532 ClassFinalizer::kIgnore); |
8494 } | 8533 } |
8495 intptr_t loop_var_pos = TokenPos(); | 8534 TokenDescriptor loop_var_pos = TokenPos(); |
8496 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 8535 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
8497 | 8536 |
8498 // Parse stream expression. | 8537 // Parse stream expression. |
8499 ExpectToken(Token::kIN); | 8538 ExpectToken(Token::kIN); |
8500 const intptr_t stream_expr_pos = TokenPos(); | 8539 const TokenDescriptor stream_expr_pos = TokenPos(); |
8501 AstNode* stream_expr = | 8540 AstNode* stream_expr = |
8502 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8541 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8503 ExpectToken(Token::kRPAREN); | 8542 ExpectToken(Token::kRPAREN); |
8504 | 8543 |
8505 // Open a block for the iterator variable and the try-finally | 8544 // Open a block for the iterator variable and the try-finally |
8506 // statement that contains the loop. | 8545 // statement that contains the loop. |
8507 OpenBlock(); | 8546 OpenBlock(); |
8508 const Block* loop_block = current_block_; | 8547 const Block* loop_block = current_block_; |
8509 | 8548 |
8510 // Build creation of implicit StreamIterator. | 8549 // Build creation of implicit StreamIterator. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8587 | 8626 |
8588 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8627 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
8589 // here, but that does not work well because we have to insert an implicit | 8628 // here, but that does not work well because we have to insert an implicit |
8590 // variable assignment and potentially a variable declaration in the | 8629 // variable assignment and potentially a variable declaration in the |
8591 // loop body. | 8630 // loop body. |
8592 OpenLoopBlock(); | 8631 OpenLoopBlock(); |
8593 | 8632 |
8594 SourceLabel* label = | 8633 SourceLabel* label = |
8595 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); | 8634 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); |
8596 current_block_->scope->AddLabel(label); | 8635 current_block_->scope->AddLabel(label); |
8597 const intptr_t loop_var_assignment_pos = TokenPos(); | 8636 const TokenDescriptor loop_var_assignment_pos = TokenPos(); |
8598 | 8637 |
8599 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8638 AstNode* iterator_current = new(Z) InstanceGetterNode( |
8600 loop_var_assignment_pos, | 8639 loop_var_assignment_pos, |
8601 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8640 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
8602 Symbols::Current()); | 8641 Symbols::Current()); |
8603 | 8642 |
8604 // Generate assignment of next iterator value to loop variable. | 8643 // Generate assignment of next iterator value to loop variable. |
8605 AstNode* loop_var_assignment = NULL; | 8644 AstNode* loop_var_assignment = NULL; |
8606 if (new_loop_var) { | 8645 if (new_loop_var) { |
8607 // The for loop variable is new for each iteration. | 8646 // The for loop variable is new for each iteration. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8652 current_block_->statements->Add(while_node); | 8691 current_block_->statements->Add(while_node); |
8653 SequenceNode* try_block = CloseBlock(); | 8692 SequenceNode* try_block = CloseBlock(); |
8654 | 8693 |
8655 // Create an empty "catch all" block that rethrows the current | 8694 // Create an empty "catch all" block that rethrows the current |
8656 // exception and stacktrace. | 8695 // exception and stacktrace. |
8657 try_stack_->enter_catch(); | 8696 try_stack_->enter_catch(); |
8658 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); | 8697 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); |
8659 | 8698 |
8660 if (outer_saved_try_ctx != NULL) { | 8699 if (outer_saved_try_ctx != NULL) { |
8661 catch_block->Add(new (Z) StoreLocalNode( | 8700 catch_block->Add(new (Z) StoreLocalNode( |
8662 Token::kNoSourcePos, | 8701 TokenDescriptor::kNoSource, |
8663 outer_saved_try_ctx, | 8702 outer_saved_try_ctx, |
8664 new (Z) LoadLocalNode(Token::kNoSourcePos, | 8703 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
8665 outer_async_saved_try_ctx))); | 8704 outer_async_saved_try_ctx))); |
8666 } | 8705 } |
8667 | 8706 |
8668 // We don't need to copy the current exception and stack trace variables | 8707 // We don't need to copy the current exception and stack trace variables |
8669 // into :saved_exception_var and :saved_stack_trace_var here because there | 8708 // into :saved_exception_var and :saved_stack_trace_var here because there |
8670 // is no code in the catch clause that could suspend the function. | 8709 // is no code in the catch clause that could suspend the function. |
8671 | 8710 |
8672 // Rethrow the exception. | 8711 // Rethrow the exception. |
8673 catch_block->Add(new(Z) ThrowNode( | 8712 catch_block->Add(new(Z) ThrowNode( |
8674 await_for_pos, | 8713 await_for_pos, |
(...skipping 11 matching lines...) Expand all Loading... |
8686 | 8725 |
8687 // Inline the finally block to the exit points in the try block. | 8726 // Inline the finally block to the exit points in the try block. |
8688 intptr_t node_index = 0; | 8727 intptr_t node_index = 0; |
8689 SequenceNode* finally_clause = NULL; | 8728 SequenceNode* finally_clause = NULL; |
8690 if (try_stack_ != NULL) { | 8729 if (try_stack_ != NULL) { |
8691 try_stack_->enter_finally(); | 8730 try_stack_->enter_finally(); |
8692 } | 8731 } |
8693 do { | 8732 do { |
8694 OpenBlock(); | 8733 OpenBlock(); |
8695 ArgumentListNode* no_args = | 8734 ArgumentListNode* no_args = |
8696 new(Z) ArgumentListNode(Token::kNoSourcePos); | 8735 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
8697 current_block_->statements->Add( | 8736 current_block_->statements->Add( |
8698 new(Z) InstanceCallNode(Token::kNoSourcePos, | 8737 new(Z) InstanceCallNode(TokenDescriptor::kNoSource, |
8699 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_var), | 8738 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, iterator_var), |
8700 Symbols::Cancel(), | 8739 Symbols::Cancel(), |
8701 no_args)); | 8740 no_args)); |
8702 finally_clause = CloseBlock(); | 8741 finally_clause = CloseBlock(); |
8703 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 8742 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
8704 if (node_to_inline != NULL) { | 8743 if (node_to_inline != NULL) { |
8705 InlinedFinallyNode* node = | 8744 InlinedFinallyNode* node = |
8706 new(Z) InlinedFinallyNode(Token::kNoSourcePos, | 8745 new(Z) InlinedFinallyNode(TokenDescriptor::kNoSource, |
8707 finally_clause, | 8746 finally_clause, |
8708 context_var, | 8747 context_var, |
8709 outer_try_index); | 8748 outer_try_index); |
8710 finally_clause = NULL; | 8749 finally_clause = NULL; |
8711 AddFinallyClauseToNode(true, node_to_inline, node); | 8750 AddFinallyClauseToNode(true, node_to_inline, node); |
8712 node_index++; | 8751 node_index++; |
8713 } | 8752 } |
8714 } while (finally_clause == NULL); | 8753 } while (finally_clause == NULL); |
8715 | 8754 |
8716 if (try_stack_ != NULL) { | 8755 if (try_stack_ != NULL) { |
(...skipping 27 matching lines...) Expand all Loading... |
8744 try_index, | 8783 try_index, |
8745 finally_clause); | 8784 finally_clause); |
8746 | 8785 |
8747 ASSERT(current_block_ == loop_block); | 8786 ASSERT(current_block_ == loop_block); |
8748 loop_block->statements->Add(try_catch_node); | 8787 loop_block->statements->Add(try_catch_node); |
8749 | 8788 |
8750 return CloseBlock(); // Implicit block around while loop. | 8789 return CloseBlock(); // Implicit block around while loop. |
8751 } | 8790 } |
8752 | 8791 |
8753 | 8792 |
8754 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 8793 AstNode* Parser::ParseForInStatement(TokenDescriptor forin_pos, |
8755 SourceLabel* label) { | 8794 SourceLabel* label) { |
8756 TRACE_PARSER("ParseForInStatement"); | 8795 TRACE_PARSER("ParseForInStatement"); |
8757 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8796 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
8758 if (CurrentToken() == Token::kCONST) { | 8797 if (CurrentToken() == Token::kCONST) { |
8759 ReportError("Loop variable cannot be 'const'"); | 8798 ReportError("Loop variable cannot be 'const'"); |
8760 } | 8799 } |
8761 const String* loop_var_name = NULL; | 8800 const String* loop_var_name = NULL; |
8762 intptr_t loop_var_pos = Token::kNoSourcePos; | 8801 TokenDescriptor loop_var_pos = TokenDescriptor::kNoSource; |
8763 bool new_loop_var = false; | 8802 bool new_loop_var = false; |
8764 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8803 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
8765 if (LookaheadToken(1) == Token::kIN) { | 8804 if (LookaheadToken(1) == Token::kIN) { |
8766 loop_var_pos = TokenPos(); | 8805 loop_var_pos = TokenPos(); |
8767 loop_var_name = ExpectIdentifier("variable name expected"); | 8806 loop_var_name = ExpectIdentifier("variable name expected"); |
8768 } else { | 8807 } else { |
8769 // The case without a type is handled above, so require a type here. | 8808 // The case without a type is handled above, so require a type here. |
8770 // Delay creation of the local variable until we know its actual | 8809 // Delay creation of the local variable until we know its actual |
8771 // position, which is inside the loop body. | 8810 // position, which is inside the loop body. |
8772 new_loop_var = true; | 8811 new_loop_var = true; |
8773 loop_var_type = ParseConstFinalVarOrType( | 8812 loop_var_type = ParseConstFinalVarOrType( |
8774 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8813 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
8775 ClassFinalizer::kIgnore); | 8814 ClassFinalizer::kIgnore); |
8776 loop_var_name = ExpectIdentifier("variable name expected"); | 8815 loop_var_name = ExpectIdentifier("variable name expected"); |
8777 } | 8816 } |
8778 ExpectToken(Token::kIN); | 8817 ExpectToken(Token::kIN); |
8779 const intptr_t collection_pos = TokenPos(); | 8818 const TokenDescriptor collection_pos = TokenPos(); |
8780 AstNode* collection_expr = | 8819 AstNode* collection_expr = |
8781 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8820 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8782 ExpectToken(Token::kRPAREN); | 8821 ExpectToken(Token::kRPAREN); |
8783 | 8822 |
8784 OpenBlock(); // Implicit block around while loop. | 8823 OpenBlock(); // Implicit block around while loop. |
8785 | 8824 |
8786 // Generate implicit iterator variable and add to scope. | 8825 // Generate implicit iterator variable and add to scope. |
8787 // We could set the type of the implicit iterator variable to Iterator<T> | 8826 // We could set the type of the implicit iterator variable to Iterator<T> |
8788 // where T is the type of the for loop variable. However, the type error | 8827 // where T is the type of the for loop variable. However, the type error |
8789 // would refer to the compiler generated iterator and could confuse the user. | 8828 // would refer to the compiler generated iterator and could confuse the user. |
(...skipping 18 matching lines...) Expand all Loading... |
8808 new(Z) LoadLocalNode(collection_pos, iterator_var), | 8847 new(Z) LoadLocalNode(collection_pos, iterator_var), |
8809 Symbols::MoveNext(), | 8848 Symbols::MoveNext(), |
8810 no_args); | 8849 no_args); |
8811 | 8850 |
8812 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8851 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
8813 // here, but that does not work well because we have to insert an implicit | 8852 // here, but that does not work well because we have to insert an implicit |
8814 // variable assignment and potentially a variable declaration in the | 8853 // variable assignment and potentially a variable declaration in the |
8815 // loop body. | 8854 // loop body. |
8816 OpenLoopBlock(); | 8855 OpenLoopBlock(); |
8817 current_block_->scope->AddLabel(label); | 8856 current_block_->scope->AddLabel(label); |
8818 const intptr_t loop_var_assignment_pos = TokenPos(); | 8857 const TokenDescriptor loop_var_assignment_pos = TokenPos(); |
8819 | 8858 |
8820 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8859 AstNode* iterator_current = new(Z) InstanceGetterNode( |
8821 loop_var_assignment_pos, | 8860 loop_var_assignment_pos, |
8822 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8861 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
8823 Symbols::Current()); | 8862 Symbols::Current()); |
8824 | 8863 |
8825 // Generate assignment of next iterator value to loop variable. | 8864 // Generate assignment of next iterator value to loop variable. |
8826 AstNode* loop_var_assignment = NULL; | 8865 AstNode* loop_var_assignment = NULL; |
8827 if (new_loop_var) { | 8866 if (new_loop_var) { |
8828 // The for loop variable is new for each iteration. | 8867 // The for loop variable is new for each iteration. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8866 AstNode* while_statement = new(Z) WhileNode( | 8905 AstNode* while_statement = new(Z) WhileNode( |
8867 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 8906 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
8868 current_block_->statements->Add(while_statement); | 8907 current_block_->statements->Add(while_statement); |
8869 | 8908 |
8870 return CloseBlock(); // Implicit block around while loop. | 8909 return CloseBlock(); // Implicit block around while loop. |
8871 } | 8910 } |
8872 | 8911 |
8873 | 8912 |
8874 AstNode* Parser::ParseForStatement(String* label_name) { | 8913 AstNode* Parser::ParseForStatement(String* label_name) { |
8875 TRACE_PARSER("ParseForStatement"); | 8914 TRACE_PARSER("ParseForStatement"); |
8876 const intptr_t for_pos = TokenPos(); | 8915 const TokenDescriptor for_pos = TokenPos(); |
8877 ConsumeToken(); | 8916 ConsumeToken(); |
8878 ExpectToken(Token::kLPAREN); | 8917 ExpectToken(Token::kLPAREN); |
8879 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 8918 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
8880 if (IsForInStatement()) { | 8919 if (IsForInStatement()) { |
8881 return ParseForInStatement(for_pos, label); | 8920 return ParseForInStatement(for_pos, label); |
8882 } | 8921 } |
8883 // Open a block that contains the loop variable. Make it a loop block so | 8922 // Open a block that contains the loop variable. Make it a loop block so |
8884 // that we allocate a new context if the loop variable is captured. | 8923 // that we allocate a new context if the loop variable is captured. |
8885 OpenLoopBlock(); | 8924 OpenLoopBlock(); |
8886 AstNode* initializer = NULL; | 8925 AstNode* initializer = NULL; |
8887 const intptr_t init_pos = TokenPos(); | 8926 const TokenDescriptor init_pos = TokenPos(); |
8888 LocalScope* init_scope = current_block_->scope; | 8927 LocalScope* init_scope = current_block_->scope; |
8889 if (CurrentToken() != Token::kSEMICOLON) { | 8928 if (CurrentToken() != Token::kSEMICOLON) { |
8890 if (IsVariableDeclaration()) { | 8929 if (IsVariableDeclaration()) { |
8891 initializer = ParseVariableDeclarationList(); | 8930 initializer = ParseVariableDeclarationList(); |
8892 } else { | 8931 } else { |
8893 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8932 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8894 } | 8933 } |
8895 } | 8934 } |
8896 ExpectSemicolon(); | 8935 ExpectSemicolon(); |
8897 AstNode* condition = NULL; | 8936 AstNode* condition = NULL; |
8898 SequenceNode* condition_preamble = NULL; | 8937 SequenceNode* condition_preamble = NULL; |
8899 if (CurrentToken() != Token::kSEMICOLON) { | 8938 if (CurrentToken() != Token::kSEMICOLON) { |
8900 condition = ParseAwaitableExpr( | 8939 condition = ParseAwaitableExpr( |
8901 kAllowConst, kConsumeCascades, &condition_preamble); | 8940 kAllowConst, kConsumeCascades, &condition_preamble); |
8902 } | 8941 } |
8903 ExpectSemicolon(); | 8942 ExpectSemicolon(); |
8904 AstNode* increment = NULL; | 8943 AstNode* increment = NULL; |
8905 const intptr_t incr_pos = TokenPos(); | 8944 const TokenDescriptor incr_pos = TokenPos(); |
8906 if (CurrentToken() != Token::kRPAREN) { | 8945 if (CurrentToken() != Token::kRPAREN) { |
8907 increment = ParseAwaitableExprList(); | 8946 increment = ParseAwaitableExprList(); |
8908 } | 8947 } |
8909 ExpectToken(Token::kRPAREN); | 8948 ExpectToken(Token::kRPAREN); |
8910 const bool parsing_loop_body = true; | 8949 const bool parsing_loop_body = true; |
8911 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 8950 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
8912 | 8951 |
8913 // Check whether any of the variables in the initializer part of | 8952 // Check whether any of the variables in the initializer part of |
8914 // the for statement are captured by a closure. If so, we insert a | 8953 // the for statement are captured by a closure. If so, we insert a |
8915 // node that creates a new Context for the loop variable before | 8954 // node that creates a new Context for the loop variable before |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8948 const Function& func = Function::ZoneHandle(Z, | 8987 const Function& func = Function::ZoneHandle(Z, |
8949 Resolver::ResolveStatic(cls, | 8988 Resolver::ResolveStatic(cls, |
8950 func_name, | 8989 func_name, |
8951 arguments->length(), | 8990 arguments->length(), |
8952 arguments->names())); | 8991 arguments->names())); |
8953 ASSERT(!func.IsNull()); | 8992 ASSERT(!func.IsNull()); |
8954 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); | 8993 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); |
8955 } | 8994 } |
8956 | 8995 |
8957 | 8996 |
8958 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 8997 AstNode* Parser::MakeAssertCall(TokenDescriptor begin, TokenDescriptor end) { |
8959 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); | 8998 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); |
8960 arguments->Add(new(Z) LiteralNode(begin, | 8999 arguments->Add(new(Z) LiteralNode(begin, |
8961 Integer::ZoneHandle(Z, Integer::New(begin)))); | 9000 Integer::ZoneHandle(Z, Integer::New(begin.value())))); |
8962 arguments->Add(new(Z) LiteralNode(end, | 9001 arguments->Add(new(Z) LiteralNode(end, |
8963 Integer::ZoneHandle(Z, Integer::New(end)))); | 9002 Integer::ZoneHandle(Z, Integer::New(end.value())))); |
8964 return MakeStaticCall(Symbols::AssertionError(), | 9003 return MakeStaticCall(Symbols::AssertionError(), |
8965 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 9004 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
8966 arguments); | 9005 arguments); |
8967 } | 9006 } |
8968 | 9007 |
8969 | 9008 |
8970 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 9009 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
8971 if (condition->IsClosureNode() || | 9010 if (condition->IsClosureNode() || |
8972 (condition->IsStoreLocalNode() && | 9011 (condition->IsStoreLocalNode() && |
8973 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 9012 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
8974 // Function literal in assert implies a call. | 9013 // Function literal in assert implies a call. |
8975 const intptr_t pos = condition->token_pos(); | 9014 const TokenDescriptor pos = condition->token_pos(); |
8976 condition = BuildClosureCall(pos, | 9015 condition = BuildClosureCall(pos, |
8977 condition, | 9016 condition, |
8978 new(Z) ArgumentListNode(pos)); | 9017 new(Z) ArgumentListNode(pos)); |
8979 } else if (condition->IsConditionalExprNode()) { | 9018 } else if (condition->IsConditionalExprNode()) { |
8980 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 9019 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
8981 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 9020 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
8982 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 9021 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
8983 } | 9022 } |
8984 return condition; | 9023 return condition; |
8985 } | 9024 } |
8986 | 9025 |
8987 | 9026 |
8988 AstNode* Parser::ParseAssertStatement() { | 9027 AstNode* Parser::ParseAssertStatement() { |
8989 TRACE_PARSER("ParseAssertStatement"); | 9028 TRACE_PARSER("ParseAssertStatement"); |
8990 ConsumeToken(); // Consume assert keyword. | 9029 ConsumeToken(); // Consume assert keyword. |
8991 ExpectToken(Token::kLPAREN); | 9030 ExpectToken(Token::kLPAREN); |
8992 const intptr_t condition_pos = TokenPos(); | 9031 const TokenDescriptor condition_pos = TokenPos(); |
8993 if (!I->flags().asserts()) { | 9032 if (!I->flags().asserts()) { |
8994 SkipExpr(); | 9033 SkipExpr(); |
8995 ExpectToken(Token::kRPAREN); | 9034 ExpectToken(Token::kRPAREN); |
8996 return NULL; | 9035 return NULL; |
8997 } | 9036 } |
8998 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9037 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8999 const intptr_t condition_end = TokenPos(); | 9038 const TokenDescriptor condition_end = TokenPos(); |
9000 ExpectToken(Token::kRPAREN); | 9039 ExpectToken(Token::kRPAREN); |
9001 condition = InsertClosureCallNodes(condition); | 9040 condition = InsertClosureCallNodes(condition); |
9002 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); | 9041 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); |
9003 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 9042 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
9004 return new(Z) IfNode( | 9043 return new(Z) IfNode( |
9005 condition_pos, | 9044 condition_pos, |
9006 condition, | 9045 condition, |
9007 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 9046 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
9008 NULL); | 9047 NULL); |
9009 } | 9048 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9053 ASSERT(innermost_function().IsAsyncClosure() || | 9092 ASSERT(innermost_function().IsAsyncClosure() || |
9054 innermost_function().IsAsyncFunction() || | 9093 innermost_function().IsAsyncFunction() || |
9055 innermost_function().IsSyncGenClosure() || | 9094 innermost_function().IsSyncGenClosure() || |
9056 innermost_function().IsSyncGenerator() || | 9095 innermost_function().IsSyncGenerator() || |
9057 innermost_function().IsAsyncGenClosure() || | 9096 innermost_function().IsAsyncGenClosure() || |
9058 innermost_function().IsAsyncGenerator()); | 9097 innermost_function().IsAsyncGenerator()); |
9059 | 9098 |
9060 ASSERT(saved_exception_var != NULL); | 9099 ASSERT(saved_exception_var != NULL); |
9061 ASSERT(exception_var != NULL); | 9100 ASSERT(exception_var != NULL); |
9062 statements->Add(new(Z) StoreLocalNode( | 9101 statements->Add(new(Z) StoreLocalNode( |
9063 Token::kNoSourcePos, | 9102 TokenDescriptor::kNoSource, |
9064 saved_exception_var, | 9103 saved_exception_var, |
9065 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 9104 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_var))); |
9066 | 9105 |
9067 ASSERT(saved_stack_trace_var != NULL); | 9106 ASSERT(saved_stack_trace_var != NULL); |
9068 ASSERT(stack_trace_var != NULL); | 9107 ASSERT(stack_trace_var != NULL); |
9069 statements->Add(new(Z) StoreLocalNode( | 9108 statements->Add(new(Z) StoreLocalNode( |
9070 Token::kNoSourcePos, | 9109 TokenDescriptor::kNoSource, |
9071 saved_stack_trace_var, | 9110 saved_stack_trace_var, |
9072 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 9111 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, stack_trace_var))); |
9073 } | 9112 } |
9074 | 9113 |
9075 | 9114 |
9076 SequenceNode* Parser::EnsureFinallyClause( | 9115 SequenceNode* Parser::EnsureFinallyClause( |
9077 bool parse, | 9116 bool parse, |
9078 bool is_async, | 9117 bool is_async, |
9079 LocalVariable* exception_var, | 9118 LocalVariable* exception_var, |
9080 LocalVariable* stack_trace_var, | 9119 LocalVariable* stack_trace_var, |
9081 LocalVariable* rethrow_exception_var, | 9120 LocalVariable* rethrow_exception_var, |
9082 LocalVariable* rethrow_stack_trace_var) { | 9121 LocalVariable* rethrow_stack_trace_var) { |
(...skipping 14 matching lines...) Expand all Loading... |
9097 if (try_stack_ != NULL) { | 9136 if (try_stack_ != NULL) { |
9098 LocalScope* scope = try_stack_->try_block()->scope; | 9137 LocalScope* scope = try_stack_->try_block()->scope; |
9099 if (scope->function_level() == current_block_->scope->function_level()) { | 9138 if (scope->function_level() == current_block_->scope->function_level()) { |
9100 LocalVariable* saved_try_ctx = | 9139 LocalVariable* saved_try_ctx = |
9101 LookupSavedTryContextVar(scope->parent()); | 9140 LookupSavedTryContextVar(scope->parent()); |
9102 LocalVariable* async_saved_try_ctx = | 9141 LocalVariable* async_saved_try_ctx = |
9103 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9142 LookupAsyncSavedTryContextVar(async_temp_scope_, |
9104 try_stack_->try_index()); | 9143 try_stack_->try_index()); |
9105 current_block_->statements->Add( | 9144 current_block_->statements->Add( |
9106 new (Z) StoreLocalNode( | 9145 new (Z) StoreLocalNode( |
9107 Token::kNoSourcePos, | 9146 TokenDescriptor::kNoSource, |
9108 saved_try_ctx, | 9147 saved_try_ctx, |
9109 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9148 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
9110 async_saved_try_ctx))); | 9149 async_saved_try_ctx))); |
9111 } | 9150 } |
9112 } | 9151 } |
9113 // We need to save the exception variables as in catch clauses, whether | 9152 // We need to save the exception variables as in catch clauses, whether |
9114 // there is an outer try or not. Note that this is only necessary if the | 9153 // there is an outer try or not. Note that this is only necessary if the |
9115 // finally clause contains an await or yield. | 9154 // finally clause contains an await or yield. |
9116 // TODO(hausner): Optimize. | 9155 // TODO(hausner): Optimize. |
9117 SaveExceptionAndStacktrace(current_block_->statements, | 9156 SaveExceptionAndStacktrace(current_block_->statements, |
9118 exception_var, | 9157 exception_var, |
9119 stack_trace_var, | 9158 stack_trace_var, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9183 return_node->AddInlinedFinallyNode(finally_clause); | 9222 return_node->AddInlinedFinallyNode(finally_clause); |
9184 return; | 9223 return; |
9185 } | 9224 } |
9186 JumpNode* jump_node = node->AsJumpNode(); | 9225 JumpNode* jump_node = node->AsJumpNode(); |
9187 ASSERT(jump_node != NULL); | 9226 ASSERT(jump_node != NULL); |
9188 jump_node->AddInlinedFinallyNode(finally_clause); | 9227 jump_node->AddInlinedFinallyNode(finally_clause); |
9189 } | 9228 } |
9190 | 9229 |
9191 | 9230 |
9192 SequenceNode* Parser::ParseCatchClauses( | 9231 SequenceNode* Parser::ParseCatchClauses( |
9193 intptr_t handler_pos, | 9232 TokenDescriptor handler_pos, |
9194 bool is_async, | 9233 bool is_async, |
9195 LocalVariable* exception_var, | 9234 LocalVariable* exception_var, |
9196 LocalVariable* stack_trace_var, | 9235 LocalVariable* stack_trace_var, |
9197 LocalVariable* rethrow_exception_var, | 9236 LocalVariable* rethrow_exception_var, |
9198 LocalVariable* rethrow_stack_trace_var, | 9237 LocalVariable* rethrow_stack_trace_var, |
9199 const GrowableObjectArray& handler_types, | 9238 const GrowableObjectArray& handler_types, |
9200 bool* needs_stack_trace) { | 9239 bool* needs_stack_trace) { |
9201 // All catch blocks are merged into an if-then-else sequence of the | 9240 // All catch blocks are merged into an if-then-else sequence of the |
9202 // different types specified using the 'is' operator. While parsing | 9241 // different types specified using the 'is' operator. While parsing |
9203 // record the type tests (either a ComparisonNode or else the LiteralNode | 9242 // record the type tests (either a ComparisonNode or else the LiteralNode |
9204 // true for a generic catch) and the catch bodies in a pair of parallel | 9243 // true for a generic catch) and the catch bodies in a pair of parallel |
9205 // lists. Afterward, construct the nested if-then-else. | 9244 // lists. Afterward, construct the nested if-then-else. |
9206 bool generic_catch_seen = false; | 9245 bool generic_catch_seen = false; |
9207 GrowableArray<AstNode*> type_tests; | 9246 GrowableArray<AstNode*> type_tests; |
9208 GrowableArray<SequenceNode*> catch_blocks; | 9247 GrowableArray<SequenceNode*> catch_blocks; |
9209 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { | 9248 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { |
9210 // Open a block that contains the if or an unconditional body. It's | 9249 // Open a block that contains the if or an unconditional body. It's |
9211 // closed in the loop that builds the if-then-else nest. | 9250 // closed in the loop that builds the if-then-else nest. |
9212 OpenBlock(); | 9251 OpenBlock(); |
9213 const intptr_t catch_pos = TokenPos(); | 9252 const TokenDescriptor catch_pos = TokenPos(); |
9214 CatchParamDesc exception_param; | 9253 CatchParamDesc exception_param; |
9215 CatchParamDesc stack_trace_param; | 9254 CatchParamDesc stack_trace_param; |
9216 if (IsSymbol(Symbols::On())) { | 9255 if (IsSymbol(Symbols::On())) { |
9217 ConsumeToken(); | 9256 ConsumeToken(); |
9218 exception_param.type = &AbstractType::ZoneHandle(Z, | 9257 exception_param.type = &AbstractType::ZoneHandle(Z, |
9219 ParseType(ClassFinalizer::kCanonicalize)); | 9258 ParseType(ClassFinalizer::kCanonicalize)); |
9220 } else { | 9259 } else { |
9221 exception_param.type = &Object::dynamic_type(); | 9260 exception_param.type = &Object::dynamic_type(); |
9222 } | 9261 } |
9223 if (CurrentToken() == Token::kCATCH) { | 9262 if (CurrentToken() == Token::kCATCH) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9370 if (try_block != NULL) { | 9409 if (try_block != NULL) { |
9371 LocalScope* scope = try_block->try_block()->scope; | 9410 LocalScope* scope = try_block->try_block()->scope; |
9372 if (scope->function_level() == current_block_->scope->function_level()) { | 9411 if (scope->function_level() == current_block_->scope->function_level()) { |
9373 LocalVariable* saved_try_ctx = | 9412 LocalVariable* saved_try_ctx = |
9374 LookupSavedTryContextVar(scope->parent()); | 9413 LookupSavedTryContextVar(scope->parent()); |
9375 LocalVariable* async_saved_try_ctx = | 9414 LocalVariable* async_saved_try_ctx = |
9376 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9415 LookupAsyncSavedTryContextVar(async_temp_scope_, |
9377 try_block->try_index()); | 9416 try_block->try_index()); |
9378 async_code->Add( | 9417 async_code->Add( |
9379 new (Z) StoreLocalNode( | 9418 new (Z) StoreLocalNode( |
9380 Token::kNoSourcePos, | 9419 TokenDescriptor::kNoSource, |
9381 saved_try_ctx, | 9420 saved_try_ctx, |
9382 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9421 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
9383 async_saved_try_ctx))); | 9422 async_saved_try_ctx))); |
9384 } | 9423 } |
9385 } | 9424 } |
9386 SaveExceptionAndStacktrace(async_code, | 9425 SaveExceptionAndStacktrace(async_code, |
9387 exception_var, | 9426 exception_var, |
9388 stack_trace_var, | 9427 stack_trace_var, |
9389 rethrow_exception_var, | 9428 rethrow_exception_var, |
9390 rethrow_stack_trace_var); | 9429 rethrow_stack_trace_var); |
9391 // The async_code node sequence contains code to restore the context (if | 9430 // The async_code node sequence contains code to restore the context (if |
9392 // an outer try block is present) and code to save the exception and | 9431 // an outer try block is present) and code to save the exception and |
9393 // stack trace variables. | 9432 // stack trace variables. |
9394 // This async code is inserted before the current node sequence containing | 9433 // This async code is inserted before the current node sequence containing |
9395 // the chain of if/then/else handling all catch clauses. | 9434 // the chain of if/then/else handling all catch clauses. |
9396 async_code->Add(current); | 9435 async_code->Add(current); |
9397 current = async_code; | 9436 current = async_code; |
9398 } | 9437 } |
9399 return current; | 9438 return current; |
9400 } | 9439 } |
9401 | 9440 |
9402 | 9441 |
9403 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 9442 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
9404 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, | 9443 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, |
9405 Symbols::NewFormatted("%s%d", | 9444 Symbols::NewFormatted("%s%d", |
9406 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 9445 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
9407 last_used_try_index_ - 1)); | 9446 last_used_try_index_ - 1)); |
9408 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 9447 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
9409 Token::kNoSourcePos, | 9448 TokenDescriptor::kNoSource, |
9410 async_saved_try_ctx_name, | 9449 async_saved_try_ctx_name, |
9411 Object::dynamic_type()); | 9450 Object::dynamic_type()); |
9412 ASSERT(async_temp_scope_ != NULL); | 9451 ASSERT(async_temp_scope_ != NULL); |
9413 async_temp_scope_->AddVariable(async_saved_try_ctx); | 9452 async_temp_scope_->AddVariable(async_saved_try_ctx); |
9414 ASSERT(saved_try_context != NULL); | 9453 ASSERT(saved_try_context != NULL); |
9415 current_block_->statements->Add(new(Z) StoreLocalNode( | 9454 current_block_->statements->Add(new(Z) StoreLocalNode( |
9416 Token::kNoSourcePos, | 9455 TokenDescriptor::kNoSource, |
9417 async_saved_try_ctx, | 9456 async_saved_try_ctx, |
9418 new(Z) LoadLocalNode(Token::kNoSourcePos, saved_try_context))); | 9457 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, saved_try_context))); |
9419 } | 9458 } |
9420 | 9459 |
9421 | 9460 |
9422 // We create three variables for exceptions: | 9461 // We create three variables for exceptions: |
9423 // ':saved_try_context_var' - Used to save the context before the start of | 9462 // ':saved_try_context_var' - Used to save the context before the start of |
9424 // the try block. The context register is | 9463 // the try block. The context register is |
9425 // restored from this variable before | 9464 // restored from this variable before |
9426 // processing the catch block handler. | 9465 // processing the catch block handler. |
9427 // ':exception_var' - Used to save the current exception object that was | 9466 // ':exception_var' - Used to save the current exception object that was |
9428 // thrown. | 9467 // thrown. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9487 Object::dynamic_type()); | 9526 Object::dynamic_type()); |
9488 try_scope->AddVariable(*saved_stack_trace_var); | 9527 try_scope->AddVariable(*saved_stack_trace_var); |
9489 } | 9528 } |
9490 } | 9529 } |
9491 } | 9530 } |
9492 | 9531 |
9493 | 9532 |
9494 AstNode* Parser::ParseTryStatement(String* label_name) { | 9533 AstNode* Parser::ParseTryStatement(String* label_name) { |
9495 TRACE_PARSER("ParseTryStatement"); | 9534 TRACE_PARSER("ParseTryStatement"); |
9496 | 9535 |
9497 const intptr_t try_pos = TokenPos(); | 9536 const TokenDescriptor try_pos = TokenPos(); |
9498 SourceLabel* try_label = NULL; | 9537 SourceLabel* try_label = NULL; |
9499 if (label_name != NULL) { | 9538 if (label_name != NULL) { |
9500 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 9539 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
9501 OpenBlock(); | 9540 OpenBlock(); |
9502 current_block_->scope->AddLabel(try_label); | 9541 current_block_->scope->AddLabel(try_label); |
9503 } | 9542 } |
9504 | 9543 |
9505 const bool is_async = innermost_function().IsAsyncClosure() || | 9544 const bool is_async = innermost_function().IsAsyncClosure() || |
9506 innermost_function().IsAsyncFunction() || | 9545 innermost_function().IsAsyncFunction() || |
9507 innermost_function().IsSyncGenClosure() || | 9546 innermost_function().IsSyncGenClosure() || |
(...skipping 28 matching lines...) Expand all Loading... |
9536 ExpectToken(Token::kRBRACE); | 9575 ExpectToken(Token::kRBRACE); |
9537 SequenceNode* try_block = CloseBlock(); | 9576 SequenceNode* try_block = CloseBlock(); |
9538 | 9577 |
9539 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && | 9578 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && |
9540 (CurrentToken() != Token::kFINALLY)) { | 9579 (CurrentToken() != Token::kFINALLY)) { |
9541 ReportError("catch or finally clause expected"); | 9580 ReportError("catch or finally clause expected"); |
9542 } | 9581 } |
9543 | 9582 |
9544 // Now parse the 'catch' blocks if any. | 9583 // Now parse the 'catch' blocks if any. |
9545 try_stack_->enter_catch(); | 9584 try_stack_->enter_catch(); |
9546 const intptr_t handler_pos = TokenPos(); | 9585 const TokenDescriptor handler_pos = TokenPos(); |
9547 const GrowableObjectArray& handler_types = | 9586 const GrowableObjectArray& handler_types = |
9548 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 9587 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
9549 bool needs_stack_trace = false; | 9588 bool needs_stack_trace = false; |
9550 SequenceNode* catch_handler_list = | 9589 SequenceNode* catch_handler_list = |
9551 ParseCatchClauses(handler_pos, | 9590 ParseCatchClauses(handler_pos, |
9552 is_async, | 9591 is_async, |
9553 exception_var, | 9592 exception_var, |
9554 stack_trace_var, | 9593 stack_trace_var, |
9555 is_async ? saved_exception_var : exception_var, | 9594 is_async ? saved_exception_var : exception_var, |
9556 is_async ? saved_stack_trace_var : stack_trace_var, | 9595 is_async ? saved_stack_trace_var : stack_trace_var, |
(...skipping 10 matching lines...) Expand all Loading... |
9567 // A finally clause is required in async code to restore the saved try context | 9606 // A finally clause is required in async code to restore the saved try context |
9568 // of an existing outer try. Generate a finally clause to this purpose if it | 9607 // of an existing outer try. Generate a finally clause to this purpose if it |
9569 // is not declared. | 9608 // is not declared. |
9570 SequenceNode* finally_clause = NULL; | 9609 SequenceNode* finally_clause = NULL; |
9571 SequenceNode* rethrow_clause = NULL; | 9610 SequenceNode* rethrow_clause = NULL; |
9572 const bool parse = CurrentToken() == Token::kFINALLY; | 9611 const bool parse = CurrentToken() == Token::kFINALLY; |
9573 if (parse || (is_async && (try_stack_ != NULL))) { | 9612 if (parse || (is_async && (try_stack_ != NULL))) { |
9574 if (parse) { | 9613 if (parse) { |
9575 ConsumeToken(); // Consume the 'finally'. | 9614 ConsumeToken(); // Consume the 'finally'. |
9576 } | 9615 } |
9577 const intptr_t finally_pos = TokenPos(); | 9616 const TokenDescriptor finally_pos = TokenPos(); |
9578 // Add the finally block to the exit points recorded so far. | 9617 // Add the finally block to the exit points recorded so far. |
9579 intptr_t node_index = 0; | 9618 intptr_t node_index = 0; |
9580 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 9619 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
9581 while (node_to_inline != NULL) { | 9620 while (node_to_inline != NULL) { |
9582 finally_clause = EnsureFinallyClause( | 9621 finally_clause = EnsureFinallyClause( |
9583 parse, | 9622 parse, |
9584 is_async, | 9623 is_async, |
9585 exception_var, | 9624 exception_var, |
9586 stack_trace_var, | 9625 stack_trace_var, |
9587 is_async ? saved_exception_var : exception_var, | 9626 is_async ? saved_exception_var : exception_var, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9647 } | 9686 } |
9648 | 9687 |
9649 return try_catch_node; | 9688 return try_catch_node; |
9650 } | 9689 } |
9651 | 9690 |
9652 | 9691 |
9653 AstNode* Parser::ParseJump(String* label_name) { | 9692 AstNode* Parser::ParseJump(String* label_name) { |
9654 TRACE_PARSER("ParseJump"); | 9693 TRACE_PARSER("ParseJump"); |
9655 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 9694 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
9656 Token::Kind jump_kind = CurrentToken(); | 9695 Token::Kind jump_kind = CurrentToken(); |
9657 const intptr_t jump_pos = TokenPos(); | 9696 const TokenDescriptor jump_pos = TokenPos(); |
9658 SourceLabel* target = NULL; | 9697 SourceLabel* target = NULL; |
9659 ConsumeToken(); | 9698 ConsumeToken(); |
9660 if (IsIdentifier()) { | 9699 if (IsIdentifier()) { |
9661 // Explicit label after break/continue. | 9700 // Explicit label after break/continue. |
9662 const String& target_name = *CurrentLiteral(); | 9701 const String& target_name = *CurrentLiteral(); |
9663 ConsumeToken(); | 9702 ConsumeToken(); |
9664 // Handle pathological cases first. | 9703 // Handle pathological cases first. |
9665 if (label_name != NULL && target_name.Equals(*label_name)) { | 9704 if (label_name != NULL && target_name.Equals(*label_name)) { |
9666 if (jump_kind == Token::kCONTINUE) { | 9705 if (jump_kind == Token::kCONTINUE) { |
9667 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", | 9706 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9712 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 9751 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
9713 ReportError(jump_pos, "'%s' target must be in same function context", | 9752 ReportError(jump_pos, "'%s' target must be in same function context", |
9714 Token::Str(jump_kind)); | 9753 Token::Str(jump_kind)); |
9715 } | 9754 } |
9716 return new(Z) JumpNode(jump_pos, jump_kind, target); | 9755 return new(Z) JumpNode(jump_pos, jump_kind, target); |
9717 } | 9756 } |
9718 | 9757 |
9719 | 9758 |
9720 AstNode* Parser::ParseYieldStatement() { | 9759 AstNode* Parser::ParseYieldStatement() { |
9721 bool is_yield_each = false; | 9760 bool is_yield_each = false; |
9722 const intptr_t yield_pos = TokenPos(); | 9761 const TokenDescriptor yield_pos = TokenPos(); |
9723 ConsumeToken(); // yield reserved word. | 9762 ConsumeToken(); // yield reserved word. |
9724 if (CurrentToken() == Token::kMUL) { | 9763 if (CurrentToken() == Token::kMUL) { |
9725 is_yield_each = true; | 9764 is_yield_each = true; |
9726 ConsumeToken(); | 9765 ConsumeToken(); |
9727 } | 9766 } |
9728 if (!innermost_function().IsGenerator() && | 9767 if (!innermost_function().IsGenerator() && |
9729 !innermost_function().IsGeneratorClosure()) { | 9768 !innermost_function().IsGeneratorClosure()) { |
9730 ReportError(yield_pos, | 9769 ReportError(yield_pos, |
9731 "yield%s statement only allowed in generator functions", | 9770 "yield%s statement only allowed in generator functions", |
9732 is_yield_each ? "*" : ""); | 9771 is_yield_each ? "*" : ""); |
9733 } | 9772 } |
9734 | 9773 |
9735 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9774 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9736 | 9775 |
9737 LetNode* yield = new(Z) LetNode(yield_pos); | 9776 LetNode* yield = new(Z) LetNode(yield_pos); |
9738 if (innermost_function().IsSyncGenerator() || | 9777 if (innermost_function().IsSyncGenerator() || |
9739 innermost_function().IsSyncGenClosure()) { | 9778 innermost_function().IsSyncGenClosure()) { |
9740 // Yield statement in sync* function. | 9779 // Yield statement in sync* function. |
9741 | 9780 |
9742 LocalVariable* iterator_param = | 9781 LocalVariable* iterator_param = |
9743 LookupLocalScope(Symbols::IteratorParameter()); | 9782 LookupLocalScope(Symbols::IteratorParameter()); |
9744 ASSERT(iterator_param != NULL); | 9783 ASSERT(iterator_param != NULL); |
9745 // Generate :iterator.current = expr; | 9784 // Generate :iterator.current = expr; |
9746 AstNode* iterator = | 9785 AstNode* iterator = |
9747 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_param); | 9786 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, iterator_param); |
9748 AstNode* store_current = | 9787 AstNode* store_current = |
9749 new(Z) InstanceSetterNode(Token::kNoSourcePos, | 9788 new(Z) InstanceSetterNode(TokenDescriptor::kNoSource, |
9750 iterator, | 9789 iterator, |
9751 String::ZoneHandle(Symbols::Current().raw()), | 9790 String::ZoneHandle(Symbols::Current().raw()), |
9752 expr); | 9791 expr); |
9753 yield->AddNode(store_current); | 9792 yield->AddNode(store_current); |
9754 if (is_yield_each) { | 9793 if (is_yield_each) { |
9755 // Generate :iterator.isYieldEach = true; | 9794 // Generate :iterator.isYieldEach = true; |
9756 AstNode* set_is_yield_each = | 9795 AstNode* set_is_yield_each = |
9757 new(Z) InstanceSetterNode(Token::kNoSourcePos, | 9796 new(Z) InstanceSetterNode(TokenDescriptor::kNoSource, |
9758 iterator, | 9797 iterator, |
9759 String::ZoneHandle(Symbols::IsYieldEach().raw()), | 9798 String::ZoneHandle(Symbols::IsYieldEach().raw()), |
9760 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9799 new(Z) LiteralNode(TokenPos(), Bool::True())); |
9761 yield->AddNode(set_is_yield_each); | 9800 yield->AddNode(set_is_yield_each); |
9762 } | 9801 } |
9763 AwaitMarkerNode* await_marker = | 9802 AwaitMarkerNode* await_marker = |
9764 new(Z) AwaitMarkerNode(async_temp_scope_, | 9803 new(Z) AwaitMarkerNode(async_temp_scope_, |
9765 current_block_->scope, | 9804 current_block_->scope, |
9766 Token::kNoSourcePos); | 9805 TokenDescriptor::kNoSource); |
9767 yield->AddNode(await_marker); | 9806 yield->AddNode(await_marker); |
9768 // Return true to indicate that a value has been generated. | 9807 // Return true to indicate that a value has been generated. |
9769 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, | 9808 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, |
9770 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9809 new(Z) LiteralNode(TokenPos(), Bool::True())); |
9771 return_true->set_return_type(ReturnNode::kContinuationTarget); | 9810 return_true->set_return_type(ReturnNode::kContinuationTarget); |
9772 yield->AddNode(return_true); | 9811 yield->AddNode(return_true); |
9773 | 9812 |
9774 // If this expression is part of a try block, also append the code for | 9813 // If this expression is part of a try block, also append the code for |
9775 // restoring the saved try context that lives on the stack and possibly the | 9814 // restoring the saved try context that lives on the stack and possibly the |
9776 // saved try context of the outer try block. | 9815 // saved try context of the outer try block. |
9777 LocalVariable* saved_try_ctx; | 9816 LocalVariable* saved_try_ctx; |
9778 LocalVariable* async_saved_try_ctx; | 9817 LocalVariable* async_saved_try_ctx; |
9779 LocalVariable* outer_saved_try_ctx; | 9818 LocalVariable* outer_saved_try_ctx; |
9780 LocalVariable* outer_async_saved_try_ctx; | 9819 LocalVariable* outer_async_saved_try_ctx; |
9781 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9820 CheckAsyncOpInTryBlock(&saved_try_ctx, |
9782 &async_saved_try_ctx, | 9821 &async_saved_try_ctx, |
9783 &outer_saved_try_ctx, | 9822 &outer_saved_try_ctx, |
9784 &outer_async_saved_try_ctx); | 9823 &outer_async_saved_try_ctx); |
9785 if (saved_try_ctx != NULL) { | 9824 if (saved_try_ctx != NULL) { |
9786 yield->AddNode(new (Z) StoreLocalNode( | 9825 yield->AddNode(new (Z) StoreLocalNode( |
9787 Token::kNoSourcePos, | 9826 TokenDescriptor::kNoSource, |
9788 saved_try_ctx, | 9827 saved_try_ctx, |
9789 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9828 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
9790 async_saved_try_ctx))); | 9829 async_saved_try_ctx))); |
9791 if (outer_saved_try_ctx != NULL) { | 9830 if (outer_saved_try_ctx != NULL) { |
9792 yield->AddNode(new (Z) StoreLocalNode( | 9831 yield->AddNode(new (Z) StoreLocalNode( |
9793 Token::kNoSourcePos, | 9832 TokenDescriptor::kNoSource, |
9794 outer_saved_try_ctx, | 9833 outer_saved_try_ctx, |
9795 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9834 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
9796 outer_async_saved_try_ctx))); | 9835 outer_async_saved_try_ctx))); |
9797 } | 9836 } |
9798 } else { | 9837 } else { |
9799 ASSERT(outer_saved_try_ctx == NULL); | 9838 ASSERT(outer_saved_try_ctx == NULL); |
9800 } | 9839 } |
9801 } else { | 9840 } else { |
9802 // yield statement in async* function. | 9841 // yield statement in async* function. |
9803 ASSERT(innermost_function().IsAsyncGenerator() || | 9842 ASSERT(innermost_function().IsAsyncGenerator() || |
9804 innermost_function().IsAsyncGenClosure()); | 9843 innermost_function().IsAsyncGenClosure()); |
9805 | 9844 |
9806 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); | 9845 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); |
9807 ASSERT(controller_var != NULL); | 9846 ASSERT(controller_var != NULL); |
9808 // :controller.add[Stream](expr); | 9847 // :controller.add[Stream](expr); |
9809 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); | 9848 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); |
9810 add_args->Add(expr); | 9849 add_args->Add(expr); |
9811 AstNode* add_call = | 9850 AstNode* add_call = |
9812 new(Z) InstanceCallNode(yield_pos, | 9851 new(Z) InstanceCallNode(yield_pos, |
9813 new(Z) LoadLocalNode(Token::kNoSourcePos, controller_var), | 9852 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, controller_var), |
9814 is_yield_each ? Symbols::AddStream() : Symbols::add(), | 9853 is_yield_each ? Symbols::AddStream() : Symbols::add(), |
9815 add_args); | 9854 add_args); |
9816 | 9855 |
9817 // if (:controller.add[Stream](expr)) { | 9856 // if (:controller.add[Stream](expr)) { |
9818 // return; | 9857 // return; |
9819 // } | 9858 // } |
9820 // await_marker; | 9859 // await_marker; |
9821 // continuation_return; | 9860 // continuation_return; |
9822 // restore saved_try_context | 9861 // restore saved_try_context |
9823 | 9862 |
9824 SequenceNode* true_branch = | 9863 SequenceNode* true_branch = |
9825 new(Z) SequenceNode(Token::kNoSourcePos, NULL); | 9864 new(Z) SequenceNode(TokenDescriptor::kNoSource, NULL); |
9826 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); | 9865 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); |
9827 true_branch->Add(return_from_generator); | 9866 true_branch->Add(return_from_generator); |
9828 AddNodeForFinallyInlining(return_from_generator); | 9867 AddNodeForFinallyInlining(return_from_generator); |
9829 AstNode* if_is_cancelled = | 9868 AstNode* if_is_cancelled = |
9830 new(Z) IfNode(Token::kNoSourcePos, add_call, true_branch, NULL); | 9869 new(Z) IfNode(TokenDescriptor::kNoSource, add_call, true_branch, NULL); |
9831 yield->AddNode(if_is_cancelled); | 9870 yield->AddNode(if_is_cancelled); |
9832 | 9871 |
9833 AwaitMarkerNode* await_marker = | 9872 AwaitMarkerNode* await_marker = |
9834 new(Z) AwaitMarkerNode(async_temp_scope_, | 9873 new(Z) AwaitMarkerNode(async_temp_scope_, |
9835 current_block_->scope, | 9874 current_block_->scope, |
9836 Token::kNoSourcePos); | 9875 TokenDescriptor::kNoSource); |
9837 yield->AddNode(await_marker); | 9876 yield->AddNode(await_marker); |
9838 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); | 9877 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); |
9839 continuation_return->set_return_type(ReturnNode::kContinuationTarget); | 9878 continuation_return->set_return_type(ReturnNode::kContinuationTarget); |
9840 yield->AddNode(continuation_return); | 9879 yield->AddNode(continuation_return); |
9841 | 9880 |
9842 // If this expression is part of a try block, also append the code for | 9881 // If this expression is part of a try block, also append the code for |
9843 // restoring the saved try context that lives on the stack and possibly the | 9882 // restoring the saved try context that lives on the stack and possibly the |
9844 // saved try context of the outer try block. | 9883 // saved try context of the outer try block. |
9845 LocalVariable* saved_try_ctx; | 9884 LocalVariable* saved_try_ctx; |
9846 LocalVariable* async_saved_try_ctx; | 9885 LocalVariable* async_saved_try_ctx; |
9847 LocalVariable* outer_saved_try_ctx; | 9886 LocalVariable* outer_saved_try_ctx; |
9848 LocalVariable* outer_async_saved_try_ctx; | 9887 LocalVariable* outer_async_saved_try_ctx; |
9849 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9888 CheckAsyncOpInTryBlock(&saved_try_ctx, |
9850 &async_saved_try_ctx, | 9889 &async_saved_try_ctx, |
9851 &outer_saved_try_ctx, | 9890 &outer_saved_try_ctx, |
9852 &outer_async_saved_try_ctx); | 9891 &outer_async_saved_try_ctx); |
9853 if (saved_try_ctx != NULL) { | 9892 if (saved_try_ctx != NULL) { |
9854 yield->AddNode(new (Z) StoreLocalNode( | 9893 yield->AddNode(new (Z) StoreLocalNode( |
9855 Token::kNoSourcePos, | 9894 TokenDescriptor::kNoSource, |
9856 saved_try_ctx, | 9895 saved_try_ctx, |
9857 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9896 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
9858 async_saved_try_ctx))); | 9897 async_saved_try_ctx))); |
9859 if (outer_saved_try_ctx != NULL) { | 9898 if (outer_saved_try_ctx != NULL) { |
9860 yield->AddNode(new (Z) StoreLocalNode( | 9899 yield->AddNode(new (Z) StoreLocalNode( |
9861 Token::kNoSourcePos, | 9900 TokenDescriptor::kNoSource, |
9862 outer_saved_try_ctx, | 9901 outer_saved_try_ctx, |
9863 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9902 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
9864 outer_async_saved_try_ctx))); | 9903 outer_async_saved_try_ctx))); |
9865 } | 9904 } |
9866 } else { | 9905 } else { |
9867 ASSERT(outer_saved_try_ctx == NULL); | 9906 ASSERT(outer_saved_try_ctx == NULL); |
9868 } | 9907 } |
9869 } | 9908 } |
9870 return yield; | 9909 return yield; |
9871 } | 9910 } |
9872 | 9911 |
9873 | 9912 |
9874 AstNode* Parser::ParseStatement() { | 9913 AstNode* Parser::ParseStatement() { |
9875 TRACE_PARSER("ParseStatement"); | 9914 TRACE_PARSER("ParseStatement"); |
9876 AstNode* statement = NULL; | 9915 AstNode* statement = NULL; |
9877 intptr_t label_pos = Token::kNoSourcePos; | 9916 TokenDescriptor label_pos = TokenDescriptor::kNoSource; |
9878 String* label_name = NULL; | 9917 String* label_name = NULL; |
9879 if (IsIdentifier()) { | 9918 if (IsIdentifier()) { |
9880 if (LookaheadToken(1) == Token::kCOLON) { | 9919 if (LookaheadToken(1) == Token::kCOLON) { |
9881 // Statement starts with a label. | 9920 // Statement starts with a label. |
9882 label_name = CurrentLiteral(); | 9921 label_name = CurrentLiteral(); |
9883 label_pos = TokenPos(); | 9922 label_pos = TokenPos(); |
9884 ASSERT(label_pos >= 0); | 9923 ASSERT(label_pos.IsReal()); |
9885 ConsumeToken(); // Consume identifier. | 9924 ConsumeToken(); // Consume identifier. |
9886 ConsumeToken(); // Consume colon. | 9925 ConsumeToken(); // Consume colon. |
9887 } | 9926 } |
9888 } | 9927 } |
9889 const intptr_t statement_pos = TokenPos(); | 9928 const TokenDescriptor statement_pos = TokenPos(); |
9890 const Token::Kind token = CurrentToken(); | 9929 const Token::Kind token = CurrentToken(); |
9891 | 9930 |
9892 if (token == Token::kWHILE) { | 9931 if (token == Token::kWHILE) { |
9893 statement = ParseWhileStatement(label_name); | 9932 statement = ParseWhileStatement(label_name); |
9894 } else if (token == Token::kFOR) { | 9933 } else if (token == Token::kFOR) { |
9895 statement = ParseForStatement(label_name); | 9934 statement = ParseForStatement(label_name); |
9896 } else if (IsAwaitKeyword() && (LookaheadToken(1) == Token::kFOR)) { | 9935 } else if (IsAwaitKeyword() && (LookaheadToken(1) == Token::kFOR)) { |
9897 statement = ParseAwaitForStatement(label_name); | 9936 statement = ParseAwaitForStatement(label_name); |
9898 } else if (token == Token::kDO) { | 9937 } else if (token == Token::kDO) { |
9899 statement = ParseDoWhileStatement(label_name); | 9938 statement = ParseDoWhileStatement(label_name); |
9900 } else if (token == Token::kSWITCH) { | 9939 } else if (token == Token::kSWITCH) { |
9901 statement = ParseSwitchStatement(label_name); | 9940 statement = ParseSwitchStatement(label_name); |
9902 } else if (token == Token::kTRY) { | 9941 } else if (token == Token::kTRY) { |
9903 statement = ParseTryStatement(label_name); | 9942 statement = ParseTryStatement(label_name); |
9904 } else if (token == Token::kRETURN) { | 9943 } else if (token == Token::kRETURN) { |
9905 const intptr_t return_pos = TokenPos(); | 9944 const TokenDescriptor return_pos = TokenPos(); |
9906 ConsumeToken(); | 9945 ConsumeToken(); |
9907 if (CurrentToken() != Token::kSEMICOLON) { | 9946 if (CurrentToken() != Token::kSEMICOLON) { |
9908 const intptr_t expr_pos = TokenPos(); | 9947 const TokenDescriptor expr_pos = TokenPos(); |
9909 if (current_function().IsGenerativeConstructor() && | 9948 if (current_function().IsGenerativeConstructor() && |
9910 (current_block_->scope->function_level() == 0)) { | 9949 (current_block_->scope->function_level() == 0)) { |
9911 ReportError(expr_pos, | 9950 ReportError(expr_pos, |
9912 "return of a value is not allowed in constructors"); | 9951 "return of a value is not allowed in constructors"); |
9913 } else if (current_function().IsGeneratorClosure() && | 9952 } else if (current_function().IsGeneratorClosure() && |
9914 (current_block_->scope->function_level() == 0)) { | 9953 (current_block_->scope->function_level() == 0)) { |
9915 ReportError(expr_pos, "generator functions may not return a value"); | 9954 ReportError(expr_pos, "generator functions may not return a value"); |
9916 } | 9955 } |
9917 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9956 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9918 statement = new(Z) ReturnNode(statement_pos, expr); | 9957 statement = new(Z) ReturnNode(statement_pos, expr); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10014 } | 10053 } |
10015 | 10054 |
10016 | 10055 |
10017 void Parser::ReportError(const Error& error) { | 10056 void Parser::ReportError(const Error& error) { |
10018 Report::LongJump(error); | 10057 Report::LongJump(error); |
10019 UNREACHABLE(); | 10058 UNREACHABLE(); |
10020 } | 10059 } |
10021 | 10060 |
10022 | 10061 |
10023 void Parser::ReportErrors(const Error& prev_error, | 10062 void Parser::ReportErrors(const Error& prev_error, |
10024 const Script& script, intptr_t token_pos, | 10063 const Script& script, TokenDescriptor token_pos, |
10025 const char* format, ...) { | 10064 const char* format, ...) { |
10026 va_list args; | 10065 va_list args; |
10027 va_start(args, format); | 10066 va_start(args, format); |
10028 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10067 Report::LongJumpV(prev_error, script, token_pos, format, args); |
10029 va_end(args); | 10068 va_end(args); |
10030 UNREACHABLE(); | 10069 UNREACHABLE(); |
10031 } | 10070 } |
10032 | 10071 |
10033 | 10072 |
10034 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const { | 10073 void Parser::ReportError(TokenDescriptor token_pos, |
| 10074 const char* format, ...) const { |
10035 va_list args; | 10075 va_list args; |
10036 va_start(args, format); | 10076 va_start(args, format); |
10037 Report::MessageV(Report::kError, | 10077 Report::MessageV(Report::kError, |
10038 script_, token_pos, Report::AtLocation, format, args); | 10078 script_, token_pos, Report::AtLocation, format, args); |
10039 va_end(args); | 10079 va_end(args); |
10040 UNREACHABLE(); | 10080 UNREACHABLE(); |
10041 } | 10081 } |
10042 | 10082 |
10043 | 10083 |
10044 void Parser::ReportErrorBefore(const char* format, ...) { | 10084 void Parser::ReportErrorBefore(const char* format, ...) { |
(...skipping 10 matching lines...) Expand all Loading... |
10055 void Parser::ReportError(const char* format, ...) const { | 10095 void Parser::ReportError(const char* format, ...) const { |
10056 va_list args; | 10096 va_list args; |
10057 va_start(args, format); | 10097 va_start(args, format); |
10058 Report::MessageV(Report::kError, | 10098 Report::MessageV(Report::kError, |
10059 script_, TokenPos(), Report::AtLocation, format, args); | 10099 script_, TokenPos(), Report::AtLocation, format, args); |
10060 va_end(args); | 10100 va_end(args); |
10061 UNREACHABLE(); | 10101 UNREACHABLE(); |
10062 } | 10102 } |
10063 | 10103 |
10064 | 10104 |
10065 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const { | 10105 void Parser::ReportWarning(TokenDescriptor token_pos, |
| 10106 const char* format, ...) const { |
10066 va_list args; | 10107 va_list args; |
10067 va_start(args, format); | 10108 va_start(args, format); |
10068 Report::MessageV(Report::kWarning, | 10109 Report::MessageV(Report::kWarning, |
10069 script_, token_pos, Report::AtLocation, format, args); | 10110 script_, token_pos, Report::AtLocation, format, args); |
10070 va_end(args); | 10111 va_end(args); |
10071 } | 10112 } |
10072 | 10113 |
10073 | 10114 |
10074 void Parser::ReportWarning(const char* format, ...) const { | 10115 void Parser::ReportWarning(const char* format, ...) const { |
10075 va_list args; | 10116 va_list args; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10155 } | 10196 } |
10156 | 10197 |
10157 | 10198 |
10158 static bool IsPrefixOperator(Token::Kind token) { | 10199 static bool IsPrefixOperator(Token::Kind token) { |
10159 return (token == Token::kSUB) || | 10200 return (token == Token::kSUB) || |
10160 (token == Token::kNOT) || | 10201 (token == Token::kNOT) || |
10161 (token == Token::kBIT_NOT); | 10202 (token == Token::kBIT_NOT); |
10162 } | 10203 } |
10163 | 10204 |
10164 | 10205 |
10165 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos, | 10206 SequenceNode* Parser::NodeAsSequenceNode(TokenDescriptor sequence_pos, |
10166 AstNode* node, | 10207 AstNode* node, |
10167 LocalScope* scope) { | 10208 LocalScope* scope) { |
10168 if ((node == NULL) || !node->IsSequenceNode()) { | 10209 if ((node == NULL) || !node->IsSequenceNode()) { |
10169 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); | 10210 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); |
10170 if (node != NULL) { | 10211 if (node != NULL) { |
10171 sequence->Add(node); | 10212 sequence->Add(node); |
10172 } | 10213 } |
10173 return sequence; | 10214 return sequence; |
10174 } | 10215 } |
10175 return node->AsSequenceNode(); | 10216 return node->AsSequenceNode(); |
10176 } | 10217 } |
10177 | 10218 |
10178 | 10219 |
10179 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10220 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
10180 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type, | 10221 AstNode* Parser::ThrowTypeError(TokenDescriptor type_pos, |
| 10222 const AbstractType& type, |
10181 LibraryPrefix* prefix) { | 10223 LibraryPrefix* prefix) { |
10182 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); | 10224 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); |
10183 | 10225 |
10184 String& method_name = String::Handle(Z); | 10226 String& method_name = String::Handle(Z); |
10185 if (prefix == NULL) { | 10227 if (prefix == NULL) { |
10186 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10228 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
10187 } else { | 10229 } else { |
10188 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); | 10230 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); |
10189 method_name = Library::PrivateCoreLibName( | 10231 method_name = Library::PrivateCoreLibName( |
10190 Symbols::ThrowNewIfNotLoaded()).raw(); | 10232 Symbols::ThrowNewIfNotLoaded()).raw(); |
10191 } | 10233 } |
10192 // Location argument. | 10234 // Location argument. |
10193 arguments->Add(new(Z) LiteralNode( | 10235 arguments->Add(new(Z) LiteralNode( |
10194 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos)))); | 10236 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos.value())))); |
10195 // Src value argument. | 10237 // Src value argument. |
10196 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); | 10238 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); |
10197 // Dst type name argument. | 10239 // Dst type name argument. |
10198 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); | 10240 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); |
10199 // Dst name argument. | 10241 // Dst name argument. |
10200 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); | 10242 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); |
10201 // Malformed type error or malbounded type error. | 10243 // Malformed type error or malbounded type error. |
10202 const Error& error = Error::Handle(Z, type.error()); | 10244 const Error& error = Error::Handle(Z, type.error()); |
10203 ASSERT(!error.IsNull()); | 10245 ASSERT(!error.IsNull()); |
10204 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, | 10246 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, |
10205 Symbols::New(error.ToErrorCString())))); | 10247 Symbols::New(error.ToErrorCString())))); |
10206 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); | 10248 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); |
10207 } | 10249 } |
10208 | 10250 |
10209 | 10251 |
10210 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10252 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
10211 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 10253 AstNode* Parser::ThrowNoSuchMethodError(TokenDescriptor call_pos, |
10212 const Class& cls, | 10254 const Class& cls, |
10213 const String& function_name, | 10255 const String& function_name, |
10214 ArgumentListNode* function_arguments, | 10256 ArgumentListNode* function_arguments, |
10215 InvocationMirror::Call im_call, | 10257 InvocationMirror::Call im_call, |
10216 InvocationMirror::Type im_type, | 10258 InvocationMirror::Type im_type, |
10217 const Function* func, | 10259 const Function* func, |
10218 const LibraryPrefix* prefix) { | 10260 const LibraryPrefix* prefix) { |
10219 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); | 10261 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); |
10220 | 10262 |
10221 String& method_name = String::Handle(Z); | 10263 String& method_name = String::Handle(Z); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10307 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10349 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
10308 AstNode* left_operand = ParseUnaryExpr(); | 10350 AstNode* left_operand = ParseUnaryExpr(); |
10309 if (left_operand->IsPrimaryNode() && | 10351 if (left_operand->IsPrimaryNode() && |
10310 (left_operand->AsPrimaryNode()->IsSuper())) { | 10352 (left_operand->AsPrimaryNode()->IsSuper())) { |
10311 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10353 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
10312 } | 10354 } |
10313 int current_preced = Token::Precedence(CurrentToken()); | 10355 int current_preced = Token::Precedence(CurrentToken()); |
10314 while (current_preced >= min_preced) { | 10356 while (current_preced >= min_preced) { |
10315 while (Token::Precedence(CurrentToken()) == current_preced) { | 10357 while (Token::Precedence(CurrentToken()) == current_preced) { |
10316 Token::Kind op_kind = CurrentToken(); | 10358 Token::Kind op_kind = CurrentToken(); |
10317 const intptr_t op_pos = TokenPos(); | 10359 const TokenDescriptor op_pos = TokenPos(); |
10318 ConsumeToken(); | 10360 ConsumeToken(); |
10319 AstNode* right_operand = NULL; | 10361 AstNode* right_operand = NULL; |
10320 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 10362 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
10321 right_operand = ParseBinaryExpr(current_preced + 1); | 10363 right_operand = ParseBinaryExpr(current_preced + 1); |
10322 } else { | 10364 } else { |
10323 // For 'is' and 'as' we expect the right operand to be a type. | 10365 // For 'is' and 'as' we expect the right operand to be a type. |
10324 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 10366 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
10325 ConsumeToken(); | 10367 ConsumeToken(); |
10326 op_kind = Token::kISNOT; | 10368 op_kind = Token::kISNOT; |
10327 } | 10369 } |
10328 const intptr_t type_pos = TokenPos(); | 10370 const TokenDescriptor type_pos = TokenPos(); |
10329 const AbstractType& type = AbstractType::ZoneHandle(Z, | 10371 const AbstractType& type = AbstractType::ZoneHandle(Z, |
10330 ParseType(ClassFinalizer::kCanonicalize)); | 10372 ParseType(ClassFinalizer::kCanonicalize)); |
10331 if (!type.IsInstantiated() && | 10373 if (!type.IsInstantiated() && |
10332 (current_block_->scope->function_level() > 0)) { | 10374 (current_block_->scope->function_level() > 0)) { |
10333 // Make sure that the instantiator is captured. | 10375 // Make sure that the instantiator is captured. |
10334 CaptureInstantiator(); | 10376 CaptureInstantiator(); |
10335 } | 10377 } |
10336 right_operand = new(Z) TypeNode(type_pos, type); | 10378 right_operand = new(Z) TypeNode(type_pos, type); |
10337 // In production mode, the type may be malformed. | 10379 // In production mode, the type may be malformed. |
10338 // In checked mode, the type may be malformed or malbounded. | 10380 // In checked mode, the type may be malformed or malbounded. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10396 return expressions; | 10438 return expressions; |
10397 } | 10439 } |
10398 | 10440 |
10399 | 10441 |
10400 void Parser::EnsureExpressionTemp() { | 10442 void Parser::EnsureExpressionTemp() { |
10401 // Temporary used later by the flow_graph_builder. | 10443 // Temporary used later by the flow_graph_builder. |
10402 parsed_function()->EnsureExpressionTemp(); | 10444 parsed_function()->EnsureExpressionTemp(); |
10403 } | 10445 } |
10404 | 10446 |
10405 | 10447 |
10406 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 10448 LocalVariable* Parser::CreateTempConstVariable(TokenDescriptor token_pos, |
10407 const char* s) { | 10449 const char* s) { |
10408 char name[64]; | 10450 char name[64]; |
10409 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); | 10451 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); |
10410 LocalVariable* temp = new(Z) LocalVariable( | 10452 LocalVariable* temp = new(Z) LocalVariable( |
10411 token_pos, | 10453 token_pos, |
10412 String::ZoneHandle(Z, Symbols::New(name)), | 10454 String::ZoneHandle(Z, Symbols::New(name)), |
10413 Object::dynamic_type()); | 10455 Object::dynamic_type()); |
10414 temp->set_is_final(); | 10456 temp->set_is_final(); |
10415 current_block_->scope->AddVariable(temp); | 10457 current_block_->scope->AddVariable(temp); |
10416 return temp; | 10458 return temp; |
10417 } | 10459 } |
10418 | 10460 |
10419 | 10461 |
10420 // TODO(srdjan): Implement other optimizations. | 10462 // TODO(srdjan): Implement other optimizations. |
10421 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 10463 AstNode* Parser::OptimizeBinaryOpNode(TokenDescriptor op_pos, |
10422 Token::Kind binary_op, | 10464 Token::Kind binary_op, |
10423 AstNode* lhs, | 10465 AstNode* lhs, |
10424 AstNode* rhs) { | 10466 AstNode* rhs) { |
10425 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 10467 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
10426 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 10468 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
10427 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 10469 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
10428 if (lhs_literal->literal().IsDouble() && | 10470 if (lhs_literal->literal().IsDouble() && |
10429 rhs_literal->literal().IsDouble()) { | 10471 rhs_literal->literal().IsDouble()) { |
10430 double left_double = Double::Cast(lhs_literal->literal()).value(); | 10472 double left_double = Double::Cast(lhs_literal->literal()).value(); |
10431 double right_double = Double::Cast(rhs_literal->literal()).value(); | 10473 double right_double = Double::Cast(rhs_literal->literal()).value(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10469 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); | 10511 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); |
10470 } | 10512 } |
10471 CacheConstantValue(op_pos, expr_value); | 10513 CacheConstantValue(op_pos, expr_value); |
10472 } | 10514 } |
10473 return new(Z) LiteralNode(op_pos, expr_value); | 10515 return new(Z) LiteralNode(op_pos, expr_value); |
10474 } | 10516 } |
10475 | 10517 |
10476 LetNode* result = new(Z) LetNode(op_pos); | 10518 LetNode* result = new(Z) LetNode(op_pos); |
10477 LocalVariable* left_temp = result->AddInitializer(lhs); | 10519 LocalVariable* left_temp = result->AddInitializer(lhs); |
10478 left_temp->set_is_final(); | 10520 left_temp->set_is_final(); |
10479 const intptr_t no_pos = Token::kNoSourcePos; | 10521 const TokenDescriptor no_pos = TokenDescriptor::kNoSource; |
10480 LiteralNode* null_operand = | 10522 LiteralNode* null_operand = |
10481 new(Z) LiteralNode(no_pos, Object::null_instance()); | 10523 new(Z) LiteralNode(no_pos, Object::null_instance()); |
10482 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); | 10524 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); |
10483 ComparisonNode* null_compare = | 10525 ComparisonNode* null_compare = |
10484 new(Z) ComparisonNode(no_pos, | 10526 new(Z) ComparisonNode(no_pos, |
10485 Token::kNE_STRICT, | 10527 Token::kNE_STRICT, |
10486 load_left_temp, | 10528 load_left_temp, |
10487 null_operand); | 10529 null_operand); |
10488 result->AddNode(new(Z) ConditionalExprNode(op_pos, | 10530 result->AddNode(new(Z) ConditionalExprNode(op_pos, |
10489 null_compare, | 10531 null_compare, |
10490 load_left_temp, | 10532 load_left_temp, |
10491 rhs)); | 10533 rhs)); |
10492 return result; | 10534 return result; |
10493 } | 10535 } |
10494 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 10536 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
10495 } | 10537 } |
10496 | 10538 |
10497 | 10539 |
10498 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 10540 AstNode* Parser::ExpandAssignableOp(TokenDescriptor op_pos, |
10499 Token::Kind assignment_op, | 10541 Token::Kind assignment_op, |
10500 AstNode* lhs, | 10542 AstNode* lhs, |
10501 AstNode* rhs) { | 10543 AstNode* rhs) { |
10502 TRACE_PARSER("ExpandAssignableOp"); | 10544 TRACE_PARSER("ExpandAssignableOp"); |
10503 switch (assignment_op) { | 10545 switch (assignment_op) { |
10504 case Token::kASSIGN: | 10546 case Token::kASSIGN: |
10505 return rhs; | 10547 return rhs; |
10506 case Token::kASSIGN_ADD: | 10548 case Token::kASSIGN_ADD: |
10507 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 10549 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
10508 case Token::kASSIGN_SUB: | 10550 case Token::kASSIGN_SUB: |
(...skipping 23 matching lines...) Expand all Loading... |
10532 "internal error: ExpandAssignableOp '%s' unimplemented", | 10574 "internal error: ExpandAssignableOp '%s' unimplemented", |
10533 Token::Name(assignment_op)); | 10575 Token::Name(assignment_op)); |
10534 UNIMPLEMENTED(); | 10576 UNIMPLEMENTED(); |
10535 return NULL; | 10577 return NULL; |
10536 } | 10578 } |
10537 } | 10579 } |
10538 | 10580 |
10539 | 10581 |
10540 // Evaluates the value of the compile time constant expression | 10582 // Evaluates the value of the compile time constant expression |
10541 // and returns a literal node for the value. | 10583 // and returns a literal node for the value. |
10542 LiteralNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 10584 LiteralNode* Parser::FoldConstExpr(TokenDescriptor expr_pos, AstNode* expr) { |
10543 if (expr->IsLiteralNode()) { | 10585 if (expr->IsLiteralNode()) { |
10544 return expr->AsLiteralNode(); | 10586 return expr->AsLiteralNode(); |
10545 } | 10587 } |
10546 if (expr->EvalConstExpr() == NULL) { | 10588 if (expr->EvalConstExpr() == NULL) { |
10547 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 10589 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
10548 } | 10590 } |
10549 return new(Z) LiteralNode( | 10591 return new(Z) LiteralNode( |
10550 expr_pos, EvaluateConstExpr(expr_pos, expr)); | 10592 expr_pos, EvaluateConstExpr(expr_pos, expr)); |
10551 } | 10593 } |
10552 | 10594 |
10553 | 10595 |
10554 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 10596 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
10555 AstNode* node = *expr; | 10597 AstNode* node = *expr; |
10556 intptr_t token_pos = node->token_pos(); | 10598 TokenDescriptor token_pos = node->token_pos(); |
10557 LetNode* result = new(Z) LetNode(token_pos); | 10599 LetNode* result = new(Z) LetNode(token_pos); |
10558 if (node->IsLoadIndexedNode()) { | 10600 if (node->IsLoadIndexedNode()) { |
10559 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 10601 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
10560 AstNode* array = load_indexed->array(); | 10602 AstNode* array = load_indexed->array(); |
10561 AstNode* index = load_indexed->index_expr(); | 10603 AstNode* index = load_indexed->index_expr(); |
10562 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 10604 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
10563 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 10605 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
10564 array = new(Z) LoadLocalNode(token_pos, t0); | 10606 array = new(Z) LoadLocalNode(token_pos, t0); |
10565 } | 10607 } |
10566 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { | 10608 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { |
(...skipping 23 matching lines...) Expand all Loading... |
10590 | 10632 |
10591 | 10633 |
10592 // Check whether the syntax of expression expr is a grammatically legal | 10634 // Check whether the syntax of expression expr is a grammatically legal |
10593 // assignable expression. This check is used to detect situations where | 10635 // assignable expression. This check is used to detect situations where |
10594 // the expression itself is assignable, but the source is grammatically | 10636 // the expression itself is assignable, but the source is grammatically |
10595 // wrong. The AST representation of an expression cannot distinguish | 10637 // wrong. The AST representation of an expression cannot distinguish |
10596 // between x = 0 and (x) = 0. The latter is illegal. | 10638 // between x = 0 and (x) = 0. The latter is illegal. |
10597 // A syntactically legal assignable expression always ends with an | 10639 // A syntactically legal assignable expression always ends with an |
10598 // identifier token or a ] token. We rewind the token iterator and | 10640 // identifier token or a ] token. We rewind the token iterator and |
10599 // check whether the token before end_pos is an identifier or ]. | 10641 // check whether the token before end_pos is an identifier or ]. |
10600 bool Parser::IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos) { | 10642 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenDescriptor end_pos) { |
10601 ASSERT(expr->token_pos() >= 0); | 10643 ASSERT(expr->token_pos().IsReal()); |
10602 ASSERT(expr->token_pos() < end_pos); | 10644 ASSERT(expr->token_pos() < end_pos); |
10603 SetPosition(expr->token_pos()); | 10645 SetPosition(expr->token_pos()); |
10604 Token::Kind token = Token::kILLEGAL; | 10646 Token::Kind token = Token::kILLEGAL; |
10605 while (TokenPos() < end_pos) { | 10647 while (TokenPos() < end_pos) { |
10606 token = CurrentToken(); | 10648 token = CurrentToken(); |
10607 ConsumeToken(); | 10649 ConsumeToken(); |
10608 } | 10650 } |
10609 ASSERT(TokenPos() == end_pos); | 10651 ASSERT(TokenPos() == end_pos); |
10610 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 10652 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
10611 } | 10653 } |
10612 | 10654 |
10613 | 10655 |
10614 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 10656 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
10615 AstNode* rhs, | 10657 AstNode* rhs, |
10616 const String* left_ident, | 10658 const String* left_ident, |
10617 intptr_t left_pos, | 10659 TokenDescriptor left_pos, |
10618 bool is_compound /* = false */) { | 10660 bool is_compound /* = false */) { |
10619 AstNode* result = original->MakeAssignmentNode(rhs); | 10661 AstNode* result = original->MakeAssignmentNode(rhs); |
10620 if (result == NULL) { | 10662 if (result == NULL) { |
10621 String& name = String::ZoneHandle(Z); | 10663 String& name = String::ZoneHandle(Z); |
10622 const Class* target_cls = ¤t_class(); | 10664 const Class* target_cls = ¤t_class(); |
10623 if (original->IsTypeNode()) { | 10665 if (original->IsTypeNode()) { |
10624 name = Symbols::New(original->AsTypeNode()->TypeName()); | 10666 name = Symbols::New(original->AsTypeNode()->TypeName()); |
10625 } else if (original->IsLoadStaticFieldNode()) { | 10667 } else if (original->IsLoadStaticFieldNode()) { |
10626 name = original->AsLoadStaticFieldNode()->field().name(); | 10668 name = original->AsLoadStaticFieldNode()->field().name(); |
10627 target_cls = &Class::Handle(Z, | 10669 target_cls = &Class::Handle(Z, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10665 result = OptimizeBinaryOpNode(ifnull->token_pos(), | 10707 result = OptimizeBinaryOpNode(ifnull->token_pos(), |
10666 ifnull->kind(), | 10708 ifnull->kind(), |
10667 ifnull->left(), | 10709 ifnull->left(), |
10668 modified_assign); | 10710 modified_assign); |
10669 } | 10711 } |
10670 return result; | 10712 return result; |
10671 } | 10713 } |
10672 | 10714 |
10673 | 10715 |
10674 AstNode* Parser::ParseCascades(AstNode* expr) { | 10716 AstNode* Parser::ParseCascades(AstNode* expr) { |
10675 intptr_t cascade_pos = TokenPos(); | 10717 TokenDescriptor cascade_pos = TokenPos(); |
10676 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10718 LetNode* cascade = new(Z) LetNode(cascade_pos); |
10677 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10719 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
10678 while (CurrentToken() == Token::kCASCADE) { | 10720 while (CurrentToken() == Token::kCASCADE) { |
10679 cascade_pos = TokenPos(); | 10721 cascade_pos = TokenPos(); |
10680 LoadLocalNode* load_cascade_receiver = | 10722 LoadLocalNode* load_cascade_receiver = |
10681 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); | 10723 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
10682 if (Token::IsIdentifier(LookaheadToken(1))) { | 10724 if (Token::IsIdentifier(LookaheadToken(1))) { |
10683 // Replace .. with . for ParseSelectors(). | 10725 // Replace .. with . for ParseSelectors(). |
10684 token_kind_ = Token::kPERIOD; | 10726 token_kind_ = Token::kPERIOD; |
10685 } else if (LookaheadToken(1) == Token::kLBRACK) { | 10727 } else if (LookaheadToken(1) == Token::kLBRACK) { |
10686 ConsumeToken(); | 10728 ConsumeToken(); |
10687 } else { | 10729 } else { |
10688 ReportError("identifier or [ expected after .."); | 10730 ReportError("identifier or [ expected after .."); |
10689 } | 10731 } |
10690 String* expr_ident = | 10732 String* expr_ident = |
10691 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10733 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10692 const intptr_t expr_pos = TokenPos(); | 10734 const TokenDescriptor expr_pos = TokenPos(); |
10693 expr = ParseSelectors(load_cascade_receiver, true); | 10735 expr = ParseSelectors(load_cascade_receiver, true); |
10694 | 10736 |
10695 // Assignments after a cascade are part of the cascade. The | 10737 // Assignments after a cascade are part of the cascade. The |
10696 // assigned expression must not contain cascades. | 10738 // assigned expression must not contain cascades. |
10697 if (Token::IsAssignmentOperator(CurrentToken())) { | 10739 if (Token::IsAssignmentOperator(CurrentToken())) { |
10698 Token::Kind assignment_op = CurrentToken(); | 10740 Token::Kind assignment_op = CurrentToken(); |
10699 const intptr_t assignment_pos = TokenPos(); | 10741 const TokenDescriptor assignment_pos = TokenPos(); |
10700 ConsumeToken(); | 10742 ConsumeToken(); |
10701 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); | 10743 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
10702 if (assignment_op != Token::kASSIGN) { | 10744 if (assignment_op != Token::kASSIGN) { |
10703 // Compound assignment: store inputs with side effects into | 10745 // Compound assignment: store inputs with side effects into |
10704 // temporary locals. | 10746 // temporary locals. |
10705 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10747 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
10706 right_expr = | 10748 right_expr = |
10707 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10749 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
10708 AstNode* assign_expr = | 10750 AstNode* assign_expr = |
10709 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); | 10751 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10769 } | 10811 } |
10770 return expr; | 10812 return expr; |
10771 } | 10813 } |
10772 | 10814 |
10773 | 10815 |
10774 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 10816 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
10775 bool consume_cascades) { | 10817 bool consume_cascades) { |
10776 TRACE_PARSER("ParseExpr"); | 10818 TRACE_PARSER("ParseExpr"); |
10777 String* expr_ident = | 10819 String* expr_ident = |
10778 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10820 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10779 const intptr_t expr_pos = TokenPos(); | 10821 const TokenDescriptor expr_pos = TokenPos(); |
10780 | 10822 |
10781 RecursionChecker rc(this); | 10823 RecursionChecker rc(this); |
10782 | 10824 |
10783 if (CurrentToken() == Token::kTHROW) { | 10825 if (CurrentToken() == Token::kTHROW) { |
10784 if (require_compiletime_const) { | 10826 if (require_compiletime_const) { |
10785 ReportError("'throw expr' is not a valid compile-time constant"); | 10827 ReportError("'throw expr' is not a valid compile-time constant"); |
10786 } | 10828 } |
10787 ConsumeToken(); | 10829 ConsumeToken(); |
10788 if (CurrentToken() == Token::kSEMICOLON) { | 10830 if (CurrentToken() == Token::kSEMICOLON) { |
10789 ReportError("expression expected after throw"); | 10831 ReportError("expression expected after throw"); |
(...skipping 25 matching lines...) Expand all Loading... |
10815 } else { | 10857 } else { |
10816 expr = LiteralIfStaticConst(Z, expr); | 10858 expr = LiteralIfStaticConst(Z, expr); |
10817 } | 10859 } |
10818 return expr; | 10860 return expr; |
10819 } | 10861 } |
10820 // Assignment expressions. | 10862 // Assignment expressions. |
10821 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 10863 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
10822 ReportError(expr_pos, "expression is not assignable"); | 10864 ReportError(expr_pos, "expression is not assignable"); |
10823 } | 10865 } |
10824 const Token::Kind assignment_op = CurrentToken(); | 10866 const Token::Kind assignment_op = CurrentToken(); |
10825 const intptr_t assignment_pos = TokenPos(); | 10867 const TokenDescriptor assignment_pos = TokenPos(); |
10826 ConsumeToken(); | 10868 ConsumeToken(); |
10827 const intptr_t right_expr_pos = TokenPos(); | 10869 const TokenDescriptor right_expr_pos = TokenPos(); |
10828 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 10870 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
10829 ReportError(right_expr_pos, | 10871 ReportError(right_expr_pos, |
10830 "expression is not a valid compile-time constant"); | 10872 "expression is not a valid compile-time constant"); |
10831 } | 10873 } |
10832 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 10874 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
10833 if (assignment_op != Token::kASSIGN) { | 10875 if (assignment_op != Token::kASSIGN) { |
10834 // Compound assignment: store inputs with side effects into temp. locals. | 10876 // Compound assignment: store inputs with side effects into temp. locals. |
10835 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10877 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
10836 AstNode* assigned_value = | 10878 AstNode* assigned_value = |
10837 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10879 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
10838 AstNode* assign_expr = | 10880 AstNode* assign_expr = |
10839 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); | 10881 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); |
10840 ASSERT(assign_expr != NULL); | 10882 ASSERT(assign_expr != NULL); |
10841 let_expr->AddNode(assign_expr); | 10883 let_expr->AddNode(assign_expr); |
10842 return let_expr; | 10884 return let_expr; |
10843 } else { | 10885 } else { |
10844 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 10886 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
10845 AstNode* assign_expr = | 10887 AstNode* assign_expr = |
10846 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10888 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
10847 ASSERT(assign_expr != NULL); | 10889 ASSERT(assign_expr != NULL); |
10848 return assign_expr; | 10890 return assign_expr; |
10849 } | 10891 } |
10850 } | 10892 } |
10851 | 10893 |
10852 | 10894 |
10853 LiteralNode* Parser::ParseConstExpr() { | 10895 LiteralNode* Parser::ParseConstExpr() { |
10854 TRACE_PARSER("ParseConstExpr"); | 10896 TRACE_PARSER("ParseConstExpr"); |
10855 intptr_t expr_pos = TokenPos(); | 10897 TokenDescriptor expr_pos = TokenPos(); |
10856 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 10898 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
10857 if (!expr->IsLiteralNode()) { | 10899 if (!expr->IsLiteralNode()) { |
10858 ReportError(expr_pos, "expression must be a compile-time constant"); | 10900 ReportError(expr_pos, "expression must be a compile-time constant"); |
10859 } | 10901 } |
10860 return expr->AsLiteralNode(); | 10902 return expr->AsLiteralNode(); |
10861 } | 10903 } |
10862 | 10904 |
10863 | 10905 |
10864 AstNode* Parser::ParseConditionalExpr() { | 10906 AstNode* Parser::ParseConditionalExpr() { |
10865 TRACE_PARSER("ParseConditionalExpr"); | 10907 TRACE_PARSER("ParseConditionalExpr"); |
10866 const intptr_t expr_pos = TokenPos(); | 10908 const TokenDescriptor expr_pos = TokenPos(); |
10867 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); | 10909 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
10868 if (CurrentToken() == Token::kCONDITIONAL) { | 10910 if (CurrentToken() == Token::kCONDITIONAL) { |
10869 EnsureExpressionTemp(); | 10911 EnsureExpressionTemp(); |
10870 ConsumeToken(); | 10912 ConsumeToken(); |
10871 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 10913 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
10872 ExpectToken(Token::kCOLON); | 10914 ExpectToken(Token::kCOLON); |
10873 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 10915 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
10874 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 10916 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
10875 } | 10917 } |
10876 return expr; | 10918 return expr; |
10877 } | 10919 } |
10878 | 10920 |
10879 | 10921 |
10880 AstNode* Parser::ParseUnaryExpr() { | 10922 AstNode* Parser::ParseUnaryExpr() { |
10881 TRACE_PARSER("ParseUnaryExpr"); | 10923 TRACE_PARSER("ParseUnaryExpr"); |
10882 AstNode* expr = NULL; | 10924 AstNode* expr = NULL; |
10883 const intptr_t op_pos = TokenPos(); | 10925 const TokenDescriptor op_pos = TokenPos(); |
10884 if (IsAwaitKeyword()) { | 10926 if (IsAwaitKeyword()) { |
10885 TRACE_PARSER("ParseAwaitExpr"); | 10927 TRACE_PARSER("ParseAwaitExpr"); |
10886 if (!innermost_function().IsAsyncFunction() && | 10928 if (!innermost_function().IsAsyncFunction() && |
10887 !innermost_function().IsAsyncClosure() && | 10929 !innermost_function().IsAsyncClosure() && |
10888 !innermost_function().IsAsyncGenerator() && | 10930 !innermost_function().IsAsyncGenerator() && |
10889 !innermost_function().IsAsyncGenClosure()) { | 10931 !innermost_function().IsAsyncGenClosure()) { |
10890 ReportError("await operator is only allowed in an asynchronous function"); | 10932 ReportError("await operator is only allowed in an asynchronous function"); |
10891 } | 10933 } |
10892 ConsumeToken(); | 10934 ConsumeToken(); |
10893 parsed_function()->record_await(); | 10935 parsed_function()->record_await(); |
(...skipping 23 matching lines...) Expand all Loading... |
10917 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { | 10959 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
10918 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); | 10960 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
10919 } else { | 10961 } else { |
10920 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 10962 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
10921 } | 10963 } |
10922 } else if (IsIncrementOperator(CurrentToken())) { | 10964 } else if (IsIncrementOperator(CurrentToken())) { |
10923 Token::Kind incr_op = CurrentToken(); | 10965 Token::Kind incr_op = CurrentToken(); |
10924 ConsumeToken(); | 10966 ConsumeToken(); |
10925 String* expr_ident = | 10967 String* expr_ident = |
10926 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10968 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
10927 const intptr_t expr_pos = TokenPos(); | 10969 const TokenDescriptor expr_pos = TokenPos(); |
10928 expr = ParseUnaryExpr(); | 10970 expr = ParseUnaryExpr(); |
10929 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 10971 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
10930 ReportError(expr_pos, "expression is not assignable"); | 10972 ReportError(expr_pos, "expression is not assignable"); |
10931 } | 10973 } |
10932 // Is prefix. | 10974 // Is prefix. |
10933 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10975 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
10934 Token::Kind binary_op = | 10976 Token::Kind binary_op = |
10935 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 10977 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
10936 BinaryOpNode* add = new(Z) BinaryOpNode( | 10978 BinaryOpNode* add = new(Z) BinaryOpNode( |
10937 op_pos, | 10979 op_pos, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10998 SetAllowFunctionLiterals(saved_mode); | 11040 SetAllowFunctionLiterals(saved_mode); |
10999 if (named_argument_seen) { | 11041 if (named_argument_seen) { |
11000 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); | 11042 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); |
11001 } | 11043 } |
11002 return arguments; | 11044 return arguments; |
11003 } | 11045 } |
11004 | 11046 |
11005 | 11047 |
11006 AstNode* Parser::ParseStaticCall(const Class& cls, | 11048 AstNode* Parser::ParseStaticCall(const Class& cls, |
11007 const String& func_name, | 11049 const String& func_name, |
11008 intptr_t ident_pos) { | 11050 TokenDescriptor ident_pos) { |
11009 TRACE_PARSER("ParseStaticCall"); | 11051 TRACE_PARSER("ParseStaticCall"); |
11010 const intptr_t call_pos = TokenPos(); | 11052 const TokenDescriptor call_pos = TokenPos(); |
11011 ASSERT(CurrentToken() == Token::kLPAREN); | 11053 ASSERT(CurrentToken() == Token::kLPAREN); |
11012 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11054 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11013 const int num_arguments = arguments->length(); | 11055 const int num_arguments = arguments->length(); |
11014 const Function& func = Function::ZoneHandle(Z, | 11056 const Function& func = Function::ZoneHandle(Z, |
11015 Resolver::ResolveStatic(cls, | 11057 Resolver::ResolveStatic(cls, |
11016 func_name, | 11058 func_name, |
11017 num_arguments, | 11059 num_arguments, |
11018 arguments->names())); | 11060 arguments->names())); |
11019 if (func.IsNull()) { | 11061 if (func.IsNull()) { |
11020 // Check if there is a static field of the same name, it could be a closure | 11062 // 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... |
11086 arguments->NodeAt(0), | 11128 arguments->NodeAt(0), |
11087 arguments->NodeAt(1)); | 11129 arguments->NodeAt(1)); |
11088 } | 11130 } |
11089 } | 11131 } |
11090 return new(Z) StaticCallNode(ident_pos, func, arguments); | 11132 return new(Z) StaticCallNode(ident_pos, func, arguments); |
11091 } | 11133 } |
11092 | 11134 |
11093 | 11135 |
11094 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 11136 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
11095 const String& func_name, | 11137 const String& func_name, |
11096 intptr_t ident_pos, | 11138 TokenDescriptor ident_pos, |
11097 bool is_conditional) { | 11139 bool is_conditional) { |
11098 TRACE_PARSER("ParseInstanceCall"); | 11140 TRACE_PARSER("ParseInstanceCall"); |
11099 CheckToken(Token::kLPAREN); | 11141 CheckToken(Token::kLPAREN); |
11100 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11142 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11101 return new(Z) InstanceCallNode(ident_pos, | 11143 return new(Z) InstanceCallNode(ident_pos, |
11102 receiver, | 11144 receiver, |
11103 func_name, | 11145 func_name, |
11104 arguments, | 11146 arguments, |
11105 is_conditional); | 11147 is_conditional); |
11106 } | 11148 } |
11107 | 11149 |
11108 | 11150 |
11109 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 11151 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
11110 TRACE_PARSER("ParseClosureCall"); | 11152 TRACE_PARSER("ParseClosureCall"); |
11111 const intptr_t call_pos = TokenPos(); | 11153 const TokenDescriptor call_pos = TokenPos(); |
11112 ASSERT(CurrentToken() == Token::kLPAREN); | 11154 ASSERT(CurrentToken() == Token::kLPAREN); |
11113 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11155 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
11114 return BuildClosureCall(call_pos, closure, arguments); | 11156 return BuildClosureCall(call_pos, closure, arguments); |
11115 } | 11157 } |
11116 | 11158 |
11117 | 11159 |
11118 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 11160 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
11119 intptr_t ident_pos) { | 11161 TokenDescriptor ident_pos) { |
11120 // If the static field has an initializer, initialize the field at compile | 11162 // If the static field has an initializer, initialize the field at compile |
11121 // time, which is only possible if the field is const. | 11163 // time, which is only possible if the field is const. |
11122 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11164 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
11123 if (initializing_getter != NULL) { | 11165 if (initializing_getter != NULL) { |
11124 // The field is not yet initialized and could not be initialized at compile | 11166 // The field is not yet initialized and could not be initialized at compile |
11125 // time. The getter will initialize the field. | 11167 // time. The getter will initialize the field. |
11126 return initializing_getter; | 11168 return initializing_getter; |
11127 } | 11169 } |
11128 // The field is initialized. | 11170 // The field is initialized. |
11129 ASSERT(field.is_static()); | 11171 ASSERT(field.is_static()); |
(...skipping 13 matching lines...) Expand all Loading... |
11143 NULL, // Receiver. | 11185 NULL, // Receiver. |
11144 field_owner, | 11186 field_owner, |
11145 field_name); | 11187 field_name); |
11146 } | 11188 } |
11147 } | 11189 } |
11148 | 11190 |
11149 | 11191 |
11150 // Reference to 'field_name' with explicit class as primary. | 11192 // Reference to 'field_name' with explicit class as primary. |
11151 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, | 11193 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, |
11152 const String& field_name, | 11194 const String& field_name, |
11153 intptr_t ident_pos) { | 11195 TokenDescriptor ident_pos) { |
11154 AstNode* access = NULL; | 11196 AstNode* access = NULL; |
11155 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); | 11197 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
11156 Function& func = Function::ZoneHandle(Z); | 11198 Function& func = Function::ZoneHandle(Z); |
11157 if (field.IsNull()) { | 11199 if (field.IsNull()) { |
11158 // No field, check if we have an explicit getter function. | 11200 // No field, check if we have an explicit getter function. |
11159 func = cls.LookupGetterFunction(field_name); | 11201 func = cls.LookupGetterFunction(field_name); |
11160 if (func.IsNull() || func.IsDynamicFunction()) { | 11202 if (func.IsNull() || func.IsDynamicFunction()) { |
11161 // We might be referring to an implicit closure, check to see if | 11203 // We might be referring to an implicit closure, check to see if |
11162 // there is a function of the same name. | 11204 // there is a function of the same name. |
11163 func = cls.LookupStaticFunction(field_name); | 11205 func = cls.LookupStaticFunction(field_name); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11250 AstNode* left = primary; | 11292 AstNode* left = primary; |
11251 while (true) { | 11293 while (true) { |
11252 AstNode* selector = NULL; | 11294 AstNode* selector = NULL; |
11253 if ((CurrentToken() == Token::kPERIOD) || | 11295 if ((CurrentToken() == Token::kPERIOD) || |
11254 (CurrentToken() == Token::kQM_PERIOD)) { | 11296 (CurrentToken() == Token::kQM_PERIOD)) { |
11255 // Unconditional or conditional property extraction or method call. | 11297 // Unconditional or conditional property extraction or method call. |
11256 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | 11298 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; |
11257 ConsumeToken(); | 11299 ConsumeToken(); |
11258 if (left->IsPrimaryNode()) { | 11300 if (left->IsPrimaryNode()) { |
11259 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11301 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11260 const intptr_t primary_pos = primary_node->token_pos(); | 11302 const TokenDescriptor primary_pos = primary_node->token_pos(); |
11261 if (primary_node->primary().IsFunction()) { | 11303 if (primary_node->primary().IsFunction()) { |
11262 left = LoadClosure(primary_node); | 11304 left = LoadClosure(primary_node); |
11263 } else if (primary_node->primary().IsTypeParameter()) { | 11305 } else if (primary_node->primary().IsTypeParameter()) { |
11264 if (ParsingStaticMember()) { | 11306 if (ParsingStaticMember()) { |
11265 const String& name = String::Handle(Z, | 11307 const String& name = String::Handle(Z, |
11266 TypeParameter::Cast(primary_node->primary()).name()); | 11308 TypeParameter::Cast(primary_node->primary()).name()); |
11267 ReportError(primary_pos, | 11309 ReportError(primary_pos, |
11268 "cannot access type parameter '%s' " | 11310 "cannot access type parameter '%s' " |
11269 "from static function", | 11311 "from static function", |
11270 name.ToCString()); | 11312 name.ToCString()); |
11271 } | 11313 } |
11272 if (current_block_->scope->function_level() > 0) { | 11314 if (current_block_->scope->function_level() > 0) { |
11273 // Make sure that the instantiator is captured. | 11315 // Make sure that the instantiator is captured. |
11274 CaptureInstantiator(); | 11316 CaptureInstantiator(); |
11275 } | 11317 } |
11276 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11318 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
11277 type_parameter ^= ClassFinalizer::FinalizeType( | 11319 type_parameter ^= ClassFinalizer::FinalizeType( |
11278 current_class(), | 11320 current_class(), |
11279 TypeParameter::Cast(primary_node->primary()), | 11321 TypeParameter::Cast(primary_node->primary()), |
11280 ClassFinalizer::kCanonicalize); | 11322 ClassFinalizer::kCanonicalize); |
11281 ASSERT(!type_parameter.IsMalformed()); | 11323 ASSERT(!type_parameter.IsMalformed()); |
11282 left = new(Z) TypeNode(primary->token_pos(), type_parameter); | 11324 left = new(Z) TypeNode(primary->token_pos(), type_parameter); |
11283 } else { | 11325 } else { |
11284 // Super field access handled in ParseSuperFieldAccess(), | 11326 // Super field access handled in ParseSuperFieldAccess(), |
11285 // super calls handled in ParseSuperCall(). | 11327 // super calls handled in ParseSuperCall(). |
11286 ASSERT(!primary_node->IsSuper()); | 11328 ASSERT(!primary_node->IsSuper()); |
11287 left = LoadFieldIfUnresolved(left); | 11329 left = LoadFieldIfUnresolved(left); |
11288 } | 11330 } |
11289 } | 11331 } |
11290 const intptr_t ident_pos = TokenPos(); | 11332 const TokenDescriptor ident_pos = TokenPos(); |
11291 String* ident = ExpectIdentifier("identifier expected"); | 11333 String* ident = ExpectIdentifier("identifier expected"); |
11292 if (CurrentToken() == Token::kLPAREN) { | 11334 if (CurrentToken() == Token::kLPAREN) { |
11293 // Identifier followed by a opening paren: method call. | 11335 // Identifier followed by a opening paren: method call. |
11294 if (left->IsPrimaryNode() && | 11336 if (left->IsPrimaryNode() && |
11295 left->AsPrimaryNode()->primary().IsClass()) { | 11337 left->AsPrimaryNode()->primary().IsClass()) { |
11296 // Static method call prefixed with class name. | 11338 // Static method call prefixed with class name. |
11297 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 11339 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
11298 selector = ParseStaticCall(cls, *ident, ident_pos); | 11340 selector = ParseStaticCall(cls, *ident, ident_pos); |
11299 } else { | 11341 } else { |
11300 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); | 11342 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); |
(...skipping 25 matching lines...) Expand all Loading... |
11326 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 11368 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
11327 } else if (selector->IsStaticGetterNode()) { | 11369 } else if (selector->IsStaticGetterNode()) { |
11328 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); | 11370 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); |
11329 } | 11371 } |
11330 } | 11372 } |
11331 } | 11373 } |
11332 } else if (CurrentToken() == Token::kLBRACK) { | 11374 } else if (CurrentToken() == Token::kLBRACK) { |
11333 // Super index operator handled in ParseSuperOperator(). | 11375 // Super index operator handled in ParseSuperOperator(). |
11334 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); | 11376 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); |
11335 | 11377 |
11336 const intptr_t bracket_pos = TokenPos(); | 11378 const TokenDescriptor bracket_pos = TokenPos(); |
11337 ConsumeToken(); | 11379 ConsumeToken(); |
11338 left = LoadFieldIfUnresolved(left); | 11380 left = LoadFieldIfUnresolved(left); |
11339 const bool saved_mode = SetAllowFunctionLiterals(true); | 11381 const bool saved_mode = SetAllowFunctionLiterals(true); |
11340 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); | 11382 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); |
11341 SetAllowFunctionLiterals(saved_mode); | 11383 SetAllowFunctionLiterals(saved_mode); |
11342 ExpectToken(Token::kRBRACK); | 11384 ExpectToken(Token::kRBRACK); |
11343 AstNode* array = left; | 11385 AstNode* array = left; |
11344 if (left->IsPrimaryNode()) { | 11386 if (left->IsPrimaryNode()) { |
11345 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11387 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11346 const intptr_t primary_pos = primary_node->token_pos(); | 11388 const TokenDescriptor primary_pos = primary_node->token_pos(); |
11347 if (primary_node->primary().IsFunction()) { | 11389 if (primary_node->primary().IsFunction()) { |
11348 array = LoadClosure(primary_node); | 11390 array = LoadClosure(primary_node); |
11349 } else if (primary_node->primary().IsClass()) { | 11391 } else if (primary_node->primary().IsClass()) { |
11350 const Class& type_class = Class::Cast(primary_node->primary()); | 11392 const Class& type_class = Class::Cast(primary_node->primary()); |
11351 AbstractType& type = Type::ZoneHandle(Z, | 11393 AbstractType& type = Type::ZoneHandle(Z, |
11352 Type::New(type_class, TypeArguments::Handle(Z), | 11394 Type::New(type_class, TypeArguments::Handle(Z), |
11353 primary_pos, Heap::kOld)); | 11395 primary_pos, Heap::kOld)); |
11354 type ^= ClassFinalizer::FinalizeType( | 11396 type ^= ClassFinalizer::FinalizeType( |
11355 current_class(), type, ClassFinalizer::kCanonicalize); | 11397 current_class(), type, ClassFinalizer::kCanonicalize); |
11356 // Type may be malbounded, but not malformed. | 11398 // Type may be malbounded, but not malformed. |
(...skipping 21 matching lines...) Expand all Loading... |
11378 array = new(Z) TypeNode(primary_pos, type_parameter); | 11420 array = new(Z) TypeNode(primary_pos, type_parameter); |
11379 } else { | 11421 } else { |
11380 UNREACHABLE(); // Internal parser error. | 11422 UNREACHABLE(); // Internal parser error. |
11381 } | 11423 } |
11382 } | 11424 } |
11383 selector = new(Z) LoadIndexedNode( | 11425 selector = new(Z) LoadIndexedNode( |
11384 bracket_pos, array, index, Class::ZoneHandle(Z)); | 11426 bracket_pos, array, index, Class::ZoneHandle(Z)); |
11385 } else if (CurrentToken() == Token::kLPAREN) { | 11427 } else if (CurrentToken() == Token::kLPAREN) { |
11386 if (left->IsPrimaryNode()) { | 11428 if (left->IsPrimaryNode()) { |
11387 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11429 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11388 const intptr_t primary_pos = primary_node->token_pos(); | 11430 const TokenDescriptor primary_pos = primary_node->token_pos(); |
11389 if (primary_node->primary().IsFunction()) { | 11431 if (primary_node->primary().IsFunction()) { |
11390 const Function& func = Function::Cast(primary_node->primary()); | 11432 const Function& func = Function::Cast(primary_node->primary()); |
11391 const String& func_name = String::ZoneHandle(Z, func.name()); | 11433 const String& func_name = String::ZoneHandle(Z, func.name()); |
11392 if (func.is_static()) { | 11434 if (func.is_static()) { |
11393 // Parse static function call. | 11435 // Parse static function call. |
11394 Class& cls = Class::Handle(Z, func.Owner()); | 11436 Class& cls = Class::Handle(Z, func.Owner()); |
11395 selector = ParseStaticCall(cls, func_name, primary_pos); | 11437 selector = ParseStaticCall(cls, func_name, primary_pos); |
11396 } else { | 11438 } else { |
11397 // Dynamic function call on implicit "this" parameter. | 11439 // Dynamic function call on implicit "this" parameter. |
11398 if (current_function().is_static()) { | 11440 if (current_function().is_static()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11454 } else { | 11496 } else { |
11455 // Left is not a primary node; this must be a closure call. | 11497 // Left is not a primary node; this must be a closure call. |
11456 AstNode* closure = left; | 11498 AstNode* closure = left; |
11457 selector = ParseClosureCall(closure); | 11499 selector = ParseClosureCall(closure); |
11458 } | 11500 } |
11459 } else { | 11501 } else { |
11460 // No (more) selectors to parse. | 11502 // No (more) selectors to parse. |
11461 left = LoadFieldIfUnresolved(left); | 11503 left = LoadFieldIfUnresolved(left); |
11462 if (left->IsPrimaryNode()) { | 11504 if (left->IsPrimaryNode()) { |
11463 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11505 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11464 const intptr_t primary_pos = primary->token_pos(); | 11506 const TokenDescriptor primary_pos = primary->token_pos(); |
11465 if (primary_node->primary().IsFunction()) { | 11507 if (primary_node->primary().IsFunction()) { |
11466 // Treat as implicit closure. | 11508 // Treat as implicit closure. |
11467 left = LoadClosure(primary_node); | 11509 left = LoadClosure(primary_node); |
11468 } else if (primary_node->primary().IsClass()) { | 11510 } else if (primary_node->primary().IsClass()) { |
11469 const Class& type_class = Class::Cast(primary_node->primary()); | 11511 const Class& type_class = Class::Cast(primary_node->primary()); |
11470 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 11512 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
11471 type_class, TypeArguments::Handle(Z), primary_pos)); | 11513 type_class, TypeArguments::Handle(Z), primary_pos)); |
11472 type = ClassFinalizer::FinalizeType( | 11514 type = ClassFinalizer::FinalizeType( |
11473 current_class(), type, ClassFinalizer::kCanonicalize); | 11515 current_class(), type, ClassFinalizer::kCanonicalize); |
11474 // Type may be malbounded, but not malformed. | 11516 // Type may be malbounded, but not malformed. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11507 } | 11549 } |
11508 ASSERT(selector != NULL); | 11550 ASSERT(selector != NULL); |
11509 left = selector; | 11551 left = selector; |
11510 } | 11552 } |
11511 } | 11553 } |
11512 | 11554 |
11513 | 11555 |
11514 // Closurization e#m of getter, setter, method or operator. | 11556 // Closurization e#m of getter, setter, method or operator. |
11515 AstNode* Parser::ParseClosurization(AstNode* primary) { | 11557 AstNode* Parser::ParseClosurization(AstNode* primary) { |
11516 ExpectToken(Token::kHASH); | 11558 ExpectToken(Token::kHASH); |
11517 intptr_t property_pos = TokenPos(); | 11559 TokenDescriptor property_pos = TokenPos(); |
11518 bool is_setter_name = false; | 11560 bool is_setter_name = false; |
11519 | 11561 |
11520 String& extractor_name = String::ZoneHandle(Z); | 11562 String& extractor_name = String::ZoneHandle(Z); |
11521 if (IsIdentifier()) { | 11563 if (IsIdentifier()) { |
11522 extractor_name = CurrentLiteral()->raw(); | 11564 extractor_name = CurrentLiteral()->raw(); |
11523 ConsumeToken(); | 11565 ConsumeToken(); |
11524 if (CurrentToken() == Token::kASSIGN) { | 11566 if (CurrentToken() == Token::kASSIGN) { |
11525 ConsumeToken(); | 11567 ConsumeToken(); |
11526 is_setter_name = true; | 11568 is_setter_name = true; |
11527 } | 11569 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11648 pieces.Add(extractor_name); | 11690 pieces.Add(extractor_name); |
11649 extractor_name = Symbols::FromConcatAll(pieces); | 11691 extractor_name = Symbols::FromConcatAll(pieces); |
11650 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); | 11692 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); |
11651 } | 11693 } |
11652 | 11694 |
11653 | 11695 |
11654 AstNode* Parser::ParsePostfixExpr() { | 11696 AstNode* Parser::ParsePostfixExpr() { |
11655 TRACE_PARSER("ParsePostfixExpr"); | 11697 TRACE_PARSER("ParsePostfixExpr"); |
11656 String* expr_ident = | 11698 String* expr_ident = |
11657 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11699 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
11658 const intptr_t expr_pos = TokenPos(); | 11700 const TokenDescriptor expr_pos = TokenPos(); |
11659 AstNode* expr = ParsePrimary(); | 11701 AstNode* expr = ParsePrimary(); |
11660 if (CurrentToken() == Token::kHASH) { | 11702 if (CurrentToken() == Token::kHASH) { |
11661 expr = LoadFieldIfUnresolved(expr); | 11703 expr = LoadFieldIfUnresolved(expr); |
11662 expr = ParseClosurization(expr); | 11704 expr = ParseClosurization(expr); |
11663 } else { | 11705 } else { |
11664 expr = ParseSelectors(expr, false); | 11706 expr = ParseSelectors(expr, false); |
11665 } | 11707 } |
11666 if (IsIncrementOperator(CurrentToken())) { | 11708 if (IsIncrementOperator(CurrentToken())) { |
11667 TRACE_PARSER("IncrementOperator"); | 11709 TRACE_PARSER("IncrementOperator"); |
11668 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11710 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
11669 ReportError(expr_pos, "expression is not assignable"); | 11711 ReportError(expr_pos, "expression is not assignable"); |
11670 } | 11712 } |
11671 Token::Kind incr_op = CurrentToken(); | 11713 Token::Kind incr_op = CurrentToken(); |
11672 const intptr_t op_pos = TokenPos(); | 11714 const TokenDescriptor op_pos = TokenPos(); |
11673 ConsumeToken(); | 11715 ConsumeToken(); |
11674 // Not prefix. | 11716 // Not prefix. |
11675 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11717 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
11676 LocalVariable* temp = let_expr->AddInitializer(expr); | 11718 LocalVariable* temp = let_expr->AddInitializer(expr); |
11677 Token::Kind binary_op = | 11719 Token::Kind binary_op = |
11678 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11720 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
11679 BinaryOpNode* add = new(Z) BinaryOpNode( | 11721 BinaryOpNode* add = new(Z) BinaryOpNode( |
11680 op_pos, | 11722 op_pos, |
11681 binary_op, | 11723 binary_op, |
11682 new(Z) LoadLocalNode(op_pos, temp), | 11724 new(Z) LoadLocalNode(op_pos, temp), |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11795 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 11837 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
11796 if (current_block_ == NULL) { | 11838 if (current_block_ == NULL) { |
11797 return NULL; | 11839 return NULL; |
11798 } | 11840 } |
11799 // A found name is treated as accessed and possibly marked as captured. | 11841 // A found name is treated as accessed and possibly marked as captured. |
11800 const bool kTestOnly = false; | 11842 const bool kTestOnly = false; |
11801 return current_block_->scope->LookupVariable(ident, kTestOnly); | 11843 return current_block_->scope->LookupVariable(ident, kTestOnly); |
11802 } | 11844 } |
11803 | 11845 |
11804 | 11846 |
11805 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 11847 void Parser::CheckInstanceFieldAccess(TokenDescriptor field_pos, |
11806 const String& field_name) { | 11848 const String& field_name) { |
11807 // Fields are not accessible from a static function, except from a | 11849 // Fields are not accessible from a static function, except from a |
11808 // constructor, which is considered as non-static by the compiler. | 11850 // constructor, which is considered as non-static by the compiler. |
11809 if (current_function().is_static()) { | 11851 if (current_function().is_static()) { |
11810 ReportError(field_pos, | 11852 ReportError(field_pos, |
11811 "cannot access instance field '%s' from a static function", | 11853 "cannot access instance field '%s' from a static function", |
11812 field_name.ToCString()); | 11854 field_name.ToCString()); |
11813 } | 11855 } |
11814 } | 11856 } |
11815 | 11857 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11858 // We cache computed compile-time constants in a map so we can look them | 11900 // We cache computed compile-time constants in a map so we can look them |
11859 // up when the same code gets compiled again. The map key is a pair | 11901 // up when the same code gets compiled again. The map key is a pair |
11860 // (script url, token position) which is encoded in an array with 2 | 11902 // (script url, token position) which is encoded in an array with 2 |
11861 // elements: | 11903 // elements: |
11862 // - key[0] contains the canonicalized url of the script. | 11904 // - key[0] contains the canonicalized url of the script. |
11863 // - key[1] contains the token position of the constant in the script. | 11905 // - key[1] contains the token position of the constant in the script. |
11864 | 11906 |
11865 // ConstantPosKey allows us to look up a constant in the map without | 11907 // ConstantPosKey allows us to look up a constant in the map without |
11866 // allocating a key pair (array). | 11908 // allocating a key pair (array). |
11867 struct ConstantPosKey : ValueObject { | 11909 struct ConstantPosKey : ValueObject { |
11868 ConstantPosKey(const String& url, intptr_t pos) | 11910 ConstantPosKey(const String& url, TokenDescriptor pos) |
11869 : script_url(url), token_pos(pos) { } | 11911 : script_url(url), token_pos(pos) { } |
11870 const String& script_url; | 11912 const String& script_url; |
11871 intptr_t token_pos; | 11913 TokenDescriptor token_pos; |
11872 }; | 11914 }; |
11873 | 11915 |
11874 | 11916 |
11875 class ConstMapKeyEqualsTraits { | 11917 class ConstMapKeyEqualsTraits { |
11876 public: | 11918 public: |
11877 static bool IsMatch(const Object& a, const Object& b) { | 11919 static bool IsMatch(const Object& a, const Object& b) { |
11878 const Array& key1 = Array::Cast(a); | 11920 const Array& key1 = Array::Cast(a); |
11879 const Array& key2 = Array::Cast(b); | 11921 const Array& key2 = Array::Cast(b); |
11880 // Compare raw strings of script url symbol and raw smi of token positon. | 11922 // Compare raw strings of script url symbol and raw smi of token positon. |
11881 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); | 11923 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); |
11882 } | 11924 } |
11883 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { | 11925 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { |
11884 const Array& key2 = Array::Cast(b); | 11926 const Array& key2 = Array::Cast(b); |
11885 // Compare raw strings of script url symbol and token positon. | 11927 // Compare raw strings of script url symbol and token positon. |
11886 return (key1.script_url.raw() == key2.At(0)) | 11928 return (key1.script_url.raw() == key2.At(0)) |
11887 && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1)))); | 11929 && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1)))); |
11888 } | 11930 } |
11889 static uword Hash(const Object& obj) { | 11931 static uword Hash(const Object& obj) { |
11890 const Array& key = Array::Cast(obj); | 11932 const Array& key = Array::Cast(obj); |
11891 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); | 11933 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); |
11892 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); | 11934 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); |
11893 return HashValue(url_hash, pos); | 11935 return HashValue(url_hash, pos); |
11894 } | 11936 } |
11895 static uword Hash(const ConstantPosKey& key) { | 11937 static uword Hash(const ConstantPosKey& key) { |
11896 return HashValue(String::HashRawSymbol(key.script_url.raw()), | 11938 return HashValue(String::HashRawSymbol(key.script_url.raw()), |
11897 key.token_pos); | 11939 key.token_pos.value()); |
11898 } | 11940 } |
11899 // Used by CachConstantValue if a new constant is added to the map. | 11941 // Used by CachConstantValue if a new constant is added to the map. |
11900 static RawObject* NewKey(const ConstantPosKey& key) { | 11942 static RawObject* NewKey(const ConstantPosKey& key) { |
11901 const Array& key_obj = Array::Handle(Array::New(2)); | 11943 const Array& key_obj = Array::Handle(Array::New(2)); |
11902 key_obj.SetAt(0, key.script_url); | 11944 key_obj.SetAt(0, key.script_url); |
11903 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos))); | 11945 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value()))); |
11904 return key_obj.raw();; | 11946 return key_obj.raw();; |
11905 } | 11947 } |
11906 | 11948 |
11907 private: | 11949 private: |
11908 static uword HashValue(intptr_t url_hash, intptr_t pos) { | 11950 static uword HashValue(intptr_t url_hash, intptr_t pos) { |
11909 return url_hash * pos % (Smi::kMaxValue - 13); | 11951 return url_hash * pos % (Smi::kMaxValue - 13); |
11910 } | 11952 } |
11911 }; | 11953 }; |
11912 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; | 11954 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
11913 | 11955 |
11914 | 11956 |
11915 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) { | 11957 void Parser::CacheConstantValue(TokenDescriptor token_pos, |
| 11958 const Instance& value) { |
11916 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); | 11959 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
11917 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11960 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
11918 const intptr_t kInitialConstMapSize = 16; | 11961 const intptr_t kInitialConstMapSize = 16; |
11919 isolate()->object_store()->set_compile_time_constants( | 11962 isolate()->object_store()->set_compile_time_constants( |
11920 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, | 11963 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, |
11921 Heap::kNew))); | 11964 Heap::kNew))); |
11922 } | 11965 } |
11923 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11966 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
11924 constants.InsertNewOrGetValue(key, value); | 11967 constants.InsertNewOrGetValue(key, value); |
11925 if (FLAG_compiler_stats) { | 11968 if (FLAG_compiler_stats) { |
11926 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); | 11969 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); |
11927 } | 11970 } |
11928 isolate()->object_store()->set_compile_time_constants(constants.Release()); | 11971 isolate()->object_store()->set_compile_time_constants(constants.Release()); |
11929 } | 11972 } |
11930 | 11973 |
11931 | 11974 |
11932 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { | 11975 bool Parser::GetCachedConstant(TokenDescriptor token_pos, Instance* value) { |
11933 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11976 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
11934 return false; | 11977 return false; |
11935 } | 11978 } |
11936 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); | 11979 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
11937 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11980 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
11938 bool is_present = false; | 11981 bool is_present = false; |
11939 *value ^= constants.GetOrNull(key, &is_present); | 11982 *value ^= constants.GetOrNull(key, &is_present); |
11940 // Mutator compiler thread may add constants while background compiler | 11983 // Mutator compiler thread may add constants while background compiler |
11941 // is running , and thus change the value of 'compile_time_constants'; | 11984 // is running , and thus change the value of 'compile_time_constants'; |
11942 // do not assert that 'compile_time_constants' has not changed. | 11985 // do not assert that 'compile_time_constants' has not changed. |
11943 constants.Release(); | 11986 constants.Release(); |
11944 if (FLAG_compiler_stats && is_present) { | 11987 if (FLAG_compiler_stats && is_present) { |
11945 isolate_->compiler_stats()->num_const_cache_hits++; | 11988 isolate_->compiler_stats()->num_const_cache_hits++; |
11946 } | 11989 } |
11947 return is_present; | 11990 return is_present; |
11948 } | 11991 } |
11949 | 11992 |
11950 | 11993 |
11951 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 11994 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
11952 intptr_t token_pos) { | 11995 TokenDescriptor token_pos) { |
11953 if (instance.IsNull()) { | 11996 if (instance.IsNull()) { |
11954 return instance.raw(); | 11997 return instance.raw(); |
11955 } | 11998 } |
11956 const char* error_str = NULL; | 11999 const char* error_str = NULL; |
11957 Instance& result = | 12000 Instance& result = |
11958 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); | 12001 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); |
11959 if (result.IsNull()) { | 12002 if (result.IsNull()) { |
11960 ReportError(token_pos, "Invalid const object %s", error_str); | 12003 ReportError(token_pos, "Invalid const object %s", error_str); |
11961 } | 12004 } |
11962 return result.raw(); | 12005 return result.raw(); |
11963 } | 12006 } |
11964 | 12007 |
11965 | 12008 |
11966 // If the field is already initialized, return no ast (NULL). | 12009 // If the field is already initialized, return no ast (NULL). |
11967 // Otherwise, if the field is constant, initialize the field and return no ast. | 12010 // Otherwise, if the field is constant, initialize the field and return no ast. |
11968 // If the field is not initialized and not const, return the ast for the getter. | 12011 // If the field is not initialized and not const, return the ast for the getter. |
11969 StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field, | 12012 StaticGetterNode* Parser::RunStaticFieldInitializer( |
11970 intptr_t field_ref_pos) { | 12013 const Field& field, TokenDescriptor field_ref_pos) { |
11971 ASSERT(field.is_static()); | 12014 ASSERT(field.is_static()); |
11972 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); | 12015 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); |
11973 const String& field_name = String::ZoneHandle(Z, field.name()); | 12016 const String& field_name = String::ZoneHandle(Z, field.name()); |
11974 const String& getter_name = | 12017 const String& getter_name = |
11975 String::Handle(Z, Field::GetterSymbol(field_name)); | 12018 String::Handle(Z, Field::GetterSymbol(field_name)); |
11976 const Function& getter = Function::Handle(Z, | 12019 const Function& getter = Function::Handle(Z, |
11977 field_owner.LookupStaticFunction(getter_name)); | 12020 field_owner.LookupStaticFunction(getter_name)); |
11978 const Instance& value = Instance::Handle(Z, field.StaticValue()); | 12021 const Instance& value = Instance::Handle(Z, field.StaticValue()); |
11979 if (value.raw() == Object::transition_sentinel().raw()) { | 12022 if (value.raw() == Object::transition_sentinel().raw()) { |
11980 if (field.is_const()) { | 12023 if (field.is_const()) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12097 instance ^= result.raw(); | 12140 instance ^= result.raw(); |
12098 } | 12141 } |
12099 return TryCanonicalize(instance, TokenPos()); | 12142 return TryCanonicalize(instance, TokenPos()); |
12100 } | 12143 } |
12101 } | 12144 } |
12102 | 12145 |
12103 | 12146 |
12104 // Do a lookup for the identifier in the block scope and the class scope | 12147 // Do a lookup for the identifier in the block scope and the class scope |
12105 // return true if the identifier is found, false otherwise. | 12148 // return true if the identifier is found, false otherwise. |
12106 // If node is non NULL return an AST node corresponding to the identifier. | 12149 // If node is non NULL return an AST node corresponding to the identifier. |
12107 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 12150 bool Parser::ResolveIdentInLocalScope(TokenDescriptor ident_pos, |
12108 const String &ident, | 12151 const String &ident, |
12109 AstNode** node) { | 12152 AstNode** node) { |
12110 TRACE_PARSER("ResolveIdentInLocalScope"); | 12153 TRACE_PARSER("ResolveIdentInLocalScope"); |
12111 // First try to find the identifier in the nested local scopes. | 12154 // First try to find the identifier in the nested local scopes. |
12112 LocalVariable* local = LookupLocalScope(ident); | 12155 LocalVariable* local = LookupLocalScope(ident); |
12113 if (current_block_ != NULL) { | 12156 if (current_block_ != NULL) { |
12114 current_block_->scope->AddReferencedName(ident_pos, ident); | 12157 current_block_->scope->AddReferencedName(ident_pos, ident); |
12115 } | 12158 } |
12116 if (local != NULL) { | 12159 if (local != NULL) { |
12117 if (node != NULL) { | 12160 if (node != NULL) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12202 if (node != NULL) { | 12245 if (node != NULL) { |
12203 *node = NULL; | 12246 *node = NULL; |
12204 } | 12247 } |
12205 return false; | 12248 return false; |
12206 } | 12249 } |
12207 | 12250 |
12208 | 12251 |
12209 // Resolve an identifier by checking the global scope of the current | 12252 // Resolve an identifier by checking the global scope of the current |
12210 // library. If not found in the current library, then look in the scopes | 12253 // library. If not found in the current library, then look in the scopes |
12211 // of all libraries that are imported without a library prefix. | 12254 // of all libraries that are imported without a library prefix. |
12212 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 12255 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenDescriptor ident_pos, |
12213 const String& ident) { | 12256 const String& ident) { |
12214 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 12257 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
12215 HANDLESCOPE(thread()); | 12258 HANDLESCOPE(thread()); |
12216 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); | 12259 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
12217 if (obj.IsClass()) { | 12260 if (obj.IsClass()) { |
12218 const Class& cls = Class::Cast(obj); | 12261 const Class& cls = Class::Cast(obj); |
12219 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 12262 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
12220 } else if (obj.IsField()) { | 12263 } else if (obj.IsField()) { |
12221 const Field& field = Field::Cast(obj); | 12264 const Field& field = Field::Cast(obj); |
12222 ASSERT(field.is_static()); | 12265 ASSERT(field.is_static()); |
(...skipping 25 matching lines...) Expand all Loading... |
12248 ASSERT(obj.IsNull()); | 12291 ASSERT(obj.IsNull()); |
12249 } | 12292 } |
12250 // Lexically unresolved primary identifiers are referenced by their name. | 12293 // Lexically unresolved primary identifiers are referenced by their name. |
12251 return new(Z) PrimaryNode(ident_pos, ident); | 12294 return new(Z) PrimaryNode(ident_pos, ident); |
12252 } | 12295 } |
12253 | 12296 |
12254 | 12297 |
12255 // Do a lookup for the identifier in the scope of the specified | 12298 // Do a lookup for the identifier in the scope of the specified |
12256 // library prefix. This means trying to resolve it locally in all of the | 12299 // library prefix. This means trying to resolve it locally in all of the |
12257 // libraries present in the library prefix. | 12300 // libraries present in the library prefix. |
12258 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 12301 AstNode* Parser::ResolveIdentInPrefixScope(TokenDescriptor ident_pos, |
12259 const LibraryPrefix& prefix, | 12302 const LibraryPrefix& prefix, |
12260 const String& ident) { | 12303 const String& ident) { |
12261 TRACE_PARSER("ResolveIdentInPrefixScope"); | 12304 TRACE_PARSER("ResolveIdentInPrefixScope"); |
12262 HANDLESCOPE(thread()); | 12305 HANDLESCOPE(thread()); |
12263 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 12306 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
12264 // Private names are not exported by libraries. The name mangling | 12307 // Private names are not exported by libraries. The name mangling |
12265 // of private names with a library-specific suffix usually ensures | 12308 // of private names with a library-specific suffix usually ensures |
12266 // that _x in library A is not found when looked up from library B. | 12309 // that _x in library A is not found when looked up from library B. |
12267 // In the pathological case where a library imports itself with | 12310 // In the pathological case where a library imports itself with |
12268 // a prefix, the name mangling would not help in hiding the private | 12311 // 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... |
12327 UNREACHABLE(); | 12370 UNREACHABLE(); |
12328 return NULL; | 12371 return NULL; |
12329 } | 12372 } |
12330 | 12373 |
12331 | 12374 |
12332 // Resolve identifier. Issue an error message if | 12375 // Resolve identifier. Issue an error message if |
12333 // the ident refers to a method and allow_closure_names is false. | 12376 // the ident refers to a method and allow_closure_names is false. |
12334 // If the name cannot be resolved, turn it into an instance field access | 12377 // If the name cannot be resolved, turn it into an instance field access |
12335 // if we're compiling an instance method, or generate | 12378 // if we're compiling an instance method, or generate |
12336 // throw NoSuchMethodError if we're compiling a static method. | 12379 // throw NoSuchMethodError if we're compiling a static method. |
12337 AstNode* Parser::ResolveIdent(intptr_t ident_pos, | 12380 AstNode* Parser::ResolveIdent(TokenDescriptor ident_pos, |
12338 const String& ident, | 12381 const String& ident, |
12339 bool allow_closure_names) { | 12382 bool allow_closure_names) { |
12340 TRACE_PARSER("ResolveIdent"); | 12383 TRACE_PARSER("ResolveIdent"); |
12341 // First try to find the variable in the local scope (block scope or | 12384 // First try to find the variable in the local scope (block scope or |
12342 // class scope). | 12385 // class scope). |
12343 AstNode* resolved = NULL; | 12386 AstNode* resolved = NULL; |
12344 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 12387 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
12345 if (resolved == NULL) { | 12388 if (resolved == NULL) { |
12346 // Check whether the identifier is a type parameter. | 12389 // Check whether the identifier is a type parameter. |
12347 if (!current_class().IsNull()) { | 12390 if (!current_class().IsNull()) { |
(...skipping 10 matching lines...) Expand all Loading... |
12358 return new(Z) TypeNode(ident_pos, type_parameter); | 12401 return new(Z) TypeNode(ident_pos, type_parameter); |
12359 } | 12402 } |
12360 } | 12403 } |
12361 // Not found in the local scope, and the name is not a type parameter. | 12404 // Not found in the local scope, and the name is not a type parameter. |
12362 // Try finding the variable in the library scope (current library | 12405 // Try finding the variable in the library scope (current library |
12363 // and all libraries imported by it without a library prefix). | 12406 // and all libraries imported by it without a library prefix). |
12364 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 12407 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
12365 } | 12408 } |
12366 if (resolved->IsPrimaryNode()) { | 12409 if (resolved->IsPrimaryNode()) { |
12367 PrimaryNode* primary = resolved->AsPrimaryNode(); | 12410 PrimaryNode* primary = resolved->AsPrimaryNode(); |
12368 const intptr_t primary_pos = primary->token_pos(); | 12411 const TokenDescriptor primary_pos = primary->token_pos(); |
12369 if (primary->primary().IsString()) { | 12412 if (primary->primary().IsString()) { |
12370 // We got an unresolved name. If we are compiling a static | 12413 // We got an unresolved name. If we are compiling a static |
12371 // method, evaluation of an unresolved identifier causes a | 12414 // method, evaluation of an unresolved identifier causes a |
12372 // NoSuchMethodError to be thrown. In an instance method, we convert | 12415 // NoSuchMethodError to be thrown. In an instance method, we convert |
12373 // the unresolved name to an instance field access, since a | 12416 // the unresolved name to an instance field access, since a |
12374 // subclass might define a field with this name. | 12417 // subclass might define a field with this name. |
12375 if (current_function().is_static()) { | 12418 if (current_function().is_static()) { |
12376 resolved = ThrowNoSuchMethodError(ident_pos, | 12419 resolved = ThrowNoSuchMethodError(ident_pos, |
12377 current_class(), | 12420 current_class(), |
12378 ident, | 12421 ident, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12417 | 12460 |
12418 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 12461 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
12419 // finalize it according to the given type finalization mode. Returns prefix. | 12462 // finalize it according to the given type finalization mode. Returns prefix. |
12420 RawAbstractType* Parser::ParseType( | 12463 RawAbstractType* Parser::ParseType( |
12421 ClassFinalizer::FinalizationKind finalization, | 12464 ClassFinalizer::FinalizationKind finalization, |
12422 bool allow_deferred_type, | 12465 bool allow_deferred_type, |
12423 bool consume_unresolved_prefix, | 12466 bool consume_unresolved_prefix, |
12424 LibraryPrefix* prefix) { | 12467 LibraryPrefix* prefix) { |
12425 TRACE_PARSER("ParseType"); | 12468 TRACE_PARSER("ParseType"); |
12426 CheckToken(Token::kIDENT, "type name expected"); | 12469 CheckToken(Token::kIDENT, "type name expected"); |
12427 intptr_t ident_pos = TokenPos(); | 12470 TokenDescriptor ident_pos = TokenPos(); |
12428 String& type_name = String::Handle(Z); | 12471 String& type_name = String::Handle(Z); |
12429 | 12472 |
12430 if (finalization == ClassFinalizer::kIgnore) { | 12473 if (finalization == ClassFinalizer::kIgnore) { |
12431 if (!is_top_level_ && (current_block_ != NULL)) { | 12474 if (!is_top_level_ && (current_block_ != NULL)) { |
12432 // Add the library prefix or type class name to the list of referenced | 12475 // Add the library prefix or type class name to the list of referenced |
12433 // names of this scope, even if the type is ignored. | 12476 // names of this scope, even if the type is ignored. |
12434 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 12477 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
12435 } | 12478 } |
12436 SkipQualIdent(); | 12479 SkipQualIdent(); |
12437 } else { | 12480 } else { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12530 ResolveTypeFromClass(current_class(), finalization, &type); | 12573 ResolveTypeFromClass(current_class(), finalization, &type); |
12531 if (finalization >= ClassFinalizer::kCanonicalize) { | 12574 if (finalization >= ClassFinalizer::kCanonicalize) { |
12532 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 12575 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
12533 } | 12576 } |
12534 } | 12577 } |
12535 return type.raw(); | 12578 return type.raw(); |
12536 } | 12579 } |
12537 | 12580 |
12538 | 12581 |
12539 void Parser::CheckConstructorCallTypeArguments( | 12582 void Parser::CheckConstructorCallTypeArguments( |
12540 intptr_t pos, const Function& constructor, | 12583 TokenDescriptor pos, const Function& constructor, |
12541 const TypeArguments& type_arguments) { | 12584 const TypeArguments& type_arguments) { |
12542 if (!type_arguments.IsNull()) { | 12585 if (!type_arguments.IsNull()) { |
12543 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); | 12586 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
12544 ASSERT(!constructor_class.IsNull()); | 12587 ASSERT(!constructor_class.IsNull()); |
12545 ASSERT(constructor_class.is_finalized()); | 12588 ASSERT(constructor_class.is_finalized()); |
12546 ASSERT(type_arguments.IsCanonical()); | 12589 ASSERT(type_arguments.IsCanonical()); |
12547 // Do not report the expected vs. actual number of type arguments, because | 12590 // Do not report the expected vs. actual number of type arguments, because |
12548 // the type argument vector is flattened and raw types are allowed. | 12591 // the type argument vector is flattened and raw types are allowed. |
12549 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 12592 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
12550 ReportError(pos, "wrong number of type arguments passed to constructor"); | 12593 ReportError(pos, "wrong number of type arguments passed to constructor"); |
12551 } | 12594 } |
12552 } | 12595 } |
12553 } | 12596 } |
12554 | 12597 |
12555 | 12598 |
12556 // Parse "[" [ expr { "," expr } ["," ] "]". | 12599 // Parse "[" [ expr { "," expr } ["," ] "]". |
12557 // Note: if the list literal is empty and the brackets have no whitespace | 12600 // Note: if the list literal is empty and the brackets have no whitespace |
12558 // between them, the scanner recognizes the opening and closing bracket | 12601 // between them, the scanner recognizes the opening and closing bracket |
12559 // as one token of type Token::kINDEX. | 12602 // as one token of type Token::kINDEX. |
12560 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 12603 AstNode* Parser::ParseListLiteral(TokenDescriptor type_pos, |
12561 bool is_const, | 12604 bool is_const, |
12562 const TypeArguments& type_arguments) { | 12605 const TypeArguments& type_arguments) { |
12563 TRACE_PARSER("ParseListLiteral"); | 12606 TRACE_PARSER("ParseListLiteral"); |
12564 ASSERT(type_pos >= 0); | 12607 ASSERT(type_pos.IsReal()); |
12565 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 12608 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
12566 const intptr_t literal_pos = TokenPos(); | 12609 const TokenDescriptor literal_pos = TokenPos(); |
12567 | 12610 |
12568 if (is_const) { | 12611 if (is_const) { |
12569 Instance& existing_const = Instance::ZoneHandle(Z); | 12612 Instance& existing_const = Instance::ZoneHandle(Z); |
12570 if (GetCachedConstant(literal_pos, &existing_const)) { | 12613 if (GetCachedConstant(literal_pos, &existing_const)) { |
12571 SkipListLiteral(); | 12614 SkipListLiteral(); |
12572 return new(Z) LiteralNode(literal_pos, existing_const); | 12615 return new(Z) LiteralNode(literal_pos, existing_const); |
12573 } | 12616 } |
12574 } | 12617 } |
12575 | 12618 |
12576 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 12619 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12610 Type& type = Type::ZoneHandle(Z, | 12653 Type& type = Type::ZoneHandle(Z, |
12611 Type::New(array_class, list_type_arguments, type_pos)); | 12654 Type::New(array_class, list_type_arguments, type_pos)); |
12612 type ^= ClassFinalizer::FinalizeType( | 12655 type ^= ClassFinalizer::FinalizeType( |
12613 current_class(), type, ClassFinalizer::kCanonicalize); | 12656 current_class(), type, ClassFinalizer::kCanonicalize); |
12614 GrowableArray<AstNode*> element_list; | 12657 GrowableArray<AstNode*> element_list; |
12615 // Parse the list elements. Note: there may be an optional extra | 12658 // Parse the list elements. Note: there may be an optional extra |
12616 // comma after the last element. | 12659 // comma after the last element. |
12617 if (!is_empty_literal) { | 12660 if (!is_empty_literal) { |
12618 const bool saved_mode = SetAllowFunctionLiterals(true); | 12661 const bool saved_mode = SetAllowFunctionLiterals(true); |
12619 while (CurrentToken() != Token::kRBRACK) { | 12662 while (CurrentToken() != Token::kRBRACK) { |
12620 const intptr_t element_pos = TokenPos(); | 12663 const TokenDescriptor element_pos = TokenPos(); |
12621 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 12664 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
12622 if (I->flags().type_checks() && | 12665 if (I->flags().type_checks() && |
12623 !is_const && | 12666 !is_const && |
12624 !element_type.IsDynamicType()) { | 12667 !element_type.IsDynamicType()) { |
12625 element = new(Z) AssignableNode(element_pos, | 12668 element = new(Z) AssignableNode(element_pos, |
12626 element, | 12669 element, |
12627 element_type, | 12670 element_type, |
12628 Symbols::ListLiteralElement()); | 12671 Symbols::ListLiteralElement()); |
12629 } | 12672 } |
12630 element_list.Add(element); | 12673 element_list.Add(element); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12716 } | 12759 } |
12717 return CreateConstructorCallNode(literal_pos, | 12760 return CreateConstructorCallNode(literal_pos, |
12718 factory_type_args, | 12761 factory_type_args, |
12719 factory_method, | 12762 factory_method, |
12720 factory_param); | 12763 factory_param); |
12721 } | 12764 } |
12722 } | 12765 } |
12723 | 12766 |
12724 | 12767 |
12725 ConstructorCallNode* Parser::CreateConstructorCallNode( | 12768 ConstructorCallNode* Parser::CreateConstructorCallNode( |
12726 intptr_t token_pos, | 12769 TokenDescriptor token_pos, |
12727 const TypeArguments& type_arguments, | 12770 const TypeArguments& type_arguments, |
12728 const Function& constructor, | 12771 const Function& constructor, |
12729 ArgumentListNode* arguments) { | 12772 ArgumentListNode* arguments) { |
12730 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 12773 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
12731 EnsureExpressionTemp(); | 12774 EnsureExpressionTemp(); |
12732 } | 12775 } |
12733 return new(Z) ConstructorCallNode( | 12776 return new(Z) ConstructorCallNode( |
12734 token_pos, type_arguments, constructor, arguments); | 12777 token_pos, type_arguments, constructor, arguments); |
12735 } | 12778 } |
12736 | 12779 |
(...skipping 16 matching lines...) Expand all Loading... |
12753 (*pairs)[i + 1] = value; | 12796 (*pairs)[i + 1] = value; |
12754 return; | 12797 return; |
12755 } | 12798 } |
12756 } | 12799 } |
12757 } | 12800 } |
12758 pairs->Add(key); | 12801 pairs->Add(key); |
12759 pairs->Add(value); | 12802 pairs->Add(value); |
12760 } | 12803 } |
12761 | 12804 |
12762 | 12805 |
12763 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 12806 AstNode* Parser::ParseMapLiteral(TokenDescriptor type_pos, |
12764 bool is_const, | 12807 bool is_const, |
12765 const TypeArguments& type_arguments) { | 12808 const TypeArguments& type_arguments) { |
12766 TRACE_PARSER("ParseMapLiteral"); | 12809 TRACE_PARSER("ParseMapLiteral"); |
12767 ASSERT(type_pos >= 0); | 12810 ASSERT(type_pos.IsReal()); |
12768 ASSERT(CurrentToken() == Token::kLBRACE); | 12811 ASSERT(CurrentToken() == Token::kLBRACE); |
12769 const intptr_t literal_pos = TokenPos(); | 12812 const TokenDescriptor literal_pos = TokenPos(); |
12770 | 12813 |
12771 if (is_const) { | 12814 if (is_const) { |
12772 Instance& existing_const = Instance::ZoneHandle(Z); | 12815 Instance& existing_const = Instance::ZoneHandle(Z); |
12773 if (GetCachedConstant(literal_pos, &existing_const)) { | 12816 if (GetCachedConstant(literal_pos, &existing_const)) { |
12774 SkipMapLiteral(); | 12817 SkipMapLiteral(); |
12775 return new(Z) LiteralNode(literal_pos, existing_const); | 12818 return new(Z) LiteralNode(literal_pos, existing_const); |
12776 } | 12819 } |
12777 } | 12820 } |
12778 | 12821 |
12779 ConsumeToken(); // Opening brace. | 12822 ConsumeToken(); // Opening brace. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12812 } | 12855 } |
12813 } | 12856 } |
12814 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 12857 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
12815 map_type_arguments ^= map_type_arguments.Canonicalize(); | 12858 map_type_arguments ^= map_type_arguments.Canonicalize(); |
12816 | 12859 |
12817 GrowableArray<AstNode*> kv_pairs_list; | 12860 GrowableArray<AstNode*> kv_pairs_list; |
12818 // Parse the map entries. Note: there may be an optional extra | 12861 // Parse the map entries. Note: there may be an optional extra |
12819 // comma after the last entry. | 12862 // comma after the last entry. |
12820 while (CurrentToken() != Token::kRBRACE) { | 12863 while (CurrentToken() != Token::kRBRACE) { |
12821 const bool saved_mode = SetAllowFunctionLiterals(true); | 12864 const bool saved_mode = SetAllowFunctionLiterals(true); |
12822 const intptr_t key_pos = TokenPos(); | 12865 const TokenDescriptor key_pos = TokenPos(); |
12823 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 12866 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
12824 if (I->flags().type_checks() && | 12867 if (I->flags().type_checks() && |
12825 !is_const && | 12868 !is_const && |
12826 !key_type.IsDynamicType()) { | 12869 !key_type.IsDynamicType()) { |
12827 key = new(Z) AssignableNode( | 12870 key = new(Z) AssignableNode( |
12828 key_pos, key, key_type, Symbols::ListLiteralElement()); | 12871 key_pos, key, key_type, Symbols::ListLiteralElement()); |
12829 } | 12872 } |
12830 if (is_const) { | 12873 if (is_const) { |
12831 ASSERT(key->IsLiteralNode()); | 12874 ASSERT(key->IsLiteralNode()); |
12832 const Instance& key_value = key->AsLiteralNode()->literal(); | 12875 const Instance& key_value = key->AsLiteralNode()->literal(); |
12833 if (key_value.IsDouble()) { | 12876 if (key_value.IsDouble()) { |
12834 ReportError(key_pos, "key value must not be of type double"); | 12877 ReportError(key_pos, "key value must not be of type double"); |
12835 } | 12878 } |
12836 if (!key_value.IsInteger() && | 12879 if (!key_value.IsInteger() && |
12837 !key_value.IsString() && | 12880 !key_value.IsString() && |
12838 (key_value.clazz() != I->object_store()->symbol_class()) && | 12881 (key_value.clazz() != I->object_store()->symbol_class()) && |
12839 ImplementsEqualOperator(key_value)) { | 12882 ImplementsEqualOperator(key_value)) { |
12840 ReportError(key_pos, "key value must not implement operator =="); | 12883 ReportError(key_pos, "key value must not implement operator =="); |
12841 } | 12884 } |
12842 } | 12885 } |
12843 ExpectToken(Token::kCOLON); | 12886 ExpectToken(Token::kCOLON); |
12844 const intptr_t value_pos = TokenPos(); | 12887 const TokenDescriptor value_pos = TokenPos(); |
12845 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 12888 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
12846 SetAllowFunctionLiterals(saved_mode); | 12889 SetAllowFunctionLiterals(saved_mode); |
12847 if (I->flags().type_checks() && | 12890 if (I->flags().type_checks() && |
12848 !is_const && | 12891 !is_const && |
12849 !value_type.IsDynamicType()) { | 12892 !value_type.IsDynamicType()) { |
12850 value = new(Z) AssignableNode( | 12893 value = new(Z) AssignableNode( |
12851 value_pos, value, value_type, Symbols::ListLiteralElement()); | 12894 value_pos, value, value_type, Symbols::ListLiteralElement()); |
12852 } | 12895 } |
12853 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 12896 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
12854 | 12897 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12984 } | 13027 } |
12985 | 13028 |
12986 | 13029 |
12987 AstNode* Parser::ParseCompoundLiteral() { | 13030 AstNode* Parser::ParseCompoundLiteral() { |
12988 TRACE_PARSER("ParseCompoundLiteral"); | 13031 TRACE_PARSER("ParseCompoundLiteral"); |
12989 bool is_const = false; | 13032 bool is_const = false; |
12990 if (CurrentToken() == Token::kCONST) { | 13033 if (CurrentToken() == Token::kCONST) { |
12991 is_const = true; | 13034 is_const = true; |
12992 ConsumeToken(); | 13035 ConsumeToken(); |
12993 } | 13036 } |
12994 const intptr_t type_pos = TokenPos(); | 13037 const TokenDescriptor type_pos = TokenPos(); |
12995 TypeArguments& type_arguments = TypeArguments::Handle(Z, | 13038 TypeArguments& type_arguments = TypeArguments::Handle(Z, |
12996 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 13039 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
12997 // Malformed type arguments are mapped to dynamic, so we will not encounter | 13040 // Malformed type arguments are mapped to dynamic, so we will not encounter |
12998 // them here. | 13041 // them here. |
12999 // Map and List interfaces do not declare bounds on their type parameters, so | 13042 // Map and List interfaces do not declare bounds on their type parameters, so |
13000 // we will not see malbounded type arguments here. | 13043 // we will not see malbounded type arguments here. |
13001 AstNode* primary = NULL; | 13044 AstNode* primary = NULL; |
13002 if ((CurrentToken() == Token::kLBRACK) || | 13045 if ((CurrentToken() == Token::kLBRACK) || |
13003 (CurrentToken() == Token::kINDEX)) { | 13046 (CurrentToken() == Token::kINDEX)) { |
13004 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 13047 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
13005 } else if (CurrentToken() == Token::kLBRACE) { | 13048 } else if (CurrentToken() == Token::kLBRACE) { |
13006 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 13049 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
13007 } else { | 13050 } else { |
13008 UnexpectedToken(); | 13051 UnexpectedToken(); |
13009 } | 13052 } |
13010 return primary; | 13053 return primary; |
13011 } | 13054 } |
13012 | 13055 |
13013 | 13056 |
13014 AstNode* Parser::ParseSymbolLiteral() { | 13057 AstNode* Parser::ParseSymbolLiteral() { |
13015 ASSERT(CurrentToken() == Token::kHASH); | 13058 ASSERT(CurrentToken() == Token::kHASH); |
13016 ConsumeToken(); | 13059 ConsumeToken(); |
13017 intptr_t symbol_pos = TokenPos(); | 13060 TokenDescriptor symbol_pos = TokenPos(); |
13018 String& symbol = String::ZoneHandle(Z); | 13061 String& symbol = String::ZoneHandle(Z); |
13019 if (IsIdentifier()) { | 13062 if (IsIdentifier()) { |
13020 symbol = CurrentLiteral()->raw(); | 13063 symbol = CurrentLiteral()->raw(); |
13021 ConsumeToken(); | 13064 ConsumeToken(); |
13022 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13065 GrowableHandlePtrArray<const String> pieces(Z, 3); |
13023 pieces.Add(symbol); | 13066 pieces.Add(symbol); |
13024 while (CurrentToken() == Token::kPERIOD) { | 13067 while (CurrentToken() == Token::kPERIOD) { |
13025 pieces.Add(Symbols::Dot()); | 13068 pieces.Add(Symbols::Dot()); |
13026 ConsumeToken(); | 13069 ConsumeToken(); |
13027 pieces.Add(*ExpectIdentifier("identifier expected")); | 13070 pieces.Add(*ExpectIdentifier("identifier expected")); |
(...skipping 29 matching lines...) Expand all Loading... |
13057 ReportErrors(Error::Cast(result), | 13100 ReportErrors(Error::Cast(result), |
13058 script_, symbol_pos, | 13101 script_, symbol_pos, |
13059 "error executing const Symbol constructor"); | 13102 "error executing const Symbol constructor"); |
13060 } | 13103 } |
13061 symbol_instance ^= result.raw(); | 13104 symbol_instance ^= result.raw(); |
13062 CacheConstantValue(symbol_pos, symbol_instance); | 13105 CacheConstantValue(symbol_pos, symbol_instance); |
13063 return new(Z) LiteralNode(symbol_pos, symbol_instance); | 13106 return new(Z) LiteralNode(symbol_pos, symbol_instance); |
13064 } | 13107 } |
13065 | 13108 |
13066 | 13109 |
13067 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, | 13110 RawFunction* Parser::BuildConstructorClosureFunction( |
13068 intptr_t token_pos) { | 13111 const Function& ctr, TokenDescriptor token_pos) { |
13069 ASSERT(ctr.kind() == RawFunction::kConstructor); | 13112 ASSERT(ctr.kind() == RawFunction::kConstructor); |
13070 Function& closure = Function::Handle(Z); | 13113 Function& closure = Function::Handle(Z); |
13071 closure = I->LookupClosureFunction(innermost_function(), token_pos); | 13114 closure = I->LookupClosureFunction(innermost_function(), token_pos); |
13072 if (!closure.IsNull()) { | 13115 if (!closure.IsNull()) { |
13073 ASSERT(closure.IsConstructorClosureFunction()); | 13116 ASSERT(closure.IsConstructorClosureFunction()); |
13074 return closure.raw(); | 13117 return closure.raw(); |
13075 } | 13118 } |
13076 | 13119 |
13077 String& closure_name = String::Handle(Z, ctr.name()); | 13120 String& closure_name = String::Handle(Z, ctr.name()); |
13078 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(), | 13121 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(), |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13175 } | 13218 } |
13176 *type_arguments = type.arguments(); | 13219 *type_arguments = type.arguments(); |
13177 *constructor = constructor->RedirectionTarget(); | 13220 *constructor = constructor->RedirectionTarget(); |
13178 } | 13221 } |
13179 } | 13222 } |
13180 } | 13223 } |
13181 | 13224 |
13182 | 13225 |
13183 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13226 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
13184 TRACE_PARSER("ParseNewOperator"); | 13227 TRACE_PARSER("ParseNewOperator"); |
13185 const intptr_t new_pos = TokenPos(); | 13228 const TokenDescriptor new_pos = TokenPos(); |
13186 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13229 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
13187 bool is_const = (op_kind == Token::kCONST); | 13230 bool is_const = (op_kind == Token::kCONST); |
13188 if (!IsIdentifier()) { | 13231 if (!IsIdentifier()) { |
13189 ReportError("type name expected"); | 13232 ReportError("type name expected"); |
13190 } | 13233 } |
13191 intptr_t type_pos = TokenPos(); | 13234 TokenDescriptor type_pos = TokenPos(); |
13192 // Can't allocate const objects of a deferred type. | 13235 // Can't allocate const objects of a deferred type. |
13193 const bool allow_deferred_type = !is_const; | 13236 const bool allow_deferred_type = !is_const; |
13194 const Token::Kind la3 = LookaheadToken(3); | 13237 const Token::Kind la3 = LookaheadToken(3); |
13195 const bool consume_unresolved_prefix = | 13238 const bool consume_unresolved_prefix = |
13196 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | 13239 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
13197 | 13240 |
13198 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 13241 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
13199 AbstractType& type = AbstractType::Handle(Z, | 13242 AbstractType& type = AbstractType::Handle(Z, |
13200 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 13243 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
13201 allow_deferred_type, | 13244 allow_deferred_type, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13252 ConsumeToken(); | 13295 ConsumeToken(); |
13253 if (IsIdentifier()) { | 13296 if (IsIdentifier()) { |
13254 named_constructor = ExpectIdentifier("name of constructor expected"); | 13297 named_constructor = ExpectIdentifier("name of constructor expected"); |
13255 } | 13298 } |
13256 } else if (CurrentToken() == Token::kPERIOD) { | 13299 } else if (CurrentToken() == Token::kPERIOD) { |
13257 ConsumeToken(); | 13300 ConsumeToken(); |
13258 named_constructor = ExpectIdentifier("name of constructor expected"); | 13301 named_constructor = ExpectIdentifier("name of constructor expected"); |
13259 } | 13302 } |
13260 | 13303 |
13261 // Parse constructor parameters. | 13304 // Parse constructor parameters. |
13262 intptr_t call_pos = TokenPos(); | 13305 TokenDescriptor call_pos = TokenPos(); |
13263 ArgumentListNode* arguments = NULL; | 13306 ArgumentListNode* arguments = NULL; |
13264 if (!is_tearoff_expression) { | 13307 if (!is_tearoff_expression) { |
13265 CheckToken(Token::kLPAREN); | 13308 CheckToken(Token::kLPAREN); |
13266 call_pos = TokenPos(); | 13309 call_pos = TokenPos(); |
13267 arguments = ParseActualParameters(NULL, is_const); | 13310 arguments = ParseActualParameters(NULL, is_const); |
13268 } else { | 13311 } else { |
13269 // Allocate dummy node with no arguments so we don't have to deal | 13312 // Allocate dummy node with no arguments so we don't have to deal |
13270 // with the NULL corner case below. | 13313 // with the NULL corner case below. |
13271 arguments = new(Z) ArgumentListNode(TokenPos()); | 13314 arguments = new(Z) ArgumentListNode(TokenPos()); |
13272 } | 13315 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13392 // It is ok to call a factory method of an abstract class, but it is | 13435 // It is ok to call a factory method of an abstract class, but it is |
13393 // a dynamic error to instantiate an abstract class. | 13436 // a dynamic error to instantiate an abstract class. |
13394 if (type_class.is_abstract() && !constructor.IsFactory()) { | 13437 if (type_class.is_abstract() && !constructor.IsFactory()) { |
13395 // Evaluate arguments before throwing. | 13438 // Evaluate arguments before throwing. |
13396 LetNode* result = new(Z) LetNode(call_pos); | 13439 LetNode* result = new(Z) LetNode(call_pos); |
13397 for (intptr_t i = 0; i < arguments->length(); ++i) { | 13440 for (intptr_t i = 0; i < arguments->length(); ++i) { |
13398 result->AddNode(arguments->NodeAt(i)); | 13441 result->AddNode(arguments->NodeAt(i)); |
13399 } | 13442 } |
13400 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); | 13443 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); |
13401 error_arguments->Add(new(Z) LiteralNode( | 13444 error_arguments->Add(new(Z) LiteralNode( |
13402 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos)))); | 13445 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos.value())))); |
13403 error_arguments->Add(new(Z) LiteralNode( | 13446 error_arguments->Add(new(Z) LiteralNode( |
13404 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); | 13447 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); |
13405 result->AddNode( | 13448 result->AddNode( |
13406 MakeStaticCall(Symbols::AbstractClassInstantiationError(), | 13449 MakeStaticCall(Symbols::AbstractClassInstantiationError(), |
13407 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 13450 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
13408 error_arguments)); | 13451 error_arguments)); |
13409 return result; | 13452 return result; |
13410 } | 13453 } |
13411 | 13454 |
13412 type_arguments ^= type_arguments.Canonicalize(); | 13455 type_arguments ^= type_arguments.Canonicalize(); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13570 | 13613 |
13571 // A string literal consists of the concatenation of the next n tokens | 13614 // A string literal consists of the concatenation of the next n tokens |
13572 // that satisfy the EBNF grammar: | 13615 // that satisfy the EBNF grammar: |
13573 // literal = kSTRING {{ interpol } kSTRING } | 13616 // literal = kSTRING {{ interpol } kSTRING } |
13574 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 13617 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
13575 // In other words, the scanner breaks down interpolated strings so that | 13618 // In other words, the scanner breaks down interpolated strings so that |
13576 // a string literal always begins and ends with a kSTRING token. | 13619 // a string literal always begins and ends with a kSTRING token. |
13577 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 13620 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
13578 TRACE_PARSER("ParseStringLiteral"); | 13621 TRACE_PARSER("ParseStringLiteral"); |
13579 AstNode* primary = NULL; | 13622 AstNode* primary = NULL; |
13580 const intptr_t literal_start = TokenPos(); | 13623 const TokenDescriptor literal_start = TokenPos(); |
13581 ASSERT(CurrentToken() == Token::kSTRING); | 13624 ASSERT(CurrentToken() == Token::kSTRING); |
13582 Token::Kind l1_token = LookaheadToken(1); | 13625 Token::Kind l1_token = LookaheadToken(1); |
13583 if ((l1_token != Token::kSTRING) && | 13626 if ((l1_token != Token::kSTRING) && |
13584 (l1_token != Token::kINTERPOL_VAR) && | 13627 (l1_token != Token::kINTERPOL_VAR) && |
13585 (l1_token != Token::kINTERPOL_START)) { | 13628 (l1_token != Token::kINTERPOL_START)) { |
13586 // Common case: no interpolation. | 13629 // Common case: no interpolation. |
13587 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); | 13630 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); |
13588 ConsumeToken(); | 13631 ConsumeToken(); |
13589 return primary; | 13632 return primary; |
13590 } | 13633 } |
(...skipping 18 matching lines...) Expand all Loading... |
13609 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); | 13652 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); |
13610 } | 13653 } |
13611 ConsumeToken(); | 13654 ConsumeToken(); |
13612 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 13655 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
13613 (CurrentToken() == Token::kINTERPOL_START)) { | 13656 (CurrentToken() == Token::kINTERPOL_START)) { |
13614 if (!allow_interpolation) { | 13657 if (!allow_interpolation) { |
13615 ReportError("string interpolation not allowed in this context"); | 13658 ReportError("string interpolation not allowed in this context"); |
13616 } | 13659 } |
13617 has_interpolation = true; | 13660 has_interpolation = true; |
13618 AstNode* expr = NULL; | 13661 AstNode* expr = NULL; |
13619 const intptr_t expr_pos = TokenPos(); | 13662 const TokenDescriptor expr_pos = TokenPos(); |
13620 if (CurrentToken() == Token::kINTERPOL_VAR) { | 13663 if (CurrentToken() == Token::kINTERPOL_VAR) { |
13621 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); | 13664 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
13622 ConsumeToken(); | 13665 ConsumeToken(); |
13623 } else { | 13666 } else { |
13624 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 13667 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
13625 ConsumeToken(); | 13668 ConsumeToken(); |
13626 const bool saved_mode = SetAllowFunctionLiterals(true); | 13669 const bool saved_mode = SetAllowFunctionLiterals(true); |
13627 expr = ParseExpr(kAllowConst, kConsumeCascades); | 13670 expr = ParseExpr(kAllowConst, kConsumeCascades); |
13628 SetAllowFunctionLiterals(saved_mode); | 13671 SetAllowFunctionLiterals(saved_mode); |
13629 ExpectToken(Token::kINTERPOL_END); | 13672 ExpectToken(Token::kINTERPOL_END); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13682 ASSERT(!is_top_level_); | 13725 ASSERT(!is_top_level_); |
13683 AstNode* primary = NULL; | 13726 AstNode* primary = NULL; |
13684 const Token::Kind token = CurrentToken(); | 13727 const Token::Kind token = CurrentToken(); |
13685 if (IsFunctionLiteral()) { | 13728 if (IsFunctionLiteral()) { |
13686 // The name of a literal function is visible from inside the function, but | 13729 // The name of a literal function is visible from inside the function, but |
13687 // must not collide with names in the scope declaring the literal. | 13730 // must not collide with names in the scope declaring the literal. |
13688 OpenBlock(); | 13731 OpenBlock(); |
13689 primary = ParseFunctionStatement(true); | 13732 primary = ParseFunctionStatement(true); |
13690 CloseBlock(); | 13733 CloseBlock(); |
13691 } else if (IsIdentifier()) { | 13734 } else if (IsIdentifier()) { |
13692 intptr_t qual_ident_pos = TokenPos(); | 13735 TokenDescriptor qual_ident_pos = TokenPos(); |
13693 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13736 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
13694 if (!prefix.IsNull()) { | 13737 if (!prefix.IsNull()) { |
13695 if (CurrentToken() == Token::kHASH) { | 13738 if (CurrentToken() == Token::kHASH) { |
13696 // Closurization of top-level entity in prefix scope. | 13739 // Closurization of top-level entity in prefix scope. |
13697 return new(Z) LiteralNode(qual_ident_pos, prefix); | 13740 return new(Z) LiteralNode(qual_ident_pos, prefix); |
13698 } else { | 13741 } else { |
13699 ExpectToken(Token::kPERIOD); | 13742 ExpectToken(Token::kPERIOD); |
13700 } | 13743 } |
13701 } | 13744 } |
13702 String& ident = *CurrentLiteral(); | 13745 String& ident = *CurrentLiteral(); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13841 } else if (token == Token::kHASH) { | 13884 } else if (token == Token::kHASH) { |
13842 primary = ParseSymbolLiteral(); | 13885 primary = ParseSymbolLiteral(); |
13843 } else if (token == Token::kSUPER) { | 13886 } else if (token == Token::kSUPER) { |
13844 if (current_function().is_static()) { | 13887 if (current_function().is_static()) { |
13845 ReportError("cannot access superclass from static method"); | 13888 ReportError("cannot access superclass from static method"); |
13846 } | 13889 } |
13847 if (current_class().SuperClass() == Class::null()) { | 13890 if (current_class().SuperClass() == Class::null()) { |
13848 ReportError("class '%s' does not have a superclass", | 13891 ReportError("class '%s' does not have a superclass", |
13849 String::Handle(Z, current_class().Name()).ToCString()); | 13892 String::Handle(Z, current_class().Name()).ToCString()); |
13850 } | 13893 } |
13851 const intptr_t super_pos = TokenPos(); | 13894 const TokenDescriptor super_pos = TokenPos(); |
13852 ConsumeToken(); | 13895 ConsumeToken(); |
13853 if (CurrentToken() == Token::kPERIOD) { | 13896 if (CurrentToken() == Token::kPERIOD) { |
13854 ConsumeToken(); | 13897 ConsumeToken(); |
13855 const intptr_t ident_pos = TokenPos(); | 13898 const TokenDescriptor ident_pos = TokenPos(); |
13856 const String& ident = *ExpectIdentifier("identifier expected"); | 13899 const String& ident = *ExpectIdentifier("identifier expected"); |
13857 if (CurrentToken() == Token::kLPAREN) { | 13900 if (CurrentToken() == Token::kLPAREN) { |
13858 primary = ParseSuperCall(ident); | 13901 primary = ParseSuperCall(ident); |
13859 } else { | 13902 } else { |
13860 primary = ParseSuperFieldAccess(ident, ident_pos); | 13903 primary = ParseSuperFieldAccess(ident, ident_pos); |
13861 } | 13904 } |
13862 } else if ((CurrentToken() == Token::kLBRACK) || | 13905 } else if ((CurrentToken() == Token::kLBRACK) || |
13863 Token::CanBeOverloaded(CurrentToken()) || | 13906 Token::CanBeOverloaded(CurrentToken()) || |
13864 (CurrentToken() == Token::kNE)) { | 13907 (CurrentToken() == Token::kNE)) { |
13865 primary = ParseSuperOperator(); | 13908 primary = ParseSuperOperator(); |
13866 } else if (CurrentToken() == Token::kQM_PERIOD) { | 13909 } else if (CurrentToken() == Token::kQM_PERIOD) { |
13867 ReportError("super call or super getter may not use ?."); | 13910 ReportError("super call or super getter may not use ?."); |
13868 } else { | 13911 } else { |
13869 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); | 13912 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); |
13870 } | 13913 } |
13871 } else { | 13914 } else { |
13872 UnexpectedToken(); | 13915 UnexpectedToken(); |
13873 } | 13916 } |
13874 return primary; | 13917 return primary; |
13875 } | 13918 } |
13876 | 13919 |
13877 | 13920 |
13878 // Evaluate expression in expr and return the value. The expression must | 13921 // Evaluate expression in expr and return the value. The expression must |
13879 // be a compile time constant. | 13922 // be a compile time constant. |
13880 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { | 13923 const Instance& Parser::EvaluateConstExpr(TokenDescriptor expr_pos, |
| 13924 AstNode* expr) { |
13881 if (expr->IsLiteralNode()) { | 13925 if (expr->IsLiteralNode()) { |
13882 return expr->AsLiteralNode()->literal(); | 13926 return expr->AsLiteralNode()->literal(); |
13883 } else if (expr->IsLoadLocalNode() && | 13927 } else if (expr->IsLoadLocalNode() && |
13884 expr->AsLoadLocalNode()->local().IsConst()) { | 13928 expr->AsLoadLocalNode()->local().IsConst()) { |
13885 return *expr->AsLoadLocalNode()->local().ConstValue(); | 13929 return *expr->AsLoadLocalNode()->local().ConstValue(); |
13886 } else if (expr->IsLoadStaticFieldNode()) { | 13930 } else if (expr->IsLoadStaticFieldNode()) { |
13887 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 13931 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
13888 // We already checked that this field is const and has been | 13932 // We already checked that this field is const and has been |
13889 // initialized. | 13933 // initialized. |
13890 ASSERT(field.is_const()); | 13934 ASSERT(field.is_const()); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14342 } | 14386 } |
14343 | 14387 |
14344 | 14388 |
14345 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 14389 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
14346 UNREACHABLE(); | 14390 UNREACHABLE(); |
14347 return NULL; | 14391 return NULL; |
14348 } | 14392 } |
14349 | 14393 |
14350 | 14394 |
14351 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 14395 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
14352 intptr_t call_pos, | 14396 TokenDescriptor call_pos, |
14353 const String& function_name, | 14397 const String& function_name, |
14354 const ArgumentListNode& function_args, | 14398 const ArgumentListNode& function_args, |
14355 const LocalVariable* temp_for_last_arg, | 14399 const LocalVariable* temp_for_last_arg, |
14356 bool is_super_invocation) { | 14400 bool is_super_invocation) { |
14357 UNREACHABLE(); | 14401 UNREACHABLE(); |
14358 return NULL; | 14402 return NULL; |
14359 } | 14403 } |
14360 | 14404 |
14361 } // namespace dart | 14405 } // namespace dart |
14362 | 14406 |
14363 #endif // DART_PRECOMPILED_RUNTIME | 14407 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |