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