Index: pkg/compiler/lib/src/js_emitter/program_builder/collector.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart |
index 1bdafa9156f8463743179cb06ea0a916bf3c3060..c55ddec141335738d9366da7e0b782f61dafb732 100644 |
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart |
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart |
@@ -11,12 +11,21 @@ part of dart2js.js_emitter.program_builder; |
* The code for the containing (used) methods must exist in the `universe`. |
*/ |
class Collector { |
+ final CompilerOptions _options; |
+ final CommonElements _commonElements; |
+ final DeferredLoadTask _deferredLoadTask; |
+ final CodegenWorldBuilder _worldBuilder; |
// TODO(floitsch): the code-emitter task should not need a namer. |
- final Namer namer; |
- final Compiler compiler; |
- final ClosedWorld closedWorld; |
- final Set<ClassElement> rtiNeededClasses; |
- final Emitter emitter; |
+ final Namer _namer; |
+ final Emitter _emitter; |
+ final JavaScriptConstantCompiler _constantHandler; |
+ final NativeData _nativeData; |
+ final InterceptorData _interceptorData; |
+ final OneShotInterceptorData _oneShotInterceptorData; |
+ final MirrorsData _mirrorsData; |
+ final ClosedWorld _closedWorld; |
+ final Set<ClassElement> _rtiNeededClasses; |
+ final Map<MemberElement, js.Expression> _generatedCode; |
final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
// This field is set in [computeNeededDeclarations]. |
@@ -41,16 +50,25 @@ class Collector { |
List<TypedefElement> typedefsNeededForReflection; |
- JavaScriptBackend get backend => compiler.backend; |
- |
- CommonElements get commonElements => compiler.commonElements; |
- |
- Collector(this.compiler, this.namer, this.closedWorld, this.rtiNeededClasses, |
- this.emitter); |
+ Collector( |
+ this._options, |
+ this._commonElements, |
+ this._deferredLoadTask, |
+ this._worldBuilder, |
+ this._namer, |
+ this._emitter, |
+ this._constantHandler, |
+ this._nativeData, |
+ this._interceptorData, |
+ this._oneShotInterceptorData, |
+ this._mirrorsData, |
+ this._closedWorld, |
+ this._rtiNeededClasses, |
+ this._generatedCode); |
Set<ClassElement> computeInterceptorsReferencedFromConstants() { |
Set<ClassElement> classes = new Set<ClassElement>(); |
- JavaScriptConstantCompiler handler = backend.constants; |
+ JavaScriptConstantCompiler handler = _constantHandler; |
List<ConstantValue> constants = handler.getConstantsForEmission(); |
for (ConstantValue constant in constants) { |
if (constant is InterceptorConstantValue) { |
@@ -66,43 +84,42 @@ class Collector { |
* that needs to be emitted. |
*/ |
Function computeClassFilter() { |
- if (backend.mirrorsData.isTreeShakingDisabled) { |
+ if (_mirrorsData.isTreeShakingDisabled) { |
return (ClassElement cls) => true; |
} |
Set<ClassEntity> unneededClasses = new Set<ClassEntity>(); |
// The [Bool] class is not marked as abstract, but has a factory |
// constructor that always throws. We never need to emit it. |
- unneededClasses.add(commonElements.boolClass); |
+ unneededClasses.add(_commonElements.boolClass); |
// Go over specialized interceptors and then constants to know which |
// interceptors are needed. |
Set<ClassEntity> needed = new Set<ClassEntity>(); |
for (js.Name name |
- in backend.oneShotInterceptorData.specializedGetInterceptorNames) { |
- needed.addAll(backend.oneShotInterceptorData |
- .getSpecializedGetInterceptorsFor(name)); |
+ in _oneShotInterceptorData.specializedGetInterceptorNames) { |
+ needed.addAll( |
+ _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)); |
} |
// Add interceptors referenced by constants. |
needed.addAll(computeInterceptorsReferencedFromConstants()); |
// Add unneeded interceptors to the [unneededClasses] set. |
- for (ClassEntity interceptor |
- in backend.interceptorData.interceptedClasses) { |
+ for (ClassEntity interceptor in _interceptorData.interceptedClasses) { |
if (!needed.contains(interceptor) && |
- interceptor != commonElements.objectClass) { |
+ interceptor != _commonElements.objectClass) { |
unneededClasses.add(interceptor); |
} |
} |
// These classes are just helpers for the backend's type system. |
- unneededClasses.add(commonElements.jsMutableArrayClass); |
- unneededClasses.add(commonElements.jsFixedArrayClass); |
- unneededClasses.add(commonElements.jsExtendableArrayClass); |
- unneededClasses.add(commonElements.jsUInt32Class); |
- unneededClasses.add(commonElements.jsUInt31Class); |
- unneededClasses.add(commonElements.jsPositiveIntClass); |
+ unneededClasses.add(_commonElements.jsMutableArrayClass); |
+ unneededClasses.add(_commonElements.jsFixedArrayClass); |
+ unneededClasses.add(_commonElements.jsExtendableArrayClass); |
+ unneededClasses.add(_commonElements.jsUInt32Class); |
+ unneededClasses.add(_commonElements.jsUInt31Class); |
+ unneededClasses.add(_commonElements.jsPositiveIntClass); |
return (ClassEntity cls) => !unneededClasses.contains(cls); |
} |
@@ -113,29 +130,29 @@ class Collector { |
void computeNeededConstants() { |
// Make sure we retain all metadata of all elements. This could add new |
// constants to the handler. |
- if (backend.mirrorsData.mustRetainMetadata) { |
+ if (_mirrorsData.mustRetainMetadata) { |
// TODO(floitsch): verify that we don't run through the same elements |
// multiple times. |
- for (MemberElement element in backend.generatedCode.keys) { |
- if (backend.mirrorsData.isMemberAccessibleByReflection(element)) { |
+ for (MemberElement element in _generatedCode.keys) { |
+ if (_mirrorsData.isMemberAccessibleByReflection(element)) { |
bool shouldRetainMetadata = |
- backend.mirrorsData.retainMetadataOfMember(element); |
+ _mirrorsData.retainMetadataOfMember(element); |
if (shouldRetainMetadata && |
(element.isFunction || |
element.isConstructor || |
element.isSetter)) { |
MethodElement function = element; |
- function.functionSignature.forEachParameter( |
- backend.mirrorsData.retainMetadataOfParameter); |
+ function.functionSignature |
+ .forEachParameter(_mirrorsData.retainMetadataOfParameter); |
} |
} |
} |
for (ClassElement cls in neededClasses) { |
final onlyForRti = classesOnlyNeededForRti.contains(cls); |
if (!onlyForRti) { |
- backend.mirrorsData.retainMetadataOfClass(cls); |
- new FieldVisitor(compiler.options, compiler.codegenWorldBuilder, |
- backend.nativeData, backend.mirrorsData, namer, closedWorld) |
+ _mirrorsData.retainMetadataOfClass(cls); |
+ new FieldVisitor(_options, _worldBuilder, _nativeData, _mirrorsData, |
+ _namer, _closedWorld) |
.visitFields(cls, false, (FieldElement member, |
js.Name name, |
js.Name accessorName, |
@@ -144,31 +161,30 @@ class Collector { |
bool needsCheckedSetter) { |
bool needsAccessor = needsGetter || needsSetter; |
if (needsAccessor && |
- backend.mirrorsData.isMemberAccessibleByReflection(member)) { |
- backend.mirrorsData.retainMetadataOfMember(member); |
+ _mirrorsData.isMemberAccessibleByReflection(member)) { |
+ _mirrorsData.retainMetadataOfMember(member); |
} |
}); |
} |
} |
- typedefsNeededForReflection |
- .forEach(backend.mirrorsData.retainMetadataOfTypedef); |
+ typedefsNeededForReflection.forEach(_mirrorsData.retainMetadataOfTypedef); |
} |
- JavaScriptConstantCompiler handler = backend.constants; |
+ JavaScriptConstantCompiler handler = _constantHandler; |
List<ConstantValue> constants = |
- handler.getConstantsForEmission(emitter.compareConstants); |
+ handler.getConstantsForEmission(_emitter.compareConstants); |
for (ConstantValue constant in constants) { |
- if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; |
+ if (_emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; |
if (constant.isList) outputContainsConstantList = true; |
OutputUnit constantUnit = |
- compiler.deferredLoadTask.outputUnitForConstant(constant); |
+ _deferredLoadTask.outputUnitForConstant(constant); |
if (constantUnit == null) { |
// The back-end introduces some constants, like "InterceptorConstant" or |
// some list constants. They are emitted in the main output-unit. |
// TODO(sigurdm): We should track those constants. |
- constantUnit = compiler.deferredLoadTask.mainOutputUnit; |
+ constantUnit = _deferredLoadTask.mainOutputUnit; |
} |
outputConstantLists |
.putIfAbsent(constantUnit, () => new List<ConstantValue>()) |
@@ -179,19 +195,18 @@ class Collector { |
/// Compute all the classes and typedefs that must be emitted. |
void computeNeededDeclarations() { |
// Compute needed typedefs. |
- typedefsNeededForReflection = Elements.sortedByPosition(closedWorld |
+ typedefsNeededForReflection = Elements.sortedByPosition(_closedWorld |
.allTypedefs |
- .where(backend.mirrorsData.isTypedefAccessibleByReflection) |
+ .where(_mirrorsData.isTypedefAccessibleByReflection) |
.toList()); |
// Compute needed classes. |
- Set<ClassElement> instantiatedClasses = compiler |
+ Set<ClassElement> instantiatedClasses = |
// TODO(johnniwinther): This should be accessed from a codegen closed |
// world. |
- .codegenWorldBuilder |
- .directlyInstantiatedClasses |
- .where(computeClassFilter()) |
- .toSet(); |
+ _worldBuilder.directlyInstantiatedClasses |
+ .where(computeClassFilter()) |
+ .toSet(); |
void addClassWithSuperclasses(ClassElement cls) { |
neededClasses.add(cls); |
@@ -225,48 +240,46 @@ class Collector { |
// these are thought to not have been instantiated, so we neeed to be able |
// to identify them later and make sure we only emit "empty shells" without |
// fields, etc. |
- classesOnlyNeededForRti = rtiNeededClasses.difference(neededClasses); |
+ classesOnlyNeededForRti = _rtiNeededClasses.difference(neededClasses); |
neededClasses.addAll(classesOnlyNeededForRti); |
// TODO(18175, floitsch): remove once issue 18175 is fixed. |
- if (neededClasses.contains(commonElements.jsIntClass)) { |
- neededClasses.add(commonElements.intClass); |
+ if (neededClasses.contains(_commonElements.jsIntClass)) { |
+ neededClasses.add(_commonElements.intClass); |
} |
- if (neededClasses.contains(commonElements.jsDoubleClass)) { |
- neededClasses.add(commonElements.doubleClass); |
+ if (neededClasses.contains(_commonElements.jsDoubleClass)) { |
+ neededClasses.add(_commonElements.doubleClass); |
} |
- if (neededClasses.contains(commonElements.jsNumberClass)) { |
- neededClasses.add(commonElements.numClass); |
+ if (neededClasses.contains(_commonElements.jsNumberClass)) { |
+ neededClasses.add(_commonElements.numClass); |
} |
- if (neededClasses.contains(commonElements.jsStringClass)) { |
- neededClasses.add(commonElements.stringClass); |
+ if (neededClasses.contains(_commonElements.jsStringClass)) { |
+ neededClasses.add(_commonElements.stringClass); |
} |
- if (neededClasses.contains(commonElements.jsBoolClass)) { |
- neededClasses.add(commonElements.boolClass); |
+ if (neededClasses.contains(_commonElements.jsBoolClass)) { |
+ neededClasses.add(_commonElements.boolClass); |
} |
- if (neededClasses.contains(commonElements.jsArrayClass)) { |
- neededClasses.add(commonElements.listClass); |
+ if (neededClasses.contains(_commonElements.jsArrayClass)) { |
+ neededClasses.add(_commonElements.listClass); |
} |
// 4. Finally, sort the classes. |
List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses); |
for (ClassElement element in sortedClasses) { |
- if (backend.nativeData.isNativeOrExtendsNative(element) && |
+ if (_nativeData.isNativeOrExtendsNative(element) && |
!classesOnlyNeededForRti.contains(element)) { |
// For now, native classes and related classes cannot be deferred. |
nativeClassesAndSubclasses.add(element); |
- assert( |
- invariant(element, !compiler.deferredLoadTask.isDeferred(element))); |
+ assert(invariant(element, !_deferredLoadTask.isDeferred(element))); |
outputClassLists |
- .putIfAbsent(compiler.deferredLoadTask.mainOutputUnit, |
+ .putIfAbsent(_deferredLoadTask.mainOutputUnit, |
() => new List<ClassElement>()) |
.add(element); |
} else { |
outputClassLists |
- .putIfAbsent( |
- compiler.deferredLoadTask.outputUnitForElement(element), |
+ .putIfAbsent(_deferredLoadTask.outputUnitForElement(element), |
() => new List<ClassElement>()) |
.add(element); |
} |
@@ -278,11 +291,11 @@ class Collector { |
!element.isInstanceMember && !element.isField; |
Iterable<MemberElement> elements = |
- backend.generatedCode.keys.where(isStaticFunction); |
+ _generatedCode.keys.where(isStaticFunction); |
for (Element element in Elements.sortedByPosition(elements)) { |
List<Element> list = outputStaticLists.putIfAbsent( |
- compiler.deferredLoadTask.outputUnitForElement(element), |
+ _deferredLoadTask.outputUnitForElement(element), |
() => new List<Element>()); |
list.add(element); |
} |
@@ -291,17 +304,15 @@ class Collector { |
void computeNeededStaticNonFinalFields() { |
addToOutputUnit(Element element) { |
List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent( |
- compiler.deferredLoadTask.outputUnitForElement(element), |
+ _deferredLoadTask.outputUnitForElement(element), |
() => new List<VariableElement>()); |
list.add(element); |
} |
- Iterable<FieldElement> fields = compiler |
+ Iterable<FieldElement> fields = |
// TODO(johnniwinther): This should be accessed from a codegen closed |
// world. |
- .codegenWorldBuilder |
- .allReferencedStaticFields |
- .where((FieldElement field) { |
+ _worldBuilder.allReferencedStaticFields.where((FieldElement field) { |
if (!field.isConst) { |
return field.isField && |
!field.isInstanceMember && |
@@ -310,7 +321,7 @@ class Collector { |
} else { |
// We also need to emit static const fields if they are available for |
// reflection. |
- return backend.mirrorsData.isMemberAccessibleByReflection(field); |
+ return _mirrorsData.isMemberAccessibleByReflection(field); |
} |
}); |
@@ -319,14 +330,14 @@ class Collector { |
void computeNeededLibraries() { |
void addSurroundingLibraryToSet(Element element) { |
- OutputUnit unit = compiler.deferredLoadTask.outputUnitForElement(element); |
+ OutputUnit unit = _deferredLoadTask.outputUnitForElement(element); |
LibraryElement library = element.library; |
outputLibraryLists |
.putIfAbsent(unit, () => new Set<LibraryElement>()) |
.add(library); |
} |
- backend.generatedCode.keys.forEach(addSurroundingLibraryToSet); |
+ _generatedCode.keys.forEach(addSurroundingLibraryToSet); |
neededClasses.forEach(addSurroundingLibraryToSet); |
} |