| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library js_backend.backend.impact_transformer; | 5 library js_backend.backend.impact_transformer; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common_elements.dart'; |
| 8 import '../common/backend_api.dart' show ImpactTransformer; | 9 import '../common/backend_api.dart' show ImpactTransformer; |
| 9 import '../common/codegen.dart' show CodegenImpact; | 10 import '../common/codegen.dart' show CodegenImpact; |
| 10 import '../common/resolution.dart' show ResolutionImpact; | 11 import '../common/resolution.dart' show Resolution, ResolutionImpact; |
| 11 import '../constants/expressions.dart'; | 12 import '../constants/expressions.dart'; |
| 12 import '../constants/values.dart'; | 13 import '../constants/values.dart'; |
| 13 import '../common_elements.dart' show ElementEnvironment; | 14 import '../common_elements.dart' show ElementEnvironment; |
| 14 import '../elements/elements.dart'; | 15 import '../elements/elements.dart'; |
| 15 import '../elements/resolution_types.dart'; | 16 import '../elements/resolution_types.dart'; |
| 16 import '../enqueue.dart' show ResolutionEnqueuer; | 17 import '../enqueue.dart' show ResolutionEnqueuer; |
| 18 import '../native/enqueue.dart'; |
| 17 import '../native/native.dart' as native; | 19 import '../native/native.dart' as native; |
| 20 import '../options.dart'; |
| 18 import '../universe/feature.dart'; | 21 import '../universe/feature.dart'; |
| 19 import '../universe/use.dart' | 22 import '../universe/use.dart' |
| 20 show StaticUse, StaticUseKind, TypeUse, TypeUseKind; | 23 show StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
| 21 import '../universe/world_impact.dart' show TransformedWorldImpact, WorldImpact; | 24 import '../universe/world_impact.dart' show TransformedWorldImpact, WorldImpact; |
| 22 import '../util/util.dart'; | 25 import '../util/util.dart'; |
| 23 import 'backend.dart'; | 26 import 'backend.dart'; |
| 27 import 'backend_helpers.dart'; |
| 24 import 'backend_impact.dart'; | 28 import 'backend_impact.dart'; |
| 25 import 'backend_usage.dart'; | 29 import 'backend_usage.dart'; |
| 26 import 'checked_mode_helpers.dart'; | 30 import 'checked_mode_helpers.dart'; |
| 31 import 'custom_elements_analysis.dart'; |
| 32 import 'interceptor_data.dart'; |
| 33 import 'lookup_map_analysis.dart'; |
| 34 import 'mirrors_data.dart'; |
| 35 import 'namer.dart'; |
| 36 import 'native_data.dart'; |
| 27 | 37 |
| 28 class JavaScriptImpactTransformer extends ImpactTransformer { | 38 class JavaScriptImpactTransformer extends ImpactTransformer { |
| 29 final JavaScriptBackend backend; | 39 final CompilerOptions _options; |
| 40 final Resolution _resolution; |
| 41 final ElementEnvironment _elementEnvironment; |
| 42 final CommonElements _commonElements; |
| 43 final BackendImpacts _impacts; |
| 44 final NativeClassData _nativeClassData; |
| 45 final NativeResolutionEnqueuer _nativeResolutionEnqueuer; |
| 46 final BackendUsageBuilder _backendUsageBuider; |
| 47 final MirrorsData _mirrorsData; |
| 48 final CustomElementsResolutionAnalysis _customElementsResolutionAnalysis; |
| 49 final RuntimeTypesNeedBuilder _rtiNeedBuilder; |
| 30 | 50 |
| 31 JavaScriptImpactTransformer(this.backend); | 51 JavaScriptImpactTransformer( |
| 32 | 52 this._options, |
| 33 BackendImpacts get impacts => backend.impacts; | 53 this._resolution, |
| 34 | 54 this._elementEnvironment, |
| 35 ElementEnvironment get elementEnvironment => | 55 this._commonElements, |
| 36 backend.compiler.elementEnvironment; | 56 this._impacts, |
| 57 this._nativeClassData, |
| 58 this._nativeResolutionEnqueuer, |
| 59 this._backendUsageBuider, |
| 60 this._mirrorsData, |
| 61 this._customElementsResolutionAnalysis, |
| 62 this._rtiNeedBuilder); |
| 37 | 63 |
| 38 @override | 64 @override |
| 39 WorldImpact transformResolutionImpact( | 65 WorldImpact transformResolutionImpact( |
| 40 ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) { | 66 ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) { |
| 41 BackendUsageBuilder backendUsage = backend.backendUsageBuilder; | |
| 42 TransformedWorldImpact transformed = | 67 TransformedWorldImpact transformed = |
| 43 new TransformedWorldImpact(worldImpact); | 68 new TransformedWorldImpact(worldImpact); |
| 44 | 69 |
| 45 void registerImpact(BackendImpact impact) { | 70 void registerImpact(BackendImpact impact) { |
| 46 impact.registerImpact(transformed, elementEnvironment); | 71 impact.registerImpact(transformed, _elementEnvironment); |
| 47 backendUsage.processBackendImpact(impact); | 72 _backendUsageBuider.processBackendImpact(impact); |
| 48 } | 73 } |
| 49 | 74 |
| 50 for (Feature feature in worldImpact.features) { | 75 for (Feature feature in worldImpact.features) { |
| 51 switch (feature) { | 76 switch (feature) { |
| 52 case Feature.ABSTRACT_CLASS_INSTANTIATION: | 77 case Feature.ABSTRACT_CLASS_INSTANTIATION: |
| 53 registerImpact(impacts.abstractClassInstantiation); | 78 registerImpact(_impacts.abstractClassInstantiation); |
| 54 break; | 79 break; |
| 55 case Feature.ASSERT: | 80 case Feature.ASSERT: |
| 56 registerImpact(impacts.assertWithoutMessage); | 81 registerImpact(_impacts.assertWithoutMessage); |
| 57 break; | 82 break; |
| 58 case Feature.ASSERT_WITH_MESSAGE: | 83 case Feature.ASSERT_WITH_MESSAGE: |
| 59 registerImpact(impacts.assertWithMessage); | 84 registerImpact(_impacts.assertWithMessage); |
| 60 break; | 85 break; |
| 61 case Feature.ASYNC: | 86 case Feature.ASYNC: |
| 62 registerImpact(impacts.asyncBody); | 87 registerImpact(_impacts.asyncBody); |
| 63 break; | 88 break; |
| 64 case Feature.ASYNC_FOR_IN: | 89 case Feature.ASYNC_FOR_IN: |
| 65 registerImpact(impacts.asyncForIn); | 90 registerImpact(_impacts.asyncForIn); |
| 66 break; | 91 break; |
| 67 case Feature.ASYNC_STAR: | 92 case Feature.ASYNC_STAR: |
| 68 registerImpact(impacts.asyncStarBody); | 93 registerImpact(_impacts.asyncStarBody); |
| 69 break; | 94 break; |
| 70 case Feature.CATCH_STATEMENT: | 95 case Feature.CATCH_STATEMENT: |
| 71 registerImpact(impacts.catchStatement); | 96 registerImpact(_impacts.catchStatement); |
| 72 break; | 97 break; |
| 73 case Feature.COMPILE_TIME_ERROR: | 98 case Feature.COMPILE_TIME_ERROR: |
| 74 if (backend.compiler.options.generateCodeWithCompileTimeErrors) { | 99 if (_options.generateCodeWithCompileTimeErrors) { |
| 75 // TODO(johnniwinther): This should have its own uncatchable error. | 100 // TODO(johnniwinther): This should have its own uncatchable error. |
| 76 registerImpact(impacts.throwRuntimeError); | 101 registerImpact(_impacts.throwRuntimeError); |
| 77 } | 102 } |
| 78 break; | 103 break; |
| 79 case Feature.FALL_THROUGH_ERROR: | 104 case Feature.FALL_THROUGH_ERROR: |
| 80 registerImpact(impacts.fallThroughError); | 105 registerImpact(_impacts.fallThroughError); |
| 81 break; | 106 break; |
| 82 case Feature.FIELD_WITHOUT_INITIALIZER: | 107 case Feature.FIELD_WITHOUT_INITIALIZER: |
| 83 case Feature.LOCAL_WITHOUT_INITIALIZER: | 108 case Feature.LOCAL_WITHOUT_INITIALIZER: |
| 84 transformed.registerTypeUse( | 109 transformed.registerTypeUse( |
| 85 new TypeUse.instantiation(backend.commonElements.nullType)); | 110 new TypeUse.instantiation(_commonElements.nullType)); |
| 86 registerImpact(impacts.nullLiteral); | 111 registerImpact(_impacts.nullLiteral); |
| 87 break; | 112 break; |
| 88 case Feature.LAZY_FIELD: | 113 case Feature.LAZY_FIELD: |
| 89 registerImpact(impacts.lazyField); | 114 registerImpact(_impacts.lazyField); |
| 90 break; | 115 break; |
| 91 case Feature.STACK_TRACE_IN_CATCH: | 116 case Feature.STACK_TRACE_IN_CATCH: |
| 92 registerImpact(impacts.stackTraceInCatch); | 117 registerImpact(_impacts.stackTraceInCatch); |
| 93 break; | 118 break; |
| 94 case Feature.STRING_INTERPOLATION: | 119 case Feature.STRING_INTERPOLATION: |
| 95 registerImpact(impacts.stringInterpolation); | 120 registerImpact(_impacts.stringInterpolation); |
| 96 break; | 121 break; |
| 97 case Feature.STRING_JUXTAPOSITION: | 122 case Feature.STRING_JUXTAPOSITION: |
| 98 registerImpact(impacts.stringJuxtaposition); | 123 registerImpact(_impacts.stringJuxtaposition); |
| 99 break; | 124 break; |
| 100 case Feature.SUPER_NO_SUCH_METHOD: | 125 case Feature.SUPER_NO_SUCH_METHOD: |
| 101 registerImpact(impacts.superNoSuchMethod); | 126 registerImpact(_impacts.superNoSuchMethod); |
| 102 break; | 127 break; |
| 103 case Feature.SYMBOL_CONSTRUCTOR: | 128 case Feature.SYMBOL_CONSTRUCTOR: |
| 104 registerImpact(impacts.symbolConstructor); | 129 registerImpact(_impacts.symbolConstructor); |
| 105 break; | 130 break; |
| 106 case Feature.SYNC_FOR_IN: | 131 case Feature.SYNC_FOR_IN: |
| 107 registerImpact(impacts.syncForIn); | 132 registerImpact(_impacts.syncForIn); |
| 108 break; | 133 break; |
| 109 case Feature.SYNC_STAR: | 134 case Feature.SYNC_STAR: |
| 110 registerImpact(impacts.syncStarBody); | 135 registerImpact(_impacts.syncStarBody); |
| 111 break; | 136 break; |
| 112 case Feature.THROW_EXPRESSION: | 137 case Feature.THROW_EXPRESSION: |
| 113 registerImpact(impacts.throwExpression); | 138 registerImpact(_impacts.throwExpression); |
| 114 break; | 139 break; |
| 115 case Feature.THROW_NO_SUCH_METHOD: | 140 case Feature.THROW_NO_SUCH_METHOD: |
| 116 registerImpact(impacts.throwNoSuchMethod); | 141 registerImpact(_impacts.throwNoSuchMethod); |
| 117 break; | 142 break; |
| 118 case Feature.THROW_RUNTIME_ERROR: | 143 case Feature.THROW_RUNTIME_ERROR: |
| 119 registerImpact(impacts.throwRuntimeError); | 144 registerImpact(_impacts.throwRuntimeError); |
| 120 break; | 145 break; |
| 121 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: | 146 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: |
| 122 registerImpact(impacts.typeVariableBoundCheck); | 147 registerImpact(_impacts.typeVariableBoundCheck); |
| 123 break; | 148 break; |
| 124 } | 149 } |
| 125 } | 150 } |
| 126 | 151 |
| 127 bool hasAsCast = false; | 152 bool hasAsCast = false; |
| 128 bool hasTypeLiteral = false; | 153 bool hasTypeLiteral = false; |
| 129 for (TypeUse typeUse in worldImpact.typeUses) { | 154 for (TypeUse typeUse in worldImpact.typeUses) { |
| 130 ResolutionDartType type = typeUse.type; | 155 ResolutionDartType type = typeUse.type; |
| 131 switch (typeUse.kind) { | 156 switch (typeUse.kind) { |
| 132 case TypeUseKind.INSTANTIATION: | 157 case TypeUseKind.INSTANTIATION: |
| 133 case TypeUseKind.MIRROR_INSTANTIATION: | 158 case TypeUseKind.MIRROR_INSTANTIATION: |
| 134 case TypeUseKind.NATIVE_INSTANTIATION: | 159 case TypeUseKind.NATIVE_INSTANTIATION: |
| 135 registerRequiredType(type); | 160 registerRequiredType(type); |
| 136 break; | 161 break; |
| 137 case TypeUseKind.IS_CHECK: | 162 case TypeUseKind.IS_CHECK: |
| 138 onIsCheck(type, transformed); | 163 onIsCheck(type, transformed); |
| 139 break; | 164 break; |
| 140 case TypeUseKind.AS_CAST: | 165 case TypeUseKind.AS_CAST: |
| 141 onIsCheck(type, transformed); | 166 onIsCheck(type, transformed); |
| 142 hasAsCast = true; | 167 hasAsCast = true; |
| 143 break; | 168 break; |
| 144 case TypeUseKind.CHECKED_MODE_CHECK: | 169 case TypeUseKind.CHECKED_MODE_CHECK: |
| 145 if (backend.compiler.options.enableTypeAssertions) { | 170 if (_options.enableTypeAssertions) { |
| 146 onIsCheck(type, transformed); | 171 onIsCheck(type, transformed); |
| 147 } | 172 } |
| 148 break; | 173 break; |
| 149 case TypeUseKind.CATCH_TYPE: | 174 case TypeUseKind.CATCH_TYPE: |
| 150 onIsCheck(type, transformed); | 175 onIsCheck(type, transformed); |
| 151 break; | 176 break; |
| 152 case TypeUseKind.TYPE_LITERAL: | 177 case TypeUseKind.TYPE_LITERAL: |
| 153 backend.customElementsResolutionAnalysis.registerTypeLiteral(type); | 178 _customElementsResolutionAnalysis.registerTypeLiteral(type); |
| 154 if (type.isTypeVariable && type is! MethodTypeVariableType) { | 179 if (type.isTypeVariable && type is! MethodTypeVariableType) { |
| 155 // GENERIC_METHODS: The `is!` test above filters away method type | 180 // GENERIC_METHODS: The `is!` test above filters away method type |
| 156 // variables, because they have the value `dynamic` with the | 181 // variables, because they have the value `dynamic` with the |
| 157 // incomplete support for generic methods offered with | 182 // incomplete support for generic methods offered with |
| 158 // '--generic-method-syntax'. This must be revised in order to | 183 // '--generic-method-syntax'. This must be revised in order to |
| 159 // support generic methods fully. | 184 // support generic methods fully. |
| 160 ClassElement cls = type.element.enclosingClass; | 185 ClassElement cls = type.element.enclosingClass; |
| 161 backend.rtiNeedBuilder | 186 _rtiNeedBuilder.registerClassUsingTypeVariableExpression(cls); |
| 162 .registerClassUsingTypeVariableExpression(cls); | 187 registerImpact(_impacts.typeVariableExpression); |
| 163 registerImpact(impacts.typeVariableExpression); | |
| 164 } | 188 } |
| 165 hasTypeLiteral = true; | 189 hasTypeLiteral = true; |
| 166 break; | 190 break; |
| 167 } | 191 } |
| 168 } | 192 } |
| 169 | 193 |
| 170 if (hasAsCast) { | 194 if (hasAsCast) { |
| 171 registerImpact(impacts.asCheck); | 195 registerImpact(_impacts.asCheck); |
| 172 } | 196 } |
| 173 | 197 |
| 174 if (hasTypeLiteral) { | 198 if (hasTypeLiteral) { |
| 175 transformed.registerTypeUse( | 199 transformed |
| 176 new TypeUse.instantiation(backend.compiler.commonElements.typeType)); | 200 .registerTypeUse(new TypeUse.instantiation(_commonElements.typeType)); |
| 177 registerImpact(impacts.typeLiteral); | 201 registerImpact(_impacts.typeLiteral); |
| 178 } | 202 } |
| 179 | 203 |
| 180 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) { | 204 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) { |
| 181 // TODO(johnniwinther): Use the [isEmpty] property when factory | 205 // TODO(johnniwinther): Use the [isEmpty] property when factory |
| 182 // constructors are registered directly. | 206 // constructors are registered directly. |
| 183 if (mapLiteralUse.isConstant) { | 207 if (mapLiteralUse.isConstant) { |
| 184 registerImpact(impacts.constantMapLiteral); | 208 registerImpact(_impacts.constantMapLiteral); |
| 185 } else { | 209 } else { |
| 186 transformed | 210 transformed |
| 187 .registerTypeUse(new TypeUse.instantiation(mapLiteralUse.type)); | 211 .registerTypeUse(new TypeUse.instantiation(mapLiteralUse.type)); |
| 188 } | 212 } |
| 189 ResolutionInterfaceType type = mapLiteralUse.type; | 213 ResolutionInterfaceType type = mapLiteralUse.type; |
| 190 registerRequiredType(type); | 214 registerRequiredType(type); |
| 191 } | 215 } |
| 192 | 216 |
| 193 for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) { | 217 for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) { |
| 194 // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when | 218 // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when |
| 195 // factory constructors are registered directly. | 219 // factory constructors are registered directly. |
| 196 transformed | 220 transformed |
| 197 .registerTypeUse(new TypeUse.instantiation(listLiteralUse.type)); | 221 .registerTypeUse(new TypeUse.instantiation(listLiteralUse.type)); |
| 198 ResolutionInterfaceType type = listLiteralUse.type; | 222 ResolutionInterfaceType type = listLiteralUse.type; |
| 199 registerRequiredType(type); | 223 registerRequiredType(type); |
| 200 } | 224 } |
| 201 | 225 |
| 202 if (worldImpact.constSymbolNames.isNotEmpty) { | 226 if (worldImpact.constSymbolNames.isNotEmpty) { |
| 203 registerImpact(impacts.constSymbol); | 227 registerImpact(_impacts.constSymbol); |
| 204 for (String constSymbolName in worldImpact.constSymbolNames) { | 228 for (String constSymbolName in worldImpact.constSymbolNames) { |
| 205 backend.mirrorsData.registerConstSymbol(constSymbolName); | 229 _mirrorsData.registerConstSymbol(constSymbolName); |
| 206 } | 230 } |
| 207 } | 231 } |
| 208 | 232 |
| 209 for (StaticUse staticUse in worldImpact.staticUses) { | 233 for (StaticUse staticUse in worldImpact.staticUses) { |
| 210 switch (staticUse.kind) { | 234 switch (staticUse.kind) { |
| 211 case StaticUseKind.CLOSURE: | 235 case StaticUseKind.CLOSURE: |
| 212 registerImpact(impacts.closure); | 236 registerImpact(_impacts.closure); |
| 213 LocalFunctionElement closure = staticUse.element; | 237 LocalFunctionElement closure = staticUse.element; |
| 214 if (closure.type.containsTypeVariables) { | 238 if (closure.type.containsTypeVariables) { |
| 215 registerImpact(impacts.computeSignature); | 239 registerImpact(_impacts.computeSignature); |
| 216 } | 240 } |
| 217 break; | 241 break; |
| 218 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 242 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 219 case StaticUseKind.CONSTRUCTOR_INVOKE: | 243 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 220 registerRequiredType(staticUse.type); | 244 registerRequiredType(staticUse.type); |
| 221 break; | 245 break; |
| 222 default: | 246 default: |
| 223 } | 247 } |
| 224 } | 248 } |
| 225 | 249 |
| 226 for (ConstantExpression constant in worldImpact.constantLiterals) { | 250 for (ConstantExpression constant in worldImpact.constantLiterals) { |
| 227 switch (constant.kind) { | 251 switch (constant.kind) { |
| 228 case ConstantExpressionKind.NULL: | 252 case ConstantExpressionKind.NULL: |
| 229 registerImpact(impacts.nullLiteral); | 253 registerImpact(_impacts.nullLiteral); |
| 230 break; | 254 break; |
| 231 case ConstantExpressionKind.BOOL: | 255 case ConstantExpressionKind.BOOL: |
| 232 registerImpact(impacts.boolLiteral); | 256 registerImpact(_impacts.boolLiteral); |
| 233 break; | 257 break; |
| 234 case ConstantExpressionKind.INT: | 258 case ConstantExpressionKind.INT: |
| 235 registerImpact(impacts.intLiteral); | 259 registerImpact(_impacts.intLiteral); |
| 236 break; | 260 break; |
| 237 case ConstantExpressionKind.DOUBLE: | 261 case ConstantExpressionKind.DOUBLE: |
| 238 registerImpact(impacts.doubleLiteral); | 262 registerImpact(_impacts.doubleLiteral); |
| 239 break; | 263 break; |
| 240 case ConstantExpressionKind.STRING: | 264 case ConstantExpressionKind.STRING: |
| 241 registerImpact(impacts.stringLiteral); | 265 registerImpact(_impacts.stringLiteral); |
| 242 break; | 266 break; |
| 243 default: | 267 default: |
| 244 assert(invariant(NO_LOCATION_SPANNABLE, false, | 268 assert(invariant(NO_LOCATION_SPANNABLE, false, |
| 245 message: "Unexpected constant literal: ${constant.kind}.")); | 269 message: "Unexpected constant literal: ${constant.kind}.")); |
| 246 } | 270 } |
| 247 } | 271 } |
| 248 | 272 |
| 249 for (native.NativeBehavior behavior in worldImpact.nativeData) { | 273 for (native.NativeBehavior behavior in worldImpact.nativeData) { |
| 250 backend.nativeResolutionEnqueuer | 274 _nativeResolutionEnqueuer.registerNativeBehavior( |
| 251 .registerNativeBehavior(transformed, behavior, worldImpact); | 275 transformed, behavior, worldImpact); |
| 252 } | 276 } |
| 253 | 277 |
| 254 return transformed; | 278 return transformed; |
| 255 } | 279 } |
| 256 | 280 |
| 257 /// Register [type] as required for the runtime type information system. | 281 /// Register [type] as required for the runtime type information system. |
| 258 void registerRequiredType(ResolutionDartType type) { | 282 void registerRequiredType(ResolutionDartType type) { |
| 259 if (!type.isInterfaceType) return; | 283 if (!type.isInterfaceType) return; |
| 260 // If [argument] has type variables or is a type variable, this method | 284 // If [argument] has type variables or is a type variable, this method |
| 261 // registers a RTI dependency between the class where the type variable is | 285 // registers a RTI dependency between the class where the type variable is |
| 262 // defined (that is the enclosing class of the current element being | 286 // defined (that is the enclosing class of the current element being |
| 263 // resolved) and the class of [type]. If the class of [type] requires RTI, | 287 // resolved) and the class of [type]. If the class of [type] requires RTI, |
| 264 // then the class of the type variable does too. | 288 // then the class of the type variable does too. |
| 265 ClassElement contextClass = Types.getClassContext(type); | 289 ClassElement contextClass = Types.getClassContext(type); |
| 266 if (contextClass != null) { | 290 if (contextClass != null) { |
| 267 backend.rtiNeedBuilder.registerRtiDependency(type.element, contextClass); | 291 _rtiNeedBuilder.registerRtiDependency(type.element, contextClass); |
| 268 } | 292 } |
| 269 } | 293 } |
| 270 | 294 |
| 271 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. | 295 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. |
| 272 void onIsCheck(ResolutionDartType type, TransformedWorldImpact transformed) { | 296 void onIsCheck(ResolutionDartType type, TransformedWorldImpact transformed) { |
| 273 BackendUsageBuilder backendUsage = backend.backendUsageBuilder; | |
| 274 | |
| 275 void registerImpact(BackendImpact impact) { | 297 void registerImpact(BackendImpact impact) { |
| 276 impact.registerImpact(transformed, elementEnvironment); | 298 impact.registerImpact(transformed, _elementEnvironment); |
| 277 backendUsage.processBackendImpact(impact); | 299 _backendUsageBuider.processBackendImpact(impact); |
| 278 } | 300 } |
| 279 | 301 |
| 280 registerRequiredType(type); | 302 registerRequiredType(type); |
| 281 type.computeUnaliased(backend.resolution); | 303 type.computeUnaliased(_resolution); |
| 282 type = type.unaliased; | 304 type = type.unaliased; |
| 283 registerImpact(impacts.typeCheck); | 305 registerImpact(_impacts.typeCheck); |
| 284 | 306 |
| 285 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; | 307 bool inCheckedMode = _options.enableTypeAssertions; |
| 286 if (inCheckedMode) { | 308 if (inCheckedMode) { |
| 287 registerImpact(impacts.checkedModeTypeCheck); | 309 registerImpact(_impacts.checkedModeTypeCheck); |
| 288 } | 310 } |
| 289 if (type.isMalformed) { | 311 if (type.isMalformed) { |
| 290 registerImpact(impacts.malformedTypeCheck); | 312 registerImpact(_impacts.malformedTypeCheck); |
| 291 } | 313 } |
| 292 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { | 314 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { |
| 293 registerImpact(impacts.genericTypeCheck); | 315 registerImpact(_impacts.genericTypeCheck); |
| 294 if (inCheckedMode) { | 316 if (inCheckedMode) { |
| 295 registerImpact(impacts.genericCheckedModeTypeCheck); | 317 registerImpact(_impacts.genericCheckedModeTypeCheck); |
| 296 } | 318 } |
| 297 if (type.isTypeVariable) { | 319 if (type.isTypeVariable) { |
| 298 registerImpact(impacts.typeVariableTypeCheck); | 320 registerImpact(_impacts.typeVariableTypeCheck); |
| 299 if (inCheckedMode) { | 321 if (inCheckedMode) { |
| 300 registerImpact(impacts.typeVariableCheckedModeTypeCheck); | 322 registerImpact(_impacts.typeVariableCheckedModeTypeCheck); |
| 301 } | 323 } |
| 302 } | 324 } |
| 303 } | 325 } |
| 304 if (type is ResolutionFunctionType) { | 326 if (type is ResolutionFunctionType) { |
| 305 registerImpact(impacts.functionTypeCheck); | 327 registerImpact(_impacts.functionTypeCheck); |
| 306 } | 328 } |
| 307 if (type is ResolutionInterfaceType && | 329 if (type is ResolutionInterfaceType && |
| 308 backend.nativeClassData.isNativeClass(type.element)) { | 330 _nativeClassData.isNativeClass(type.element)) { |
| 309 registerImpact(impacts.nativeTypeCheck); | 331 registerImpact(_impacts.nativeTypeCheck); |
| 310 } | 332 } |
| 311 } | 333 } |
| 334 } |
| 335 |
| 336 class CodegenImpactTransformer { |
| 337 // TODO(johnniwinther): Remove the need for this. |
| 338 final JavaScriptBackend _backend; |
| 339 |
| 340 final CompilerOptions _options; |
| 341 final ElementEnvironment _elementEnvironment; |
| 342 final BackendHelpers _helpers; |
| 343 final BackendImpacts _impacts; |
| 344 final CheckedModeHelpers _checkedModeHelpers; |
| 345 final NativeData _nativeData; |
| 346 final RuntimeTypesNeed _rtiNeed; |
| 347 final NativeCodegenEnqueuer _nativeCodegenEnqueuer; |
| 348 final Namer _namer; |
| 349 final MirrorsData _mirrorsData; |
| 350 final OneShotInterceptorData _oneShotInterceptorData; |
| 351 final LookupMapAnalysis _lookupMapAnalysis; |
| 352 final CustomElementsCodegenAnalysis _customElementsCodegenAnalysis; |
| 353 |
| 354 CodegenImpactTransformer( |
| 355 this._backend, |
| 356 this._options, |
| 357 this._elementEnvironment, |
| 358 this._helpers, |
| 359 this._impacts, |
| 360 this._checkedModeHelpers, |
| 361 this._nativeData, |
| 362 this._rtiNeed, |
| 363 this._nativeCodegenEnqueuer, |
| 364 this._namer, |
| 365 this._mirrorsData, |
| 366 this._oneShotInterceptorData, |
| 367 this._lookupMapAnalysis, |
| 368 this._customElementsCodegenAnalysis); |
| 312 | 369 |
| 313 void onIsCheckForCodegen( | 370 void onIsCheckForCodegen( |
| 314 ResolutionDartType type, TransformedWorldImpact transformed) { | 371 ResolutionDartType type, TransformedWorldImpact transformed) { |
| 315 if (type.isDynamic) return; | 372 if (type.isDynamic) return; |
| 316 type = type.unaliased; | 373 type = type.unaliased; |
| 317 impacts.typeCheck.registerImpact(transformed, elementEnvironment); | 374 _impacts.typeCheck.registerImpact(transformed, _elementEnvironment); |
| 318 | 375 |
| 319 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; | 376 bool inCheckedMode = _options.enableTypeAssertions; |
| 320 // [registerIsCheck] is also called for checked mode checks, so we | 377 // [registerIsCheck] is also called for checked mode checks, so we |
| 321 // need to register checked mode helpers. | 378 // need to register checked mode helpers. |
| 322 if (inCheckedMode) { | 379 if (inCheckedMode) { |
| 323 // All helpers are added to resolution queue in enqueueHelpers. These | 380 // All helpers are added to resolution queue in enqueueHelpers. These |
| 324 // calls to [enqueue] with the resolution enqueuer serve as assertions | 381 // calls to [enqueue] with the resolution enqueuer serve as assertions |
| 325 // that the helper was in fact added. | 382 // that the helper was in fact added. |
| 326 // TODO(13155): Find a way to enqueue helpers lazily. | 383 // TODO(13155): Find a way to enqueue helpers lazily. |
| 327 CheckedModeHelper helper = backend.checkedModeHelpers | 384 CheckedModeHelper helper = |
| 328 .getCheckedModeHelper(type, typeCast: false); | 385 _checkedModeHelpers.getCheckedModeHelper(type, typeCast: false); |
| 329 if (helper != null) { | 386 if (helper != null) { |
| 330 StaticUse staticUse = helper.getStaticUse(backend.helpers); | 387 StaticUse staticUse = helper.getStaticUse(_helpers); |
| 331 transformed.registerStaticUse(staticUse); | 388 transformed.registerStaticUse(staticUse); |
| 332 } | 389 } |
| 333 // We also need the native variant of the check (for DOM types). | 390 // We also need the native variant of the check (for DOM types). |
| 334 helper = backend.checkedModeHelpers | 391 helper = |
| 335 .getNativeCheckedModeHelper(type, typeCast: false); | 392 _checkedModeHelpers.getNativeCheckedModeHelper(type, typeCast: false); |
| 336 if (helper != null) { | 393 if (helper != null) { |
| 337 StaticUse staticUse = helper.getStaticUse(backend.helpers); | 394 StaticUse staticUse = helper.getStaticUse(_helpers); |
| 338 transformed.registerStaticUse(staticUse); | 395 transformed.registerStaticUse(staticUse); |
| 339 } | 396 } |
| 340 } | 397 } |
| 341 if (!type.treatAsRaw || type.containsTypeVariables) { | 398 if (!type.treatAsRaw || type.containsTypeVariables) { |
| 342 impacts.genericIsCheck.registerImpact(transformed, elementEnvironment); | 399 _impacts.genericIsCheck.registerImpact(transformed, _elementEnvironment); |
| 343 } | 400 } |
| 344 if (type is ResolutionInterfaceType && | 401 if (type is ResolutionInterfaceType && |
| 345 backend.nativeData.isNativeClass(type.element)) { | 402 _nativeData.isNativeClass(type.element)) { |
| 346 // We will neeed to add the "$is" and "$as" properties on the | 403 // We will neeed to add the "$is" and "$as" properties on the |
| 347 // JavaScript object prototype, so we make sure | 404 // JavaScript object prototype, so we make sure |
| 348 // [:defineProperty:] is compiled. | 405 // [:defineProperty:] is compiled. |
| 349 impacts.nativeTypeCheck.registerImpact(transformed, elementEnvironment); | 406 _impacts.nativeTypeCheck.registerImpact(transformed, _elementEnvironment); |
| 350 } | 407 } |
| 351 } | 408 } |
| 352 | 409 |
| 353 @override | 410 @override |
| 354 WorldImpact transformCodegenImpact(CodegenImpact impact) { | 411 WorldImpact transformCodegenImpact(CodegenImpact impact) { |
| 355 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); | 412 TransformedWorldImpact transformed = new TransformedWorldImpact(impact); |
| 356 | 413 |
| 357 for (TypeUse typeUse in impact.typeUses) { | 414 for (TypeUse typeUse in impact.typeUses) { |
| 358 ResolutionDartType type = typeUse.type; | 415 ResolutionDartType type = typeUse.type; |
| 359 switch (typeUse.kind) { | 416 switch (typeUse.kind) { |
| 360 case TypeUseKind.INSTANTIATION: | 417 case TypeUseKind.INSTANTIATION: |
| 361 backend.lookupMapAnalysis.registerInstantiatedType(type); | 418 _lookupMapAnalysis.registerInstantiatedType(type); |
| 362 break; | 419 break; |
| 363 case TypeUseKind.IS_CHECK: | 420 case TypeUseKind.IS_CHECK: |
| 364 onIsCheckForCodegen(type, transformed); | 421 onIsCheckForCodegen(type, transformed); |
| 365 break; | 422 break; |
| 366 default: | 423 default: |
| 367 } | 424 } |
| 368 } | 425 } |
| 369 | 426 |
| 370 for (ConstantValue constant in impact.compileTimeConstants) { | 427 for (ConstantValue constant in impact.compileTimeConstants) { |
| 371 backend.computeImpactForCompileTimeConstant(constant, transformed, | 428 _backend.computeImpactForCompileTimeConstant(constant, transformed, |
| 372 forResolution: false); | 429 forResolution: false); |
| 373 backend.addCompileTimeConstantForEmission(constant); | 430 _backend.addCompileTimeConstantForEmission(constant); |
| 374 } | 431 } |
| 375 | 432 |
| 376 for (Pair<ResolutionDartType, ResolutionDartType> check | 433 for (Pair<ResolutionDartType, ResolutionDartType> check |
| 377 in impact.typeVariableBoundsSubtypeChecks) { | 434 in impact.typeVariableBoundsSubtypeChecks) { |
| 378 backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); | 435 _backend.registerTypeVariableBoundsSubtypeCheck(check.a, check.b); |
| 379 } | 436 } |
| 380 | 437 |
| 381 for (StaticUse staticUse in impact.staticUses) { | 438 for (StaticUse staticUse in impact.staticUses) { |
| 382 switch (staticUse.kind) { | 439 switch (staticUse.kind) { |
| 383 case StaticUseKind.CLOSURE: | 440 case StaticUseKind.CLOSURE: |
| 384 LocalFunctionElement closure = staticUse.element; | 441 LocalFunctionElement closure = staticUse.element; |
| 385 if (backend.rtiNeed.localFunctionNeedsRti(closure)) { | 442 if (_rtiNeed.localFunctionNeedsRti(closure)) { |
| 386 impacts.computeSignature | 443 _impacts.computeSignature |
| 387 .registerImpact(transformed, elementEnvironment); | 444 .registerImpact(transformed, _elementEnvironment); |
| 388 } | 445 } |
| 389 break; | 446 break; |
| 390 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 447 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 391 case StaticUseKind.CONSTRUCTOR_INVOKE: | 448 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 392 backend.lookupMapAnalysis.registerInstantiatedType(staticUse.type); | 449 _lookupMapAnalysis.registerInstantiatedType(staticUse.type); |
| 393 break; | 450 break; |
| 394 default: | 451 default: |
| 395 } | 452 } |
| 396 } | 453 } |
| 397 | 454 |
| 398 for (String name in impact.constSymbols) { | 455 for (String name in impact.constSymbols) { |
| 399 backend.mirrorsData.registerConstSymbol(name); | 456 _mirrorsData.registerConstSymbol(name); |
| 400 } | 457 } |
| 401 | 458 |
| 402 for (Set<ClassElement> classes in impact.specializedGetInterceptors) { | 459 for (Set<ClassElement> classes in impact.specializedGetInterceptors) { |
| 403 backend.oneShotInterceptorData | 460 _oneShotInterceptorData.registerSpecializedGetInterceptor( |
| 404 .registerSpecializedGetInterceptor(classes, backend.namer); | 461 classes, _namer); |
| 405 } | 462 } |
| 406 | 463 |
| 407 if (impact.usesInterceptor) { | 464 if (impact.usesInterceptor) { |
| 408 if (backend.nativeCodegenEnqueuer.hasInstantiatedNativeClasses) { | 465 if (_nativeCodegenEnqueuer.hasInstantiatedNativeClasses) { |
| 409 impacts.interceptorUse.registerImpact(transformed, elementEnvironment); | 466 _impacts.interceptorUse |
| 467 .registerImpact(transformed, _elementEnvironment); |
| 410 } | 468 } |
| 411 } | 469 } |
| 412 | 470 |
| 413 for (ClassElement element in impact.typeConstants) { | 471 for (ClassElement element in impact.typeConstants) { |
| 414 backend.customElementsCodegenAnalysis.registerTypeConstant(element); | 472 _customElementsCodegenAnalysis.registerTypeConstant(element); |
| 415 backend.lookupMapAnalysis.registerTypeConstant(element); | 473 _lookupMapAnalysis.registerTypeConstant(element); |
| 416 } | 474 } |
| 417 | 475 |
| 418 for (FunctionElement element in impact.asyncMarkers) { | 476 for (FunctionElement element in impact.asyncMarkers) { |
| 419 switch (element.asyncMarker) { | 477 switch (element.asyncMarker) { |
| 420 case AsyncMarker.ASYNC: | 478 case AsyncMarker.ASYNC: |
| 421 impacts.asyncBody.registerImpact(transformed, elementEnvironment); | 479 _impacts.asyncBody.registerImpact(transformed, _elementEnvironment); |
| 422 break; | 480 break; |
| 423 case AsyncMarker.SYNC_STAR: | 481 case AsyncMarker.SYNC_STAR: |
| 424 impacts.syncStarBody.registerImpact(transformed, elementEnvironment); | 482 _impacts.syncStarBody |
| 483 .registerImpact(transformed, _elementEnvironment); |
| 425 break; | 484 break; |
| 426 case AsyncMarker.ASYNC_STAR: | 485 case AsyncMarker.ASYNC_STAR: |
| 427 impacts.asyncStarBody.registerImpact(transformed, elementEnvironment); | 486 _impacts.asyncStarBody |
| 487 .registerImpact(transformed, _elementEnvironment); |
| 428 break; | 488 break; |
| 429 } | 489 } |
| 430 } | 490 } |
| 431 | 491 |
| 432 // TODO(johnniwinther): Remove eager registration. | 492 // TODO(johnniwinther): Remove eager registration. |
| 433 return transformed; | 493 return transformed; |
| 434 } | 494 } |
| 435 } | 495 } |
| OLD | NEW |