| Index: pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
|
| index 92cfbd7241f4404edbae666d5028734ffbac59dc..ab310f8b156453223d43d862409e80c58c097f53 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
|
| @@ -27,14 +27,21 @@ typedef void AcceptField(FieldEntity member, js.Name name, js.Name accessorName,
|
|
|
| class FieldVisitor {
|
| final CompilerOptions _options;
|
| + final ElementEnvironment _elementEnvironment;
|
| final CodegenWorldBuilder _codegenWorldBuilder;
|
| final NativeData _nativeData;
|
| final MirrorsData _mirrorsData;
|
| final Namer _namer;
|
| final ClosedWorld _closedWorld;
|
|
|
| - FieldVisitor(this._options, this._codegenWorldBuilder, this._nativeData,
|
| - this._mirrorsData, this._namer, this._closedWorld);
|
| + FieldVisitor(
|
| + this._options,
|
| + this._elementEnvironment,
|
| + this._codegenWorldBuilder,
|
| + this._nativeData,
|
| + this._mirrorsData,
|
| + this._namer,
|
| + this._closedWorld);
|
|
|
| /**
|
| * Invokes [f] for each of the fields of [element].
|
| @@ -52,33 +59,35 @@ class FieldVisitor {
|
| *
|
| * Invariant: [element] must be a declaration element.
|
| */
|
| - void visitFields(Element element, bool visitStatics, AcceptField f) {
|
| - assert(element.isDeclaration, failedAt(element));
|
| + void visitFields(AcceptField f,
|
| + {bool visitStatics: false, LibraryEntity library, ClassEntity cls}) {
|
| + assert(!(library is LibraryElement && !library.isDeclaration),
|
| + failedAt(library));
|
| + assert(!(cls is ClassElement && !cls.isDeclaration), failedAt(cls));
|
|
|
| - ClassElement cls;
|
| bool isNativeClass = false;
|
| bool isLibrary = false;
|
| bool isInstantiated = false;
|
| - if (element.isClass) {
|
| - cls = element;
|
| + if (cls != null) {
|
| isNativeClass = _nativeData.isNativeClass(cls);
|
|
|
| // If the class is never instantiated we still need to set it up for
|
| // inheritance purposes, but we can simplify its JavaScript constructor.
|
| isInstantiated =
|
| _codegenWorldBuilder.directlyInstantiatedClasses.contains(cls);
|
| - } else if (element.isLibrary) {
|
| + } else if (library != null) {
|
| isLibrary = true;
|
| - assert(visitStatics, failedAt(element));
|
| + assert(visitStatics, failedAt(library));
|
| } else {
|
| - throw new SpannableAssertionFailure(
|
| - element, 'Expected a ClassElement or a LibraryElement.');
|
| + throw new SpannableAssertionFailure(NO_LOCATION_SPANNABLE,
|
| + 'Expected a ClassElement or a LibraryElement.');
|
| }
|
|
|
| - void visitField(Element holder, FieldElement field) {
|
| - assert(field.isDeclaration, failedAt(element));
|
| + void visitField(FieldElement field, {ClassEntity holder}) {
|
| + assert(field.isDeclaration, failedAt(field));
|
|
|
| - bool isMixinNativeField = isNativeClass && holder.isMixinApplication;
|
| + bool isMixinNativeField = isNativeClass &&
|
| + _elementEnvironment.isUnnamedMixinApplication(holder);
|
|
|
| // See if we can dynamically create getters and setters.
|
| // We can only generate getters and setters for [element] since
|
| @@ -86,7 +95,7 @@ class FieldVisitor {
|
| // setters.
|
| bool needsGetter = false;
|
| bool needsSetter = false;
|
| - if (isLibrary || isMixinNativeField || holder == element) {
|
| + if (isLibrary || isMixinNativeField || holder == cls) {
|
| needsGetter = fieldNeedsGetter(field);
|
| needsSetter = fieldNeedsSetter(field);
|
| }
|
| @@ -110,12 +119,16 @@ class FieldVisitor {
|
| }
|
|
|
| if (isLibrary) {
|
| - LibraryElement library = element;
|
| - library.implementation.forEachLocalMember((Element member) {
|
| - if (member.isField) visitField(library, member);
|
| + _elementEnvironment.forEachLibraryMember(library, (MemberEntity member) {
|
| + if (member.isField) visitField(member);
|
| });
|
| } else if (visitStatics) {
|
| - cls.implementation.forEachStaticField(visitField);
|
| + _elementEnvironment.forEachClassMember(cls,
|
| + (ClassEntity holder, MemberEntity member) {
|
| + if (cls == holder && member.isField && member.isStatic) {
|
| + visitField(member, holder: holder);
|
| + }
|
| + });
|
| } else {
|
| // TODO(kasperl): We should make sure to only emit one version of
|
| // overridden fields. Right now, we rely on the ordering so the
|
| @@ -126,8 +139,13 @@ class FieldVisitor {
|
| // generate the field getter/setter dynamically. Since this is only
|
| // allowed on fields that are in [element] we don't need to visit
|
| // superclasses for non-instantiated classes.
|
| - cls.implementation.forEachInstanceField(visitField,
|
| - includeSuperAndInjectedMembers: isInstantiated);
|
| + _elementEnvironment.forEachClassMember(cls,
|
| + (ClassEntity holder, MemberEntity member) {
|
| + if (cls != holder && !isInstantiated) return;
|
| + if (member.isField && !member.isStatic) {
|
| + visitField(member, holder: holder);
|
| + }
|
| + });
|
| }
|
| }
|
|
|
|
|