Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: pkg/compiler/lib/src/enqueue.dart

Issue 2543753004: Move processing of instance members from ResolutionEnqueuer to ResolutionWorldBuilderImpl (Closed)
Patch Set: Updated cf. comments. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/elements/entities.dart ('k') | pkg/compiler/lib/src/js_backend/enqueuer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/enqueue.dart
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 79d2ffd5d18a73cfec82255c249b685023b461c2..852fa0e2519c28ab22a09e0449619b54cab55891 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -25,18 +25,18 @@ import 'elements/elements.dart'
ConstructorElement,
Element,
Entity,
- FunctionElement,
LibraryElement,
LocalFunctionElement,
- TypedElement;
+ MemberElement;
+import 'elements/entities.dart';
import 'native/native.dart' as native;
import 'types/types.dart' show TypeMaskStrategy;
-import 'universe/selector.dart' show Selector;
import 'universe/world_builder.dart';
import 'universe/use.dart'
show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
import 'universe/world_impact.dart'
show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor;
+import 'util/enumset.dart';
import 'util/util.dart' show Setlet;
import 'world.dart' show OpenWorld;
@@ -122,7 +122,7 @@ abstract class Enqueuer {
abstract class EnqueuerImpl extends Enqueuer {
CompilerTask get task;
EnqueuerStrategy get strategy;
- void processInstantiatedClassMember(ClassElement cls, Element member);
+ void checkClass(ClassElement cls);
void processStaticUse(StaticUse staticUse);
void processTypeUse(TypeUse typeUse);
void processDynamicUse(DynamicUse dynamicUse);
@@ -143,10 +143,6 @@ class ResolutionEnqueuer extends EnqueuerImpl {
final native.NativeEnqueuer nativeEnqueuer;
final EnqueuerStrategy strategy;
- final Map<String, Set<Element>> _instanceMembersByName =
- new Map<String, Set<Element>>();
- final Map<String, Set<Element>> _instanceFunctionsByName =
- new Map<String, Set<Element>>();
final Set<ClassElement> _processedClasses = new Set<ClassElement>();
Set<ClassElement> _recentClasses = new Setlet<ClassElement>();
final ResolutionWorldBuilderImpl _universe;
@@ -167,18 +163,18 @@ class ResolutionEnqueuer extends EnqueuerImpl {
ResolutionEnqueuer(
this.task,
this._options,
- this._resolution,
+ Resolution resolution,
this.strategy,
this._globalDependencies,
Backend backend,
- CommonElements commonElements,
+ this._commonElements,
CacheStrategy cacheStrategy,
[this.name = 'resolution enqueuer'])
: this.backend = backend,
- this._commonElements = commonElements,
+ this._resolution = resolution,
this.nativeEnqueuer = backend.nativeResolutionEnqueuer(),
_universe = new ResolutionWorldBuilderImpl(
- backend, commonElements, cacheStrategy, const TypeMaskStrategy()) {
+ backend, resolution, cacheStrategy, const TypeMaskStrategy()) {
_impactVisitor = new EnqueuerImplImpactVisitor(this);
}
@@ -233,94 +229,42 @@ class ResolutionEnqueuer extends EnqueuerImpl {
return strategy.checkEnqueuerConsistency(this);
}
- void processInstantiatedClassMember(ClassElement cls, Element member) {
- assert(invariant(member, member.isDeclaration));
- if (isProcessed(member)) return;
- if (!member.isInstanceMember) return;
- String memberName = member.name;
-
- if (member.isField) {
- // The obvious thing to test here would be "member.isNative",
- // however, that only works after metadata has been parsed/analyzed,
- // and that may not have happened yet.
- // So instead we use the enclosing class, which we know have had
- // its metadata parsed and analyzed.
- // Note: this assumes that there are no non-native fields on native
- // classes, which may not be the case when a native class is subclassed.
- if (backend.isNative(cls)) {
- _openWorld.registerUsedElement(member);
- if (_universe.hasInvokedGetter(member, _openWorld) ||
- _universe.hasInvocation(member, _openWorld)) {
- _addToWorkList(member);
- return;
- }
- if (_universe.hasInvokedSetter(member, _openWorld)) {
- _addToWorkList(member);
- return;
- }
- // Native fields need to go into instanceMembersByName as they
- // are virtual instantiation points and escape points.
- } else {
- // All field initializers must be resolved as they could
- // have an observable side-effect (and cannot be tree-shaken
- // away).
- _addToWorkList(member);
- return;
+ void checkClass(ClassElement cls) {
+ _processClassMembers(cls,
+ (MemberElement member, EnumSet<MemberUse> useSet) {
+ if (useSet.isNotEmpty) {
+ _reporter.internalError(member,
+ 'Unenqueued use of $member: ${useSet.iterable(MemberUse.values)}');
}
- } else if (member.isFunction) {
- FunctionElement function = member;
- function.computeType(_resolution);
+ });
+ }
+
+ /// Callback for applying the first seen use of a [member].
+ void _applyFirstUse(MemberElement member, EnumSet<MemberUse> useSet) {
+ ClassElement cls = member.enclosingClass;
+ if (member.isFunction) {
+ MemberElement function = member;
if (function.name == Identifiers.noSuchMethod_) {
_registerNoSuchMethod(function);
}
if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
_registerCallMethodWithFreeTypeVariables(function);
}
- // If there is a property access with the same name as a method we
- // need to emit the method.
- if (_universe.hasInvokedGetter(function, _openWorld)) {
- _registerClosurizedMember(function);
- _addToWorkList(function);
- return;
- }
- // Store the member in [instanceFunctionsByName] to catch
- // getters on the function.
- _instanceFunctionsByName
- .putIfAbsent(memberName, () => new Set<Element>())
- .add(member);
- if (_universe.hasInvocation(function, _openWorld)) {
- _addToWorkList(function);
- return;
- }
- } else if (member.isGetter) {
- FunctionElement getter = member;
- getter.computeType(_resolution);
- if (_universe.hasInvokedGetter(getter, _openWorld)) {
- _addToWorkList(getter);
- return;
- }
- // We don't know what selectors the returned closure accepts. If
- // the set contains any selector we have to assume that it matches.
- if (_universe.hasInvocation(getter, _openWorld)) {
- _addToWorkList(getter);
- return;
- }
- } else if (member.isSetter) {
- FunctionElement setter = member;
- setter.computeType(_resolution);
- if (_universe.hasInvokedSetter(setter, _openWorld)) {
- _addToWorkList(setter);
- return;
- }
}
+ _applyUse(member, useSet);
+ }
- // The element is not yet used. Add it to the list of instance
- // members to still be processed.
- _instanceMembersByName
- .putIfAbsent(memberName, () => new Set<Element>())
- .add(member);
+ /// Callback for applying the use of a [member].
+ void _applyUse(Entity member, EnumSet<MemberUse> useSet) {
+ if (useSet.contains(MemberUse.NORMAL)) {
+ _addToWorkList(member);
+ }
+ if (useSet.contains(MemberUse.CLOSURIZE)) {
+ _registerClosurizedMember(member);
+ }
}
+ /// TODO(johnniwinther): Move this to [ResolutionWorldBuilderImpl].
void _processInstantiatedClass(ClassElement cls) {
task.measure(() {
if (_processedClasses.contains(cls)) return;
@@ -334,7 +278,7 @@ class ResolutionEnqueuer extends EnqueuerImpl {
_processedClasses.add(superclass);
_recentClasses.add(superclass);
superclass.ensureResolved(_resolution);
- superclass.implementation.forEachMember(processInstantiatedClassMember);
+ _processClassMembers(superclass, _applyFirstUse);
_resolution.ensureClassMembers(superclass);
// We only tell the backend once that [superclass] was instantiated, so
// any additional dependencies must be treated as global
@@ -351,59 +295,17 @@ class ResolutionEnqueuer extends EnqueuerImpl {
});
}
- void processDynamicUse(DynamicUse dynamicUse) {
- task.measure(() {
- if (_universe.registerDynamicUse(dynamicUse)) {
- _handleUnseenSelector(dynamicUse);
- }
+ /// TODO(johnniwinther): Move this to [ResolutionWorldBuilderImpl].
+ void _processClassMembers(ClassElement cls, MemberUsed memberUsed) {
+ cls.implementation.forEachMember((ClassElement cls, MemberElement member) {
+ _universe.processInstantiatedClassMember(cls, member, memberUsed);
});
}
- void _processSet(
- Map<String, Set<Element>> map, String memberName, bool f(Element e)) {
- Set<Element> members = map[memberName];
- if (members == null) return;
- // [f] might add elements to [: map[memberName] :] during the loop below
- // so we create a new list for [: map[memberName] :] and prepend the
- // [remaining] members after the loop.
- map[memberName] = new Set<Element>();
- Set<Element> remaining = new Set<Element>();
- for (Element member in members) {
- if (!f(member)) remaining.add(member);
- }
- map[memberName].addAll(remaining);
- }
-
- void _processInstanceMembers(String n, bool f(Element e)) {
- _processSet(_instanceMembersByName, n, f);
- }
-
- void _processInstanceFunctions(String n, bool f(Element e)) {
- _processSet(_instanceFunctionsByName, n, f);
- }
-
- void _handleUnseenSelector(DynamicUse dynamicUse) {
- Selector selector = dynamicUse.selector;
- String methodName = selector.name;
- _processInstanceMembers(methodName, (Element member) {
- if (dynamicUse.appliesUnnamed(member, _openWorld)) {
- if (member.isFunction && selector.isGetter) {
- _registerClosurizedMember(member);
- }
- _addToWorkList(member);
- return true;
- }
- return false;
+ void processDynamicUse(DynamicUse dynamicUse) {
+ task.measure(() {
+ _universe.registerDynamicUse(dynamicUse, _applyUse);
});
- if (selector.isGetter) {
- _processInstanceFunctions(methodName, (Element member) {
- if (dynamicUse.appliesUnnamed(member, _openWorld)) {
- _registerClosurizedMember(member);
- return true;
- }
- return false;
- });
- }
}
void processStaticUse(StaticUse staticUse) {
@@ -499,9 +401,9 @@ class ResolutionEnqueuer extends EnqueuerImpl {
_universe.callMethodsWithFreeTypeVariables.add(element);
}
- void _registerClosurizedMember(TypedElement element) {
+ void _registerClosurizedMember(MemberElement element) {
assert(element.isInstanceMember);
- if (element.computeType(_resolution).containsTypeVariables) {
+ if (element.type.containsTypeVariables) {
applyImpact(backend.registerClosureWithFreeTypeVariables(element,
forResolution: true));
_universe.closuresWithFreeTypeVariables.add(element);
@@ -656,8 +558,6 @@ class ResolutionEnqueuer extends EnqueuerImpl {
void forgetElement(Element element, Compiler compiler) {
_universe.forgetElement(element, compiler);
_processedClasses.remove(element);
- _instanceMembersByName[element.name]?.remove(element);
- _instanceFunctionsByName[element.name]?.remove(element);
processedElements.remove(element);
}
}
@@ -728,8 +628,7 @@ class TreeShakingEnqueuerStrategy extends EnqueuerStrategy {
for (ClassElement currentClass = classElement;
currentClass != null;
currentClass = currentClass.superclass) {
- currentClass.implementation
- .forEachMember(enqueuer.processInstantiatedClassMember);
+ enqueuer.checkClass(currentClass);
}
}
});
« no previous file with comments | « pkg/compiler/lib/src/elements/entities.dart ('k') | pkg/compiler/lib/src/js_backend/enqueuer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698