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 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 } | 552 } |
553 | 553 |
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 const String& setter_name = String::Handle(Field::SetterName(field_name())); | 562 if (is_super_getter()) { |
563 | |
564 if (is_super_getter_) { | |
565 ASSERT(receiver() != NULL); | 563 ASSERT(receiver() != NULL); |
566 // If the static setter is not found in the superclass, noSuchMethod will be | 564 // If the static setter is not found in the superclass, noSuchMethod will be |
567 // called at runtime. | 565 // called at runtime. |
568 return new StaticSetterNode(token_pos(), | 566 return new StaticSetterNode(token_pos(), |
569 receiver(), | 567 receiver(), |
570 cls(), | 568 cls(), |
571 field_name(), | 569 field_name(), |
572 rhs); | 570 rhs); |
573 } | 571 } |
| 572 |
574 const Function& setter = | 573 const Function& setter = |
575 Function::ZoneHandle(cls().LookupStaticFunction(setter_name)); | 574 Function::Handle(cls().LookupSetterFunction(field_name())); |
576 if (!setter.IsNull()) { | 575 if (!setter.IsNull() && setter.IsStaticFunction()) { |
577 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 576 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); |
578 } | 577 } |
579 // Could not find a static setter. Look for a field. | 578 // Could not find a static setter. Look for a field. |
580 // Access to a lazily initialized static field that has not yet been | 579 // Access to a lazily initialized static field that has not yet been |
581 // initialized is compiled to a static implicit getter. | 580 // initialized is compiled to a static implicit getter. |
582 // A setter may not exist for such a field. | 581 // A setter may not exist for such a field. |
583 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name())); | 582 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name())); |
584 if (!field.IsNull()) { | 583 if (!field.IsNull()) { |
585 if (field.is_final()) { | 584 if (field.is_final()) { |
586 // Attempting to assign to a final variable will cause a NoSuchMethodError | 585 // Attempting to assign to a final variable will cause a NoSuchMethodError |
(...skipping 10 matching lines...) Expand all Loading... |
597 #endif | 596 #endif |
598 if (Isolate::Current()->TypeChecksEnabled()) { | 597 if (Isolate::Current()->TypeChecksEnabled()) { |
599 rhs = new AssignableNode( | 598 rhs = new AssignableNode( |
600 field.token_pos(), | 599 field.token_pos(), |
601 rhs, | 600 rhs, |
602 AbstractType::ZoneHandle(field.type()), | 601 AbstractType::ZoneHandle(field.type()), |
603 String::ZoneHandle(field.name())); | 602 String::ZoneHandle(field.name())); |
604 } | 603 } |
605 return new StoreStaticFieldNode(token_pos(), field, rhs); | 604 return new StoreStaticFieldNode(token_pos(), field, rhs); |
606 } | 605 } |
607 // Didn't find a static setter or a static field. | 606 // Didn't find a static setter or a static field. Make a call to |
608 // If this static getter is in an instance function where | 607 // the non-existent setter to trigger a NoSuchMethodError at runtime. |
609 // a receiver is available, we turn this static getter | |
610 // into an instance setter (and will get an error at runtime if an | |
611 // instance setter cannot be found either). | |
612 if (receiver() != NULL) { | |
613 return new InstanceSetterNode(token_pos(), receiver(), field_name(), rhs); | |
614 } | |
615 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 608 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); |
616 } | 609 } |
617 | 610 |
618 | 611 |
619 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { | 612 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { |
620 // Return this node if it represents a 'throw NoSuchMethodError' indicating | 613 // Return this node if it represents a 'throw NoSuchMethodError' indicating |
621 // that a getter was not found, otherwise return null. | 614 // that a getter was not found, otherwise return null. |
622 const Class& cls = Class::Handle(function().Owner()); | 615 const Class& cls = Class::Handle(function().Owner()); |
623 const String& cls_name = String::Handle(cls.Name()); | 616 const String& cls_name = String::Handle(cls.Name()); |
624 const String& func_name = String::Handle(function().name()); | 617 const String& func_name = String::Handle(function().name()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 if (result.IsError() || result.IsNull()) { | 654 if (result.IsError() || result.IsNull()) { |
662 // TODO(turnidge): We could get better error messages by returning | 655 // TODO(turnidge): We could get better error messages by returning |
663 // the Error object directly to the parser. This will involve | 656 // the Error object directly to the parser. This will involve |
664 // replumbing all of the EvalConstExpr methods. | 657 // replumbing all of the EvalConstExpr methods. |
665 return NULL; | 658 return NULL; |
666 } | 659 } |
667 return &Instance::ZoneHandle(Instance::Cast(result).raw()); | 660 return &Instance::ZoneHandle(Instance::Cast(result).raw()); |
668 } | 661 } |
669 | 662 |
670 } // namespace dart | 663 } // namespace dart |
OLD | NEW |