OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/ast.h" | 5 #include "vm/ast.h" |
6 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 } | 565 } |
566 | 566 |
567 | 567 |
568 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { | 568 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { |
569 Thread* thread = Thread::Current(); | 569 Thread* thread = Thread::Current(); |
570 Zone* zone = thread->zone(); | 570 Zone* zone = thread->zone(); |
571 Isolate* isolate = thread->isolate(); | 571 Isolate* isolate = thread->isolate(); |
572 if (is_super_getter()) { | 572 if (is_super_getter()) { |
573 ASSERT(receiver() != NULL); | 573 ASSERT(receiver() != NULL); |
574 const String& setter_name = | 574 const String& setter_name = |
575 String::ZoneHandle(zone, Field::SetterSymbol(field_name_)); | 575 String::ZoneHandle(zone, Field::LookupSetterSymbol(field_name_)); |
576 Function& setter = Function::ZoneHandle(zone, | 576 Function& setter = Function::ZoneHandle(zone); |
577 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); | 577 if (!setter_name.IsNull()) { |
| 578 setter = Resolver::ResolveDynamicAnyArgs(cls(), setter_name); |
| 579 } |
578 if (setter.IsNull() || setter.is_abstract()) { | 580 if (setter.IsNull() || setter.is_abstract()) { |
579 // No instance setter found in super class chain, | 581 // No instance setter found in super class chain, |
580 // noSuchMethod will be called at runtime. | 582 // noSuchMethod will be called at runtime. |
581 return new StaticSetterNode(token_pos(), | 583 return new StaticSetterNode(token_pos(), |
582 receiver(), | 584 receiver(), |
583 cls(), | 585 cls(), |
584 field_name_, | 586 field_name_, |
585 rhs); | 587 rhs); |
586 } | 588 } |
587 return new StaticSetterNode(token_pos(), | 589 return new StaticSetterNode(token_pos(), |
(...skipping 23 matching lines...) Expand all Loading... |
611 rhs = new AssignableNode(field.token_pos(), | 613 rhs = new AssignableNode(field.token_pos(), |
612 rhs, | 614 rhs, |
613 AbstractType::ZoneHandle(zone, field.type()), | 615 AbstractType::ZoneHandle(zone, field.type()), |
614 field_name_); | 616 field_name_); |
615 } | 617 } |
616 return new StoreStaticFieldNode(token_pos(), field, rhs); | 618 return new StoreStaticFieldNode(token_pos(), field, rhs); |
617 } | 619 } |
618 } | 620 } |
619 | 621 |
620 // No field found in prefix. Look for a setter function. | 622 // No field found in prefix. Look for a setter function. |
621 const String& setter_name = String::Handle(zone, | 623 const String& setter_name = |
622 Field::SetterName(field_name_)); | 624 String::Handle(zone, Field::LookupSetterSymbol(field_name_)); |
623 obj = prefix.LookupObject(setter_name); | 625 if (!setter_name.IsNull()) { |
624 if (obj.IsFunction()) { | 626 obj = prefix.LookupObject(setter_name); |
625 const Function& setter = Function::ZoneHandle(zone, | 627 if (obj.IsFunction()) { |
626 Function::Cast(obj).raw()); | 628 const Function& setter = |
627 ASSERT(setter.is_static() && setter.IsSetterFunction()); | 629 Function::ZoneHandle(zone, Function::Cast(obj).raw()); |
628 return new StaticSetterNode( | 630 ASSERT(setter.is_static() && setter.IsSetterFunction()); |
629 token_pos(), NULL, field_name_, setter, rhs); | 631 return new StaticSetterNode( |
| 632 token_pos(), NULL, field_name_, setter, rhs); |
| 633 } |
630 } | 634 } |
631 | 635 |
632 // No writeable field and no setter found in the prefix. Return a | 636 // No writeable field and no setter found in the prefix. Return a |
633 // non-existing setter that will throw an NSM error. | 637 // non-existing setter that will throw an NSM error. |
634 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 638 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
635 } | 639 } |
636 | 640 |
637 if (owner().IsLibrary()) { | 641 if (owner().IsLibrary()) { |
638 const Library& library = Library::Cast(owner()); | 642 const Library& library = Library::Cast(owner()); |
639 Object& obj = Object::Handle(zone, library.ResolveName(field_name_)); | 643 Object& obj = Object::Handle(zone, library.ResolveName(field_name_)); |
640 if (obj.IsField()) { | 644 if (obj.IsField()) { |
641 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); | 645 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); |
642 if (!field.is_final()) { | 646 if (!field.is_final()) { |
643 if (isolate->flags().type_checks()) { | 647 if (isolate->flags().type_checks()) { |
644 rhs = new AssignableNode(field.token_pos(), | 648 rhs = new AssignableNode(field.token_pos(), |
645 rhs, | 649 rhs, |
646 AbstractType::ZoneHandle(zone, field.type()), | 650 AbstractType::ZoneHandle(zone, field.type()), |
647 field_name_); | 651 field_name_); |
648 } | 652 } |
649 return new StoreStaticFieldNode(token_pos(), field, rhs); | 653 return new StoreStaticFieldNode(token_pos(), field, rhs); |
650 } | 654 } |
651 } | 655 } |
652 | 656 |
653 // No field found in library. Look for a setter function. | 657 // No field found in library. Look for a setter function. |
654 const String& setter_name = String::Handle(zone, | 658 const String& setter_name = |
655 Field::SetterName(field_name_)); | 659 String::Handle(zone, Field::LookupSetterSymbol(field_name_)); |
656 obj = library.ResolveName(setter_name); | 660 if (!setter_name.IsNull()) { |
657 if (obj.IsFunction()) { | 661 obj = library.ResolveName(setter_name); |
658 const Function& setter = Function::ZoneHandle(zone, | 662 if (obj.IsFunction()) { |
659 Function::Cast(obj).raw()); | 663 const Function& setter = |
660 ASSERT(setter.is_static() && setter.IsSetterFunction()); | 664 Function::ZoneHandle(zone, Function::Cast(obj).raw()); |
661 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); | 665 ASSERT(setter.is_static() && setter.IsSetterFunction()); |
| 666 return |
| 667 new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); |
| 668 } |
662 } | 669 } |
663 | 670 |
664 // No writeable field and no setter found in the library. Return a | 671 // No writeable field and no setter found in the library. Return a |
665 // non-existing setter that will throw an NSM error. | 672 // non-existing setter that will throw an NSM error. |
666 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 673 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
667 } | 674 } |
668 | 675 |
669 const Function& setter = | 676 const Function& setter = |
670 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_)); | 677 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_)); |
671 if (!setter.IsNull() && setter.IsStaticFunction()) { | 678 if (!setter.IsNull() && setter.IsStaticFunction()) { |
672 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); | 679 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); |
673 } | 680 } |
674 // Could not find a static setter. Look for a field. | 681 // Could not find a static setter. Look for a field. |
675 // Access to a lazily initialized static field that has not yet been | 682 // Access to a lazily initialized static field that has not yet been |
676 // initialized is compiled to a static implicit getter. | 683 // initialized is compiled to a static implicit getter. |
677 // A setter may not exist for such a field. | 684 // A setter may not exist for such a field. |
678 const Field& field = Field::ZoneHandle(zone, | 685 const Field& field = Field::ZoneHandle(zone, |
679 cls().LookupStaticField(field_name_)); | 686 cls().LookupStaticField(field_name_)); |
680 if (!field.IsNull()) { | 687 if (!field.IsNull()) { |
681 if (field.is_final()) { | 688 if (field.is_final()) { |
682 // Attempting to assign to a final variable will cause a NoSuchMethodError | 689 // Attempting to assign to a final variable will cause a NoSuchMethodError |
683 // to be thrown. Change static getter to non-existent static setter in | 690 // to be thrown. Change static getter to non-existent static setter in |
684 // order to trigger the throw at runtime. | 691 // order to trigger the throw at runtime. |
685 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 692 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
686 } | 693 } |
687 #if defined(DEBUG) | 694 #if defined(DEBUG) |
688 const String& getter_name = String::Handle(zone, | 695 const String& getter_name = |
689 Field::GetterName(field_name_)); | 696 String::Handle(zone, Field::LookupGetterSymbol(field_name_)); |
| 697 ASSERT(!getter_name.IsNull()); |
690 const Function& getter = | 698 const Function& getter = |
691 Function::Handle(zone, cls().LookupStaticFunction(getter_name)); | 699 Function::Handle(zone, cls().LookupStaticFunction(getter_name)); |
692 ASSERT(!getter.IsNull() && | 700 ASSERT(!getter.IsNull() && |
693 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); | 701 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); |
694 #endif | 702 #endif |
695 if (isolate->flags().type_checks()) { | 703 if (isolate->flags().type_checks()) { |
696 rhs = new AssignableNode( | 704 rhs = new AssignableNode( |
697 field.token_pos(), | 705 field.token_pos(), |
698 rhs, | 706 rhs, |
699 AbstractType::ZoneHandle(zone, field.type()), | 707 AbstractType::ZoneHandle(zone, field.type()), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 } | 742 } |
735 return true; | 743 return true; |
736 } | 744 } |
737 | 745 |
738 | 746 |
739 const Instance* StaticGetterNode::EvalConstExpr() const { | 747 const Instance* StaticGetterNode::EvalConstExpr() const { |
740 if (is_deferred_reference_) { | 748 if (is_deferred_reference_) { |
741 return NULL; | 749 return NULL; |
742 } | 750 } |
743 const String& getter_name = | 751 const String& getter_name = |
744 String::Handle(Field::GetterName(this->field_name())); | 752 String::Handle(Field::LookupGetterSymbol(this->field_name())); |
| 753 if (getter_name.IsNull()) { |
| 754 return NULL; |
| 755 } |
745 const Function& getter_func = | 756 const Function& getter_func = |
746 Function::Handle(this->cls().LookupStaticFunction(getter_name)); | 757 Function::Handle(this->cls().LookupStaticFunction(getter_name)); |
747 if (getter_func.IsNull() || !getter_func.is_const()) { | 758 if (getter_func.IsNull() || !getter_func.is_const()) { |
748 return NULL; | 759 return NULL; |
749 } | 760 } |
750 const Object& result = Object::Handle( | 761 const Object& result = Object::Handle( |
751 DartEntry::InvokeFunction(getter_func, Object::empty_array())); | 762 DartEntry::InvokeFunction(getter_func, Object::empty_array())); |
752 if (result.IsError() || result.IsNull()) { | 763 if (result.IsError() || result.IsNull()) { |
753 // TODO(turnidge): We could get better error messages by returning | 764 // TODO(turnidge): We could get better error messages by returning |
754 // the Error object directly to the parser. This will involve | 765 // the Error object directly to the parser. This will involve |
755 // replumbing all of the EvalConstExpr methods. | 766 // replumbing all of the EvalConstExpr methods. |
756 return NULL; | 767 return NULL; |
757 } | 768 } |
758 return &Instance::ZoneHandle(Instance::Cast(result).raw()); | 769 return &Instance::ZoneHandle(Instance::Cast(result).raw()); |
759 } | 770 } |
760 | 771 |
761 } // namespace dart | 772 } // namespace dart |
OLD | NEW |