| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 45315)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -3912,8 +3912,8 @@
|
| if (field->has_static && has_initializer) {
|
| class_field.set_value(init_value);
|
| if (!has_simple_literal) {
|
| - String& getter_name = String::Handle(Z,
|
| - Field::GetterSymbol(*field->name));
|
| + String& getter_name =
|
| + String::Handle(Z, Field::GetterSymbol(*field->name));
|
| getter = Function::New(getter_name,
|
| RawFunction::kImplicitStaticFinalGetter,
|
| field->has_static,
|
| @@ -3934,8 +3934,8 @@
|
|
|
| // For instance fields, we create implicit getter and setter methods.
|
| if (!field->has_static) {
|
| - String& getter_name = String::Handle(Z,
|
| - Field::GetterSymbol(*field->name));
|
| + String& getter_name =
|
| + String::Handle(Z, Field::GetterSymbol(*field->name));
|
| getter = Function::New(getter_name, RawFunction::kImplicitGetter,
|
| field->has_static,
|
| field->has_final,
|
| @@ -3953,8 +3953,8 @@
|
| members->AddFunction(getter);
|
| if (!field->has_final) {
|
| // Build a setter accessor for non-const fields.
|
| - String& setter_name = String::Handle(Z,
|
| - Field::SetterSymbol(*field->name));
|
| + String& setter_name =
|
| + String::Handle(Z, Field::SetterSymbol(*field->name));
|
| setter = Function::New(setter_name, RawFunction::kImplicitSetter,
|
| field->has_static,
|
| field->has_final,
|
| @@ -10529,7 +10529,8 @@
|
| static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) {
|
| if (expr->IsLoadStaticFieldNode()) {
|
| const Field& field = expr->AsLoadStaticFieldNode()->field();
|
| - if (field.is_const()) {
|
| + if (field.is_const() &&
|
| + !expr->AsLoadStaticFieldNode()->is_deferred_reference()) {
|
| ASSERT(field.value() != Object::sentinel().raw());
|
| ASSERT(field.value() != Object::transition_sentinel().raw());
|
| return new(zone) LiteralNode(expr->token_pos(),
|
| @@ -10898,24 +10899,17 @@
|
| }
|
|
|
|
|
| -AstNode* Parser::ParseStaticFieldAccess(const Class& cls,
|
| - const String& field_name,
|
| - intptr_t ident_pos,
|
| - bool consume_cascades) {
|
| - TRACE_PARSER("ParseStaticFieldAccess");
|
| +// Reference to 'field_name' with explicit class as primary.
|
| +AstNode* Parser::GenerateStaticFieldAccess(const Class& cls,
|
| + const String& field_name,
|
| + intptr_t ident_pos) {
|
| AstNode* access = NULL;
|
| const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name));
|
| Function& func = Function::ZoneHandle(Z);
|
| if (field.IsNull()) {
|
| // No field, check if we have an explicit getter function.
|
| - const String& getter_name =
|
| - String::ZoneHandle(Z, Field::GetterName(field_name));
|
| - const int kNumArguments = 0; // no arguments.
|
| - func = Resolver::ResolveStatic(cls,
|
| - getter_name,
|
| - kNumArguments,
|
| - Object::empty_array());
|
| - if (func.IsNull()) {
|
| + func = cls.LookupGetterFunction(field_name);
|
| + if (func.IsNull() || func.IsDynamicFunction()) {
|
| // We might be referring to an implicit closure, check to see if
|
| // there is a function of the same name.
|
| func = cls.LookupStaticFunction(field_name);
|
| @@ -11056,12 +11050,14 @@
|
| } else {
|
| // Field access.
|
| Class& cls = Class::Handle(Z);
|
| + bool is_deferred = false;
|
| if (left->IsPrimaryNode()) {
|
| PrimaryNode* primary_node = left->AsPrimaryNode();
|
| if (primary_node->primary().IsClass()) {
|
| // If the primary node referred to a class we are loading a
|
| // qualified static field.
|
| cls ^= primary_node->primary().raw();
|
| + is_deferred = primary_node->is_deferred_reference();
|
| }
|
| }
|
| if (cls.IsNull()) {
|
| @@ -11069,8 +11065,13 @@
|
| selector = CallGetter(ident_pos, left, *ident);
|
| } else {
|
| // Static field access.
|
| - selector =
|
| - ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade);
|
| + selector = GenerateStaticFieldAccess(cls, *ident, ident_pos);
|
| + ASSERT(selector != NULL);
|
| + if (selector->IsLoadStaticFieldNode()) {
|
| + selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred);
|
| + } else if (selector->IsStaticGetterNode()) {
|
| + selector->AsStaticGetterNode()->set_is_deferred(is_deferred);
|
| + }
|
| }
|
| }
|
| } else if (CurrentToken() == Token::kLBRACK) {
|
| @@ -11466,8 +11467,8 @@
|
| // If the field is already initialized, return no ast (NULL).
|
| // Otherwise, if the field is constant, initialize the field and return no ast.
|
| // If the field is not initialized and not const, return the ast for the getter.
|
| -AstNode* Parser::RunStaticFieldInitializer(const Field& field,
|
| - intptr_t field_ref_pos) {
|
| +StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field,
|
| + intptr_t field_ref_pos) {
|
| ASSERT(field.is_static());
|
| const Class& field_owner = Class::ZoneHandle(Z, field.owner());
|
| const String& field_name = String::ZoneHandle(Z, field.name());
|
| @@ -11752,16 +11753,22 @@
|
| } else if (obj.IsField()) {
|
| const Field& field = Field::Cast(obj);
|
| ASSERT(field.is_static());
|
| - return GenerateStaticFieldLookup(field, ident_pos);
|
| + AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos);
|
| + if (get_field->IsStaticGetterNode()) {
|
| + get_field->AsStaticGetterNode()->set_owner(library_);
|
| + }
|
| + return get_field;
|
| } else if (obj.IsFunction()) {
|
| const Function& func = Function::Cast(obj);
|
| ASSERT(func.is_static());
|
| if (func.IsGetterFunction() || func.IsSetterFunction()) {
|
| - return new(Z) StaticGetterNode(ident_pos,
|
| - /* receiver */ NULL,
|
| - Class::ZoneHandle(Z, func.Owner()),
|
| - ident);
|
| -
|
| + StaticGetterNode* getter =
|
| + new(Z) StaticGetterNode(ident_pos,
|
| + /* receiver */ NULL,
|
| + Class::ZoneHandle(Z, func.Owner()),
|
| + ident);
|
| + getter->set_owner(library_);
|
| + return getter;
|
| } else {
|
| return new(Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw()));
|
| }
|
| @@ -11796,7 +11803,7 @@
|
| // Private names are not exported by libraries. The name mangling
|
| // of private names with a library-specific suffix usually ensures
|
| // that _x in library A is not found when looked up from library B.
|
| - // In the pathological case where a library includes itself with
|
| + // In the pathological case where a library imports itself with
|
| // a prefix, the name mangling would not help in hiding the private
|
| // name, so we need to explicitly reject private names here.
|
| return NULL;
|
| @@ -11833,6 +11840,7 @@
|
| get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred);
|
| } else if (get_field->IsStaticGetterNode()) {
|
| get_field->AsStaticGetterNode()->set_is_deferred(is_deferred);
|
| + get_field->AsStaticGetterNode()->set_owner(prefix);
|
| }
|
| return get_field;
|
| } else if (obj.IsFunction()) {
|
| @@ -11840,11 +11848,12 @@
|
| ASSERT(func.is_static());
|
| if (func.IsGetterFunction() || func.IsSetterFunction()) {
|
| StaticGetterNode* getter = new(Z) StaticGetterNode(
|
| - ident_pos,
|
| - /* receiver */ NULL,
|
| - Class::ZoneHandle(Z, func.Owner()),
|
| - ident);
|
| + ident_pos,
|
| + /* receiver */ NULL,
|
| + Class::ZoneHandle(Z, func.Owner()),
|
| + ident);
|
| getter->set_is_deferred(is_deferred);
|
| + getter->set_owner(prefix);
|
| return getter;
|
| } else {
|
| PrimaryNode* primary = new(Z) PrimaryNode(
|
|
|