Chromium Code Reviews| Index: pkg/compiler/lib/src/universe/world_builder.dart |
| diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart |
| index f7683986429ce451043d9a0e9b04ce2738e6bbe8..e25042fa47f9901528b8854bdca78f9723e6b011 100644 |
| --- a/pkg/compiler/lib/src/universe/world_builder.dart |
| +++ b/pkg/compiler/lib/src/universe/world_builder.dart |
| @@ -375,7 +375,11 @@ class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { |
| final Map<ClassElement, _ClassUsage> _processedClasses = |
| <ClassElement, _ClassUsage>{}; |
| - /// Map of registers usage of instance members of live classes. |
| + /// Map of registered usage of static members of live classes. |
| + final Map<Entity, _StaticMemberUsage> _staticMemberUsage = |
| + <Entity, _StaticMemberUsage>{}; |
| + |
| + /// Map of registered usage of instance members of live classes. |
| final Map<MemberEntity, _MemberUsage> _instanceMemberUsage = |
| <MemberEntity, _MemberUsage>{}; |
| @@ -690,35 +694,65 @@ class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { |
| return type; |
| } |
| - void registerStaticUse(StaticUse staticUse) { |
| + void registerStaticUse(StaticUse staticUse, MemberUsed memberUsed) { |
|
Harry Terkelsen
2016/12/07 21:02:00
Maybe rename this typedef to 'MemberUsedCallback'
Johnni Winther
2016/12/08 08:56:12
Done.
|
| Element element = staticUse.element; |
| + assert(invariant(element, element.isDeclaration, |
| + message: "Element ${element} is not the declaration.")); |
| + _StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () { |
| + if ((element.isStatic || element.isTopLevel) && element.isFunction) { |
| + return new _StaticFunctionUsage(element); |
| + } else { |
| + return new _GeneralStaticMemberUsage(element); |
| + } |
| + }); |
| + EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
| + |
| if (Elements.isStaticOrTopLevel(element) && element.isField) { |
| allReferencedStaticFields.add(element); |
| } |
| + // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and |
| + // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. |
| + // Also [CLOSURE] contains [LocalFunctionElement] which we cannot |
| + // enqueue. |
| switch (staticUse.kind) { |
| - case StaticUseKind.SUPER_FIELD_SET: |
| + case StaticUseKind.FIELD_GET: |
| + break; |
| case StaticUseKind.FIELD_SET: |
| fieldSetters.add(element); |
| break; |
| + case StaticUseKind.CLOSURE: |
| + LocalFunctionElement closure = staticUse.element; |
| + if (closure.type.containsTypeVariables) { |
| + closuresWithFreeTypeVariables.add(closure); |
| + } |
| + allClosures.add(element); |
| + break; |
| case StaticUseKind.SUPER_TEAR_OFF: |
| + useSet.addAll(usage.tearOff()); |
| methodsNeedingSuperGetter.add(element); |
| break; |
| + case StaticUseKind.SUPER_FIELD_SET: |
| + fieldSetters.add(element); |
| + useSet.addAll(usage.normalUse()); |
| + break; |
| + case StaticUseKind.STATIC_TEAR_OFF: |
| + useSet.addAll(usage.tearOff()); |
| + break; |
| case StaticUseKind.GENERAL: |
| case StaticUseKind.DIRECT_USE: |
| - case StaticUseKind.STATIC_TEAR_OFF: |
| - case StaticUseKind.FIELD_GET: |
| case StaticUseKind.CONSTRUCTOR_INVOKE: |
| case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| case StaticUseKind.REDIRECTION: |
| - break; |
| - case StaticUseKind.CLOSURE: |
| - allClosures.add(element); |
| + useSet.addAll(usage.normalUse()); |
| break; |
| case StaticUseKind.DIRECT_INVOKE: |
| invariant( |
| element, 'Direct static use is not supported for resolution.'); |
| break; |
| } |
| + if (useSet.isNotEmpty) { |
| + memberUsed(usage.entity, useSet); |
| + } |
| } |
| void forgetEntity(Entity entity, Compiler compiler) { |
| @@ -1449,3 +1483,51 @@ class ClassUses { |
| } |
| typedef void ClassUsed(ClassEntity cls, EnumSet<ClassUse> useSet); |
| + |
| +// TODO(johnniwinther): Merge this with [_MemberUsage]. |
| +abstract class _StaticMemberUsage extends _AbstractUsage<MemberUse> { |
| + final Entity entity; |
| + |
| + bool hasNormalUse = false; |
| + bool get hasClosurization => false; |
| + |
| + _StaticMemberUsage.internal(this.entity); |
| + |
| + EnumSet<MemberUse> normalUse() { |
| + if (hasNormalUse) { |
| + return MemberUses.NONE; |
| + } |
| + hasNormalUse = true; |
| + return _pendingUse.removeAll(MemberUses.NORMAL_ONLY); |
| + } |
| + |
| + EnumSet<MemberUse> tearOff(); |
| + |
| + @override |
| + EnumSet<MemberUse> get _originalUse => MemberUses.NORMAL_ONLY; |
| + |
| + String toString() => entity.toString(); |
| +} |
| + |
| +class _GeneralStaticMemberUsage extends _StaticMemberUsage { |
| + _GeneralStaticMemberUsage(Entity entity) : super.internal(entity); |
| + |
| + EnumSet<MemberUse> tearOff() => normalUse(); |
| +} |
| + |
| +class _StaticFunctionUsage extends _StaticMemberUsage { |
| + bool hasClosurization = false; |
| + |
| + _StaticFunctionUsage(Entity entity) : super.internal(entity); |
| + |
| + EnumSet<MemberUse> tearOff() { |
| + if (hasClosurization) { |
| + return MemberUses.NONE; |
| + } |
| + hasNormalUse = hasClosurization = true; |
| + return _pendingUse.removeAll(MemberUses.ALL); |
| + } |
| + |
| + @override |
| + EnumSet<MemberUse> get _originalUse => MemberUses.ALL; |
| +} |