| Index: runtime/vm/ast.cc
|
| ===================================================================
|
| --- runtime/vm/ast.cc (revision 10409)
|
| +++ runtime/vm/ast.cc (working copy)
|
| @@ -7,6 +7,7 @@
|
| #include "vm/dart_entry.h"
|
| #include "vm/isolate.h"
|
| #include "vm/object_store.h"
|
| +#include "vm/resolver.h"
|
|
|
|
|
| namespace dart {
|
| @@ -320,36 +321,59 @@
|
|
|
|
|
| AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
|
| - // If no setter exist, set the field directly.
|
| const String& setter_name = String::Handle(Field::SetterName(field_name()));
|
| - const Function& setter =
|
| - Function::ZoneHandle(cls().LookupStaticFunction(setter_name));
|
| - if (setter.IsNull()) {
|
| - const Field& field = Field::ZoneHandle(
|
| - cls().LookupStaticField(field_name()));
|
| - if (field.IsNull()) {
|
| - // A static getter is declared, but no setter and no field.
|
| - if (receiver() != NULL) {
|
| - return new InstanceSetterNode(token_pos(),
|
| - receiver(),
|
| - field_name(),
|
| - rhs);
|
| - }
|
| - return NULL;
|
| +
|
| + if (is_super_getter_) {
|
| + // Resolve the (dynamic) setter method.
|
| + ASSERT(receiver() != NULL);
|
| + const Function& super_setter = Function::ZoneHandle(
|
| + Resolver::ResolveDynamicAnyArgs(cls(), setter_name));
|
| + if (!super_setter.IsNull()) {
|
| + return new StaticSetterNode(token_pos(),
|
| + receiver(),
|
| + cls(),
|
| + field_name(),
|
| + rhs);
|
| }
|
| + // If setter is found in the superclass, do not turn this into an
|
| + // instance setter resolved at runtime, since a super getter/setter
|
| + // explicitly refers to the static superclass of the enclosing function.
|
| + return NULL;
|
| + } else {
|
| + const Function& setter =
|
| + Function::ZoneHandle(cls().LookupStaticFunction(setter_name));
|
| + if (!setter.IsNull()) {
|
| + return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs);
|
| + }
|
| + // Could not find a static setter. Look for a field.
|
| // Access to a lazily initialized static field that has not yet been
|
| // initialized is compiled to a static implicit getter.
|
| // A setter may not exist for such a field.
|
| + const Field& field =
|
| + Field::ZoneHandle(cls().LookupStaticField(field_name()));
|
| + if (!field.IsNull()) {
|
| #if defined(DEBUG)
|
| - const String& getter_name = String::Handle(Field::GetterName(field_name()));
|
| - const Function& getter =
|
| - Function::ZoneHandle(cls().LookupStaticFunction(getter_name));
|
| - ASSERT(!getter.IsNull() &&
|
| - (getter.kind() == RawFunction::kConstImplicitGetter));
|
| + const String& getter_name =
|
| + String::Handle(Field::GetterName(field_name()));
|
| + const Function& getter =
|
| + Function::ZoneHandle(cls().LookupStaticFunction(getter_name));
|
| + ASSERT(!getter.IsNull() &&
|
| + (getter.kind() == RawFunction::kConstImplicitGetter));
|
| #endif
|
| - return new StoreStaticFieldNode(token_pos(), field, rhs);
|
| - } else {
|
| - return new StaticSetterNode(token_pos(), cls(), field_name(), rhs);
|
| + return new StoreStaticFieldNode(token_pos(), field, rhs);
|
| + }
|
| + // Didn't find a static setter or a static field.
|
| + // If this static getter is in an instance function where
|
| + // a receiver is available, we turn this static getter
|
| + // into an instance setter (and will get an error at runtime if an
|
| + // instance setter cannot be found either).
|
| + if (receiver() != NULL) {
|
| + return new InstanceSetterNode(token_pos(),
|
| + receiver(),
|
| + field_name(),
|
| + rhs);
|
| + }
|
| + return NULL;
|
| }
|
| }
|
|
|
|
|