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; |
+} |