Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(757)

Side by Side Diff: pkg/compiler/lib/src/js_backend/impact_transformer.dart

Issue 2728393005: Extract CodegenImpactTransformer from ImpactTransformer (Closed)
Patch Set: Updated cf. comments. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/backend.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698