| 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 |