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