Index: pkg/compiler/lib/src/enqueue.dart |
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart |
index 38c02bf9d235533193f90615711ffc7ad57cc5fd..ff3c21c35f92ca5b897bb6600fbe7542832af69a 100644 |
--- a/pkg/compiler/lib/src/enqueue.dart |
+++ b/pkg/compiler/lib/src/enqueue.dart |
@@ -4,66 +4,44 @@ |
library dart2js.enqueue; |
-import 'dart:collection' show |
- Queue; |
+import 'dart:collection' show Queue; |
import 'common.dart'; |
-import 'common/names.dart' show |
- Identifiers; |
-import 'common/resolution.dart' show |
- Resolution; |
-import 'common/work.dart' show |
- ItemCompilationContext, |
- WorkItem; |
-import 'common/tasks.dart' show |
- CompilerTask, |
- DeferredAction, |
- DeferredTask; |
-import 'common/codegen.dart' show |
- CodegenWorkItem; |
-import 'common/resolution.dart' show |
- ResolutionWorkItem; |
-import 'compiler.dart' show |
- Compiler; |
-import 'dart_types.dart' show |
- DartType, |
- InterfaceType; |
-import 'elements/elements.dart' show |
- AnalyzableElement, |
- AstElement, |
- ClassElement, |
- ConstructorElement, |
- Element, |
- Elements, |
- FunctionElement, |
- LibraryElement, |
- LocalFunctionElement, |
- Member, |
- MemberElement, |
- MethodElement, |
- Name, |
- TypedElement, |
- TypedefElement; |
+import 'common/names.dart' show Identifiers; |
+import 'common/resolution.dart' show Resolution; |
+import 'common/work.dart' show ItemCompilationContext, WorkItem; |
+import 'common/tasks.dart' show CompilerTask, DeferredAction, DeferredTask; |
+import 'common/codegen.dart' show CodegenWorkItem; |
+import 'common/resolution.dart' show ResolutionWorkItem; |
+import 'compiler.dart' show Compiler; |
+import 'dart_types.dart' show DartType, InterfaceType; |
+import 'elements/elements.dart' |
+ show |
+ AnalyzableElement, |
+ AstElement, |
+ ClassElement, |
+ ConstructorElement, |
+ Element, |
+ Elements, |
+ FunctionElement, |
+ LibraryElement, |
+ LocalFunctionElement, |
+ Member, |
+ MemberElement, |
+ MethodElement, |
+ Name, |
+ TypedElement, |
+ TypedefElement; |
import 'js/js.dart' as js; |
import 'native/native.dart' as native; |
-import 'types/types.dart' show |
- TypeMaskStrategy; |
-import 'universe/selector.dart' show |
- Selector; |
+import 'types/types.dart' show TypeMaskStrategy; |
+import 'universe/selector.dart' show Selector; |
import 'universe/universe.dart'; |
-import 'universe/use.dart' show |
- DynamicUse, |
- StaticUse, |
- StaticUseKind, |
- TypeUse, |
- TypeUseKind; |
-import 'universe/world_impact.dart' show |
- ImpactUseCase, |
- WorldImpact, |
- WorldImpactVisitor; |
-import 'util/util.dart' show |
- Link, |
- Setlet; |
+import 'universe/use.dart' |
+ show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
+import 'universe/world_impact.dart' |
+ show ImpactUseCase, WorldImpact, WorldImpactVisitor; |
+import 'util/util.dart' show Link, Setlet; |
typedef ItemCompilationContext ItemCompilationContextCreator(); |
@@ -74,14 +52,17 @@ class EnqueueTask extends CompilerTask { |
String get name => 'Enqueue'; |
EnqueueTask(Compiler compiler) |
- : resolution = new ResolutionEnqueuer( |
- compiler, compiler.backend.createItemCompilationContext, |
- compiler.options.analyzeOnly && compiler.options.analyzeMain |
- ? const EnqueuerStrategy() : const TreeShakingEnqueuerStrategy()), |
- codegen = new CodegenEnqueuer( |
- compiler, compiler.backend.createItemCompilationContext, |
- const TreeShakingEnqueuerStrategy()), |
- super(compiler) { |
+ : resolution = new ResolutionEnqueuer( |
+ compiler, |
+ compiler.backend.createItemCompilationContext, |
+ compiler.options.analyzeOnly && compiler.options.analyzeMain |
+ ? const EnqueuerStrategy() |
+ : const TreeShakingEnqueuerStrategy()), |
+ codegen = new CodegenEnqueuer( |
+ compiler, |
+ compiler.backend.createItemCompilationContext, |
+ const TreeShakingEnqueuerStrategy()), |
+ super(compiler) { |
codegen.task = this; |
resolution.task = this; |
@@ -101,10 +82,10 @@ abstract class Enqueuer { |
final Compiler compiler; // TODO(ahe): Remove this dependency. |
final EnqueuerStrategy strategy; |
final ItemCompilationContextCreator itemCompilationContextCreator; |
- final Map<String, Set<Element>> instanceMembersByName |
- = new Map<String, Set<Element>>(); |
- final Map<String, Set<Element>> instanceFunctionsByName |
- = new Map<String, Set<Element>>(); |
+ 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 Universe universe = new Universe(const TypeMaskStrategy()); |
@@ -114,17 +95,15 @@ abstract class Enqueuer { |
bool queueIsClosed = false; |
EnqueueTask task; |
- native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
+ native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
bool hasEnqueuedReflectiveElements = false; |
bool hasEnqueuedReflectiveStaticFields = false; |
WorldImpactVisitor impactVisitor; |
- Enqueuer(this.name, |
- this.compiler, |
- this.itemCompilationContextCreator, |
- this.strategy) { |
+ Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator, |
+ this.strategy) { |
impactVisitor = new _EnqueuerImpactVisitor(this); |
} |
@@ -160,8 +139,8 @@ abstract class Enqueuer { |
if (internalAddToWorkList(element) && compiler.options.dumpInfo) { |
// TODO(sigmund): add other missing dependencies (internals, selectors |
// enqueued after allocations), also enable only for the codegen enqueuer. |
- compiler.dumpInfoTask.registerDependency( |
- compiler.currentElement, element); |
+ compiler.dumpInfoTask |
+ .registerDependency(compiler.currentElement, element); |
} |
} |
@@ -174,23 +153,20 @@ abstract class Enqueuer { |
/// Apply the [worldImpact] of processing [element] to this enqueuer. |
void applyImpact(Element element, WorldImpact worldImpact) { |
- compiler.impactStrategy.visitImpact( |
- element, worldImpact, impactVisitor, impactUse); |
+ compiler.impactStrategy |
+ .visitImpact(element, worldImpact, impactVisitor, impactUse); |
} |
- void registerInstantiatedType(InterfaceType type, |
- {bool mirrorUsage: false}) { |
+ void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { |
task.measure(() { |
ClassElement cls = type.element; |
cls.ensureResolved(resolution); |
bool isNative = compiler.backend.isNative(cls); |
- universe.registerTypeInstantiation( |
- type, |
+ universe.registerTypeInstantiation(type, |
isNative: isNative, |
- byMirrors: mirrorUsage, |
- onImplemented: (ClassElement cls) { |
- compiler.backend.registerImplementedClass( |
- cls, this, compiler.globalDependencies); |
+ byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { |
+ compiler.backend |
+ .registerImplementedClass(cls, this, compiler.globalDependencies); |
}); |
// TODO(johnniwinther): Share this reasoning with [Universe]. |
if (!cls.isAbstract || isNative || mirrorUsage) { |
@@ -260,8 +236,7 @@ abstract class Enqueuer { |
if (function.name == Identifiers.noSuchMethod_) { |
registerNoSuchMethod(function); |
} |
- if (function.name == Identifiers.call && |
- !cls.typeVariables.isEmpty) { |
+ if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { |
registerCallMethodWithFreeTypeVariables(function); |
} |
// If there is a property access with the same name as a method we |
@@ -273,7 +248,8 @@ abstract class Enqueuer { |
} |
// Store the member in [instanceFunctionsByName] to catch |
// getters on the function. |
- instanceFunctionsByName.putIfAbsent(memberName, () => new Set<Element>()) |
+ instanceFunctionsByName |
+ .putIfAbsent(memberName, () => new Set<Element>()) |
.add(member); |
if (universe.hasInvocation(function, compiler.world)) { |
addToWorkList(function); |
@@ -303,7 +279,8 @@ abstract class Enqueuer { |
// The element is not yet used. Add it to the list of instance |
// members to still be processed. |
- instanceMembersByName.putIfAbsent(memberName, () => new Set<Element>()) |
+ instanceMembersByName |
+ .putIfAbsent(memberName, () => new Set<Element>()) |
.add(member); |
} |
@@ -368,7 +345,7 @@ abstract class Enqueuer { |
* The actual implementation depends on the current compiler phase. |
*/ |
bool shouldIncludeElementDueToMirrors(Element element, |
- {bool includedEnclosing}); |
+ {bool includedEnclosing}); |
void logEnqueueReflectiveAction(action, [msg = ""]) { |
if (TRACE_MIRROR_ENQUEUING) { |
@@ -380,16 +357,14 @@ abstract class Enqueuer { |
/// |
/// [enclosingWasIncluded] provides a hint whether the enclosing element was |
/// needed for reflection. |
- void enqueueReflectiveConstructor(ConstructorElement ctor, |
- bool enclosingWasIncluded) { |
+ void enqueueReflectiveConstructor( |
+ ConstructorElement ctor, bool enclosingWasIncluded) { |
if (shouldIncludeElementDueToMirrors(ctor, |
includedEnclosing: enclosingWasIncluded)) { |
logEnqueueReflectiveAction(ctor); |
ClassElement cls = ctor.declaration.enclosingClass; |
compiler.backend.registerInstantiatedType( |
- cls.rawType, |
- this, |
- compiler.mirrorDependencies, |
+ cls.rawType, this, compiler.mirrorDependencies, |
mirrorUsage: true); |
registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); |
} |
@@ -401,7 +376,7 @@ abstract class Enqueuer { |
/// needed for reflection. |
void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { |
if (shouldIncludeElementDueToMirrors(element, |
- includedEnclosing: enclosingWasIncluded)) { |
+ includedEnclosing: enclosingWasIncluded)) { |
logEnqueueReflectiveAction(element); |
if (element.isTypedef) { |
TypedefElement typedef = element; |
@@ -413,13 +388,14 @@ abstract class Enqueuer { |
// We need to enqueue all members matching this one in subclasses, as |
// well. |
// TODO(herhut): Use TypedSelector.subtype for enqueueing |
- DynamicUse dynamicUse = new DynamicUse( |
- new Selector.fromElement(element), null); |
+ DynamicUse dynamicUse = |
+ new DynamicUse(new Selector.fromElement(element), null); |
registerDynamicUse(dynamicUse); |
if (element.isField) { |
DynamicUse dynamicUse = new DynamicUse( |
- new Selector.setter(new Name( |
- element.name, element.library, isSetter: true)), null); |
+ new Selector.setter( |
+ new Name(element.name, element.library, isSetter: true)), |
+ null); |
registerDynamicUse(dynamicUse); |
} |
} |
@@ -431,8 +407,7 @@ abstract class Enqueuer { |
/// [enclosingWasIncluded] provides a hint whether the enclosing element was |
/// needed for reflection. |
void enqueueReflectiveElementsInClass(ClassElement cls, |
- Iterable<ClassElement> recents, |
- bool enclosingWasIncluded) { |
+ Iterable<ClassElement> recents, bool enclosingWasIncluded) { |
if (cls.library.isInternalLibrary || cls.isInjected) return; |
bool includeClass = shouldIncludeElementDueToMirrors(cls, |
includedEnclosing: enclosingWasIncluded); |
@@ -441,9 +416,7 @@ abstract class Enqueuer { |
ClassElement decl = cls.declaration; |
decl.ensureResolved(resolution); |
compiler.backend.registerInstantiatedType( |
- decl.rawType, |
- this, |
- compiler.mirrorDependencies, |
+ decl.rawType, this, compiler.mirrorDependencies, |
mirrorUsage: true); |
} |
// If the class is never instantiated, we know nothing of it can possibly |
@@ -475,9 +448,7 @@ abstract class Enqueuer { |
logEnqueueReflectiveAction(cls); |
cls.ensureResolved(resolution); |
compiler.backend.registerInstantiatedType( |
- cls.rawType, |
- this, |
- compiler.mirrorDependencies, |
+ cls.rawType, this, compiler.mirrorDependencies, |
mirrorUsage: true); |
} |
} |
@@ -485,10 +456,10 @@ abstract class Enqueuer { |
/// Enqeue all local members of the library [lib] if they are required for |
/// reflection. |
- void enqueueReflectiveElementsInLibrary(LibraryElement lib, |
- Iterable<ClassElement> recents) { |
- bool includeLibrary = shouldIncludeElementDueToMirrors(lib, |
- includedEnclosing: false); |
+ void enqueueReflectiveElementsInLibrary( |
+ LibraryElement lib, Iterable<ClassElement> recents) { |
+ bool includeLibrary = |
+ shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); |
lib.forEachLocalMember((Element member) { |
if (member.isClass) { |
enqueueReflectiveElementsInClass(member, recents, includeLibrary); |
@@ -522,7 +493,9 @@ abstract class Enqueuer { |
// Keep looking at new classes until fixpoint is reached. |
logEnqueueReflectiveAction("!START enqueueRecents"); |
recents.forEach((ClassElement cls) { |
- enqueueReflectiveElementsInClass(cls, recents, |
+ enqueueReflectiveElementsInClass( |
+ cls, |
+ recents, |
shouldIncludeElementDueToMirrors(cls.library, |
includedEnclosing: false)); |
}); |
@@ -541,9 +514,7 @@ abstract class Enqueuer { |
} |
void processSet( |
- Map<String, Set<Element>> map, |
- String memberName, |
- bool f(Element e)) { |
+ 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 |
@@ -577,7 +548,8 @@ abstract class Enqueuer { |
if (member.isFunction && selector.isGetter) { |
registerClosurizedMember(member); |
} |
- if (member.isField && compiler.backend.isNative(member.enclosingClass)) { |
+ if (member.isField && |
+ compiler.backend.isNative(member.enclosingClass)) { |
if (selector.isGetter || selector.isCall) { |
nativeEnqueuer.registerFieldLoad(member); |
// We have to also handle storing to the field because we only get |
@@ -677,8 +649,7 @@ abstract class Enqueuer { |
// Even in checked mode, type annotations for return type and argument |
// types do not imply type checks, so there should never be a check |
// against the type variable of a typedef. |
- assert(!type.isTypeVariable || |
- !type.element.enclosingElement.isTypedef); |
+ assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
} |
void registerCallMethodWithFreeTypeVariables(Element element) { |
@@ -748,17 +719,17 @@ class ResolutionEnqueuer extends Enqueuer { |
*/ |
final Queue<DeferredTask> deferredTaskQueue; |
- static const ImpactUseCase IMPACT_USE = const ImpactUseCase('ResolutionEnqueuer'); |
+ static const ImpactUseCase IMPACT_USE = |
+ const ImpactUseCase('ResolutionEnqueuer'); |
ImpactUseCase get impactUse => IMPACT_USE; |
- ResolutionEnqueuer(Compiler compiler, |
- ItemCompilationContext itemCompilationContextCreator(), |
- EnqueuerStrategy strategy) |
- : super('resolution enqueuer', |
- compiler, |
- itemCompilationContextCreator, |
- strategy), |
+ ResolutionEnqueuer( |
+ Compiler compiler, |
+ ItemCompilationContext itemCompilationContextCreator(), |
+ EnqueuerStrategy strategy) |
+ : super('resolution enqueuer', compiler, itemCompilationContextCreator, |
+ strategy), |
processedElements = new Set<AstElement>(), |
queue = new Queue<ResolutionWorkItem>(), |
deferredTaskQueue = new Queue<DeferredTask>(); |
@@ -786,8 +757,9 @@ class ResolutionEnqueuer extends Enqueuer { |
* yet. |
*/ |
bool shouldIncludeElementDueToMirrors(Element element, |
- {bool includedEnclosing}) { |
- return includedEnclosing || compiler.backend.requiredByMirrorSystem(element); |
+ {bool includedEnclosing}) { |
+ return includedEnclosing || |
+ compiler.backend.requiredByMirrorSystem(element); |
} |
bool internalAddToWorkList(Element element) { |
@@ -797,22 +769,21 @@ class ResolutionEnqueuer extends Enqueuer { |
message: 'Element $element is not analyzable.')); |
if (hasBeenProcessed(element)) return false; |
if (queueIsClosed) { |
- throw new SpannableAssertionFailure(element, |
- "Resolution work list is closed. Trying to add $element."); |
+ throw new SpannableAssertionFailure( |
+ element, "Resolution work list is closed. Trying to add $element."); |
} |
compiler.world.registerUsedElement(element); |
- ResolutionWorkItem workItem = compiler.resolution.createWorkItem( |
- element, itemCompilationContextCreator()); |
+ ResolutionWorkItem workItem = compiler.resolution |
+ .createWorkItem(element, itemCompilationContextCreator()); |
queue.add(workItem); |
// Enable isolate support if we start using something from the isolate |
// library, or timers for the async library. We exclude constant fields, |
// which are ending here because their initializing expression is compiled. |
LibraryElement library = element.library; |
- if (!compiler.hasIsolateSupport && |
- (!element.isField || !element.isConst)) { |
+ if (!compiler.hasIsolateSupport && (!element.isField || !element.isConst)) { |
String uri = library.canonicalUri.toString(); |
if (uri == 'dart:isolate') { |
enableIsolateSupport(); |
@@ -861,7 +832,8 @@ class ResolutionEnqueuer extends Enqueuer { |
*/ |
void addDeferredAction(Element element, DeferredAction action) { |
if (queueIsClosed) { |
- throw new SpannableAssertionFailure(element, |
+ throw new SpannableAssertionFailure( |
+ element, |
"Resolution work list is closed. " |
"Trying to add deferred action for $element"); |
} |
@@ -901,18 +873,20 @@ class CodegenEnqueuer extends Enqueuer { |
bool enabledNoSuchMethod = false; |
- static const ImpactUseCase IMPACT_USE = const ImpactUseCase('CodegenEnqueuer'); |
+ static const ImpactUseCase IMPACT_USE = |
+ const ImpactUseCase('CodegenEnqueuer'); |
ImpactUseCase get impactUse => IMPACT_USE; |
- CodegenEnqueuer(Compiler compiler, |
- ItemCompilationContext itemCompilationContextCreator(), |
- EnqueuerStrategy strategy) |
+ CodegenEnqueuer( |
+ Compiler compiler, |
+ ItemCompilationContext itemCompilationContextCreator(), |
+ EnqueuerStrategy strategy) |
: queue = new Queue<CodegenWorkItem>(), |
newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
newlySeenSelectors = compiler.cacheStrategy.newSet(), |
super('codegen enqueuer', compiler, itemCompilationContextCreator, |
- strategy); |
+ strategy); |
bool isProcessed(Element member) => |
member.isAbstract || generatedCode.containsKey(member); |
@@ -925,7 +899,7 @@ class CodegenEnqueuer extends Enqueuer { |
* subtyping constraints into account. |
*/ |
bool shouldIncludeElementDueToMirrors(Element element, |
- {bool includedEnclosing}) { |
+ {bool includedEnclosing}) { |
return compiler.backend.isAccessibleByReflection(element); |
} |
@@ -936,8 +910,8 @@ class CodegenEnqueuer extends Enqueuer { |
// Codegen inlines field initializers. It only needs to generate |
// code for checked setters. |
if (element.isField && element.isInstanceMember) { |
- if (!compiler.options.enableTypeAssertions |
- || element.enclosingElement.isClosure) { |
+ if (!compiler.options.enableTypeAssertions || |
+ element.enclosingElement.isClosure) { |
return false; |
} |
} |
@@ -947,11 +921,11 @@ class CodegenEnqueuer extends Enqueuer { |
} |
if (queueIsClosed) { |
- throw new SpannableAssertionFailure(element, |
- "Codegen work list is closed. Trying to add $element"); |
+ throw new SpannableAssertionFailure( |
+ element, "Codegen work list is closed. Trying to add $element"); |
} |
- CodegenWorkItem workItem = new CodegenWorkItem( |
- compiler, element, itemCompilationContextCreator()); |
+ CodegenWorkItem workItem = |
+ new CodegenWorkItem(compiler, element, itemCompilationContextCreator()); |
queue.add(workItem); |
return true; |
} |
@@ -992,11 +966,11 @@ class QueueFilter { |
bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
enqueuer.task.measure(() { |
// Run through the classes and see if we need to compile methods. |
- for (ClassElement classElement in |
- enqueuer.universe.directlyInstantiatedClasses) { |
+ for (ClassElement classElement |
+ in enqueuer.universe.directlyInstantiatedClasses) { |
for (ClassElement currentClass = classElement; |
- currentClass != null; |
- currentClass = currentClass.superclass) { |
+ currentClass != null; |
+ currentClass = currentClass.superclass) { |
enqueuer.processInstantiatedClassMembers(currentClass); |
} |
} |