|  | // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | library dart2js.js_helpers.impact; | 
|  |  | 
|  | import '../common/elements.dart' show CommonElements, ElementEnvironment; | 
|  | import '../common/names.dart'; | 
|  | import '../elements/types.dart' show InterfaceType; | 
|  | import '../elements/entities.dart'; | 
|  | import '../universe/selector.dart'; | 
|  | import '../universe/world_impact.dart' | 
|  | show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl; | 
|  | import '../universe/use.dart'; | 
|  | import '../util/enumset.dart'; | 
|  | import '../options.dart'; | 
|  |  | 
|  | /// Backend specific features required by a backend impact. | 
|  | enum BackendFeature { | 
|  | needToInitializeIsolateAffinityTag, | 
|  | needToInitializeDispatchProperty, | 
|  | } | 
|  |  | 
|  | /// A set of JavaScript backend dependencies. | 
|  | class BackendImpact { | 
|  | final List<FunctionEntity> staticUses; | 
|  | final List<FunctionEntity> globalUses; | 
|  | final List<Selector> dynamicUses; | 
|  | final List<InterfaceType> instantiatedTypes; | 
|  | final List<ClassEntity> instantiatedClasses; | 
|  | final List<ClassEntity> globalClasses; | 
|  | final List<BackendImpact> otherImpacts; | 
|  | final EnumSet<BackendFeature> _features; | 
|  |  | 
|  | const BackendImpact( | 
|  | {this.staticUses = const [], | 
|  | this.globalUses = const [], | 
|  | this.dynamicUses = const [], | 
|  | this.instantiatedTypes = const [], | 
|  | this.instantiatedClasses = const [], | 
|  | this.globalClasses = const [], | 
|  | this.otherImpacts = const [], | 
|  | EnumSet<BackendFeature> features = const EnumSet.fixed(0)}) | 
|  | : this._features = features; | 
|  |  | 
|  | Iterable<BackendFeature> get features => | 
|  | _features.iterable(BackendFeature.values); | 
|  |  | 
|  | WorldImpact createImpact(ElementEnvironment elementEnvironment) { | 
|  | WorldImpactBuilderImpl impactBuilder = WorldImpactBuilderImpl(); | 
|  | registerImpact(impactBuilder, elementEnvironment); | 
|  | return impactBuilder; | 
|  | } | 
|  |  | 
|  | /// Register this backend impact to the [worldImpactBuilder]. | 
|  | void registerImpact(WorldImpactBuilder worldImpactBuilder, | 
|  | ElementEnvironment elementEnvironment) { | 
|  | for (FunctionEntity staticUse in staticUses) { | 
|  | assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound. | 
|  | worldImpactBuilder.registerStaticUse(StaticUse.implicitInvoke(staticUse)); | 
|  | } | 
|  | for (FunctionEntity staticUse in globalUses) { | 
|  | assert((staticUse as dynamic) != null); // TODO(48820): Remove when sound. | 
|  | worldImpactBuilder.registerStaticUse(StaticUse.implicitInvoke(staticUse)); | 
|  | } | 
|  | for (Selector selector in dynamicUses) { | 
|  | assert((selector as dynamic) != null); // TODO(48820): Remove when sound. | 
|  | worldImpactBuilder | 
|  | .registerDynamicUse(DynamicUse(selector, null, const [])); | 
|  | } | 
|  | for (InterfaceType instantiatedType in instantiatedTypes) { | 
|  | worldImpactBuilder | 
|  | .registerTypeUse(TypeUse.instantiation(instantiatedType)); | 
|  | } | 
|  | for (ClassEntity cls in instantiatedClasses) { | 
|  | worldImpactBuilder.registerTypeUse( | 
|  | TypeUse.instantiation(elementEnvironment.getRawType(cls))); | 
|  | } | 
|  | for (ClassEntity cls in globalClasses) { | 
|  | worldImpactBuilder.registerTypeUse( | 
|  | TypeUse.instantiation(elementEnvironment.getRawType(cls))); | 
|  | } | 
|  | for (BackendImpact otherImpact in otherImpacts) { | 
|  | otherImpact.registerImpact(worldImpactBuilder, elementEnvironment); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /// The JavaScript backend dependencies for various features. | 
|  | class BackendImpacts { | 
|  | final CommonElements _commonElements; | 
|  | final CompilerOptions _options; | 
|  |  | 
|  | BackendImpacts(this._commonElements, this._options); | 
|  |  | 
|  | late final BackendImpact getRuntimeTypeArgument = BackendImpact( | 
|  | globalUses: [], | 
|  | otherImpacts: [newRtiImpact], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact computeSignature = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.setArrayType, | 
|  | ], | 
|  | otherImpacts: [listValues], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact mainWithArguments = BackendImpact( | 
|  | globalUses: [_commonElements.convertMainArgumentList], | 
|  | instantiatedClasses: [ | 
|  | _commonElements.jsArrayClass, | 
|  | _commonElements.jsStringClass | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact asyncBody = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.asyncHelperAwait, | 
|  | _commonElements.asyncHelperReturn, | 
|  | _commonElements.asyncHelperRethrow, | 
|  | _commonElements.streamIteratorConstructor, | 
|  | _commonElements.wrapBody, | 
|  | _commonElements.asyncHelperStartSync | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact syncStarBody = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.endOfIteration, | 
|  | _commonElements.yieldStar, | 
|  | _commonElements.syncStarUncaughtError, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact asyncStarBody = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.asyncStarHelper, | 
|  | _commonElements.streamOfController, | 
|  | _commonElements.yieldSingle, | 
|  | _commonElements.yieldStar, | 
|  | _commonElements.streamIteratorConstructor, | 
|  | _commonElements.wrapBody, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact typeVariableBoundCheck = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.checkTypeBound, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact asCheck = BackendImpact( | 
|  | staticUses: [], | 
|  | otherImpacts: [ | 
|  | newRtiImpact, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact stringValues = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.jsStringClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact numValues = BackendImpact( | 
|  | instantiatedClasses: [ | 
|  | _commonElements.jsIntClass, | 
|  | _commonElements.jsPositiveIntClass, | 
|  | _commonElements.jsUInt32Class, | 
|  | _commonElements.jsUInt31Class, | 
|  | _commonElements.jsNumberClass, | 
|  | _commonElements.jsNumNotIntClass, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | BackendImpact get intValues => numValues; | 
|  |  | 
|  | BackendImpact get doubleValues => numValues; | 
|  |  | 
|  | late final BackendImpact boolValues = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.jsBoolClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact nullValue = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.jsNullClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact listValues = BackendImpact( | 
|  | globalClasses: [ | 
|  | _commonElements.jsArrayClass, | 
|  | _commonElements.jsMutableArrayClass, | 
|  | _commonElements.jsFixedArrayClass, | 
|  | _commonElements.jsExtendableArrayClass, | 
|  | _commonElements.jsUnmodifiableArrayClass | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact throwUnsupportedError = BackendImpact( | 
|  | staticUses: [_commonElements.throwUnsupportedError], | 
|  | otherImpacts: [ | 
|  | // Also register the types of the arguments passed to this method. | 
|  | stringValues | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact superNoSuchMethod = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.createInvocationMirror, | 
|  | _commonElements.objectNoSuchMethod | 
|  | ], | 
|  | otherImpacts: [ | 
|  | _needsInt('Needed to encode the invocation kind of super.noSuchMethod.'), | 
|  | _needsList('Needed to encode the arguments of super.noSuchMethod.'), | 
|  | _needsString('Needed to encode the name of super.noSuchMethod.') | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact constantMapLiteral = BackendImpact( | 
|  | instantiatedClasses: [ | 
|  | _commonElements.constantMapClass, | 
|  | _commonElements.constantStringMapClass, | 
|  | _commonElements.generalConstantMapClass, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact constantSetLiteral = BackendImpact( | 
|  | instantiatedClasses: [ | 
|  | _commonElements.constSetLiteralClass, | 
|  | ], | 
|  | otherImpacts: [constantMapLiteral], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact constSymbol = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.symbolImplementationClass], | 
|  | staticUses: [_commonElements.symbolConstructorTarget], | 
|  | ); | 
|  |  | 
|  | /// Helper for registering that `int` is needed. | 
|  | BackendImpact _needsInt(String reason) { | 
|  | // TODO(johnniwinther): Register [reason] for use in dump-info. | 
|  | return intValues; | 
|  | } | 
|  |  | 
|  | /// Helper for registering that `List` is needed. | 
|  | BackendImpact _needsList(String reason) { | 
|  | // TODO(johnniwinther): Register [reason] for use in dump-info. | 
|  | return listValues; | 
|  | } | 
|  |  | 
|  | /// Helper for registering that `String` is needed. | 
|  | BackendImpact _needsString(String reason) { | 
|  | // TODO(johnniwinther): Register [reason] for use in dump-info. | 
|  | return stringValues; | 
|  | } | 
|  |  | 
|  | late final BackendImpact assertWithoutMessage = BackendImpact( | 
|  | staticUses: [_commonElements.assertHelper], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact assertWithMessage = BackendImpact( | 
|  | staticUses: [_commonElements.assertTest, _commonElements.assertThrow], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact asyncForIn = BackendImpact( | 
|  | staticUses: [_commonElements.streamIteratorConstructor], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact stringInterpolation = BackendImpact( | 
|  | dynamicUses: [Selectors.toString_], | 
|  | staticUses: [_commonElements.stringInterpolationHelper], | 
|  | otherImpacts: [_needsString('Strings are created.')], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact stringJuxtaposition = | 
|  | _needsString('String.concat is used.'); | 
|  |  | 
|  | BackendImpact get nullLiteral => nullValue; | 
|  |  | 
|  | BackendImpact get boolLiteral => boolValues; | 
|  |  | 
|  | BackendImpact get intLiteral => intValues; | 
|  |  | 
|  | BackendImpact get doubleLiteral => doubleValues; | 
|  |  | 
|  | BackendImpact get stringLiteral => stringValues; | 
|  |  | 
|  | late final BackendImpact catchStatement = BackendImpact( | 
|  | staticUses: [_commonElements.exceptionUnwrapper], | 
|  | instantiatedClasses: [ | 
|  | _commonElements.jsPlainJavaScriptObjectClass, | 
|  | _commonElements.jsUnknownJavaScriptObjectClass | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact throwExpression = BackendImpact( | 
|  | // We don't know ahead of time whether we will need the throw in a statement | 
|  | // context or an expression context, so we register both here, even though | 
|  | // we may not need the throwExpression helper. | 
|  | staticUses: [ | 
|  | _commonElements.wrapExceptionHelper, | 
|  | _commonElements.throwExpressionHelper | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact lazyField = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.cyclicThrowHelper, | 
|  | _commonElements.throwLateFieldADI, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact typeLiteral = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.typeLiteralClass], | 
|  | staticUses: [ | 
|  | _commonElements.createRuntimeType, | 
|  | _commonElements.typeLiteralMaker, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact stackTraceInCatch = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.stackTraceHelperClass], | 
|  | staticUses: [_commonElements.traceFromException], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact syncForIn = BackendImpact( | 
|  | // The SSA builder recognizes certain for-in loops and can generate | 
|  | // calls to throwConcurrentModificationError. | 
|  | staticUses: [_commonElements.checkConcurrentModificationError], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact typeVariableExpression = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.setArrayType, | 
|  | _commonElements.createRuntimeType | 
|  | ], | 
|  | otherImpacts: [ | 
|  | listValues, | 
|  | getRuntimeTypeArgument, | 
|  | _needsInt('Needed for accessing a type variable literal on this.') | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact typeCheck = | 
|  | BackendImpact(otherImpacts: [boolValues, newRtiImpact]); | 
|  |  | 
|  | late final BackendImpact genericTypeCheck = BackendImpact( | 
|  | staticUses: [ | 
|  | // TODO(johnniwinther): Investigate why this is needed. | 
|  | _commonElements.setArrayType, | 
|  | ], | 
|  | otherImpacts: [ | 
|  | listValues, | 
|  | getRuntimeTypeArgument, | 
|  | newRtiImpact, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact genericIsCheck = | 
|  | BackendImpact(otherImpacts: [intValues, newRtiImpact]); | 
|  |  | 
|  | late final BackendImpact typeVariableTypeCheck = | 
|  | BackendImpact(staticUses: [], otherImpacts: [newRtiImpact]); | 
|  |  | 
|  | late final BackendImpact functionTypeCheck = BackendImpact( | 
|  | staticUses: [/*helpers.functionTypeTestMetaHelper*/], | 
|  | otherImpacts: [newRtiImpact], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact futureOrTypeCheck = BackendImpact( | 
|  | staticUses: [], | 
|  | otherImpacts: [newRtiImpact], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact nativeTypeCheck = BackendImpact( | 
|  | staticUses: [ | 
|  | // We will need to add the "$is" and "$as" properties on the | 
|  | // JavaScript object prototype, so we make sure | 
|  | // [:defineProperty:] is compiled. | 
|  | _commonElements.defineProperty | 
|  | ], | 
|  | otherImpacts: [newRtiImpact], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact closure = BackendImpact( | 
|  | instantiatedClasses: [_commonElements.functionClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact interceptorUse = BackendImpact( | 
|  | staticUses: [_commonElements.getNativeInterceptorMethod], | 
|  | instantiatedClasses: [ | 
|  | _commonElements.jsJavaScriptObjectClass, | 
|  | _commonElements.jsLegacyJavaScriptObjectClass, | 
|  | _commonElements.jsPlainJavaScriptObjectClass, | 
|  | _commonElements.jsJavaScriptFunctionClass | 
|  | ], | 
|  | features: EnumSet<BackendFeature>.fromValues([ | 
|  | BackendFeature.needToInitializeDispatchProperty, | 
|  | BackendFeature.needToInitializeIsolateAffinityTag | 
|  | ], fixed: true), | 
|  | ); | 
|  |  | 
|  | late final BackendImpact allowInterop = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.jsAllowInterop1!, | 
|  | _commonElements.jsAllowInterop2!, | 
|  | ], | 
|  | features: EnumSet<BackendFeature>.fromValues([ | 
|  | BackendFeature.needToInitializeIsolateAffinityTag, | 
|  | ], fixed: true), | 
|  | ); | 
|  |  | 
|  | late final BackendImpact numClasses = BackendImpact( | 
|  | // The backend will try to optimize number operations and use the | 
|  | // `iae` helper directly. | 
|  | globalUses: [_commonElements.throwIllegalArgumentException], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact listOrStringClasses = BackendImpact( | 
|  | // The backend will try to optimize array and string access and use the | 
|  | // `ioore` and `iae` _commonElements directly. | 
|  | globalUses: [ | 
|  | _commonElements.throwIndexOutOfRangeException, | 
|  | _commonElements.throwIllegalArgumentException | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact functionClass = BackendImpact( | 
|  | globalClasses: [ | 
|  | _commonElements.closureClass, | 
|  | _commonElements.closureClass0Args, | 
|  | _commonElements.closureClass2Args, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact mapClass = BackendImpact( | 
|  | // The backend will use a literal list to initialize the entries of the map. | 
|  | globalClasses: [_commonElements.listClass, _commonElements.mapLiteralClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact setClass = BackendImpact( | 
|  | globalClasses: [ | 
|  | // The backend will use a literal list to initialize the entries of the | 
|  | // set. | 
|  | _commonElements.listClass, | 
|  | _commonElements.setLiteralClass, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact boundClosureClass = BackendImpact( | 
|  | globalClasses: [_commonElements.boundClosureClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact nativeOrExtendsClass = BackendImpact( | 
|  | globalUses: [_commonElements.getNativeInterceptorMethod], | 
|  | globalClasses: [ | 
|  | _commonElements.jsInterceptorClass, | 
|  | _commonElements.jsJavaScriptObjectClass, | 
|  | _commonElements.jsLegacyJavaScriptObjectClass, | 
|  | _commonElements.jsPlainJavaScriptObjectClass, | 
|  | _commonElements.jsJavaScriptFunctionClass | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact mapLiteralClass = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.mapLiteralConstructor, | 
|  | _commonElements.mapLiteralConstructorEmpty, | 
|  | _commonElements.mapLiteralUntypedMaker, | 
|  | _commonElements.mapLiteralUntypedEmptyMaker | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact setLiteralClass = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.setLiteralConstructor, | 
|  | _commonElements.setLiteralConstructorEmpty, | 
|  | _commonElements.setLiteralUntypedMaker, | 
|  | _commonElements.setLiteralUntypedEmptyMaker, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact closureClass = BackendImpact( | 
|  | globalUses: [_commonElements.closureFromTearOff], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact listClasses = BackendImpact( | 
|  | // Literal lists can be translated into calls to these functions: | 
|  | globalUses: [ | 
|  | _commonElements.jsArrayTypedConstructor, | 
|  | _commonElements.setArrayType, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact jsIndexingBehavior = BackendImpact( | 
|  | // These two _commonElements 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. | 
|  | globalUses: [_commonElements.isJsIndexable], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact traceHelper = BackendImpact( | 
|  | globalUses: [_commonElements.traceHelper], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact assertUnreachable = BackendImpact( | 
|  | globalUses: [_commonElements.assertUnreachableMethod], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact runtimeTypeSupport = BackendImpact( | 
|  | globalClasses: [_commonElements.listClass], | 
|  | globalUses: [ | 
|  | _commonElements.setArrayType, | 
|  | ], | 
|  | otherImpacts: [getRuntimeTypeArgument, computeSignature], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact deferredLoading = BackendImpact( | 
|  | globalUses: [_commonElements.checkDeferredIsLoaded], | 
|  | // Also register the types of the arguments passed to this method. | 
|  | globalClasses: [_commonElements.stringClass], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact noSuchMethodSupport = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.createInvocationMirror, | 
|  | _commonElements.createUnmangledInvocationMirror | 
|  | ], | 
|  | dynamicUses: [Selectors.noSuchMethod_], | 
|  | ); | 
|  |  | 
|  | /// Backend impact for accessing a `loadLibrary` function on a deferred | 
|  | /// prefix. | 
|  | late final BackendImpact loadLibrary = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.loadDeferredLibrary, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | /// Backend impact for performing member closurization. | 
|  | late final BackendImpact memberClosure = | 
|  | BackendImpact(globalClasses: [_commonElements.boundClosureClass]); | 
|  |  | 
|  | /// Backend impact for performing closurization of a top-level or static | 
|  | /// function. | 
|  | late final BackendImpact staticClosure = | 
|  | BackendImpact(globalClasses: [_commonElements.closureClass]); | 
|  |  | 
|  | final Map<int, BackendImpact> _genericInstantiation = {}; | 
|  |  | 
|  | BackendImpact getGenericInstantiation(int typeArgumentCount) => | 
|  | _genericInstantiation[typeArgumentCount] ??= BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.getInstantiateFunction(typeArgumentCount), | 
|  | _commonElements.instantiatedGenericFunctionTypeNewRti, | 
|  | _commonElements.closureFunctionType, | 
|  | ], | 
|  | instantiatedClasses: [ | 
|  | _commonElements.getInstantiationClass(typeArgumentCount), | 
|  | ], | 
|  | ); | 
|  |  | 
|  | // TODO(sra): Split into refined impacts. | 
|  | late final BackendImpact newRtiImpact = BackendImpact( | 
|  | staticUses: [ | 
|  | _commonElements.findType, | 
|  | _commonElements.instanceType, | 
|  | _commonElements.arrayInstanceType, | 
|  | _commonElements.simpleInstanceType, | 
|  | _commonElements.rtiEvalMethod, | 
|  | _commonElements.rtiBindMethod, | 
|  | _commonElements.installSpecializedIsTest, | 
|  | _commonElements.generalIsTestImplementation, | 
|  | _commonElements.generalAsCheckImplementation, | 
|  | _commonElements.installSpecializedAsCheck, | 
|  | _commonElements.generalNullableIsTestImplementation, | 
|  | _commonElements.generalNullableAsCheckImplementation, | 
|  | // Specialized checks. | 
|  | _commonElements.specializedIsBool, | 
|  | _commonElements.specializedAsBool, | 
|  | _commonElements.specializedAsBoolLegacy, | 
|  | _commonElements.specializedAsBoolNullable, | 
|  | // no specializedIsDouble. | 
|  | _commonElements.specializedAsDouble, | 
|  | _commonElements.specializedAsDoubleLegacy, | 
|  | _commonElements.specializedAsDoubleNullable, | 
|  | _commonElements.specializedIsInt, | 
|  | _commonElements.specializedAsInt, | 
|  | _commonElements.specializedAsIntLegacy, | 
|  | _commonElements.specializedAsIntNullable, | 
|  | _commonElements.specializedIsNum, | 
|  | _commonElements.specializedAsNum, | 
|  | _commonElements.specializedAsNumLegacy, | 
|  | _commonElements.specializedAsNumNullable, | 
|  | _commonElements.specializedIsString, | 
|  | _commonElements.specializedAsString, | 
|  | _commonElements.specializedAsStringLegacy, | 
|  | _commonElements.specializedAsStringNullable, | 
|  | _commonElements.specializedIsTop, | 
|  | _commonElements.specializedAsTop, | 
|  | _commonElements.specializedIsObject, | 
|  | _commonElements.specializedAsObject, | 
|  | ], | 
|  | globalClasses: [ | 
|  | _commonElements.closureClass, // instanceOrFunctionType uses this. | 
|  | ], | 
|  | ); | 
|  |  | 
|  | // TODO(fishythefish): Split into refined impacts. | 
|  | late final BackendImpact rtiAddRules = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.rtiAddRulesMethod, | 
|  | _commonElements.rtiAddErasedTypesMethod, | 
|  | if (_options.enableVariance) | 
|  | _commonElements.rtiAddTypeParameterVariancesMethod, | 
|  | ], | 
|  | otherImpacts: [_needsString('Needed to encode the new RTI ruleset.')], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact lateFieldReadCheck = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.throwUnnamedLateFieldNI, | 
|  | _commonElements.throwLateFieldNI, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact lateFieldWriteOnceCheck = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.throwUnnamedLateFieldAI, | 
|  | _commonElements.throwLateFieldAI, | 
|  | ], | 
|  | ); | 
|  |  | 
|  | late final BackendImpact lateFieldInitializeOnceCheck = BackendImpact( | 
|  | globalUses: [ | 
|  | _commonElements.throwUnnamedLateFieldADI, | 
|  | _commonElements.throwLateFieldADI, | 
|  | ], | 
|  | ); | 
|  | } |