| Index: pkg/compiler/lib/src/js_backend/backend.dart
|
| diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
|
| index 48f71398234db41280be2d6ff0a7809d0120b25d..2fa04484c947dbe735145801b24a6ab36209e48b 100644
|
| --- a/pkg/compiler/lib/src/js_backend/backend.dart
|
| +++ b/pkg/compiler/lib/src/js_backend/backend.dart
|
| @@ -74,6 +74,7 @@ import 'enqueuer.dart';
|
| import 'js_interop_analysis.dart' show JsInteropAnalysis;
|
| import '../kernel/task.dart';
|
| import 'lookup_map_analysis.dart' show LookupMapAnalysis;
|
| +import 'mirrors_analysis.dart';
|
| import 'namer.dart';
|
| import 'native_data.dart' show NativeData;
|
| import 'no_such_method_registry.dart';
|
| @@ -572,6 +573,9 @@ class JavaScriptBackend extends Backend {
|
| /// Support for classifying `noSuchMethod` implementations.
|
| NoSuchMethodRegistry noSuchMethodRegistry;
|
|
|
| + /// Resolution and codegen support for computing reflectable elements.
|
| + MirrorsAnalysis mirrorsAnalysis;
|
| +
|
| /// Builds kernel representation for the program.
|
| KernelTask kernelTask;
|
|
|
| @@ -628,6 +632,7 @@ class JavaScriptBackend extends Backend {
|
| customElementsAnalysis = new CustomElementsAnalysis(this);
|
| lookupMapAnalysis = new LookupMapAnalysis(this, reporter);
|
| jsInteropAnalysis = new JsInteropAnalysis(this);
|
| + mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution);
|
|
|
| noSuchMethodRegistry = new NoSuchMethodRegistry(this);
|
| kernelTask = new KernelTask(compiler);
|
| @@ -1053,7 +1058,7 @@ class JavaScriptBackend extends Backend {
|
| }
|
| }
|
|
|
| - void addInterceptors(ClassElement cls, Enqueuer enqueuer, Registry registry) {
|
| + void addInterceptors(ClassElement cls, Enqueuer enqueuer) {
|
| if (enqueuer.isResolutionQueue) {
|
| _interceptedClasses.add(helpers.jsInterceptorClass);
|
| _interceptedClasses.add(cls);
|
| @@ -1066,7 +1071,7 @@ class JavaScriptBackend extends Backend {
|
| set.add(member);
|
| }, includeSuperAndInjectedMembers: true);
|
| }
|
| - enqueueClass(enqueuer, cls, registry);
|
| + enqueueClass(enqueuer, cls);
|
| }
|
|
|
| Set<ClassElement> get interceptedClasses {
|
| @@ -1159,20 +1164,17 @@ class JavaScriptBackend extends Backend {
|
| }
|
| }
|
|
|
| - void registerInstantiatedClass(
|
| - ClassElement cls, Enqueuer enqueuer, Registry registry) {
|
| - _processClass(cls, enqueuer, registry);
|
| + void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {
|
| + _processClass(cls, enqueuer);
|
| }
|
|
|
| - void registerImplementedClass(
|
| - ClassElement cls, Enqueuer enqueuer, Registry registry) {
|
| - _processClass(cls, enqueuer, registry);
|
| + void registerImplementedClass(ClassElement cls, Enqueuer enqueuer) {
|
| + _processClass(cls, enqueuer);
|
| }
|
|
|
| - void _processClass(ClassElement cls, Enqueuer enqueuer, Registry registry) {
|
| + void _processClass(ClassElement cls, Enqueuer enqueuer) {
|
| if (!cls.typeVariables.isEmpty) {
|
| - typeVariableHandler.registerClassWithTypeVariables(
|
| - cls, enqueuer, registry);
|
| + typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer);
|
| }
|
|
|
| // Register any helper that will be needed by the backend.
|
| @@ -1182,33 +1184,32 @@ class JavaScriptBackend extends Backend {
|
| cls == coreClasses.numClass) {
|
| // The backend will try to optimize number operations and use the
|
| // `iae` helper directly.
|
| - enqueue(enqueuer, helpers.throwIllegalArgumentException, registry);
|
| + enqueue(enqueuer, helpers.throwIllegalArgumentException);
|
| } else if (cls == coreClasses.listClass ||
|
| cls == coreClasses.stringClass) {
|
| // The backend will try to optimize array and string access and use the
|
| // `ioore` and `iae` helpers directly.
|
| - enqueue(enqueuer, helpers.throwIndexOutOfRangeException, registry);
|
| - enqueue(enqueuer, helpers.throwIllegalArgumentException, registry);
|
| + enqueue(enqueuer, helpers.throwIndexOutOfRangeException);
|
| + enqueue(enqueuer, helpers.throwIllegalArgumentException);
|
| } else if (cls == coreClasses.functionClass) {
|
| - enqueueClass(enqueuer, helpers.closureClass, registry);
|
| + enqueueClass(enqueuer, helpers.closureClass);
|
| } else if (cls == coreClasses.mapClass) {
|
| // The backend will use a literal list to initialize the entries
|
| // of the map.
|
| - enqueueClass(enqueuer, coreClasses.listClass, registry);
|
| - enqueueClass(enqueuer, helpers.mapLiteralClass, registry);
|
| + enqueueClass(enqueuer, coreClasses.listClass);
|
| + enqueueClass(enqueuer, helpers.mapLiteralClass);
|
| // For map literals, the dependency between the implementation class
|
| // and [Map] is not visible, so we have to add it manually.
|
| rti.registerRtiDependency(helpers.mapLiteralClass, cls);
|
| } else if (cls == helpers.boundClosureClass) {
|
| // TODO(johnniwinther): Is this a noop?
|
| - enqueueClass(enqueuer, helpers.boundClosureClass, registry);
|
| + enqueueClass(enqueuer, helpers.boundClosureClass);
|
| } else if (isNativeOrExtendsNative(cls)) {
|
| - enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry);
|
| - enqueueClass(
|
| - enqueuer, helpers.jsInterceptorClass, compiler.globalDependencies);
|
| - enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
|
| - enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
|
| - enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
|
| + enqueue(enqueuer, helpers.getNativeInterceptorMethod);
|
| + enqueueClass(enqueuer, helpers.jsInterceptorClass);
|
| + enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass);
|
| + enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass);
|
| + enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass);
|
| } else if (cls == helpers.mapLiteralClass) {
|
| // For map literals, the dependency between the implementation class
|
| // and [Map] is not visible, so we have to add it manually.
|
| @@ -1245,70 +1246,71 @@ class JavaScriptBackend extends Backend {
|
|
|
| helpers.mapLiteralConstructor = getFactory('_literal', 1);
|
| helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
|
| - enqueueInResolution(helpers.mapLiteralConstructor, registry);
|
| - enqueueInResolution(helpers.mapLiteralConstructorEmpty, registry);
|
| + enqueue(enqueuer, helpers.mapLiteralConstructor);
|
| + enqueue(enqueuer, helpers.mapLiteralConstructorEmpty);
|
|
|
| helpers.mapLiteralUntypedMaker = getMember('_makeLiteral');
|
| helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty');
|
| - enqueueInResolution(helpers.mapLiteralUntypedMaker, registry);
|
| - enqueueInResolution(helpers.mapLiteralUntypedEmptyMaker, registry);
|
| + enqueue(enqueuer, helpers.mapLiteralUntypedMaker);
|
| + enqueue(enqueuer, helpers.mapLiteralUntypedEmptyMaker);
|
| }
|
| }
|
| if (cls == helpers.closureClass) {
|
| - enqueue(enqueuer, helpers.closureFromTearOff, registry);
|
| + enqueue(enqueuer, helpers.closureFromTearOff);
|
| }
|
| if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) {
|
| - addInterceptors(helpers.jsStringClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsStringClass, enqueuer);
|
| } else if (cls == coreClasses.listClass ||
|
| cls == helpers.jsArrayClass ||
|
| cls == helpers.jsFixedArrayClass ||
|
| cls == helpers.jsExtendableArrayClass ||
|
| cls == helpers.jsUnmodifiableArrayClass) {
|
| - addInterceptors(helpers.jsArrayClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsMutableArrayClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry);
|
| - // Literal lists can be translated into calls to these functions:
|
| - enqueueInResolution(helpers.jsArrayTypedConstructor, registry);
|
| - enqueueInResolution(helpers.setRuntimeTypeInfo, registry);
|
| - enqueueInResolution(helpers.getTypeArgumentByIndex, registry);
|
| + addInterceptors(helpers.jsArrayClass, enqueuer);
|
| + addInterceptors(helpers.jsMutableArrayClass, enqueuer);
|
| + addInterceptors(helpers.jsFixedArrayClass, enqueuer);
|
| + addInterceptors(helpers.jsExtendableArrayClass, enqueuer);
|
| + addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer);
|
| + if (enqueuer.isResolutionQueue) {
|
| + // Literal lists can be translated into calls to these functions:
|
| + enqueue(enqueuer, helpers.jsArrayTypedConstructor);
|
| + enqueue(enqueuer, helpers.setRuntimeTypeInfo);
|
| + enqueue(enqueuer, helpers.getTypeArgumentByIndex);
|
| + }
|
| } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) {
|
| - addInterceptors(helpers.jsIntClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsUInt32Class, enqueuer, registry);
|
| - addInterceptors(helpers.jsUInt31Class, enqueuer, registry);
|
| - addInterceptors(helpers.jsNumberClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsIntClass, enqueuer);
|
| + addInterceptors(helpers.jsPositiveIntClass, enqueuer);
|
| + addInterceptors(helpers.jsUInt32Class, enqueuer);
|
| + addInterceptors(helpers.jsUInt31Class, enqueuer);
|
| + addInterceptors(helpers.jsNumberClass, enqueuer);
|
| } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) {
|
| - addInterceptors(helpers.jsDoubleClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsNumberClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsDoubleClass, enqueuer);
|
| + addInterceptors(helpers.jsNumberClass, enqueuer);
|
| } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) {
|
| - addInterceptors(helpers.jsBoolClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsBoolClass, enqueuer);
|
| } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) {
|
| - addInterceptors(helpers.jsNullClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsNullClass, enqueuer);
|
| } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) {
|
| - addInterceptors(helpers.jsIntClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsUInt32Class, enqueuer, registry);
|
| - addInterceptors(helpers.jsUInt31Class, enqueuer, registry);
|
| - addInterceptors(helpers.jsDoubleClass, enqueuer, registry);
|
| - addInterceptors(helpers.jsNumberClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsIntClass, enqueuer);
|
| + addInterceptors(helpers.jsPositiveIntClass, enqueuer);
|
| + addInterceptors(helpers.jsUInt32Class, enqueuer);
|
| + addInterceptors(helpers.jsUInt31Class, enqueuer);
|
| + addInterceptors(helpers.jsDoubleClass, enqueuer);
|
| + addInterceptors(helpers.jsNumberClass, enqueuer);
|
| } else if (cls == helpers.jsJavaScriptObjectClass) {
|
| - addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer);
|
| } else if (cls == helpers.jsPlainJavaScriptObjectClass) {
|
| - addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer);
|
| } else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
|
| - addInterceptors(
|
| - helpers.jsUnknownJavaScriptObjectClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer);
|
| } else if (cls == helpers.jsJavaScriptFunctionClass) {
|
| - addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer, registry);
|
| + addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer);
|
| } else if (isNativeOrExtendsNative(cls)) {
|
| addInterceptorsForNativeClassMembers(cls, enqueuer);
|
| } else if (cls == helpers.jsIndexingBehaviorInterface) {
|
| // These two helpers are used by the emitter and the codegen.
|
| // Because we cannot enqueue elements at the time of emission,
|
| // we make sure they are always generated.
|
| - enqueue(enqueuer, helpers.isJsIndexable, registry);
|
| + enqueue(enqueuer, helpers.isJsIndexable);
|
| }
|
|
|
| customElementsAnalysis.registerInstantiatedClass(cls,
|
| @@ -1318,27 +1320,23 @@ class JavaScriptBackend extends Backend {
|
| }
|
| }
|
|
|
| - void registerInstantiatedType(
|
| - InterfaceType type, Enqueuer enqueuer, Registry registry,
|
| - {bool mirrorUsage: false}) {
|
| + void registerInstantiatedType(InterfaceType type) {
|
| lookupMapAnalysis.registerInstantiatedType(type);
|
| - super.registerInstantiatedType(type, enqueuer, registry,
|
| - mirrorUsage: mirrorUsage);
|
| }
|
|
|
| - void enqueueHelpers(ResolutionEnqueuer world, Registry registry) {
|
| + void enqueueHelpers(ResolutionEnqueuer enqueuer) {
|
| assert(helpers.interceptorsLibrary != null);
|
| // TODO(ngeoffray): Not enqueuing those two classes currently make
|
| // the compiler potentially crash. However, any reasonable program
|
| // will instantiate those two classes.
|
| - addInterceptors(helpers.jsBoolClass, world, registry);
|
| - addInterceptors(helpers.jsNullClass, world, registry);
|
| + addInterceptors(helpers.jsBoolClass, enqueuer);
|
| + addInterceptors(helpers.jsNullClass, enqueuer);
|
| if (compiler.options.enableTypeAssertions) {
|
| // Unconditionally register the helper that checks if the
|
| // expression in an if/while/for is a boolean.
|
| // TODO(ngeoffray): Should we have the resolver register those instead?
|
| Element e = helpers.boolConversionCheck;
|
| - if (e != null) enqueue(world, e, registry);
|
| + if (e != null) enqueue(enqueuer, e);
|
| }
|
|
|
| if (TRACE_CALLS) {
|
| @@ -1346,10 +1344,10 @@ class JavaScriptBackend extends Backend {
|
| ? helpers.consoleTraceHelper
|
| : helpers.postTraceHelper;
|
| assert(traceHelper != null);
|
| - enqueueInResolution(traceHelper, registry);
|
| + enqueue(enqueuer, traceHelper);
|
| }
|
| - enqueueInResolution(helpers.assertUnreachableMethod, registry);
|
| - registerCheckedModeHelpers(registry);
|
| + enqueue(enqueuer, helpers.assertUnreachableMethod);
|
| + registerCheckedModeHelpers(enqueuer);
|
| }
|
|
|
| onResolutionComplete() {
|
| @@ -1364,53 +1362,47 @@ class JavaScriptBackend extends Backend {
|
| noSuchMethodRegistry.onTypeInferenceComplete();
|
| }
|
|
|
| - void registerGetRuntimeTypeArgument(Registry registry) {
|
| - enqueueImpact(
|
| - compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument, registry);
|
| + void registerGetRuntimeTypeArgument() {
|
| + enqueueImpact(compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument);
|
| }
|
|
|
| void registerCallMethodWithFreeTypeVariables(
|
| - Element callMethod, Enqueuer enqueuer, Registry registry) {
|
| + Element callMethod, Enqueuer enqueuer) {
|
| if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) {
|
| - registerComputeSignature(enqueuer, registry);
|
| + registerComputeSignature(enqueuer);
|
| }
|
| }
|
|
|
| void registerClosureWithFreeTypeVariables(
|
| - Element closure, Enqueuer enqueuer, Registry registry) {
|
| + Element closure, Enqueuer enqueuer) {
|
| if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) {
|
| - registerComputeSignature(enqueuer, registry);
|
| + registerComputeSignature(enqueuer);
|
| }
|
| }
|
|
|
| void registerBoundClosure(Enqueuer enqueuer) {
|
| helpers.boundClosureClass.ensureResolved(resolution);
|
| - registerInstantiatedType(
|
| - helpers.boundClosureClass.rawType,
|
| - enqueuer,
|
| - // Precise dependency is not important here.
|
| - compiler.globalDependencies);
|
| + enqueuer.registerInstantiatedType(helpers.boundClosureClass.rawType);
|
| }
|
|
|
| void registerGetOfStaticFunction(Enqueuer enqueuer) {
|
| helpers.closureClass.ensureResolved(resolution);
|
| - registerInstantiatedType(
|
| - helpers.closureClass.rawType, enqueuer, compiler.globalDependencies);
|
| + enqueuer.registerInstantiatedType(helpers.closureClass.rawType);
|
| }
|
|
|
| - void registerComputeSignature(Enqueuer enqueuer, Registry registry) {
|
| + void registerComputeSignature(Enqueuer enqueuer) {
|
| // Calls to [:computeSignature:] are generated by the emitter and we
|
| // therefore need to enqueue the used elements in the codegen enqueuer as
|
| // well as in the resolution enqueuer.
|
| - enqueueImpact(enqueuer, impacts.computeSignature, registry);
|
| + enqueueImpact(enqueuer, impacts.computeSignature);
|
| }
|
|
|
| - void registerRuntimeType(Enqueuer enqueuer, Registry registry) {
|
| - registerComputeSignature(enqueuer, registry);
|
| - enqueueInResolution(helpers.setRuntimeTypeInfo, registry);
|
| - registerGetRuntimeTypeArgument(registry);
|
| - enqueueInResolution(helpers.getRuntimeTypeInfo, registry);
|
| - enqueueClass(enqueuer, coreClasses.listClass, registry);
|
| + void registerRuntimeType(ResolutionEnqueuer enqueuer) {
|
| + registerComputeSignature(enqueuer);
|
| + enqueue(enqueuer, helpers.setRuntimeTypeInfo);
|
| + registerGetRuntimeTypeArgument();
|
| + enqueue(enqueuer, helpers.getRuntimeTypeInfo);
|
| + enqueueClass(enqueuer, coreClasses.listClass);
|
| }
|
|
|
| void registerTypeVariableBoundsSubtypeCheck(
|
| @@ -1418,11 +1410,10 @@ class JavaScriptBackend extends Backend {
|
| rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound);
|
| }
|
|
|
| - void registerCheckDeferredIsLoaded(Registry registry) {
|
| - enqueueInResolution(helpers.checkDeferredIsLoaded, registry);
|
| + void registerCheckDeferredIsLoaded(ResolutionEnqueuer enqueuer) {
|
| + enqueue(enqueuer, helpers.checkDeferredIsLoaded);
|
| // Also register the types of the arguments passed to this method.
|
| - enqueueClass(
|
| - compiler.enqueuer.resolution, coreClasses.stringClass, registry);
|
| + enqueueClass(enqueuer, coreClasses.stringClass);
|
| }
|
|
|
| void registerNoSuchMethod(FunctionElement noSuchMethod) {
|
| @@ -1464,7 +1455,7 @@ class JavaScriptBackend extends Backend {
|
| }
|
|
|
| void enableNoSuchMethod(Enqueuer world) {
|
| - enqueue(world, helpers.createInvocationMirror, compiler.globalDependencies);
|
| + enqueue(world, helpers.createInvocationMirror);
|
| world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null));
|
| }
|
|
|
| @@ -1527,26 +1518,17 @@ class JavaScriptBackend extends Backend {
|
| /// Enqueue [e] in [enqueuer].
|
| ///
|
| /// This method calls [registerBackendUse].
|
| - void enqueue(Enqueuer enqueuer, Element e, Registry registry) {
|
| + void enqueue(Enqueuer enqueuer, Element e) {
|
| if (e == null) return;
|
| registerBackendUse(e);
|
| enqueuer.addToWorkList(e);
|
| - registry.registerDependency(e);
|
| - }
|
| -
|
| - /// Enqueue [e] in the resolution enqueuer.
|
| - ///
|
| - /// This method calls [registerBackendUse].
|
| - void enqueueInResolution(Element e, Registry registry) {
|
| - if (e == null) return;
|
| - ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution;
|
| - enqueue(enqueuer, e, registry);
|
| + compiler.globalDependencies.registerDependency(e);
|
| }
|
|
|
| /// Register instantiation of [cls] in [enqueuer].
|
| ///
|
| /// This method calls [registerBackendUse].
|
| - void enqueueClass(Enqueuer enqueuer, ClassElement cls, Registry registry) {
|
| + void enqueueClass(Enqueuer enqueuer, ClassElement cls) {
|
| if (cls == null) return;
|
| registerBackendUse(cls);
|
| helpersUsed.add(cls.declaration);
|
| @@ -1554,13 +1536,13 @@ class JavaScriptBackend extends Backend {
|
| helpersUsed.add(cls.implementation);
|
| }
|
| cls.ensureResolved(resolution);
|
| - registerInstantiatedType(cls.rawType, enqueuer, registry);
|
| + enqueuer.registerInstantiatedType(cls.rawType);
|
| }
|
|
|
| /// Register instantiation of [type] in [enqueuer].
|
| ///
|
| /// This method calls [registerBackendUse].
|
| - void enqueueType(Enqueuer enqueuer, InterfaceType type, Registry registry) {
|
| + void enqueueType(Enqueuer enqueuer, InterfaceType type) {
|
| if (type == null) return;
|
| ClassElement cls = type.element;
|
| registerBackendUse(cls);
|
| @@ -1569,22 +1551,21 @@ class JavaScriptBackend extends Backend {
|
| helpersUsed.add(cls.implementation);
|
| }
|
| cls.ensureResolved(resolution);
|
| - registerInstantiatedType(type, enqueuer, registry);
|
| + enqueuer.registerInstantiatedType(type);
|
| }
|
|
|
| - void enqueueImpact(
|
| - Enqueuer enqueuer, BackendImpact impact, Registry registry) {
|
| + void enqueueImpact(Enqueuer enqueuer, BackendImpact impact) {
|
| for (Element staticUse in impact.staticUses) {
|
| - enqueue(enqueuer, staticUse, registry);
|
| + enqueue(enqueuer, staticUse);
|
| }
|
| for (InterfaceType type in impact.instantiatedTypes) {
|
| - enqueueType(enqueuer, type, registry);
|
| + enqueueType(enqueuer, type);
|
| }
|
| for (ClassElement cls in impact.instantiatedClasses) {
|
| - enqueueClass(enqueuer, cls, registry);
|
| + enqueueClass(enqueuer, cls);
|
| }
|
| for (BackendImpact otherImpact in impact.otherImpacts) {
|
| - enqueueImpact(enqueuer, otherImpact, registry);
|
| + enqueueImpact(enqueuer, otherImpact);
|
| }
|
| }
|
|
|
| @@ -1666,11 +1647,11 @@ class JavaScriptBackend extends Backend {
|
| }
|
|
|
| native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
|
| - return new native.NativeResolutionEnqueuer(world, compiler);
|
| + return new native.NativeResolutionEnqueuer(compiler);
|
| }
|
|
|
| native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) {
|
| - return new native.NativeCodegenEnqueuer(world, compiler, emitter);
|
| + return new native.NativeCodegenEnqueuer(compiler, emitter);
|
| }
|
|
|
| ClassElement defaultSuperclass(ClassElement element) {
|
| @@ -1870,11 +1851,11 @@ class JavaScriptBackend extends Backend {
|
| }
|
| }
|
|
|
| - void registerCheckedModeHelpers(Registry registry) {
|
| + void registerCheckedModeHelpers(ResolutionEnqueuer enqueuer) {
|
| // We register all the helpers in the resolution queue.
|
| // TODO(13155): Find a way to register fewer helpers.
|
| for (CheckedModeHelper helper in checkedModeHelpers) {
|
| - enqueueInResolution(helper.getStaticUse(compiler).element, registry);
|
| + enqueue(enqueuer, helper.getStaticUse(compiler).element);
|
| }
|
| }
|
|
|
| @@ -1906,7 +1887,7 @@ class JavaScriptBackend extends Backend {
|
| return compiler.closedWorld.hasOnlySubclasses(classElement);
|
| }
|
|
|
| - void registerStaticUse(Element element, {bool forResolution}) {
|
| + void registerStaticUse(Enqueuer enqueuer, Element element) {
|
| if (element == helpers.disableTreeShakingMarker) {
|
| isTreeShakingDisabled = true;
|
| } else if (element == helpers.preserveNamesMarker) {
|
| @@ -1923,14 +1904,15 @@ class JavaScriptBackend extends Backend {
|
| // TODO(sigurdm): Create a function registerLoadLibraryAccess.
|
| if (!isLoadLibraryFunctionResolved) {
|
| isLoadLibraryFunctionResolved = true;
|
| - enqueueInResolution(
|
| - helpers.loadLibraryWrapper, compiler.globalDependencies);
|
| + if (enqueuer.isResolutionQueue) {
|
| + enqueue(enqueuer, helpers.loadLibraryWrapper);
|
| + }
|
| }
|
| } else if (element == helpers.requiresPreambleMarker) {
|
| requiresPreamble = true;
|
| }
|
| customElementsAnalysis.registerStaticUse(element,
|
| - forResolution: forResolution);
|
| + forResolution: enqueuer.isResolutionQueue);
|
| }
|
|
|
| /// Called when [:const Symbol(name):] is seen.
|
| @@ -2395,12 +2377,14 @@ class JavaScriptBackend extends Backend {
|
| }
|
|
|
| if (isTreeShakingDisabled) {
|
| - enqueuer.enqueueReflectiveElements(recentClasses);
|
| + mirrorsAnalysis.enqueueReflectiveElements(
|
| + enqueuer, recentClasses, compiler.libraryLoader.libraries);
|
| } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) {
|
| // Add all static elements (not classes) that have been requested for
|
| // reflection. If there is no mirror-usage these are probably not
|
| // necessary, but the backend relies on them being resolved.
|
| - enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets());
|
| + mirrorsAnalysis.enqueueReflectiveStaticFields(
|
| + enqueuer, _findStaticFieldTargets());
|
| }
|
|
|
| if (mustPreserveNames) reporter.log('Preserving names.');
|
| @@ -2607,8 +2591,9 @@ class JavaScriptBackend extends Backend {
|
| }
|
|
|
| @override
|
| - bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) {
|
| - registerCheckDeferredIsLoaded(registry);
|
| + bool enableDeferredLoadingIfSupported(
|
| + ResolutionEnqueuer enqueuer, Spannable node) {
|
| + registerCheckDeferredIsLoaded(enqueuer);
|
| return true;
|
| }
|
|
|
| @@ -2792,13 +2777,9 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|
|
| BackendImpacts get impacts => backend.impacts;
|
|
|
| - // TODO(johnniwinther): Avoid this dependency.
|
| - ResolutionEnqueuer get resolutionEnqueuer {
|
| - return backend.compiler.enqueuer.resolution;
|
| - }
|
| -
|
| @override
|
| - WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
|
| + WorldImpact transformResolutionImpact(
|
| + ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) {
|
| TransformedWorldImpact transformed =
|
| new TransformedWorldImpact(worldImpact);
|
| for (Feature feature in worldImpact.features) {
|
| @@ -2885,6 +2866,8 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
| DartType type = typeUse.type;
|
| switch (typeUse.kind) {
|
| case TypeUseKind.INSTANTIATION:
|
| + case TypeUseKind.MIRROR_INSTANTIATION:
|
| + case TypeUseKind.NATIVE_INSTANTIATION:
|
| registerRequiredType(type);
|
| break;
|
| case TypeUseKind.IS_CHECK:
|
| @@ -2965,8 +2948,6 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
| registerBackendImpact(transformed, impacts.closure);
|
| LocalFunctionElement closure = staticUse.element;
|
| if (closure.type.containsTypeVariables) {
|
| - resolutionEnqueuer.universe.closuresWithFreeTypeVariables
|
| - .add(closure);
|
| registerBackendImpact(transformed, impacts.computeSignature);
|
| }
|
| break;
|
| @@ -3002,8 +2983,8 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
| }
|
|
|
| for (native.NativeBehavior behavior in worldImpact.nativeData) {
|
| - resolutionEnqueuer.nativeEnqueuer
|
| - .registerNativeBehavior(behavior, worldImpact);
|
| + enqueuer.nativeEnqueuer
|
| + .registerNativeBehavior(transformed, behavior, worldImpact);
|
| }
|
|
|
| return transformed;
|
| @@ -3103,8 +3084,8 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
| // need to register checked mode helpers.
|
| if (inCheckedMode) {
|
| // All helpers are added to resolution queue in enqueueHelpers. These
|
| - // calls to enqueueInResolution serve as assertions that the helper was
|
| - // in fact added.
|
| + // calls to [enqueue] with the resolution enqueuer serve as assertions
|
| + // that the helper was in fact added.
|
| // TODO(13155): Find a way to enqueue helpers lazily.
|
| CheckedModeHelper helper =
|
| backend.getCheckedModeHelper(type, typeCast: false);
|
|
|