OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.enqueue; | 5 library dart2js.enqueue; |
6 | 6 |
7 import 'dart:collection' show | 7 import 'dart:collection' show Queue; |
8 Queue; | |
9 | 8 |
10 import 'common.dart'; | 9 import 'common.dart'; |
11 import 'common/names.dart' show | 10 import 'common/names.dart' show Identifiers; |
12 Identifiers; | 11 import 'common/resolution.dart' show Resolution; |
13 import 'common/resolution.dart' show | 12 import 'common/work.dart' show ItemCompilationContext, WorkItem; |
14 Resolution; | 13 import 'common/tasks.dart' show CompilerTask, DeferredAction, DeferredTask; |
15 import 'common/work.dart' show | 14 import 'common/codegen.dart' show CodegenWorkItem; |
16 ItemCompilationContext, | 15 import 'common/resolution.dart' show ResolutionWorkItem; |
17 WorkItem; | 16 import 'compiler.dart' show Compiler; |
18 import 'common/tasks.dart' show | 17 import 'dart_types.dart' show DartType, InterfaceType; |
19 CompilerTask, | 18 import 'elements/elements.dart' |
20 DeferredAction, | 19 show |
21 DeferredTask; | 20 AnalyzableElement, |
22 import 'common/codegen.dart' show | 21 AstElement, |
23 CodegenWorkItem; | 22 ClassElement, |
24 import 'common/resolution.dart' show | 23 ConstructorElement, |
25 ResolutionWorkItem; | 24 Element, |
26 import 'compiler.dart' show | 25 Elements, |
27 Compiler; | 26 FunctionElement, |
28 import 'dart_types.dart' show | 27 LibraryElement, |
29 DartType, | 28 LocalFunctionElement, |
30 InterfaceType; | 29 Member, |
31 import 'elements/elements.dart' show | 30 MemberElement, |
32 AnalyzableElement, | 31 MethodElement, |
33 AstElement, | 32 Name, |
34 ClassElement, | 33 TypedElement, |
35 ConstructorElement, | 34 TypedefElement; |
36 Element, | |
37 Elements, | |
38 FunctionElement, | |
39 LibraryElement, | |
40 LocalFunctionElement, | |
41 Member, | |
42 MemberElement, | |
43 MethodElement, | |
44 Name, | |
45 TypedElement, | |
46 TypedefElement; | |
47 import 'js/js.dart' as js; | 35 import 'js/js.dart' as js; |
48 import 'native/native.dart' as native; | 36 import 'native/native.dart' as native; |
49 import 'types/types.dart' show | 37 import 'types/types.dart' show TypeMaskStrategy; |
50 TypeMaskStrategy; | 38 import 'universe/selector.dart' show Selector; |
51 import 'universe/selector.dart' show | |
52 Selector; | |
53 import 'universe/universe.dart'; | 39 import 'universe/universe.dart'; |
54 import 'universe/use.dart' show | 40 import 'universe/use.dart' |
55 DynamicUse, | 41 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
56 StaticUse, | 42 import 'universe/world_impact.dart' |
57 StaticUseKind, | 43 show ImpactUseCase, WorldImpact, WorldImpactVisitor; |
58 TypeUse, | 44 import 'util/util.dart' show Link, Setlet; |
59 TypeUseKind; | |
60 import 'universe/world_impact.dart' show | |
61 ImpactUseCase, | |
62 WorldImpact, | |
63 WorldImpactVisitor; | |
64 import 'util/util.dart' show | |
65 Link, | |
66 Setlet; | |
67 | 45 |
68 typedef ItemCompilationContext ItemCompilationContextCreator(); | 46 typedef ItemCompilationContext ItemCompilationContextCreator(); |
69 | 47 |
70 class EnqueueTask extends CompilerTask { | 48 class EnqueueTask extends CompilerTask { |
71 final ResolutionEnqueuer resolution; | 49 final ResolutionEnqueuer resolution; |
72 final CodegenEnqueuer codegen; | 50 final CodegenEnqueuer codegen; |
73 | 51 |
74 String get name => 'Enqueue'; | 52 String get name => 'Enqueue'; |
75 | 53 |
76 EnqueueTask(Compiler compiler) | 54 EnqueueTask(Compiler compiler) |
77 : resolution = new ResolutionEnqueuer( | 55 : resolution = new ResolutionEnqueuer( |
78 compiler, compiler.backend.createItemCompilationContext, | 56 compiler, |
79 compiler.options.analyzeOnly && compiler.options.analyzeMain | 57 compiler.backend.createItemCompilationContext, |
80 ? const EnqueuerStrategy() : const TreeShakingEnqueuerStrategy()), | 58 compiler.options.analyzeOnly && compiler.options.analyzeMain |
81 codegen = new CodegenEnqueuer( | 59 ? const EnqueuerStrategy() |
82 compiler, compiler.backend.createItemCompilationContext, | 60 : const TreeShakingEnqueuerStrategy()), |
83 const TreeShakingEnqueuerStrategy()), | 61 codegen = new CodegenEnqueuer( |
84 super(compiler) { | 62 compiler, |
| 63 compiler.backend.createItemCompilationContext, |
| 64 const TreeShakingEnqueuerStrategy()), |
| 65 super(compiler) { |
85 codegen.task = this; | 66 codegen.task = this; |
86 resolution.task = this; | 67 resolution.task = this; |
87 | 68 |
88 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen); | 69 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen); |
89 resolution.nativeEnqueuer = | 70 resolution.nativeEnqueuer = |
90 compiler.backend.nativeResolutionEnqueuer(resolution); | 71 compiler.backend.nativeResolutionEnqueuer(resolution); |
91 } | 72 } |
92 | 73 |
93 void forgetElement(Element element) { | 74 void forgetElement(Element element) { |
94 resolution.forgetElement(element); | 75 resolution.forgetElement(element); |
95 codegen.forgetElement(element); | 76 codegen.forgetElement(element); |
96 } | 77 } |
97 } | 78 } |
98 | 79 |
99 abstract class Enqueuer { | 80 abstract class Enqueuer { |
100 final String name; | 81 final String name; |
101 final Compiler compiler; // TODO(ahe): Remove this dependency. | 82 final Compiler compiler; // TODO(ahe): Remove this dependency. |
102 final EnqueuerStrategy strategy; | 83 final EnqueuerStrategy strategy; |
103 final ItemCompilationContextCreator itemCompilationContextCreator; | 84 final ItemCompilationContextCreator itemCompilationContextCreator; |
104 final Map<String, Set<Element>> instanceMembersByName | 85 final Map<String, Set<Element>> instanceMembersByName = |
105 = new Map<String, Set<Element>>(); | 86 new Map<String, Set<Element>>(); |
106 final Map<String, Set<Element>> instanceFunctionsByName | 87 final Map<String, Set<Element>> instanceFunctionsByName = |
107 = new Map<String, Set<Element>>(); | 88 new Map<String, Set<Element>>(); |
108 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); | 89 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); |
109 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); | 90 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); |
110 final Universe universe = new Universe(const TypeMaskStrategy()); | 91 final Universe universe = new Universe(const TypeMaskStrategy()); |
111 | 92 |
112 static final TRACE_MIRROR_ENQUEUING = | 93 static final TRACE_MIRROR_ENQUEUING = |
113 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | 94 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); |
114 | 95 |
115 bool queueIsClosed = false; | 96 bool queueIsClosed = false; |
116 EnqueueTask task; | 97 EnqueueTask task; |
117 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 98 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
118 | 99 |
119 bool hasEnqueuedReflectiveElements = false; | 100 bool hasEnqueuedReflectiveElements = false; |
120 bool hasEnqueuedReflectiveStaticFields = false; | 101 bool hasEnqueuedReflectiveStaticFields = false; |
121 | 102 |
122 WorldImpactVisitor impactVisitor; | 103 WorldImpactVisitor impactVisitor; |
123 | 104 |
124 Enqueuer(this.name, | 105 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator, |
125 this.compiler, | 106 this.strategy) { |
126 this.itemCompilationContextCreator, | |
127 this.strategy) { | |
128 impactVisitor = new _EnqueuerImpactVisitor(this); | 107 impactVisitor = new _EnqueuerImpactVisitor(this); |
129 } | 108 } |
130 | 109 |
131 // TODO(johnniwinther): Move this to [ResolutionEnqueuer]. | 110 // TODO(johnniwinther): Move this to [ResolutionEnqueuer]. |
132 Resolution get resolution => compiler.resolution; | 111 Resolution get resolution => compiler.resolution; |
133 | 112 |
134 Queue<WorkItem> get queue; | 113 Queue<WorkItem> get queue; |
135 bool get queueIsEmpty => queue.isEmpty; | 114 bool get queueIsEmpty => queue.isEmpty; |
136 | 115 |
137 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 116 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
(...skipping 15 matching lines...) Expand all Loading... |
153 /** | 132 /** |
154 * Documentation wanted -- johnniwinther | 133 * Documentation wanted -- johnniwinther |
155 * | 134 * |
156 * Invariant: [element] must be a declaration element. | 135 * Invariant: [element] must be a declaration element. |
157 */ | 136 */ |
158 void addToWorkList(Element element) { | 137 void addToWorkList(Element element) { |
159 assert(invariant(element, element.isDeclaration)); | 138 assert(invariant(element, element.isDeclaration)); |
160 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { | 139 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { |
161 // TODO(sigmund): add other missing dependencies (internals, selectors | 140 // TODO(sigmund): add other missing dependencies (internals, selectors |
162 // enqueued after allocations), also enable only for the codegen enqueuer. | 141 // enqueued after allocations), also enable only for the codegen enqueuer. |
163 compiler.dumpInfoTask.registerDependency( | 142 compiler.dumpInfoTask |
164 compiler.currentElement, element); | 143 .registerDependency(compiler.currentElement, element); |
165 } | 144 } |
166 } | 145 } |
167 | 146 |
168 /** | 147 /** |
169 * Adds [element] to the work list if it has not already been processed. | 148 * Adds [element] to the work list if it has not already been processed. |
170 * | 149 * |
171 * Returns [true] if the element was actually added to the queue. | 150 * Returns [true] if the element was actually added to the queue. |
172 */ | 151 */ |
173 bool internalAddToWorkList(Element element); | 152 bool internalAddToWorkList(Element element); |
174 | 153 |
175 /// Apply the [worldImpact] of processing [element] to this enqueuer. | 154 /// Apply the [worldImpact] of processing [element] to this enqueuer. |
176 void applyImpact(Element element, WorldImpact worldImpact) { | 155 void applyImpact(Element element, WorldImpact worldImpact) { |
177 compiler.impactStrategy.visitImpact( | 156 compiler.impactStrategy |
178 element, worldImpact, impactVisitor, impactUse); | 157 .visitImpact(element, worldImpact, impactVisitor, impactUse); |
179 } | 158 } |
180 | 159 |
181 void registerInstantiatedType(InterfaceType type, | 160 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { |
182 {bool mirrorUsage: false}) { | |
183 task.measure(() { | 161 task.measure(() { |
184 ClassElement cls = type.element; | 162 ClassElement cls = type.element; |
185 cls.ensureResolved(resolution); | 163 cls.ensureResolved(resolution); |
186 bool isNative = compiler.backend.isNative(cls); | 164 bool isNative = compiler.backend.isNative(cls); |
187 universe.registerTypeInstantiation( | 165 universe.registerTypeInstantiation(type, |
188 type, | |
189 isNative: isNative, | 166 isNative: isNative, |
190 byMirrors: mirrorUsage, | 167 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { |
191 onImplemented: (ClassElement cls) { | 168 compiler.backend |
192 compiler.backend.registerImplementedClass( | 169 .registerImplementedClass(cls, this, compiler.globalDependencies); |
193 cls, this, compiler.globalDependencies); | |
194 }); | 170 }); |
195 // TODO(johnniwinther): Share this reasoning with [Universe]. | 171 // TODO(johnniwinther): Share this reasoning with [Universe]. |
196 if (!cls.isAbstract || isNative || mirrorUsage) { | 172 if (!cls.isAbstract || isNative || mirrorUsage) { |
197 processInstantiatedClass(cls); | 173 processInstantiatedClass(cls); |
198 } | 174 } |
199 }); | 175 }); |
200 } | 176 } |
201 | 177 |
202 bool checkNoEnqueuedInvokedInstanceMethods() { | 178 bool checkNoEnqueuedInvokedInstanceMethods() { |
203 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 179 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 // away). | 229 // away). |
254 addToWorkList(member); | 230 addToWorkList(member); |
255 return; | 231 return; |
256 } | 232 } |
257 } else if (member.isFunction) { | 233 } else if (member.isFunction) { |
258 FunctionElement function = member; | 234 FunctionElement function = member; |
259 function.computeType(resolution); | 235 function.computeType(resolution); |
260 if (function.name == Identifiers.noSuchMethod_) { | 236 if (function.name == Identifiers.noSuchMethod_) { |
261 registerNoSuchMethod(function); | 237 registerNoSuchMethod(function); |
262 } | 238 } |
263 if (function.name == Identifiers.call && | 239 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { |
264 !cls.typeVariables.isEmpty) { | |
265 registerCallMethodWithFreeTypeVariables(function); | 240 registerCallMethodWithFreeTypeVariables(function); |
266 } | 241 } |
267 // If there is a property access with the same name as a method we | 242 // If there is a property access with the same name as a method we |
268 // need to emit the method. | 243 // need to emit the method. |
269 if (universe.hasInvokedGetter(function, compiler.world)) { | 244 if (universe.hasInvokedGetter(function, compiler.world)) { |
270 registerClosurizedMember(function); | 245 registerClosurizedMember(function); |
271 addToWorkList(function); | 246 addToWorkList(function); |
272 return; | 247 return; |
273 } | 248 } |
274 // Store the member in [instanceFunctionsByName] to catch | 249 // Store the member in [instanceFunctionsByName] to catch |
275 // getters on the function. | 250 // getters on the function. |
276 instanceFunctionsByName.putIfAbsent(memberName, () => new Set<Element>()) | 251 instanceFunctionsByName |
| 252 .putIfAbsent(memberName, () => new Set<Element>()) |
277 .add(member); | 253 .add(member); |
278 if (universe.hasInvocation(function, compiler.world)) { | 254 if (universe.hasInvocation(function, compiler.world)) { |
279 addToWorkList(function); | 255 addToWorkList(function); |
280 return; | 256 return; |
281 } | 257 } |
282 } else if (member.isGetter) { | 258 } else if (member.isGetter) { |
283 FunctionElement getter = member; | 259 FunctionElement getter = member; |
284 getter.computeType(resolution); | 260 getter.computeType(resolution); |
285 if (universe.hasInvokedGetter(getter, compiler.world)) { | 261 if (universe.hasInvokedGetter(getter, compiler.world)) { |
286 addToWorkList(getter); | 262 addToWorkList(getter); |
287 return; | 263 return; |
288 } | 264 } |
289 // We don't know what selectors the returned closure accepts. If | 265 // We don't know what selectors the returned closure accepts. If |
290 // the set contains any selector we have to assume that it matches. | 266 // the set contains any selector we have to assume that it matches. |
291 if (universe.hasInvocation(getter, compiler.world)) { | 267 if (universe.hasInvocation(getter, compiler.world)) { |
292 addToWorkList(getter); | 268 addToWorkList(getter); |
293 return; | 269 return; |
294 } | 270 } |
295 } else if (member.isSetter) { | 271 } else if (member.isSetter) { |
296 FunctionElement setter = member; | 272 FunctionElement setter = member; |
297 setter.computeType(resolution); | 273 setter.computeType(resolution); |
298 if (universe.hasInvokedSetter(setter, compiler.world)) { | 274 if (universe.hasInvokedSetter(setter, compiler.world)) { |
299 addToWorkList(setter); | 275 addToWorkList(setter); |
300 return; | 276 return; |
301 } | 277 } |
302 } | 278 } |
303 | 279 |
304 // The element is not yet used. Add it to the list of instance | 280 // The element is not yet used. Add it to the list of instance |
305 // members to still be processed. | 281 // members to still be processed. |
306 instanceMembersByName.putIfAbsent(memberName, () => new Set<Element>()) | 282 instanceMembersByName |
| 283 .putIfAbsent(memberName, () => new Set<Element>()) |
307 .add(member); | 284 .add(member); |
308 } | 285 } |
309 | 286 |
310 void registerNoSuchMethod(Element noSuchMethod); | 287 void registerNoSuchMethod(Element noSuchMethod); |
311 | 288 |
312 void enableIsolateSupport() {} | 289 void enableIsolateSupport() {} |
313 | 290 |
314 void processInstantiatedClass(ClassElement cls) { | 291 void processInstantiatedClass(ClassElement cls) { |
315 task.measure(() { | 292 task.measure(() { |
316 if (_processedClasses.contains(cls)) return; | 293 if (_processedClasses.contains(cls)) return; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 } | 338 } |
362 | 339 |
363 /** | 340 /** |
364 * Decides whether an element should be included to satisfy requirements | 341 * Decides whether an element should be included to satisfy requirements |
365 * of the mirror system. [includedEnclosing] provides a hint whether the | 342 * of the mirror system. [includedEnclosing] provides a hint whether the |
366 * enclosing element was included. | 343 * enclosing element was included. |
367 * | 344 * |
368 * The actual implementation depends on the current compiler phase. | 345 * The actual implementation depends on the current compiler phase. |
369 */ | 346 */ |
370 bool shouldIncludeElementDueToMirrors(Element element, | 347 bool shouldIncludeElementDueToMirrors(Element element, |
371 {bool includedEnclosing}); | 348 {bool includedEnclosing}); |
372 | 349 |
373 void logEnqueueReflectiveAction(action, [msg = ""]) { | 350 void logEnqueueReflectiveAction(action, [msg = ""]) { |
374 if (TRACE_MIRROR_ENQUEUING) { | 351 if (TRACE_MIRROR_ENQUEUING) { |
375 print("MIRROR_ENQUEUE (${isResolutionQueue ? "R" : "C"}): $action $msg"); | 352 print("MIRROR_ENQUEUE (${isResolutionQueue ? "R" : "C"}): $action $msg"); |
376 } | 353 } |
377 } | 354 } |
378 | 355 |
379 /// Enqeue the constructor [ctor] if it is required for reflection. | 356 /// Enqeue the constructor [ctor] if it is required for reflection. |
380 /// | 357 /// |
381 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 358 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
382 /// needed for reflection. | 359 /// needed for reflection. |
383 void enqueueReflectiveConstructor(ConstructorElement ctor, | 360 void enqueueReflectiveConstructor( |
384 bool enclosingWasIncluded) { | 361 ConstructorElement ctor, bool enclosingWasIncluded) { |
385 if (shouldIncludeElementDueToMirrors(ctor, | 362 if (shouldIncludeElementDueToMirrors(ctor, |
386 includedEnclosing: enclosingWasIncluded)) { | 363 includedEnclosing: enclosingWasIncluded)) { |
387 logEnqueueReflectiveAction(ctor); | 364 logEnqueueReflectiveAction(ctor); |
388 ClassElement cls = ctor.declaration.enclosingClass; | 365 ClassElement cls = ctor.declaration.enclosingClass; |
389 compiler.backend.registerInstantiatedType( | 366 compiler.backend.registerInstantiatedType( |
390 cls.rawType, | 367 cls.rawType, this, compiler.mirrorDependencies, |
391 this, | |
392 compiler.mirrorDependencies, | |
393 mirrorUsage: true); | 368 mirrorUsage: true); |
394 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); | 369 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); |
395 } | 370 } |
396 } | 371 } |
397 | 372 |
398 /// Enqeue the member [element] if it is required for reflection. | 373 /// Enqeue the member [element] if it is required for reflection. |
399 /// | 374 /// |
400 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 375 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
401 /// needed for reflection. | 376 /// needed for reflection. |
402 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { | 377 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { |
403 if (shouldIncludeElementDueToMirrors(element, | 378 if (shouldIncludeElementDueToMirrors(element, |
404 includedEnclosing: enclosingWasIncluded)) { | 379 includedEnclosing: enclosingWasIncluded)) { |
405 logEnqueueReflectiveAction(element); | 380 logEnqueueReflectiveAction(element); |
406 if (element.isTypedef) { | 381 if (element.isTypedef) { |
407 TypedefElement typedef = element; | 382 TypedefElement typedef = element; |
408 typedef.ensureResolved(resolution); | 383 typedef.ensureResolved(resolution); |
409 compiler.world.allTypedefs.add(element); | 384 compiler.world.allTypedefs.add(element); |
410 } else if (Elements.isStaticOrTopLevel(element)) { | 385 } else if (Elements.isStaticOrTopLevel(element)) { |
411 registerStaticUse(new StaticUse.foreignUse(element.declaration)); | 386 registerStaticUse(new StaticUse.foreignUse(element.declaration)); |
412 } else if (element.isInstanceMember) { | 387 } else if (element.isInstanceMember) { |
413 // We need to enqueue all members matching this one in subclasses, as | 388 // We need to enqueue all members matching this one in subclasses, as |
414 // well. | 389 // well. |
415 // TODO(herhut): Use TypedSelector.subtype for enqueueing | 390 // TODO(herhut): Use TypedSelector.subtype for enqueueing |
416 DynamicUse dynamicUse = new DynamicUse( | 391 DynamicUse dynamicUse = |
417 new Selector.fromElement(element), null); | 392 new DynamicUse(new Selector.fromElement(element), null); |
418 registerDynamicUse(dynamicUse); | 393 registerDynamicUse(dynamicUse); |
419 if (element.isField) { | 394 if (element.isField) { |
420 DynamicUse dynamicUse = new DynamicUse( | 395 DynamicUse dynamicUse = new DynamicUse( |
421 new Selector.setter(new Name( | 396 new Selector.setter( |
422 element.name, element.library, isSetter: true)), null); | 397 new Name(element.name, element.library, isSetter: true)), |
| 398 null); |
423 registerDynamicUse(dynamicUse); | 399 registerDynamicUse(dynamicUse); |
424 } | 400 } |
425 } | 401 } |
426 } | 402 } |
427 } | 403 } |
428 | 404 |
429 /// Enqeue the member [element] if it is required for reflection. | 405 /// Enqeue the member [element] if it is required for reflection. |
430 /// | 406 /// |
431 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 407 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
432 /// needed for reflection. | 408 /// needed for reflection. |
433 void enqueueReflectiveElementsInClass(ClassElement cls, | 409 void enqueueReflectiveElementsInClass(ClassElement cls, |
434 Iterable<ClassElement> recents, | 410 Iterable<ClassElement> recents, bool enclosingWasIncluded) { |
435 bool enclosingWasIncluded) { | |
436 if (cls.library.isInternalLibrary || cls.isInjected) return; | 411 if (cls.library.isInternalLibrary || cls.isInjected) return; |
437 bool includeClass = shouldIncludeElementDueToMirrors(cls, | 412 bool includeClass = shouldIncludeElementDueToMirrors(cls, |
438 includedEnclosing: enclosingWasIncluded); | 413 includedEnclosing: enclosingWasIncluded); |
439 if (includeClass) { | 414 if (includeClass) { |
440 logEnqueueReflectiveAction(cls, "register"); | 415 logEnqueueReflectiveAction(cls, "register"); |
441 ClassElement decl = cls.declaration; | 416 ClassElement decl = cls.declaration; |
442 decl.ensureResolved(resolution); | 417 decl.ensureResolved(resolution); |
443 compiler.backend.registerInstantiatedType( | 418 compiler.backend.registerInstantiatedType( |
444 decl.rawType, | 419 decl.rawType, this, compiler.mirrorDependencies, |
445 this, | |
446 compiler.mirrorDependencies, | |
447 mirrorUsage: true); | 420 mirrorUsage: true); |
448 } | 421 } |
449 // If the class is never instantiated, we know nothing of it can possibly | 422 // If the class is never instantiated, we know nothing of it can possibly |
450 // be reflected upon. | 423 // be reflected upon. |
451 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | 424 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. |
452 if (recents.contains(cls.declaration)) { | 425 if (recents.contains(cls.declaration)) { |
453 logEnqueueReflectiveAction(cls, "members"); | 426 logEnqueueReflectiveAction(cls, "members"); |
454 cls.constructors.forEach((Element element) { | 427 cls.constructors.forEach((Element element) { |
455 enqueueReflectiveConstructor(element, includeClass); | 428 enqueueReflectiveConstructor(element, includeClass); |
456 }); | 429 }); |
(...skipping 11 matching lines...) Expand all Loading... |
468 /// that none of its methods are reflectable, unless reflectable by | 441 /// that none of its methods are reflectable, unless reflectable by |
469 /// inheritance. | 442 /// inheritance. |
470 void enqueueReflectiveSpecialClasses() { | 443 void enqueueReflectiveSpecialClasses() { |
471 Iterable<ClassElement> classes = | 444 Iterable<ClassElement> classes = |
472 compiler.backend.classesRequiredForReflection; | 445 compiler.backend.classesRequiredForReflection; |
473 for (ClassElement cls in classes) { | 446 for (ClassElement cls in classes) { |
474 if (compiler.backend.referencedFromMirrorSystem(cls)) { | 447 if (compiler.backend.referencedFromMirrorSystem(cls)) { |
475 logEnqueueReflectiveAction(cls); | 448 logEnqueueReflectiveAction(cls); |
476 cls.ensureResolved(resolution); | 449 cls.ensureResolved(resolution); |
477 compiler.backend.registerInstantiatedType( | 450 compiler.backend.registerInstantiatedType( |
478 cls.rawType, | 451 cls.rawType, this, compiler.mirrorDependencies, |
479 this, | |
480 compiler.mirrorDependencies, | |
481 mirrorUsage: true); | 452 mirrorUsage: true); |
482 } | 453 } |
483 } | 454 } |
484 } | 455 } |
485 | 456 |
486 /// Enqeue all local members of the library [lib] if they are required for | 457 /// Enqeue all local members of the library [lib] if they are required for |
487 /// reflection. | 458 /// reflection. |
488 void enqueueReflectiveElementsInLibrary(LibraryElement lib, | 459 void enqueueReflectiveElementsInLibrary( |
489 Iterable<ClassElement> recents) { | 460 LibraryElement lib, Iterable<ClassElement> recents) { |
490 bool includeLibrary = shouldIncludeElementDueToMirrors(lib, | 461 bool includeLibrary = |
491 includedEnclosing: false); | 462 shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); |
492 lib.forEachLocalMember((Element member) { | 463 lib.forEachLocalMember((Element member) { |
493 if (member.isClass) { | 464 if (member.isClass) { |
494 enqueueReflectiveElementsInClass(member, recents, includeLibrary); | 465 enqueueReflectiveElementsInClass(member, recents, includeLibrary); |
495 } else { | 466 } else { |
496 enqueueReflectiveMember(member, includeLibrary); | 467 enqueueReflectiveMember(member, includeLibrary); |
497 } | 468 } |
498 }); | 469 }); |
499 } | 470 } |
500 | 471 |
501 /// Enqueue all elements that are matched by the mirrors used | 472 /// Enqueue all elements that are matched by the mirrors used |
(...skipping 13 matching lines...) Expand all Loading... |
515 enqueueReflectiveElementsInLibrary(lib, recents); | 486 enqueueReflectiveElementsInLibrary(lib, recents); |
516 } | 487 } |
517 enqueueReflectiveSpecialClasses(); | 488 enqueueReflectiveSpecialClasses(); |
518 hasEnqueuedReflectiveElements = true; | 489 hasEnqueuedReflectiveElements = true; |
519 hasEnqueuedReflectiveStaticFields = true; | 490 hasEnqueuedReflectiveStaticFields = true; |
520 logEnqueueReflectiveAction("!DONE enqueueAll"); | 491 logEnqueueReflectiveAction("!DONE enqueueAll"); |
521 } else if (recents.isNotEmpty) { | 492 } else if (recents.isNotEmpty) { |
522 // Keep looking at new classes until fixpoint is reached. | 493 // Keep looking at new classes until fixpoint is reached. |
523 logEnqueueReflectiveAction("!START enqueueRecents"); | 494 logEnqueueReflectiveAction("!START enqueueRecents"); |
524 recents.forEach((ClassElement cls) { | 495 recents.forEach((ClassElement cls) { |
525 enqueueReflectiveElementsInClass(cls, recents, | 496 enqueueReflectiveElementsInClass( |
| 497 cls, |
| 498 recents, |
526 shouldIncludeElementDueToMirrors(cls.library, | 499 shouldIncludeElementDueToMirrors(cls.library, |
527 includedEnclosing: false)); | 500 includedEnclosing: false)); |
528 }); | 501 }); |
529 logEnqueueReflectiveAction("!DONE enqueueRecents"); | 502 logEnqueueReflectiveAction("!DONE enqueueRecents"); |
530 } | 503 } |
531 } | 504 } |
532 | 505 |
533 /// Enqueue the static fields that have been marked as used by reflective | 506 /// Enqueue the static fields that have been marked as used by reflective |
534 /// usage through `MirrorsUsed`. | 507 /// usage through `MirrorsUsed`. |
535 void enqueueReflectiveStaticFields(Iterable<Element> elements) { | 508 void enqueueReflectiveStaticFields(Iterable<Element> elements) { |
536 if (hasEnqueuedReflectiveStaticFields) return; | 509 if (hasEnqueuedReflectiveStaticFields) return; |
537 hasEnqueuedReflectiveStaticFields = true; | 510 hasEnqueuedReflectiveStaticFields = true; |
538 for (Element element in elements) { | 511 for (Element element in elements) { |
539 enqueueReflectiveMember(element, true); | 512 enqueueReflectiveMember(element, true); |
540 } | 513 } |
541 } | 514 } |
542 | 515 |
543 void processSet( | 516 void processSet( |
544 Map<String, Set<Element>> map, | 517 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { |
545 String memberName, | |
546 bool f(Element e)) { | |
547 Set<Element> members = map[memberName]; | 518 Set<Element> members = map[memberName]; |
548 if (members == null) return; | 519 if (members == null) return; |
549 // [f] might add elements to [: map[memberName] :] during the loop below | 520 // [f] might add elements to [: map[memberName] :] during the loop below |
550 // so we create a new list for [: map[memberName] :] and prepend the | 521 // so we create a new list for [: map[memberName] :] and prepend the |
551 // [remaining] members after the loop. | 522 // [remaining] members after the loop. |
552 map[memberName] = new Set<Element>(); | 523 map[memberName] = new Set<Element>(); |
553 Set<Element> remaining = new Set<Element>(); | 524 Set<Element> remaining = new Set<Element>(); |
554 for (Element member in members) { | 525 for (Element member in members) { |
555 if (!f(member)) remaining.add(member); | 526 if (!f(member)) remaining.add(member); |
556 } | 527 } |
(...skipping 13 matching lines...) Expand all Loading... |
570 } | 541 } |
571 | 542 |
572 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { | 543 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { |
573 Selector selector = dynamicUse.selector; | 544 Selector selector = dynamicUse.selector; |
574 String methodName = selector.name; | 545 String methodName = selector.name; |
575 processInstanceMembers(methodName, (Element member) { | 546 processInstanceMembers(methodName, (Element member) { |
576 if (dynamicUse.appliesUnnamed(member, compiler.world)) { | 547 if (dynamicUse.appliesUnnamed(member, compiler.world)) { |
577 if (member.isFunction && selector.isGetter) { | 548 if (member.isFunction && selector.isGetter) { |
578 registerClosurizedMember(member); | 549 registerClosurizedMember(member); |
579 } | 550 } |
580 if (member.isField && compiler.backend.isNative(member.enclosingClass))
{ | 551 if (member.isField && |
| 552 compiler.backend.isNative(member.enclosingClass)) { |
581 if (selector.isGetter || selector.isCall) { | 553 if (selector.isGetter || selector.isCall) { |
582 nativeEnqueuer.registerFieldLoad(member); | 554 nativeEnqueuer.registerFieldLoad(member); |
583 // We have to also handle storing to the field because we only get | 555 // We have to also handle storing to the field because we only get |
584 // one look at each member and there might be a store we have not | 556 // one look at each member and there might be a store we have not |
585 // seen yet. | 557 // seen yet. |
586 // TODO(sra): Process fields for storing separately. | 558 // TODO(sra): Process fields for storing separately. |
587 nativeEnqueuer.registerFieldStore(member); | 559 nativeEnqueuer.registerFieldStore(member); |
588 } else { | 560 } else { |
589 assert(selector.isSetter); | 561 assert(selector.isSetter); |
590 nativeEnqueuer.registerFieldStore(member); | 562 nativeEnqueuer.registerFieldStore(member); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 case TypeUseKind.TYPE_LITERAL: | 642 case TypeUseKind.TYPE_LITERAL: |
671 break; | 643 break; |
672 } | 644 } |
673 } | 645 } |
674 | 646 |
675 void _registerIsCheck(DartType type) { | 647 void _registerIsCheck(DartType type) { |
676 type = universe.registerIsCheck(type, compiler); | 648 type = universe.registerIsCheck(type, compiler); |
677 // Even in checked mode, type annotations for return type and argument | 649 // Even in checked mode, type annotations for return type and argument |
678 // types do not imply type checks, so there should never be a check | 650 // types do not imply type checks, so there should never be a check |
679 // against the type variable of a typedef. | 651 // against the type variable of a typedef. |
680 assert(!type.isTypeVariable || | 652 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
681 !type.element.enclosingElement.isTypedef); | |
682 } | 653 } |
683 | 654 |
684 void registerCallMethodWithFreeTypeVariables(Element element) { | 655 void registerCallMethodWithFreeTypeVariables(Element element) { |
685 compiler.backend.registerCallMethodWithFreeTypeVariables( | 656 compiler.backend.registerCallMethodWithFreeTypeVariables( |
686 element, this, compiler.globalDependencies); | 657 element, this, compiler.globalDependencies); |
687 universe.callMethodsWithFreeTypeVariables.add(element); | 658 universe.callMethodsWithFreeTypeVariables.add(element); |
688 } | 659 } |
689 | 660 |
690 void registerClosurizedMember(TypedElement element) { | 661 void registerClosurizedMember(TypedElement element) { |
691 assert(element.isInstanceMember); | 662 assert(element.isInstanceMember); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 final Set<AstElement> processedElements; | 712 final Set<AstElement> processedElements; |
742 | 713 |
743 final Queue<ResolutionWorkItem> queue; | 714 final Queue<ResolutionWorkItem> queue; |
744 | 715 |
745 /** | 716 /** |
746 * A deferred task queue for the resolution phase which is processed | 717 * A deferred task queue for the resolution phase which is processed |
747 * when the resolution queue has been emptied. | 718 * when the resolution queue has been emptied. |
748 */ | 719 */ |
749 final Queue<DeferredTask> deferredTaskQueue; | 720 final Queue<DeferredTask> deferredTaskQueue; |
750 | 721 |
751 static const ImpactUseCase IMPACT_USE = const ImpactUseCase('ResolutionEnqueue
r'); | 722 static const ImpactUseCase IMPACT_USE = |
| 723 const ImpactUseCase('ResolutionEnqueuer'); |
752 | 724 |
753 ImpactUseCase get impactUse => IMPACT_USE; | 725 ImpactUseCase get impactUse => IMPACT_USE; |
754 | 726 |
755 ResolutionEnqueuer(Compiler compiler, | 727 ResolutionEnqueuer( |
756 ItemCompilationContext itemCompilationContextCreator(), | 728 Compiler compiler, |
757 EnqueuerStrategy strategy) | 729 ItemCompilationContext itemCompilationContextCreator(), |
758 : super('resolution enqueuer', | 730 EnqueuerStrategy strategy) |
759 compiler, | 731 : super('resolution enqueuer', compiler, itemCompilationContextCreator, |
760 itemCompilationContextCreator, | 732 strategy), |
761 strategy), | |
762 processedElements = new Set<AstElement>(), | 733 processedElements = new Set<AstElement>(), |
763 queue = new Queue<ResolutionWorkItem>(), | 734 queue = new Queue<ResolutionWorkItem>(), |
764 deferredTaskQueue = new Queue<DeferredTask>(); | 735 deferredTaskQueue = new Queue<DeferredTask>(); |
765 | 736 |
766 bool get isResolutionQueue => true; | 737 bool get isResolutionQueue => true; |
767 | 738 |
768 bool isProcessed(Element member) => processedElements.contains(member); | 739 bool isProcessed(Element member) => processedElements.contains(member); |
769 | 740 |
770 /// Returns `true` if [element] has been processed by the resolution enqueuer. | 741 /// Returns `true` if [element] has been processed by the resolution enqueuer. |
771 bool hasBeenProcessed(Element element) { | 742 bool hasBeenProcessed(Element element) { |
772 return processedElements.contains(element.analyzableElement.declaration); | 743 return processedElements.contains(element.analyzableElement.declaration); |
773 } | 744 } |
774 | 745 |
775 /// Registers [element] as processed by the resolution enqueuer. | 746 /// Registers [element] as processed by the resolution enqueuer. |
776 void registerProcessedElement(AstElement element) { | 747 void registerProcessedElement(AstElement element) { |
777 processedElements.add(element); | 748 processedElements.add(element); |
778 } | 749 } |
779 | 750 |
780 /** | 751 /** |
781 * Decides whether an element should be included to satisfy requirements | 752 * Decides whether an element should be included to satisfy requirements |
782 * of the mirror system. | 753 * of the mirror system. |
783 * | 754 * |
784 * During resolution, we have to resort to matching elements against the | 755 * During resolution, we have to resort to matching elements against the |
785 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, | 756 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, |
786 * yet. | 757 * yet. |
787 */ | 758 */ |
788 bool shouldIncludeElementDueToMirrors(Element element, | 759 bool shouldIncludeElementDueToMirrors(Element element, |
789 {bool includedEnclosing}) { | 760 {bool includedEnclosing}) { |
790 return includedEnclosing || compiler.backend.requiredByMirrorSystem(element)
; | 761 return includedEnclosing || |
| 762 compiler.backend.requiredByMirrorSystem(element); |
791 } | 763 } |
792 | 764 |
793 bool internalAddToWorkList(Element element) { | 765 bool internalAddToWorkList(Element element) { |
794 if (element.isMalformed) return false; | 766 if (element.isMalformed) return false; |
795 | 767 |
796 assert(invariant(element, element is AnalyzableElement, | 768 assert(invariant(element, element is AnalyzableElement, |
797 message: 'Element $element is not analyzable.')); | 769 message: 'Element $element is not analyzable.')); |
798 if (hasBeenProcessed(element)) return false; | 770 if (hasBeenProcessed(element)) return false; |
799 if (queueIsClosed) { | 771 if (queueIsClosed) { |
800 throw new SpannableAssertionFailure(element, | 772 throw new SpannableAssertionFailure( |
801 "Resolution work list is closed. Trying to add $element."); | 773 element, "Resolution work list is closed. Trying to add $element."); |
802 } | 774 } |
803 | 775 |
804 compiler.world.registerUsedElement(element); | 776 compiler.world.registerUsedElement(element); |
805 | 777 |
806 ResolutionWorkItem workItem = compiler.resolution.createWorkItem( | 778 ResolutionWorkItem workItem = compiler.resolution |
807 element, itemCompilationContextCreator()); | 779 .createWorkItem(element, itemCompilationContextCreator()); |
808 queue.add(workItem); | 780 queue.add(workItem); |
809 | 781 |
810 // Enable isolate support if we start using something from the isolate | 782 // Enable isolate support if we start using something from the isolate |
811 // library, or timers for the async library. We exclude constant fields, | 783 // library, or timers for the async library. We exclude constant fields, |
812 // which are ending here because their initializing expression is compiled. | 784 // which are ending here because their initializing expression is compiled. |
813 LibraryElement library = element.library; | 785 LibraryElement library = element.library; |
814 if (!compiler.hasIsolateSupport && | 786 if (!compiler.hasIsolateSupport && (!element.isField || !element.isConst)) { |
815 (!element.isField || !element.isConst)) { | |
816 String uri = library.canonicalUri.toString(); | 787 String uri = library.canonicalUri.toString(); |
817 if (uri == 'dart:isolate') { | 788 if (uri == 'dart:isolate') { |
818 enableIsolateSupport(); | 789 enableIsolateSupport(); |
819 } else if (uri == 'dart:async') { | 790 } else if (uri == 'dart:async') { |
820 if (element.name == '_createTimer' || | 791 if (element.name == '_createTimer' || |
821 element.name == '_createPeriodicTimer') { | 792 element.name == '_createPeriodicTimer') { |
822 // The [:Timer:] class uses the event queue of the isolate | 793 // The [:Timer:] class uses the event queue of the isolate |
823 // library, so we make sure that event queue is generated. | 794 // library, so we make sure that event queue is generated. |
824 enableIsolateSupport(); | 795 enableIsolateSupport(); |
825 } | 796 } |
(...skipping 28 matching lines...) Expand all Loading... |
854 /** | 825 /** |
855 * Adds an action to the deferred task queue. | 826 * Adds an action to the deferred task queue. |
856 * | 827 * |
857 * The action is performed the next time the resolution queue has been | 828 * The action is performed the next time the resolution queue has been |
858 * emptied. | 829 * emptied. |
859 * | 830 * |
860 * The queue is processed in FIFO order. | 831 * The queue is processed in FIFO order. |
861 */ | 832 */ |
862 void addDeferredAction(Element element, DeferredAction action) { | 833 void addDeferredAction(Element element, DeferredAction action) { |
863 if (queueIsClosed) { | 834 if (queueIsClosed) { |
864 throw new SpannableAssertionFailure(element, | 835 throw new SpannableAssertionFailure( |
| 836 element, |
865 "Resolution work list is closed. " | 837 "Resolution work list is closed. " |
866 "Trying to add deferred action for $element"); | 838 "Trying to add deferred action for $element"); |
867 } | 839 } |
868 deferredTaskQueue.add(new DeferredTask(element, action)); | 840 deferredTaskQueue.add(new DeferredTask(element, action)); |
869 } | 841 } |
870 | 842 |
871 bool onQueueEmpty(Iterable<ClassElement> recentClasses) { | 843 bool onQueueEmpty(Iterable<ClassElement> recentClasses) { |
872 emptyDeferredTaskQueue(); | 844 emptyDeferredTaskQueue(); |
873 return super.onQueueEmpty(recentClasses); | 845 return super.onQueueEmpty(recentClasses); |
874 } | 846 } |
(...skipping 19 matching lines...) Expand all Loading... |
894 class CodegenEnqueuer extends Enqueuer { | 866 class CodegenEnqueuer extends Enqueuer { |
895 final Queue<CodegenWorkItem> queue; | 867 final Queue<CodegenWorkItem> queue; |
896 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{}; | 868 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{}; |
897 | 869 |
898 final Set<Element> newlyEnqueuedElements; | 870 final Set<Element> newlyEnqueuedElements; |
899 | 871 |
900 final Set<DynamicUse> newlySeenSelectors; | 872 final Set<DynamicUse> newlySeenSelectors; |
901 | 873 |
902 bool enabledNoSuchMethod = false; | 874 bool enabledNoSuchMethod = false; |
903 | 875 |
904 static const ImpactUseCase IMPACT_USE = const ImpactUseCase('CodegenEnqueuer')
; | 876 static const ImpactUseCase IMPACT_USE = |
| 877 const ImpactUseCase('CodegenEnqueuer'); |
905 | 878 |
906 ImpactUseCase get impactUse => IMPACT_USE; | 879 ImpactUseCase get impactUse => IMPACT_USE; |
907 | 880 |
908 CodegenEnqueuer(Compiler compiler, | 881 CodegenEnqueuer( |
909 ItemCompilationContext itemCompilationContextCreator(), | 882 Compiler compiler, |
910 EnqueuerStrategy strategy) | 883 ItemCompilationContext itemCompilationContextCreator(), |
| 884 EnqueuerStrategy strategy) |
911 : queue = new Queue<CodegenWorkItem>(), | 885 : queue = new Queue<CodegenWorkItem>(), |
912 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 886 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
913 newlySeenSelectors = compiler.cacheStrategy.newSet(), | 887 newlySeenSelectors = compiler.cacheStrategy.newSet(), |
914 super('codegen enqueuer', compiler, itemCompilationContextCreator, | 888 super('codegen enqueuer', compiler, itemCompilationContextCreator, |
915 strategy); | 889 strategy); |
916 | 890 |
917 bool isProcessed(Element member) => | 891 bool isProcessed(Element member) => |
918 member.isAbstract || generatedCode.containsKey(member); | 892 member.isAbstract || generatedCode.containsKey(member); |
919 | 893 |
920 /** | 894 /** |
921 * Decides whether an element should be included to satisfy requirements | 895 * Decides whether an element should be included to satisfy requirements |
922 * of the mirror system. | 896 * of the mirror system. |
923 * | 897 * |
924 * For code generation, we rely on the precomputed set of elements that takes | 898 * For code generation, we rely on the precomputed set of elements that takes |
925 * subtyping constraints into account. | 899 * subtyping constraints into account. |
926 */ | 900 */ |
927 bool shouldIncludeElementDueToMirrors(Element element, | 901 bool shouldIncludeElementDueToMirrors(Element element, |
928 {bool includedEnclosing}) { | 902 {bool includedEnclosing}) { |
929 return compiler.backend.isAccessibleByReflection(element); | 903 return compiler.backend.isAccessibleByReflection(element); |
930 } | 904 } |
931 | 905 |
932 bool internalAddToWorkList(Element element) { | 906 bool internalAddToWorkList(Element element) { |
933 // Don't generate code for foreign elements. | 907 // Don't generate code for foreign elements. |
934 if (compiler.backend.isForeign(element)) return false; | 908 if (compiler.backend.isForeign(element)) return false; |
935 | 909 |
936 // Codegen inlines field initializers. It only needs to generate | 910 // Codegen inlines field initializers. It only needs to generate |
937 // code for checked setters. | 911 // code for checked setters. |
938 if (element.isField && element.isInstanceMember) { | 912 if (element.isField && element.isInstanceMember) { |
939 if (!compiler.options.enableTypeAssertions | 913 if (!compiler.options.enableTypeAssertions || |
940 || element.enclosingElement.isClosure) { | 914 element.enclosingElement.isClosure) { |
941 return false; | 915 return false; |
942 } | 916 } |
943 } | 917 } |
944 | 918 |
945 if (compiler.options.hasIncrementalSupport && !isProcessed(element)) { | 919 if (compiler.options.hasIncrementalSupport && !isProcessed(element)) { |
946 newlyEnqueuedElements.add(element); | 920 newlyEnqueuedElements.add(element); |
947 } | 921 } |
948 | 922 |
949 if (queueIsClosed) { | 923 if (queueIsClosed) { |
950 throw new SpannableAssertionFailure(element, | 924 throw new SpannableAssertionFailure( |
951 "Codegen work list is closed. Trying to add $element"); | 925 element, "Codegen work list is closed. Trying to add $element"); |
952 } | 926 } |
953 CodegenWorkItem workItem = new CodegenWorkItem( | 927 CodegenWorkItem workItem = |
954 compiler, element, itemCompilationContextCreator()); | 928 new CodegenWorkItem(compiler, element, itemCompilationContextCreator()); |
955 queue.add(workItem); | 929 queue.add(workItem); |
956 return true; | 930 return true; |
957 } | 931 } |
958 | 932 |
959 void registerNoSuchMethod(Element element) { | 933 void registerNoSuchMethod(Element element) { |
960 if (!enabledNoSuchMethod && compiler.backend.enabledNoSuchMethod) { | 934 if (!enabledNoSuchMethod && compiler.backend.enabledNoSuchMethod) { |
961 compiler.backend.enableNoSuchMethod(this); | 935 compiler.backend.enableNoSuchMethod(this); |
962 enabledNoSuchMethod = true; | 936 enabledNoSuchMethod = true; |
963 } | 937 } |
964 } | 938 } |
(...skipping 20 matching lines...) Expand all Loading... |
985 } | 959 } |
986 super.handleUnseenSelector(dynamicUse); | 960 super.handleUnseenSelector(dynamicUse); |
987 } | 961 } |
988 } | 962 } |
989 | 963 |
990 /// Parameterizes filtering of which work items are enqueued. | 964 /// Parameterizes filtering of which work items are enqueued. |
991 class QueueFilter { | 965 class QueueFilter { |
992 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { | 966 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
993 enqueuer.task.measure(() { | 967 enqueuer.task.measure(() { |
994 // Run through the classes and see if we need to compile methods. | 968 // Run through the classes and see if we need to compile methods. |
995 for (ClassElement classElement in | 969 for (ClassElement classElement |
996 enqueuer.universe.directlyInstantiatedClasses) { | 970 in enqueuer.universe.directlyInstantiatedClasses) { |
997 for (ClassElement currentClass = classElement; | 971 for (ClassElement currentClass = classElement; |
998 currentClass != null; | 972 currentClass != null; |
999 currentClass = currentClass.superclass) { | 973 currentClass = currentClass.superclass) { |
1000 enqueuer.processInstantiatedClassMembers(currentClass); | 974 enqueuer.processInstantiatedClassMembers(currentClass); |
1001 } | 975 } |
1002 } | 976 } |
1003 }); | 977 }); |
1004 return true; | 978 return true; |
1005 } | 979 } |
1006 | 980 |
1007 void processWorkItem(void f(WorkItem work), WorkItem work) { | 981 void processWorkItem(void f(WorkItem work), WorkItem work) { |
1008 f(work); | 982 f(work); |
1009 } | 983 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 @override | 1036 @override |
1063 void visitStaticUse(StaticUse staticUse) { | 1037 void visitStaticUse(StaticUse staticUse) { |
1064 enqueuer.registerStaticUse(staticUse); | 1038 enqueuer.registerStaticUse(staticUse); |
1065 } | 1039 } |
1066 | 1040 |
1067 @override | 1041 @override |
1068 void visitTypeUse(TypeUse typeUse) { | 1042 void visitTypeUse(TypeUse typeUse) { |
1069 enqueuer.registerTypeUse(typeUse); | 1043 enqueuer.registerTypeUse(typeUse); |
1070 } | 1044 } |
1071 } | 1045 } |
OLD | NEW |