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 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
554 | 554 |
555 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { | 555 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { |
556 return new StoreIndexedNode(token_pos(), array(), index_expr(), | 556 return new StoreIndexedNode(token_pos(), array(), index_expr(), |
557 rhs, super_class()); | 557 rhs, super_class()); |
558 } | 558 } |
559 | 559 |
560 | 560 |
561 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { | 561 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { |
562 if (is_super_getter()) { | 562 if (is_super_getter()) { |
563 ASSERT(receiver() != NULL); | 563 ASSERT(receiver() != NULL); |
564 // If the static setter is not found in the superclass, noSuchMethod will be | 564 const String& setter_name = |
565 // called at runtime. | 565 String::ZoneHandle(Field::SetterSymbol(field_name_)); |
566 Function& setter = Function::ZoneHandle( | |
567 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); | |
568 if (setter.IsNull() || setter.is_abstract()) { | |
569 // No instance setter found in super class chain, | |
570 // noSuchMethod will be called at runtime. | |
571 return new StaticSetterNode(token_pos(), | |
572 receiver(), | |
573 cls(), | |
574 field_name_, | |
575 rhs); | |
576 } | |
566 return new StaticSetterNode(token_pos(), | 577 return new StaticSetterNode(token_pos(), |
567 receiver(), | 578 receiver(), |
568 cls(), | 579 field_name_, |
569 field_name(), | 580 setter, |
570 rhs); | 581 rhs); |
571 } | 582 } |
572 | 583 |
584 if (owner().IsLibraryPrefix()) { | |
585 const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_); | |
586 // The parser has already dealt with the pathological case where a | |
587 // library imports itself. See Parser::ResolveIdentInPrefixScope() | |
588 ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart); | |
589 | |
590 // If the prefix is not yet loaded, the getter doesn't exist. Return a | |
591 // setter that will throw a NSME at runtime. | |
592 if (!prefix.is_loaded()) { | |
593 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | |
594 } | |
595 | |
596 Object& obj = Object::Handle(prefix.LookupObject(field_name_)); | |
597 if (obj.IsField()) { | |
598 const Field& field = Field::ZoneHandle(Field::Cast(obj).raw()); | |
599 if (!field.is_final()) { | |
600 if (Isolate::Current()->TypeChecksEnabled()) { | |
601 rhs = new AssignableNode(field.token_pos(), | |
602 rhs, | |
603 AbstractType::ZoneHandle(field.type()), | |
604 field_name_); | |
605 } | |
606 return new StoreStaticFieldNode(token_pos(), field, rhs); | |
regis
2015/04/21 17:30:30
Indent lines 600-606.
hausner
2015/04/21 17:40:11
Done.
| |
607 } | |
608 } | |
609 | |
610 // No field found in prefix. Look for a setter function. | |
611 const String& setter_name = String::Handle(Field::SetterName(field_name_)); | |
612 obj = prefix.LookupObject(setter_name); | |
613 if (obj.IsFunction()) { | |
614 const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw()); | |
615 ASSERT(setter.is_static() && setter.IsSetterFunction()); | |
616 return new StaticSetterNode( | |
617 token_pos(), NULL, field_name_, setter, rhs); | |
618 } | |
619 | |
620 // No writeable field and no setter found in the prefix. Return a | |
621 // non-existing setter that will throw an NSM error. | |
622 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | |
623 } | |
624 | |
625 if (owner().IsLibrary()) { | |
626 const Library& library = Library::Cast(owner()); | |
627 Object& obj = Object::Handle(library.ResolveName(field_name_)); | |
628 if (obj.IsField()) { | |
629 const Field& field = Field::ZoneHandle(Field::Cast(obj).raw()); | |
630 if (!field.is_final()) { | |
631 if (Isolate::Current()->TypeChecksEnabled()) { | |
632 rhs = new AssignableNode(field.token_pos(), | |
633 rhs, | |
634 AbstractType::ZoneHandle(field.type()), | |
635 field_name_); | |
636 } | |
637 return new StoreStaticFieldNode(token_pos(), field, rhs); | |
638 } | |
639 } | |
640 | |
641 // No field found in library. Look for a setter function. | |
642 const String& setter_name = String::Handle(Field::SetterName(field_name_)); | |
643 obj = library.ResolveName(setter_name); | |
644 if (obj.IsFunction()) { | |
645 const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw()); | |
646 ASSERT(setter.is_static() && setter.IsSetterFunction()); | |
647 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); | |
648 } | |
649 | |
650 // No writeable field and no setter found in the library. Return a | |
651 // non-existing setter that will throw an NSM error. | |
652 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | |
653 } | |
654 | |
573 const Function& setter = | 655 const Function& setter = |
574 Function::Handle(cls().LookupSetterFunction(field_name())); | 656 Function::ZoneHandle(cls().LookupSetterFunction(field_name_)); |
575 if (!setter.IsNull() && setter.IsStaticFunction()) { | 657 if (!setter.IsNull() && setter.IsStaticFunction()) { |
576 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 658 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); |
577 } | 659 } |
578 // Could not find a static setter. Look for a field. | 660 // Could not find a static setter. Look for a field. |
579 // Access to a lazily initialized static field that has not yet been | 661 // Access to a lazily initialized static field that has not yet been |
580 // initialized is compiled to a static implicit getter. | 662 // initialized is compiled to a static implicit getter. |
581 // A setter may not exist for such a field. | 663 // A setter may not exist for such a field. |
582 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name())); | 664 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name_)); |
583 if (!field.IsNull()) { | 665 if (!field.IsNull()) { |
584 if (field.is_final()) { | 666 if (field.is_final()) { |
585 // Attempting to assign to a final variable will cause a NoSuchMethodError | 667 // Attempting to assign to a final variable will cause a NoSuchMethodError |
586 // to be thrown. Change static getter to non-existent static setter in | 668 // to be thrown. Change static getter to non-existent static setter in |
587 // order to trigger the throw at runtime. | 669 // order to trigger the throw at runtime. |
588 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 670 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
589 } | 671 } |
590 #if defined(DEBUG) | 672 #if defined(DEBUG) |
591 const String& getter_name = String::Handle(Field::GetterName(field_name())); | 673 const String& getter_name = String::Handle(Field::GetterName(field_name_)); |
592 const Function& getter = | 674 const Function& getter = |
593 Function::Handle(cls().LookupStaticFunction(getter_name)); | 675 Function::Handle(cls().LookupStaticFunction(getter_name)); |
594 ASSERT(!getter.IsNull() && | 676 ASSERT(!getter.IsNull() && |
595 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); | 677 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); |
596 #endif | 678 #endif |
597 if (Isolate::Current()->TypeChecksEnabled()) { | 679 if (Isolate::Current()->TypeChecksEnabled()) { |
598 rhs = new AssignableNode( | 680 rhs = new AssignableNode( |
599 field.token_pos(), | 681 field.token_pos(), |
600 rhs, | 682 rhs, |
601 AbstractType::ZoneHandle(field.type()), | 683 AbstractType::ZoneHandle(field.type()), |
602 String::ZoneHandle(field.name())); | 684 String::ZoneHandle(field.name())); |
603 } | 685 } |
604 return new StoreStaticFieldNode(token_pos(), field, rhs); | 686 return new StoreStaticFieldNode(token_pos(), field, rhs); |
605 } | 687 } |
606 // Didn't find a static setter or a static field. Make a call to | 688 // Didn't find a static setter or a static field. Make a call to |
607 // the non-existent setter to trigger a NoSuchMethodError at runtime. | 689 // the non-existent setter to trigger a NoSuchMethodError at runtime. |
608 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 690 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
609 } | 691 } |
610 | 692 |
611 | 693 |
612 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { | 694 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { |
613 // Return this node if it represents a 'throw NoSuchMethodError' indicating | 695 // Return this node if it represents a 'throw NoSuchMethodError' indicating |
614 // that a getter was not found, otherwise return null. | 696 // that a getter was not found, otherwise return null. |
615 const Class& cls = Class::Handle(function().Owner()); | 697 const Class& cls = Class::Handle(function().Owner()); |
616 const String& cls_name = String::Handle(cls.Name()); | 698 const String& cls_name = String::Handle(cls.Name()); |
617 const String& func_name = String::Handle(function().name()); | 699 const String& func_name = String::Handle(function().name()); |
618 if (cls_name.Equals(Symbols::NoSuchMethodError()) && | 700 if (cls_name.Equals(Symbols::NoSuchMethodError()) && |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
654 if (result.IsError() || result.IsNull()) { | 736 if (result.IsError() || result.IsNull()) { |
655 // TODO(turnidge): We could get better error messages by returning | 737 // TODO(turnidge): We could get better error messages by returning |
656 // the Error object directly to the parser. This will involve | 738 // the Error object directly to the parser. This will involve |
657 // replumbing all of the EvalConstExpr methods. | 739 // replumbing all of the EvalConstExpr methods. |
658 return NULL; | 740 return NULL; |
659 } | 741 } |
660 return &Instance::ZoneHandle(Instance::Cast(result).raw()); | 742 return &Instance::ZoneHandle(Instance::Cast(result).raw()); |
661 } | 743 } |
662 | 744 |
663 } // namespace dart | 745 } // namespace dart |
OLD | NEW |