| 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 | |
| 64 bool queueIsClosed = false; | 61 bool queueIsClosed = false; |
| 65 EnqueueTask task; | 62 EnqueueTask task; |
| 66 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 63 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
| 67 | 64 |
| 68 bool hasEnqueuedReflectiveElements = false; | |
| 69 bool hasEnqueuedReflectiveStaticFields = false; | |
| 70 | |
| 71 WorldImpactVisitor impactVisitor; | 65 WorldImpactVisitor impactVisitor; |
| 72 | 66 |
| 73 CodegenEnqueuer(Compiler compiler, this.strategy) | 67 CodegenEnqueuer(Compiler compiler, this.strategy) |
| 74 : queue = new Queue<CodegenWorkItem>(), | 68 : queue = new Queue<CodegenWorkItem>(), |
| 75 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 69 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
| 76 newlySeenSelectors = compiler.cacheStrategy.newSet(), | 70 newlySeenSelectors = compiler.cacheStrategy.newSet(), |
| 77 this.name = 'codegen enqueuer', | 71 this.name = 'codegen enqueuer', |
| 78 this._compiler = compiler { | 72 this._compiler = compiler { |
| 79 impactVisitor = new _EnqueuerImpactVisitor(this); | 73 impactVisitor = new _EnqueuerImpactVisitor(this); |
| 80 } | 74 } |
| 81 | 75 |
| 82 CodegenWorldBuilder get universe => _universe; | 76 CodegenWorldBuilder get universe => _universe; |
| 83 | 77 |
| 84 Backend get backend => _compiler.backend; | 78 Backend get backend => _compiler.backend; |
| 85 | 79 |
| 86 CompilerOptions get options => _compiler.options; | 80 CompilerOptions get options => _compiler.options; |
| 87 | 81 |
| 88 Registry get globalDependencies => _compiler.globalDependencies; | |
| 89 | |
| 90 Registry get mirrorDependencies => _compiler.mirrorDependencies; | |
| 91 | |
| 92 ClosedWorld get _world => _compiler.closedWorld; | 82 ClosedWorld get _world => _compiler.closedWorld; |
| 93 | 83 |
| 94 bool get queueIsEmpty => queue.isEmpty; | 84 bool get queueIsEmpty => queue.isEmpty; |
| 95 | 85 |
| 96 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 86 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
| 97 bool get isResolutionQueue => false; | 87 bool get isResolutionQueue => false; |
| 98 | 88 |
| 99 QueueFilter get filter => _compiler.enqueuerFilter; | 89 QueueFilter get filter => _compiler.enqueuerFilter; |
| 100 | 90 |
| 101 DiagnosticReporter get reporter => _compiler.reporter; | 91 DiagnosticReporter get reporter => _compiler.reporter; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 _compiler.dumpInfoTask | 123 _compiler.dumpInfoTask |
| 134 .registerDependency(_compiler.currentElement, element); | 124 .registerDependency(_compiler.currentElement, element); |
| 135 } | 125 } |
| 136 } | 126 } |
| 137 | 127 |
| 138 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { | 128 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { |
| 139 _compiler.impactStrategy | 129 _compiler.impactStrategy |
| 140 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); | 130 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); |
| 141 } | 131 } |
| 142 | 132 |
| 143 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { | 133 void registerInstantiatedType(InterfaceType type) { |
| 134 _registerInstantiatedType(type); |
| 135 } |
| 136 |
| 137 void _registerInstantiatedType(InterfaceType type, |
| 138 {bool mirrorUsage: false, bool nativeUsage: false}) { |
| 144 task.measure(() { | 139 task.measure(() { |
| 145 ClassElement cls = type.element; | 140 ClassElement cls = type.element; |
| 146 bool isNative = backend.isNative(cls); | 141 bool isNative = backend.isNative(cls); |
| 147 _universe.registerTypeInstantiation(type, | 142 _universe.registerTypeInstantiation(type, |
| 148 isNative: isNative, | 143 isNative: isNative, |
| 149 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { | 144 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { |
| 150 backend.registerImplementedClass(cls, this, globalDependencies); | 145 backend.registerImplementedClass(cls, this); |
| 151 }); | 146 }); |
| 147 if (nativeUsage) { |
| 148 nativeEnqueuer.onInstantiatedType(type); |
| 149 } |
| 150 backend.registerInstantiatedType(type); |
| 152 // TODO(johnniwinther): Share this reasoning with [Universe]. | 151 // TODO(johnniwinther): Share this reasoning with [Universe]. |
| 153 if (!cls.isAbstract || isNative || mirrorUsage) { | 152 if (!cls.isAbstract || isNative || mirrorUsage) { |
| 154 processInstantiatedClass(cls); | 153 processInstantiatedClass(cls); |
| 155 } | 154 } |
| 156 }); | 155 }); |
| 157 } | 156 } |
| 158 | 157 |
| 159 bool checkNoEnqueuedInvokedInstanceMethods() { | 158 bool checkNoEnqueuedInvokedInstanceMethods() { |
| 160 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 159 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
| 161 } | 160 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 message: "Class $superclass has not been " | 266 message: "Class $superclass has not been " |
| 268 "processed in resolution.")); | 267 "processed in resolution.")); |
| 269 */ | 268 */ |
| 270 | 269 |
| 271 _processedClasses.add(superclass); | 270 _processedClasses.add(superclass); |
| 272 recentClasses.add(superclass); | 271 recentClasses.add(superclass); |
| 273 superclass.implementation.forEachMember(processInstantiatedClassMember); | 272 superclass.implementation.forEachMember(processInstantiatedClassMember); |
| 274 // We only tell the backend once that [superclass] was instantiated, so | 273 // We only tell the backend once that [superclass] was instantiated, so |
| 275 // any additional dependencies must be treated as global | 274 // any additional dependencies must be treated as global |
| 276 // dependencies. | 275 // dependencies. |
| 277 backend.registerInstantiatedClass(superclass, this, globalDependencies); | 276 backend.registerInstantiatedClass(superclass, this); |
| 278 } | 277 } |
| 279 | 278 |
| 280 ClassElement superclass = cls; | 279 ClassElement superclass = cls; |
| 281 while (superclass != null) { | 280 while (superclass != null) { |
| 282 processClass(superclass); | 281 processClass(superclass); |
| 283 superclass = superclass.superclass; | 282 superclass = superclass.superclass; |
| 284 } | 283 } |
| 285 }); | 284 }); |
| 286 } | 285 } |
| 287 | 286 |
| 288 void registerDynamicUse(DynamicUse dynamicUse) { | 287 void registerDynamicUse(DynamicUse dynamicUse) { |
| 289 task.measure(() { | 288 task.measure(() { |
| 290 if (_universe.registerDynamicUse(dynamicUse)) { | 289 if (_universe.registerDynamicUse(dynamicUse)) { |
| 291 handleUnseenSelector(dynamicUse); | 290 handleUnseenSelector(dynamicUse); |
| 292 } | 291 } |
| 293 }); | 292 }); |
| 294 } | 293 } |
| 295 | 294 |
| 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( | 295 void processSet( |
| 456 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { | 296 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { |
| 457 Set<Element> members = map[memberName]; | 297 Set<Element> members = map[memberName]; |
| 458 if (members == null) return; | 298 if (members == null) return; |
| 459 // [f] might add elements to [: map[memberName] :] during the loop below | 299 // [f] might add elements to [: map[memberName] :] during the loop below |
| 460 // so we create a new list for [: map[memberName] :] and prepend the | 300 // so we create a new list for [: map[memberName] :] and prepend the |
| 461 // [remaining] members after the loop. | 301 // [remaining] members after the loop. |
| 462 map[memberName] = new Set<Element>(); | 302 map[memberName] = new Set<Element>(); |
| 463 Set<Element> remaining = new Set<Element>(); | 303 Set<Element> remaining = new Set<Element>(); |
| 464 for (Element member in members) { | 304 for (Element member in members) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 */ | 350 */ |
| 511 void registerStaticUse(StaticUse staticUse) { | 351 void registerStaticUse(StaticUse staticUse) { |
| 512 strategy.processStaticUse(this, staticUse); | 352 strategy.processStaticUse(this, staticUse); |
| 513 } | 353 } |
| 514 | 354 |
| 515 void registerStaticUseInternal(StaticUse staticUse) { | 355 void registerStaticUseInternal(StaticUse staticUse) { |
| 516 Element element = staticUse.element; | 356 Element element = staticUse.element; |
| 517 assert(invariant(element, element.isDeclaration, | 357 assert(invariant(element, element.isDeclaration, |
| 518 message: "Element ${element} is not the declaration.")); | 358 message: "Element ${element} is not the declaration.")); |
| 519 _universe.registerStaticUse(staticUse); | 359 _universe.registerStaticUse(staticUse); |
| 520 backend.registerStaticUse(element, forResolution: false); | 360 backend.registerStaticUse(this, element); |
| 521 bool addElement = true; | 361 bool addElement = true; |
| 522 switch (staticUse.kind) { | 362 switch (staticUse.kind) { |
| 523 case StaticUseKind.STATIC_TEAR_OFF: | 363 case StaticUseKind.STATIC_TEAR_OFF: |
| 524 backend.registerGetOfStaticFunction(this); | 364 backend.registerGetOfStaticFunction(this); |
| 525 break; | 365 break; |
| 526 case StaticUseKind.FIELD_GET: | 366 case StaticUseKind.FIELD_GET: |
| 527 case StaticUseKind.FIELD_SET: | 367 case StaticUseKind.FIELD_SET: |
| 528 case StaticUseKind.CLOSURE: | 368 case StaticUseKind.CLOSURE: |
| 529 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and | 369 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and |
| 530 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. | 370 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 546 } | 386 } |
| 547 if (addElement) { | 387 if (addElement) { |
| 548 addToWorkList(element); | 388 addToWorkList(element); |
| 549 } | 389 } |
| 550 } | 390 } |
| 551 | 391 |
| 552 void registerTypeUse(TypeUse typeUse) { | 392 void registerTypeUse(TypeUse typeUse) { |
| 553 DartType type = typeUse.type; | 393 DartType type = typeUse.type; |
| 554 switch (typeUse.kind) { | 394 switch (typeUse.kind) { |
| 555 case TypeUseKind.INSTANTIATION: | 395 case TypeUseKind.INSTANTIATION: |
| 556 registerInstantiatedType(type); | 396 _registerInstantiatedType(type); |
| 397 break; |
| 398 case TypeUseKind.MIRROR_INSTANTIATION: |
| 399 _registerInstantiatedType(type, mirrorUsage: true); |
| 400 break; |
| 401 case TypeUseKind.NATIVE_INSTANTIATION: |
| 402 _registerInstantiatedType(type, nativeUsage: true); |
| 557 break; | 403 break; |
| 558 case TypeUseKind.IS_CHECK: | 404 case TypeUseKind.IS_CHECK: |
| 559 case TypeUseKind.AS_CAST: | 405 case TypeUseKind.AS_CAST: |
| 560 case TypeUseKind.CATCH_TYPE: | 406 case TypeUseKind.CATCH_TYPE: |
| 561 _registerIsCheck(type); | 407 _registerIsCheck(type); |
| 562 break; | 408 break; |
| 563 case TypeUseKind.CHECKED_MODE_CHECK: | 409 case TypeUseKind.CHECKED_MODE_CHECK: |
| 564 if (options.enableTypeAssertions) { | 410 if (options.enableTypeAssertions) { |
| 565 _registerIsCheck(type); | 411 _registerIsCheck(type); |
| 566 } | 412 } |
| 567 break; | 413 break; |
| 568 case TypeUseKind.TYPE_LITERAL: | 414 case TypeUseKind.TYPE_LITERAL: |
| 569 break; | 415 break; |
| 570 } | 416 } |
| 571 } | 417 } |
| 572 | 418 |
| 573 void _registerIsCheck(DartType type) { | 419 void _registerIsCheck(DartType type) { |
| 574 type = _universe.registerIsCheck(type, _compiler); | 420 type = _universe.registerIsCheck(type, _compiler); |
| 575 // Even in checked mode, type annotations for return type and argument | 421 // 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 | 422 // types do not imply type checks, so there should never be a check |
| 577 // against the type variable of a typedef. | 423 // against the type variable of a typedef. |
| 578 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); | 424 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
| 579 } | 425 } |
| 580 | 426 |
| 581 void registerCallMethodWithFreeTypeVariables(Element element) { | 427 void registerCallMethodWithFreeTypeVariables(Element element) { |
| 582 backend.registerCallMethodWithFreeTypeVariables( | 428 backend.registerCallMethodWithFreeTypeVariables(element, this); |
| 583 element, this, globalDependencies); | |
| 584 } | 429 } |
| 585 | 430 |
| 586 void registerClosurizedMember(TypedElement element) { | 431 void registerClosurizedMember(TypedElement element) { |
| 587 assert(element.isInstanceMember); | 432 assert(element.isInstanceMember); |
| 588 if (element.type.containsTypeVariables) { | 433 if (element.type.containsTypeVariables) { |
| 589 backend.registerClosureWithFreeTypeVariables( | 434 backend.registerClosureWithFreeTypeVariables(element, this); |
| 590 element, this, globalDependencies); | |
| 591 } | 435 } |
| 592 backend.registerBoundClosure(this); | 436 backend.registerBoundClosure(this); |
| 593 } | 437 } |
| 594 | 438 |
| 595 void forEach(void f(WorkItem work)) { | 439 void forEach(void f(WorkItem work)) { |
| 596 do { | 440 do { |
| 597 while (queue.isNotEmpty) { | 441 while (queue.isNotEmpty) { |
| 598 // TODO(johnniwinther): Find an optimal process order. | 442 // TODO(johnniwinther): Find an optimal process order. |
| 599 filter.processWorkItem(f, queue.removeLast()); | 443 filter.processWorkItem(f, queue.removeLast()); |
| 600 } | 444 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 bool enabledNoSuchMethod = false; | 482 bool enabledNoSuchMethod = false; |
| 639 | 483 |
| 640 static const ImpactUseCase IMPACT_USE = | 484 static const ImpactUseCase IMPACT_USE = |
| 641 const ImpactUseCase('CodegenEnqueuer'); | 485 const ImpactUseCase('CodegenEnqueuer'); |
| 642 | 486 |
| 643 ImpactUseCase get impactUse => IMPACT_USE; | 487 ImpactUseCase get impactUse => IMPACT_USE; |
| 644 | 488 |
| 645 bool isProcessed(Element member) => | 489 bool isProcessed(Element member) => |
| 646 member.isAbstract || generatedCode.containsKey(member); | 490 member.isAbstract || generatedCode.containsKey(member); |
| 647 | 491 |
| 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) { | 492 void registerNoSuchMethod(Element element) { |
| 661 if (!enabledNoSuchMethod && backend.enabledNoSuchMethod) { | 493 if (!enabledNoSuchMethod && backend.enabledNoSuchMethod) { |
| 662 backend.enableNoSuchMethod(this); | 494 backend.enableNoSuchMethod(this); |
| 663 enabledNoSuchMethod = true; | 495 enabledNoSuchMethod = true; |
| 664 } | 496 } |
| 665 } | 497 } |
| 666 | 498 |
| 667 void _logSpecificSummary(log(message)) { | 499 void _logSpecificSummary(log(message)) { |
| 668 log('Compiled ${generatedCode.length} methods.'); | 500 log('Compiled ${generatedCode.length} methods.'); |
| 669 } | 501 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 682 | 514 |
| 683 void handleUnseenSelector(DynamicUse dynamicUse) { | 515 void handleUnseenSelector(DynamicUse dynamicUse) { |
| 684 if (options.hasIncrementalSupport) { | 516 if (options.hasIncrementalSupport) { |
| 685 newlySeenSelectors.add(dynamicUse); | 517 newlySeenSelectors.add(dynamicUse); |
| 686 } | 518 } |
| 687 _handleUnseenSelector(dynamicUse); | 519 _handleUnseenSelector(dynamicUse); |
| 688 } | 520 } |
| 689 | 521 |
| 690 @override | 522 @override |
| 691 Iterable<Entity> get processedEntities => generatedCode.keys; | 523 Iterable<Entity> get processedEntities => generatedCode.keys; |
| 524 |
| 525 @override |
| 526 Iterable<ClassElement> get processedClasses => _processedClasses; |
| 692 } | 527 } |
| 693 | 528 |
| 694 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 529 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
| 695 Set<Element> set = map[element.name]; | 530 Set<Element> set = map[element.name]; |
| 696 if (set == null) return; | 531 if (set == null) return; |
| 697 set.remove(element); | 532 set.remove(element); |
| 698 } | 533 } |
| 699 | 534 |
| 700 class _EnqueuerImpactVisitor implements WorldImpactVisitor { | 535 class _EnqueuerImpactVisitor implements WorldImpactVisitor { |
| 701 final CodegenEnqueuer enqueuer; | 536 final CodegenEnqueuer enqueuer; |
| 702 | 537 |
| 703 _EnqueuerImpactVisitor(this.enqueuer); | 538 _EnqueuerImpactVisitor(this.enqueuer); |
| 704 | 539 |
| 705 @override | 540 @override |
| 706 void visitDynamicUse(DynamicUse dynamicUse) { | 541 void visitDynamicUse(DynamicUse dynamicUse) { |
| 707 enqueuer.registerDynamicUse(dynamicUse); | 542 enqueuer.registerDynamicUse(dynamicUse); |
| 708 } | 543 } |
| 709 | 544 |
| 710 @override | 545 @override |
| 711 void visitStaticUse(StaticUse staticUse) { | 546 void visitStaticUse(StaticUse staticUse) { |
| 712 enqueuer.registerStaticUse(staticUse); | 547 enqueuer.registerStaticUse(staticUse); |
| 713 } | 548 } |
| 714 | 549 |
| 715 @override | 550 @override |
| 716 void visitTypeUse(TypeUse typeUse) { | 551 void visitTypeUse(TypeUse typeUse) { |
| 717 enqueuer.registerTypeUse(typeUse); | 552 enqueuer.registerTypeUse(typeUse); |
| 718 } | 553 } |
| 719 } | 554 } |
| OLD | NEW |