| 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..495988f49dfbb515b0019fe7791e4cd279f8ed8f 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>{};
|
|
|
| @@ -619,7 +623,8 @@ class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
|
| return _hasMatchingSelector(_invokedSetters[member.name], member);
|
| }
|
|
|
| - void registerDynamicUse(DynamicUse dynamicUse, MemberUsed memberUsed) {
|
| + void registerDynamicUse(
|
| + DynamicUse dynamicUse, MemberUsedCallback memberUsed) {
|
| Selector selector = dynamicUse.selector;
|
| String methodName = selector.name;
|
| switch (dynamicUse.kind) {
|
| @@ -690,35 +695,65 @@ class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
|
| return type;
|
| }
|
|
|
| - void registerStaticUse(StaticUse staticUse) {
|
| + void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) {
|
| 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) {
|
| @@ -780,7 +815,7 @@ class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
|
|
|
| /// Computes usage for all members declared by [cls]. Calls [membersUsed] with
|
| /// the usage changes for each member.
|
| - void processClassMembers(ClassElement cls, MemberUsed memberUsed) {
|
| + void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) {
|
| cls.implementation.forEachMember((ClassElement cls, MemberElement member) {
|
| _processInstantiatedClassMember(cls, member, memberUsed);
|
| });
|
| @@ -814,7 +849,7 @@ class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
|
| }
|
|
|
| void _processInstantiatedClassMember(
|
| - ClassElement cls, MemberElement member, MemberUsed memberUsed) {
|
| + ClassElement cls, MemberElement member, MemberUsedCallback memberUsed) {
|
| assert(invariant(member, member.isDeclaration));
|
| if (!member.isInstanceMember) return;
|
| String memberName = member.name;
|
| @@ -1401,7 +1436,7 @@ class MemberUses {
|
| static const EnumSet<MemberUse> ALL = const EnumSet<MemberUse>.fixed(3);
|
| }
|
|
|
| -typedef void MemberUsed(MemberEntity member, EnumSet<MemberUse> useSet);
|
| +typedef void MemberUsedCallback(MemberEntity member, EnumSet<MemberUse> useSet);
|
|
|
| /// Registry for the observed use of a class [entity] in the open world.
|
| // TODO(johnniwinther): Merge this with [InstantiationInfo].
|
| @@ -1449,3 +1484,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;
|
| +}
|
|
|