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.js.enqueue; | 5 library dart2js.js.enqueue; |
6 | 6 |
7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
8 | 8 |
9 import '../common/backend_api.dart' show Backend; | 9 import '../common/backend_api.dart' show Backend; |
10 import '../common/codegen.dart' show CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenWorkItem; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 final EnqueuerStrategy strategy; | 51 final EnqueuerStrategy strategy; |
52 final Map<String, Set<Element>> instanceMembersByName = | 52 final Map<String, Set<Element>> instanceMembersByName = |
53 new Map<String, Set<Element>>(); | 53 new Map<String, Set<Element>>(); |
54 final Map<String, Set<Element>> instanceFunctionsByName = | 54 final Map<String, Set<Element>> instanceFunctionsByName = |
55 new Map<String, Set<Element>>(); | 55 new Map<String, Set<Element>>(); |
56 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); | 56 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); |
57 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); | 57 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); |
58 final CodegenWorldBuilderImpl _universe = | 58 final CodegenWorldBuilderImpl _universe = |
59 new CodegenWorldBuilderImpl(const TypeMaskStrategy()); | 59 new CodegenWorldBuilderImpl(const TypeMaskStrategy()); |
60 | 60 |
61 static final TRACE_MIRROR_ENQUEUING = | |
62 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | |
63 | 61 |
64 bool queueIsClosed = false; | 62 bool queueIsClosed = false; |
65 EnqueueTask task; | 63 EnqueueTask task; |
66 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 64 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
67 | 65 |
68 bool hasEnqueuedReflectiveElements = false; | |
69 bool hasEnqueuedReflectiveStaticFields = false; | |
70 | 66 |
71 WorldImpactVisitor impactVisitor; | 67 WorldImpactVisitor impactVisitor; |
72 | 68 |
73 CodegenEnqueuer(Compiler compiler, this.strategy) | 69 CodegenEnqueuer(Compiler compiler, this.strategy) |
74 : queue = new Queue<CodegenWorkItem>(), | 70 : queue = new Queue<CodegenWorkItem>(), |
75 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 71 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
76 newlySeenSelectors = compiler.cacheStrategy.newSet(), | 72 newlySeenSelectors = compiler.cacheStrategy.newSet(), |
77 this.name = 'codegen enqueuer', | 73 this.name = 'codegen enqueuer', |
78 this._compiler = compiler { | 74 this._compiler = compiler { |
79 impactVisitor = new _EnqueuerImpactVisitor(this); | 75 impactVisitor = new _EnqueuerImpactVisitor(this); |
80 } | 76 } |
81 | 77 |
82 CodegenWorldBuilder get universe => _universe; | 78 CodegenWorldBuilder get universe => _universe; |
83 | 79 |
84 Backend get backend => _compiler.backend; | 80 Backend get backend => _compiler.backend; |
85 | 81 |
86 CompilerOptions get options => _compiler.options; | 82 CompilerOptions get options => _compiler.options; |
87 | 83 |
88 Registry get globalDependencies => _compiler.globalDependencies; | |
89 | |
90 Registry get mirrorDependencies => _compiler.mirrorDependencies; | |
91 | |
92 ClosedWorld get _world => _compiler.closedWorld; | 84 ClosedWorld get _world => _compiler.closedWorld; |
93 | 85 |
94 bool get queueIsEmpty => queue.isEmpty; | 86 bool get queueIsEmpty => queue.isEmpty; |
95 | 87 |
96 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 88 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
97 bool get isResolutionQueue => false; | 89 bool get isResolutionQueue => false; |
98 | 90 |
99 QueueFilter get filter => _compiler.enqueuerFilter; | 91 QueueFilter get filter => _compiler.enqueuerFilter; |
100 | 92 |
101 DiagnosticReporter get reporter => _compiler.reporter; | 93 DiagnosticReporter get reporter => _compiler.reporter; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 _compiler.dumpInfoTask | 125 _compiler.dumpInfoTask |
134 .registerDependency(_compiler.currentElement, element); | 126 .registerDependency(_compiler.currentElement, element); |
135 } | 127 } |
136 } | 128 } |
137 | 129 |
138 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { | 130 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { |
139 _compiler.impactStrategy | 131 _compiler.impactStrategy |
140 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); | 132 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); |
141 } | 133 } |
142 | 134 |
143 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { | 135 void registerInstantiatedType(InterfaceType type) { |
| 136 _registerInstantiatedType(type); |
| 137 } |
| 138 |
| 139 void _registerInstantiatedType(InterfaceType type, |
| 140 {bool mirrorUsage: false, bool nativeUsage: false}) { |
144 task.measure(() { | 141 task.measure(() { |
145 ClassElement cls = type.element; | 142 ClassElement cls = type.element; |
146 bool isNative = backend.isNative(cls); | 143 bool isNative = backend.isNative(cls); |
147 _universe.registerTypeInstantiation(type, | 144 _universe.registerTypeInstantiation(type, |
148 isNative: isNative, | 145 isNative: isNative, |
149 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { | 146 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { |
150 backend.registerImplementedClass(cls, this, globalDependencies); | 147 backend.registerImplementedClass(cls, this); |
151 }); | 148 }); |
| 149 if (nativeUsage) { |
| 150 nativeEnqueuer.onInstantiatedType(type); |
| 151 } |
| 152 backend.registerInstantiatedType(type); |
152 // TODO(johnniwinther): Share this reasoning with [Universe]. | 153 // TODO(johnniwinther): Share this reasoning with [Universe]. |
153 if (!cls.isAbstract || isNative || mirrorUsage) { | 154 if (!cls.isAbstract || isNative || mirrorUsage) { |
154 processInstantiatedClass(cls); | 155 processInstantiatedClass(cls); |
155 } | 156 } |
156 }); | 157 }); |
157 } | 158 } |
158 | 159 |
159 bool checkNoEnqueuedInvokedInstanceMethods() { | 160 bool checkNoEnqueuedInvokedInstanceMethods() { |
160 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 161 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
161 } | 162 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 message: "Class $superclass has not been " | 268 message: "Class $superclass has not been " |
268 "processed in resolution.")); | 269 "processed in resolution.")); |
269 */ | 270 */ |
270 | 271 |
271 _processedClasses.add(superclass); | 272 _processedClasses.add(superclass); |
272 recentClasses.add(superclass); | 273 recentClasses.add(superclass); |
273 superclass.implementation.forEachMember(processInstantiatedClassMember); | 274 superclass.implementation.forEachMember(processInstantiatedClassMember); |
274 // We only tell the backend once that [superclass] was instantiated, so | 275 // We only tell the backend once that [superclass] was instantiated, so |
275 // any additional dependencies must be treated as global | 276 // any additional dependencies must be treated as global |
276 // dependencies. | 277 // dependencies. |
277 backend.registerInstantiatedClass(superclass, this, globalDependencies); | 278 backend.registerInstantiatedClass(superclass, this); |
278 } | 279 } |
279 | 280 |
280 ClassElement superclass = cls; | 281 ClassElement superclass = cls; |
281 while (superclass != null) { | 282 while (superclass != null) { |
282 processClass(superclass); | 283 processClass(superclass); |
283 superclass = superclass.superclass; | 284 superclass = superclass.superclass; |
284 } | 285 } |
285 }); | 286 }); |
286 } | 287 } |
287 | 288 |
288 void registerDynamicUse(DynamicUse dynamicUse) { | 289 void registerDynamicUse(DynamicUse dynamicUse) { |
289 task.measure(() { | 290 task.measure(() { |
290 if (_universe.registerDynamicUse(dynamicUse)) { | 291 if (_universe.registerDynamicUse(dynamicUse)) { |
291 handleUnseenSelector(dynamicUse); | 292 handleUnseenSelector(dynamicUse); |
292 } | 293 } |
293 }); | 294 }); |
294 } | 295 } |
295 | 296 |
296 void logEnqueueReflectiveAction(action, [msg = ""]) { | |
297 if (TRACE_MIRROR_ENQUEUING) { | |
298 print("MIRROR_ENQUEUE (C): $action $msg"); | |
299 } | |
300 } | |
301 | |
302 /// Enqeue the constructor [ctor] if it is required for reflection. | |
303 /// | |
304 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | |
305 /// needed for reflection. | |
306 void enqueueReflectiveConstructor( | |
307 ConstructorElement ctor, bool enclosingWasIncluded) { | |
308 if (shouldIncludeElementDueToMirrors(ctor, | |
309 includedEnclosing: enclosingWasIncluded)) { | |
310 logEnqueueReflectiveAction(ctor); | |
311 ClassElement cls = ctor.declaration.enclosingClass; | |
312 backend.registerInstantiatedType(cls.rawType, this, mirrorDependencies, | |
313 mirrorUsage: true); | |
314 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); | |
315 } | |
316 } | |
317 | |
318 /// Enqeue the member [element] if it is required for reflection. | |
319 /// | |
320 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | |
321 /// needed for reflection. | |
322 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { | |
323 if (shouldIncludeElementDueToMirrors(element, | |
324 includedEnclosing: enclosingWasIncluded)) { | |
325 logEnqueueReflectiveAction(element); | |
326 if (element.isTypedef) { | |
327 // Do nothing. | |
328 } else if (Elements.isStaticOrTopLevel(element)) { | |
329 registerStaticUse(new StaticUse.foreignUse(element.declaration)); | |
330 } else if (element.isInstanceMember) { | |
331 // We need to enqueue all members matching this one in subclasses, as | |
332 // well. | |
333 // TODO(herhut): Use TypedSelector.subtype for enqueueing | |
334 DynamicUse dynamicUse = | |
335 new DynamicUse(new Selector.fromElement(element), null); | |
336 registerDynamicUse(dynamicUse); | |
337 if (element.isField) { | |
338 DynamicUse dynamicUse = new DynamicUse( | |
339 new Selector.setter( | |
340 new Name(element.name, element.library, isSetter: true)), | |
341 null); | |
342 registerDynamicUse(dynamicUse); | |
343 } | |
344 } | |
345 } | |
346 } | |
347 | |
348 /// Enqeue the member [element] if it is required for reflection. | |
349 /// | |
350 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | |
351 /// needed for reflection. | |
352 void enqueueReflectiveElementsInClass(ClassElement cls, | |
353 Iterable<ClassElement> recents, bool enclosingWasIncluded) { | |
354 if (cls.library.isInternalLibrary || cls.isInjected) return; | |
355 bool includeClass = shouldIncludeElementDueToMirrors(cls, | |
356 includedEnclosing: enclosingWasIncluded); | |
357 if (includeClass) { | |
358 logEnqueueReflectiveAction(cls, "register"); | |
359 ClassElement decl = cls.declaration; | |
360 backend.registerInstantiatedType(decl.rawType, this, mirrorDependencies, | |
361 mirrorUsage: true); | |
362 } | |
363 // If the class is never instantiated, we know nothing of it can possibly | |
364 // be reflected upon. | |
365 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | |
366 if (recents.contains(cls.declaration)) { | |
367 logEnqueueReflectiveAction(cls, "members"); | |
368 cls.constructors.forEach((Element element) { | |
369 enqueueReflectiveConstructor(element, includeClass); | |
370 }); | |
371 cls.forEachClassMember((Member member) { | |
372 enqueueReflectiveMember(member.element, includeClass); | |
373 }); | |
374 } | |
375 } | |
376 | |
377 /// Enqeue special classes that might not be visible by normal means or that | |
378 /// would not normally be enqueued: | |
379 /// | |
380 /// [Closure] is treated specially as it is the superclass of all closures. | |
381 /// Although it is in an internal library, we mark it as reflectable. Note | |
382 /// that none of its methods are reflectable, unless reflectable by | |
383 /// inheritance. | |
384 void enqueueReflectiveSpecialClasses() { | |
385 Iterable<ClassElement> classes = backend.classesRequiredForReflection; | |
386 for (ClassElement cls in classes) { | |
387 if (backend.referencedFromMirrorSystem(cls)) { | |
388 logEnqueueReflectiveAction(cls); | |
389 backend.registerInstantiatedType(cls.rawType, this, mirrorDependencies, | |
390 mirrorUsage: true); | |
391 } | |
392 } | |
393 } | |
394 | |
395 /// Enqeue all local members of the library [lib] if they are required for | |
396 /// reflection. | |
397 void enqueueReflectiveElementsInLibrary( | |
398 LibraryElement lib, Iterable<ClassElement> recents) { | |
399 bool includeLibrary = | |
400 shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); | |
401 lib.forEachLocalMember((Element member) { | |
402 if (member.isInjected) return; | |
403 if (member.isClass) { | |
404 enqueueReflectiveElementsInClass(member, recents, includeLibrary); | |
405 } else { | |
406 enqueueReflectiveMember(member, includeLibrary); | |
407 } | |
408 }); | |
409 } | |
410 | |
411 /// Enqueue all elements that are matched by the mirrors used | |
412 /// annotation or, in lack thereof, all elements. | |
413 void enqueueReflectiveElements(Iterable<ClassElement> recents) { | |
414 if (!hasEnqueuedReflectiveElements) { | |
415 logEnqueueReflectiveAction("!START enqueueAll"); | |
416 // First round of enqueuing, visit everything that is visible to | |
417 // also pick up static top levels, etc. | |
418 // Also, during the first round, consider all classes that have been seen | |
419 // as recently seen, as we do not know how many rounds of resolution might | |
420 // have run before tree shaking is disabled and thus everything is | |
421 // enqueued. | |
422 recents = _processedClasses.toSet(); | |
423 reporter.log('Enqueuing everything'); | |
424 for (LibraryElement lib in _compiler.libraryLoader.libraries) { | |
425 enqueueReflectiveElementsInLibrary(lib, recents); | |
426 } | |
427 enqueueReflectiveSpecialClasses(); | |
428 hasEnqueuedReflectiveElements = true; | |
429 hasEnqueuedReflectiveStaticFields = true; | |
430 logEnqueueReflectiveAction("!DONE enqueueAll"); | |
431 } else if (recents.isNotEmpty) { | |
432 // Keep looking at new classes until fixpoint is reached. | |
433 logEnqueueReflectiveAction("!START enqueueRecents"); | |
434 recents.forEach((ClassElement cls) { | |
435 enqueueReflectiveElementsInClass( | |
436 cls, | |
437 recents, | |
438 shouldIncludeElementDueToMirrors(cls.library, | |
439 includedEnclosing: false)); | |
440 }); | |
441 logEnqueueReflectiveAction("!DONE enqueueRecents"); | |
442 } | |
443 } | |
444 | |
445 /// Enqueue the static fields that have been marked as used by reflective | |
446 /// usage through `MirrorsUsed`. | |
447 void enqueueReflectiveStaticFields(Iterable<Element> elements) { | |
448 if (hasEnqueuedReflectiveStaticFields) return; | |
449 hasEnqueuedReflectiveStaticFields = true; | |
450 for (Element element in elements) { | |
451 enqueueReflectiveMember(element, true); | |
452 } | |
453 } | |
454 | |
455 void processSet( | 297 void processSet( |
456 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { | 298 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { |
457 Set<Element> members = map[memberName]; | 299 Set<Element> members = map[memberName]; |
458 if (members == null) return; | 300 if (members == null) return; |
459 // [f] might add elements to [: map[memberName] :] during the loop below | 301 // [f] might add elements to [: map[memberName] :] during the loop below |
460 // so we create a new list for [: map[memberName] :] and prepend the | 302 // so we create a new list for [: map[memberName] :] and prepend the |
461 // [remaining] members after the loop. | 303 // [remaining] members after the loop. |
462 map[memberName] = new Set<Element>(); | 304 map[memberName] = new Set<Element>(); |
463 Set<Element> remaining = new Set<Element>(); | 305 Set<Element> remaining = new Set<Element>(); |
464 for (Element member in members) { | 306 for (Element member in members) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 */ | 352 */ |
511 void registerStaticUse(StaticUse staticUse) { | 353 void registerStaticUse(StaticUse staticUse) { |
512 strategy.processStaticUse(this, staticUse); | 354 strategy.processStaticUse(this, staticUse); |
513 } | 355 } |
514 | 356 |
515 void registerStaticUseInternal(StaticUse staticUse) { | 357 void registerStaticUseInternal(StaticUse staticUse) { |
516 Element element = staticUse.element; | 358 Element element = staticUse.element; |
517 assert(invariant(element, element.isDeclaration, | 359 assert(invariant(element, element.isDeclaration, |
518 message: "Element ${element} is not the declaration.")); | 360 message: "Element ${element} is not the declaration.")); |
519 _universe.registerStaticUse(staticUse); | 361 _universe.registerStaticUse(staticUse); |
520 backend.registerStaticUse(element, forResolution: false); | 362 backend.registerStaticUse(this, element); |
521 bool addElement = true; | 363 bool addElement = true; |
522 switch (staticUse.kind) { | 364 switch (staticUse.kind) { |
523 case StaticUseKind.STATIC_TEAR_OFF: | 365 case StaticUseKind.STATIC_TEAR_OFF: |
524 backend.registerGetOfStaticFunction(this); | 366 backend.registerGetOfStaticFunction(this); |
525 break; | 367 break; |
526 case StaticUseKind.FIELD_GET: | 368 case StaticUseKind.FIELD_GET: |
527 case StaticUseKind.FIELD_SET: | 369 case StaticUseKind.FIELD_SET: |
528 case StaticUseKind.CLOSURE: | 370 case StaticUseKind.CLOSURE: |
529 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and | 371 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and |
530 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. | 372 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. |
(...skipping 15 matching lines...) Expand all Loading... |
546 } | 388 } |
547 if (addElement) { | 389 if (addElement) { |
548 addToWorkList(element); | 390 addToWorkList(element); |
549 } | 391 } |
550 } | 392 } |
551 | 393 |
552 void registerTypeUse(TypeUse typeUse) { | 394 void registerTypeUse(TypeUse typeUse) { |
553 DartType type = typeUse.type; | 395 DartType type = typeUse.type; |
554 switch (typeUse.kind) { | 396 switch (typeUse.kind) { |
555 case TypeUseKind.INSTANTIATION: | 397 case TypeUseKind.INSTANTIATION: |
556 registerInstantiatedType(type); | 398 _registerInstantiatedType(type); |
| 399 break; |
| 400 case TypeUseKind.MIRROR_INSTANTIATION: |
| 401 _registerInstantiatedType(type, mirrorUsage: true); |
| 402 break; |
| 403 case TypeUseKind.NATIVE_INSTANTIATION: |
| 404 _registerInstantiatedType(type, nativeUsage: true); |
557 break; | 405 break; |
558 case TypeUseKind.IS_CHECK: | 406 case TypeUseKind.IS_CHECK: |
559 case TypeUseKind.AS_CAST: | 407 case TypeUseKind.AS_CAST: |
560 case TypeUseKind.CATCH_TYPE: | 408 case TypeUseKind.CATCH_TYPE: |
561 _registerIsCheck(type); | 409 _registerIsCheck(type); |
562 break; | 410 break; |
563 case TypeUseKind.CHECKED_MODE_CHECK: | 411 case TypeUseKind.CHECKED_MODE_CHECK: |
564 if (options.enableTypeAssertions) { | 412 if (options.enableTypeAssertions) { |
565 _registerIsCheck(type); | 413 _registerIsCheck(type); |
566 } | 414 } |
567 break; | 415 break; |
568 case TypeUseKind.TYPE_LITERAL: | 416 case TypeUseKind.TYPE_LITERAL: |
569 break; | 417 break; |
570 } | 418 } |
571 } | 419 } |
572 | 420 |
573 void _registerIsCheck(DartType type) { | 421 void _registerIsCheck(DartType type) { |
574 type = _universe.registerIsCheck(type, _compiler); | 422 type = _universe.registerIsCheck(type, _compiler); |
575 // Even in checked mode, type annotations for return type and argument | 423 // Even in checked mode, type annotations for return type and argument |
576 // types do not imply type checks, so there should never be a check | 424 // types do not imply type checks, so there should never be a check |
577 // against the type variable of a typedef. | 425 // against the type variable of a typedef. |
578 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); | 426 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
579 } | 427 } |
580 | 428 |
581 void registerCallMethodWithFreeTypeVariables(Element element) { | 429 void registerCallMethodWithFreeTypeVariables(Element element) { |
582 backend.registerCallMethodWithFreeTypeVariables( | 430 backend.registerCallMethodWithFreeTypeVariables(element, this); |
583 element, this, globalDependencies); | |
584 } | 431 } |
585 | 432 |
586 void registerClosurizedMember(TypedElement element) { | 433 void registerClosurizedMember(TypedElement element) { |
587 assert(element.isInstanceMember); | 434 assert(element.isInstanceMember); |
588 if (element.type.containsTypeVariables) { | 435 if (element.type.containsTypeVariables) { |
589 backend.registerClosureWithFreeTypeVariables( | 436 backend.registerClosureWithFreeTypeVariables(element, this); |
590 element, this, globalDependencies); | |
591 } | 437 } |
592 backend.registerBoundClosure(this); | 438 backend.registerBoundClosure(this); |
593 } | 439 } |
594 | 440 |
595 void forEach(void f(WorkItem work)) { | 441 void forEach(void f(WorkItem work)) { |
596 do { | 442 do { |
597 while (queue.isNotEmpty) { | 443 while (queue.isNotEmpty) { |
598 // TODO(johnniwinther): Find an optimal process order. | 444 // TODO(johnniwinther): Find an optimal process order. |
599 filter.processWorkItem(f, queue.removeLast()); | 445 filter.processWorkItem(f, queue.removeLast()); |
600 } | 446 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 bool enabledNoSuchMethod = false; | 484 bool enabledNoSuchMethod = false; |
639 | 485 |
640 static const ImpactUseCase IMPACT_USE = | 486 static const ImpactUseCase IMPACT_USE = |
641 const ImpactUseCase('CodegenEnqueuer'); | 487 const ImpactUseCase('CodegenEnqueuer'); |
642 | 488 |
643 ImpactUseCase get impactUse => IMPACT_USE; | 489 ImpactUseCase get impactUse => IMPACT_USE; |
644 | 490 |
645 bool isProcessed(Element member) => | 491 bool isProcessed(Element member) => |
646 member.isAbstract || generatedCode.containsKey(member); | 492 member.isAbstract || generatedCode.containsKey(member); |
647 | 493 |
648 /** | |
649 * Decides whether an element should be included to satisfy requirements | |
650 * of the mirror system. | |
651 * | |
652 * For code generation, we rely on the precomputed set of elements that takes | |
653 * subtyping constraints into account. | |
654 */ | |
655 bool shouldIncludeElementDueToMirrors(Element element, | |
656 {bool includedEnclosing}) { | |
657 return backend.isAccessibleByReflection(element); | |
658 } | |
659 | |
660 void registerNoSuchMethod(Element element) { | 494 void registerNoSuchMethod(Element element) { |
661 if (!enabledNoSuchMethod && backend.enabledNoSuchMethod) { | 495 if (!enabledNoSuchMethod && backend.enabledNoSuchMethod) { |
662 backend.enableNoSuchMethod(this); | 496 backend.enableNoSuchMethod(this); |
663 enabledNoSuchMethod = true; | 497 enabledNoSuchMethod = true; |
664 } | 498 } |
665 } | 499 } |
666 | 500 |
667 void _logSpecificSummary(log(message)) { | 501 void _logSpecificSummary(log(message)) { |
668 log('Compiled ${generatedCode.length} methods.'); | 502 log('Compiled ${generatedCode.length} methods.'); |
669 } | 503 } |
(...skipping 12 matching lines...) Expand all Loading... |
682 | 516 |
683 void handleUnseenSelector(DynamicUse dynamicUse) { | 517 void handleUnseenSelector(DynamicUse dynamicUse) { |
684 if (options.hasIncrementalSupport) { | 518 if (options.hasIncrementalSupport) { |
685 newlySeenSelectors.add(dynamicUse); | 519 newlySeenSelectors.add(dynamicUse); |
686 } | 520 } |
687 _handleUnseenSelector(dynamicUse); | 521 _handleUnseenSelector(dynamicUse); |
688 } | 522 } |
689 | 523 |
690 @override | 524 @override |
691 Iterable<Entity> get processedEntities => generatedCode.keys; | 525 Iterable<Entity> get processedEntities => generatedCode.keys; |
| 526 |
| 527 @override |
| 528 Iterable<ClassElement> get processedClasses => _processedClasses; |
692 } | 529 } |
693 | 530 |
694 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 531 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
695 Set<Element> set = map[element.name]; | 532 Set<Element> set = map[element.name]; |
696 if (set == null) return; | 533 if (set == null) return; |
697 set.remove(element); | 534 set.remove(element); |
698 } | 535 } |
699 | 536 |
700 class _EnqueuerImpactVisitor implements WorldImpactVisitor { | 537 class _EnqueuerImpactVisitor implements WorldImpactVisitor { |
701 final CodegenEnqueuer enqueuer; | 538 final CodegenEnqueuer enqueuer; |
702 | 539 |
703 _EnqueuerImpactVisitor(this.enqueuer); | 540 _EnqueuerImpactVisitor(this.enqueuer); |
704 | 541 |
705 @override | 542 @override |
706 void visitDynamicUse(DynamicUse dynamicUse) { | 543 void visitDynamicUse(DynamicUse dynamicUse) { |
707 enqueuer.registerDynamicUse(dynamicUse); | 544 enqueuer.registerDynamicUse(dynamicUse); |
708 } | 545 } |
709 | 546 |
710 @override | 547 @override |
711 void visitStaticUse(StaticUse staticUse) { | 548 void visitStaticUse(StaticUse staticUse) { |
712 enqueuer.registerStaticUse(staticUse); | 549 enqueuer.registerStaticUse(staticUse); |
713 } | 550 } |
714 | 551 |
715 @override | 552 @override |
716 void visitTypeUse(TypeUse typeUse) { | 553 void visitTypeUse(TypeUse typeUse) { |
717 enqueuer.registerTypeUse(typeUse); | 554 enqueuer.registerTypeUse(typeUse); |
718 } | 555 } |
719 } | 556 } |
OLD | NEW |