| 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 Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'common/names.dart' show Identifiers; | 9 import 'common/names.dart' show Identifiers; |
| 10 import 'common/resolution.dart' show Resolution; | 10 import 'common/resolution.dart' show Resolution; |
| 11 import 'common/resolution.dart' show ResolutionWorkItem; | 11 import 'common/resolution.dart' show ResolutionWorkItem; |
| 12 import 'common/tasks.dart' show CompilerTask; | 12 import 'common/tasks.dart' show CompilerTask; |
| 13 import 'common/work.dart' show WorkItem; | 13 import 'common/work.dart' show WorkItem; |
| 14 import 'common.dart'; | 14 import 'common.dart'; |
| 15 import 'compiler.dart' show Compiler; | 15 import 'compiler.dart' show Compiler; |
| 16 import 'dart_types.dart' show DartType, InterfaceType; | 16 import 'dart_types.dart' show DartType, InterfaceType; |
| 17 import 'elements/elements.dart' | 17 import 'elements/elements.dart' |
| 18 show | 18 show |
| 19 AnalyzableElement, | 19 AnalyzableElement, |
| 20 AstElement, | 20 AstElement, |
| 21 ClassElement, | 21 ClassElement, |
| 22 ConstructorElement, | |
| 23 Element, | 22 Element, |
| 24 Elements, | |
| 25 Entity, | 23 Entity, |
| 26 FunctionElement, | 24 FunctionElement, |
| 27 LibraryElement, | 25 LibraryElement, |
| 28 Member, | 26 LocalFunctionElement, |
| 29 Name, | 27 TypedElement; |
| 30 TypedElement, | |
| 31 TypedefElement; | |
| 32 import 'native/native.dart' as native; | 28 import 'native/native.dart' as native; |
| 33 import 'types/types.dart' show TypeMaskStrategy; | 29 import 'types/types.dart' show TypeMaskStrategy; |
| 34 import 'universe/selector.dart' show Selector; | 30 import 'universe/selector.dart' show Selector; |
| 35 import 'universe/world_builder.dart'; | 31 import 'universe/world_builder.dart'; |
| 36 import 'universe/use.dart' | 32 import 'universe/use.dart' |
| 37 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; | 33 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
| 38 import 'universe/world_impact.dart' | 34 import 'universe/world_impact.dart' |
| 39 show ImpactUseCase, WorldImpact, WorldImpactVisitor; | 35 show ImpactUseCase, WorldImpact, WorldImpactVisitor; |
| 40 import 'util/util.dart' show Setlet; | 36 import 'util/util.dart' show Setlet; |
| 41 | 37 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 | 89 |
| 94 /** | 90 /** |
| 95 * Documentation wanted -- johnniwinther | 91 * Documentation wanted -- johnniwinther |
| 96 * | 92 * |
| 97 * Invariant: [element] must be a declaration element. | 93 * Invariant: [element] must be a declaration element. |
| 98 */ | 94 */ |
| 99 void addToWorkList(Element element); | 95 void addToWorkList(Element element); |
| 100 | 96 |
| 101 void enableIsolateSupport(); | 97 void enableIsolateSupport(); |
| 102 | 98 |
| 103 /// Enqueue the static fields that have been marked as used by reflective | 99 void registerInstantiatedType(InterfaceType type); |
| 104 /// usage through `MirrorsUsed`. | |
| 105 void enqueueReflectiveStaticFields(Iterable<Element> elements); | |
| 106 | |
| 107 /// Enqueue all elements that are matched by the mirrors used | |
| 108 /// annotation or, in lack thereof, all elements. | |
| 109 void enqueueReflectiveElements(Iterable<ClassElement> recents); | |
| 110 | |
| 111 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}); | |
| 112 void forEach(void f(WorkItem work)); | 100 void forEach(void f(WorkItem work)); |
| 113 | 101 |
| 114 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide
d | 102 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide
d |
| 115 /// the impact strategy will remove it from the element impact cache, if it is | 103 /// the impact strategy will remove it from the element impact cache, if it is |
| 116 /// no longer needed. | 104 /// no longer needed. |
| 117 void applyImpact(WorldImpact worldImpact, {Element impactSource}); | 105 void applyImpact(WorldImpact worldImpact, {Element impactSource}); |
| 118 bool checkNoEnqueuedInvokedInstanceMethods(); | 106 bool checkNoEnqueuedInvokedInstanceMethods(); |
| 119 void logSummary(log(message)); | 107 void logSummary(log(message)); |
| 120 | 108 |
| 121 /// Returns [:true:] if [member] has been processed by this enqueuer. | 109 /// Returns [:true:] if [member] has been processed by this enqueuer. |
| 122 bool isProcessed(Element member); | 110 bool isProcessed(Element member); |
| 123 | 111 |
| 124 Iterable<Entity> get processedEntities; | 112 Iterable<Entity> get processedEntities; |
| 113 |
| 114 Iterable<ClassElement> get processedClasses; |
| 125 } | 115 } |
| 126 | 116 |
| 127 /// [Enqueuer] which is specific to resolution. | 117 /// [Enqueuer] which is specific to resolution. |
| 128 class ResolutionEnqueuer extends Enqueuer { | 118 class ResolutionEnqueuer extends Enqueuer { |
| 129 final String name; | 119 final String name; |
| 130 final Compiler compiler; // TODO(ahe): Remove this dependency. | 120 final Compiler compiler; // TODO(ahe): Remove this dependency. |
| 131 final EnqueuerStrategy strategy; | 121 final EnqueuerStrategy strategy; |
| 132 final Map<String, Set<Element>> instanceMembersByName = | 122 final Map<String, Set<Element>> instanceMembersByName = |
| 133 new Map<String, Set<Element>>(); | 123 new Map<String, Set<Element>>(); |
| 134 final Map<String, Set<Element>> instanceFunctionsByName = | 124 final Map<String, Set<Element>> instanceFunctionsByName = |
| 135 new Map<String, Set<Element>>(); | 125 new Map<String, Set<Element>>(); |
| 136 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); | 126 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); |
| 137 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); | 127 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); |
| 138 final ResolutionWorldBuilderImpl _universe = | 128 final ResolutionWorldBuilderImpl _universe = |
| 139 new ResolutionWorldBuilderImpl(const TypeMaskStrategy()); | 129 new ResolutionWorldBuilderImpl(const TypeMaskStrategy()); |
| 140 | 130 |
| 141 static final TRACE_MIRROR_ENQUEUING = | |
| 142 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | |
| 143 | |
| 144 bool queueIsClosed = false; | 131 bool queueIsClosed = false; |
| 145 | 132 |
| 146 bool hasEnqueuedReflectiveElements = false; | |
| 147 bool hasEnqueuedReflectiveStaticFields = false; | |
| 148 | |
| 149 WorldImpactVisitor impactVisitor; | 133 WorldImpactVisitor impactVisitor; |
| 150 | 134 |
| 151 ResolutionEnqueuer(Compiler compiler, this.strategy) | 135 ResolutionEnqueuer(Compiler compiler, this.strategy) |
| 152 : this.name = 'resolution enqueuer', | 136 : this.name = 'resolution enqueuer', |
| 153 this.compiler = compiler, | 137 this.compiler = compiler, |
| 154 processedElements = new Set<AstElement>(), | 138 processedElements = new Set<AstElement>(), |
| 155 queue = new Queue<ResolutionWorkItem>(), | 139 queue = new Queue<ResolutionWorkItem>(), |
| 156 deferredQueue = new Queue<_DeferredAction>() { | 140 deferredQueue = new Queue<_DeferredAction>() { |
| 157 impactVisitor = new _EnqueuerImpactVisitor(this); | 141 impactVisitor = new _EnqueuerImpactVisitor(this); |
| 158 } | 142 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 179 void addToWorkList(Element element) { | 163 void addToWorkList(Element element) { |
| 180 assert(invariant(element, element.isDeclaration)); | 164 assert(invariant(element, element.isDeclaration)); |
| 181 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { | 165 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { |
| 182 // TODO(sigmund): add other missing dependencies (internals, selectors | 166 // TODO(sigmund): add other missing dependencies (internals, selectors |
| 183 // enqueued after allocations), also enable only for the codegen enqueuer. | 167 // enqueued after allocations), also enable only for the codegen enqueuer. |
| 184 compiler.dumpInfoTask | 168 compiler.dumpInfoTask |
| 185 .registerDependency(compiler.currentElement, element); | 169 .registerDependency(compiler.currentElement, element); |
| 186 } | 170 } |
| 187 } | 171 } |
| 188 | 172 |
| 173 void registerInstantiatedType(InterfaceType type) { |
| 174 _registerInstantiatedType(type, globalDependency: true); |
| 175 } |
| 176 |
| 189 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { | 177 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { |
| 190 compiler.impactStrategy | 178 compiler.impactStrategy |
| 191 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); | 179 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); |
| 192 } | 180 } |
| 193 | 181 |
| 194 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { | 182 void _registerInstantiatedType(InterfaceType type, |
| 183 {bool mirrorUsage: false, |
| 184 bool nativeUsage: false, |
| 185 bool globalDependency: false}) { |
| 195 task.measure(() { | 186 task.measure(() { |
| 196 ClassElement cls = type.element; | 187 ClassElement cls = type.element; |
| 197 cls.ensureResolved(resolution); | 188 cls.ensureResolved(resolution); |
| 198 bool isNative = compiler.backend.isNative(cls); | 189 bool isNative = compiler.backend.isNative(cls); |
| 199 _universe.registerTypeInstantiation(type, | 190 _universe.registerTypeInstantiation(type, |
| 200 isNative: isNative, | 191 isNative: isNative, |
| 201 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { | 192 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { |
| 202 compiler.backend | 193 compiler.backend.registerImplementedClass(cls, this); |
| 203 .registerImplementedClass(cls, this, compiler.globalDependencies); | |
| 204 }); | 194 }); |
| 195 if (globalDependency && !mirrorUsage) { |
| 196 compiler.globalDependencies.registerDependency(type.element); |
| 197 } |
| 198 if (nativeUsage) { |
| 199 nativeEnqueuer.onInstantiatedType(type); |
| 200 } |
| 201 compiler.backend.registerInstantiatedType(type); |
| 205 // TODO(johnniwinther): Share this reasoning with [Universe]. | 202 // TODO(johnniwinther): Share this reasoning with [Universe]. |
| 206 if (!cls.isAbstract || isNative || mirrorUsage) { | 203 if (!cls.isAbstract || isNative || mirrorUsage) { |
| 207 processInstantiatedClass(cls); | 204 processInstantiatedClass(cls); |
| 208 } | 205 } |
| 209 }); | 206 }); |
| 210 } | 207 } |
| 211 | 208 |
| 212 bool checkNoEnqueuedInvokedInstanceMethods() { | 209 bool checkNoEnqueuedInvokedInstanceMethods() { |
| 213 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 210 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
| 214 } | 211 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 _processedClasses.add(superclass); | 315 _processedClasses.add(superclass); |
| 319 recentClasses.add(superclass); | 316 recentClasses.add(superclass); |
| 320 superclass.ensureResolved(resolution); | 317 superclass.ensureResolved(resolution); |
| 321 superclass.implementation.forEachMember(processInstantiatedClassMember); | 318 superclass.implementation.forEachMember(processInstantiatedClassMember); |
| 322 if (!compiler.serialization.isDeserialized(superclass)) { | 319 if (!compiler.serialization.isDeserialized(superclass)) { |
| 323 compiler.resolver.checkClass(superclass); | 320 compiler.resolver.checkClass(superclass); |
| 324 } | 321 } |
| 325 // We only tell the backend once that [superclass] was instantiated, so | 322 // We only tell the backend once that [superclass] was instantiated, so |
| 326 // any additional dependencies must be treated as global | 323 // any additional dependencies must be treated as global |
| 327 // dependencies. | 324 // dependencies. |
| 328 compiler.backend.registerInstantiatedClass( | 325 compiler.backend.registerInstantiatedClass(superclass, this); |
| 329 superclass, this, compiler.globalDependencies); | |
| 330 } | 326 } |
| 331 | 327 |
| 332 ClassElement superclass = cls; | 328 ClassElement superclass = cls; |
| 333 while (superclass != null) { | 329 while (superclass != null) { |
| 334 processClass(superclass); | 330 processClass(superclass); |
| 335 superclass = superclass.superclass; | 331 superclass = superclass.superclass; |
| 336 } | 332 } |
| 337 }); | 333 }); |
| 338 } | 334 } |
| 339 | 335 |
| 340 void registerDynamicUse(DynamicUse dynamicUse) { | 336 void registerDynamicUse(DynamicUse dynamicUse) { |
| 341 task.measure(() { | 337 task.measure(() { |
| 342 if (_universe.registerDynamicUse(dynamicUse)) { | 338 if (_universe.registerDynamicUse(dynamicUse)) { |
| 343 handleUnseenSelector(dynamicUse); | 339 handleUnseenSelector(dynamicUse); |
| 344 } | 340 } |
| 345 }); | 341 }); |
| 346 } | 342 } |
| 347 | 343 |
| 348 void logEnqueueReflectiveAction(action, [msg = ""]) { | |
| 349 if (TRACE_MIRROR_ENQUEUING) { | |
| 350 print("MIRROR_ENQUEUE (R): $action $msg"); | |
| 351 } | |
| 352 } | |
| 353 | |
| 354 /// Enqeue the constructor [ctor] if it is required for reflection. | |
| 355 /// | |
| 356 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | |
| 357 /// needed for reflection. | |
| 358 void enqueueReflectiveConstructor( | |
| 359 ConstructorElement ctor, bool enclosingWasIncluded) { | |
| 360 if (shouldIncludeElementDueToMirrors(ctor, | |
| 361 includedEnclosing: enclosingWasIncluded)) { | |
| 362 logEnqueueReflectiveAction(ctor); | |
| 363 ClassElement cls = ctor.declaration.enclosingClass; | |
| 364 compiler.backend.registerInstantiatedType( | |
| 365 cls.rawType, this, compiler.mirrorDependencies, | |
| 366 mirrorUsage: true); | |
| 367 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); | |
| 368 } | |
| 369 } | |
| 370 | |
| 371 /// Enqeue the member [element] if it is required for reflection. | |
| 372 /// | |
| 373 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | |
| 374 /// needed for reflection. | |
| 375 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { | |
| 376 if (shouldIncludeElementDueToMirrors(element, | |
| 377 includedEnclosing: enclosingWasIncluded)) { | |
| 378 logEnqueueReflectiveAction(element); | |
| 379 if (element.isTypedef) { | |
| 380 TypedefElement typedef = element; | |
| 381 typedef.ensureResolved(resolution); | |
| 382 } else if (Elements.isStaticOrTopLevel(element)) { | |
| 383 registerStaticUse(new StaticUse.foreignUse(element.declaration)); | |
| 384 } else if (element.isInstanceMember) { | |
| 385 // We need to enqueue all members matching this one in subclasses, as | |
| 386 // well. | |
| 387 // TODO(herhut): Use TypedSelector.subtype for enqueueing | |
| 388 DynamicUse dynamicUse = | |
| 389 new DynamicUse(new Selector.fromElement(element), null); | |
| 390 registerDynamicUse(dynamicUse); | |
| 391 if (element.isField) { | |
| 392 DynamicUse dynamicUse = new DynamicUse( | |
| 393 new Selector.setter( | |
| 394 new Name(element.name, element.library, isSetter: true)), | |
| 395 null); | |
| 396 registerDynamicUse(dynamicUse); | |
| 397 } | |
| 398 } | |
| 399 } | |
| 400 } | |
| 401 | |
| 402 /// Enqeue the member [element] if it is required for reflection. | |
| 403 /// | |
| 404 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | |
| 405 /// needed for reflection. | |
| 406 void enqueueReflectiveElementsInClass(ClassElement cls, | |
| 407 Iterable<ClassElement> recents, bool enclosingWasIncluded) { | |
| 408 if (cls.library.isInternalLibrary || cls.isInjected) return; | |
| 409 bool includeClass = shouldIncludeElementDueToMirrors(cls, | |
| 410 includedEnclosing: enclosingWasIncluded); | |
| 411 if (includeClass) { | |
| 412 logEnqueueReflectiveAction(cls, "register"); | |
| 413 ClassElement decl = cls.declaration; | |
| 414 decl.ensureResolved(resolution); | |
| 415 compiler.backend.registerInstantiatedType( | |
| 416 decl.rawType, this, compiler.mirrorDependencies, | |
| 417 mirrorUsage: true); | |
| 418 } | |
| 419 // If the class is never instantiated, we know nothing of it can possibly | |
| 420 // be reflected upon. | |
| 421 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | |
| 422 if (recents.contains(cls.declaration)) { | |
| 423 logEnqueueReflectiveAction(cls, "members"); | |
| 424 cls.constructors.forEach((Element element) { | |
| 425 enqueueReflectiveConstructor(element, includeClass); | |
| 426 }); | |
| 427 cls.forEachClassMember((Member member) { | |
| 428 enqueueReflectiveMember(member.element, includeClass); | |
| 429 }); | |
| 430 } | |
| 431 } | |
| 432 | |
| 433 /// Enqeue special classes that might not be visible by normal means or that | |
| 434 /// would not normally be enqueued: | |
| 435 /// | |
| 436 /// [Closure] is treated specially as it is the superclass of all closures. | |
| 437 /// Although it is in an internal library, we mark it as reflectable. Note | |
| 438 /// that none of its methods are reflectable, unless reflectable by | |
| 439 /// inheritance. | |
| 440 void enqueueReflectiveSpecialClasses() { | |
| 441 Iterable<ClassElement> classes = | |
| 442 compiler.backend.classesRequiredForReflection; | |
| 443 for (ClassElement cls in classes) { | |
| 444 if (compiler.backend.referencedFromMirrorSystem(cls)) { | |
| 445 logEnqueueReflectiveAction(cls); | |
| 446 cls.ensureResolved(resolution); | |
| 447 compiler.backend.registerInstantiatedType( | |
| 448 cls.rawType, this, compiler.mirrorDependencies, | |
| 449 mirrorUsage: true); | |
| 450 } | |
| 451 } | |
| 452 } | |
| 453 | |
| 454 /// Enqeue all local members of the library [lib] if they are required for | |
| 455 /// reflection. | |
| 456 void enqueueReflectiveElementsInLibrary( | |
| 457 LibraryElement lib, Iterable<ClassElement> recents) { | |
| 458 bool includeLibrary = | |
| 459 shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); | |
| 460 lib.forEachLocalMember((Element member) { | |
| 461 if (member.isInjected) return; | |
| 462 if (member.isClass) { | |
| 463 enqueueReflectiveElementsInClass(member, recents, includeLibrary); | |
| 464 } else { | |
| 465 enqueueReflectiveMember(member, includeLibrary); | |
| 466 } | |
| 467 }); | |
| 468 } | |
| 469 | |
| 470 /// Enqueue all elements that are matched by the mirrors used | |
| 471 /// annotation or, in lack thereof, all elements. | |
| 472 void enqueueReflectiveElements(Iterable<ClassElement> recents) { | |
| 473 if (!hasEnqueuedReflectiveElements) { | |
| 474 logEnqueueReflectiveAction("!START enqueueAll"); | |
| 475 // First round of enqueuing, visit everything that is visible to | |
| 476 // also pick up static top levels, etc. | |
| 477 // Also, during the first round, consider all classes that have been seen | |
| 478 // as recently seen, as we do not know how many rounds of resolution might | |
| 479 // have run before tree shaking is disabled and thus everything is | |
| 480 // enqueued. | |
| 481 recents = _processedClasses.toSet(); | |
| 482 reporter.log('Enqueuing everything'); | |
| 483 for (LibraryElement lib in compiler.libraryLoader.libraries) { | |
| 484 enqueueReflectiveElementsInLibrary(lib, recents); | |
| 485 } | |
| 486 enqueueReflectiveSpecialClasses(); | |
| 487 hasEnqueuedReflectiveElements = true; | |
| 488 hasEnqueuedReflectiveStaticFields = true; | |
| 489 logEnqueueReflectiveAction("!DONE enqueueAll"); | |
| 490 } else if (recents.isNotEmpty) { | |
| 491 // Keep looking at new classes until fixpoint is reached. | |
| 492 logEnqueueReflectiveAction("!START enqueueRecents"); | |
| 493 recents.forEach((ClassElement cls) { | |
| 494 enqueueReflectiveElementsInClass( | |
| 495 cls, | |
| 496 recents, | |
| 497 shouldIncludeElementDueToMirrors(cls.library, | |
| 498 includedEnclosing: false)); | |
| 499 }); | |
| 500 logEnqueueReflectiveAction("!DONE enqueueRecents"); | |
| 501 } | |
| 502 } | |
| 503 | |
| 504 /// Enqueue the static fields that have been marked as used by reflective | |
| 505 /// usage through `MirrorsUsed`. | |
| 506 void enqueueReflectiveStaticFields(Iterable<Element> elements) { | |
| 507 if (hasEnqueuedReflectiveStaticFields) return; | |
| 508 hasEnqueuedReflectiveStaticFields = true; | |
| 509 for (Element element in elements) { | |
| 510 enqueueReflectiveMember(element, true); | |
| 511 } | |
| 512 } | |
| 513 | |
| 514 void processSet( | 344 void processSet( |
| 515 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { | 345 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { |
| 516 Set<Element> members = map[memberName]; | 346 Set<Element> members = map[memberName]; |
| 517 if (members == null) return; | 347 if (members == null) return; |
| 518 // [f] might add elements to [: map[memberName] :] during the loop below | 348 // [f] might add elements to [: map[memberName] :] during the loop below |
| 519 // so we create a new list for [: map[memberName] :] and prepend the | 349 // so we create a new list for [: map[memberName] :] and prepend the |
| 520 // [remaining] members after the loop. | 350 // [remaining] members after the loop. |
| 521 map[memberName] = new Set<Element>(); | 351 map[memberName] = new Set<Element>(); |
| 522 Set<Element> remaining = new Set<Element>(); | 352 Set<Element> remaining = new Set<Element>(); |
| 523 for (Element member in members) { | 353 for (Element member in members) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 */ | 399 */ |
| 570 void registerStaticUse(StaticUse staticUse) { | 400 void registerStaticUse(StaticUse staticUse) { |
| 571 strategy.processStaticUse(this, staticUse); | 401 strategy.processStaticUse(this, staticUse); |
| 572 } | 402 } |
| 573 | 403 |
| 574 void registerStaticUseInternal(StaticUse staticUse) { | 404 void registerStaticUseInternal(StaticUse staticUse) { |
| 575 Element element = staticUse.element; | 405 Element element = staticUse.element; |
| 576 assert(invariant(element, element.isDeclaration, | 406 assert(invariant(element, element.isDeclaration, |
| 577 message: "Element ${element} is not the declaration.")); | 407 message: "Element ${element} is not the declaration.")); |
| 578 _universe.registerStaticUse(staticUse); | 408 _universe.registerStaticUse(staticUse); |
| 579 compiler.backend.registerStaticUse(element, forResolution: true); | 409 compiler.backend.registerStaticUse(this, element); |
| 580 bool addElement = true; | 410 bool addElement = true; |
| 581 switch (staticUse.kind) { | 411 switch (staticUse.kind) { |
| 582 case StaticUseKind.STATIC_TEAR_OFF: | 412 case StaticUseKind.STATIC_TEAR_OFF: |
| 583 compiler.backend.registerGetOfStaticFunction(this); | 413 compiler.backend.registerGetOfStaticFunction(this); |
| 584 break; | 414 break; |
| 585 case StaticUseKind.FIELD_GET: | 415 case StaticUseKind.FIELD_GET: |
| 586 case StaticUseKind.FIELD_SET: | 416 case StaticUseKind.FIELD_SET: |
| 587 case StaticUseKind.CLOSURE: | 417 case StaticUseKind.CLOSURE: |
| 588 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and | 418 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and |
| 589 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. | 419 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. |
| 590 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot | 420 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot |
| 591 // enqueue. | 421 // enqueue. |
| 422 LocalFunctionElement closure = staticUse.element; |
| 423 if (closure.type.containsTypeVariables) { |
| 424 universe.closuresWithFreeTypeVariables.add(closure); |
| 425 } |
| 592 addElement = false; | 426 addElement = false; |
| 593 break; | 427 break; |
| 594 case StaticUseKind.SUPER_FIELD_SET: | 428 case StaticUseKind.SUPER_FIELD_SET: |
| 595 case StaticUseKind.SUPER_TEAR_OFF: | 429 case StaticUseKind.SUPER_TEAR_OFF: |
| 596 case StaticUseKind.GENERAL: | 430 case StaticUseKind.GENERAL: |
| 597 break; | 431 break; |
| 598 case StaticUseKind.CONSTRUCTOR_INVOKE: | 432 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 599 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 433 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 600 registerTypeUse(new TypeUse.instantiation(staticUse.type)); | 434 registerTypeUse(new TypeUse.instantiation(staticUse.type)); |
| 601 break; | 435 break; |
| 602 case StaticUseKind.DIRECT_INVOKE: | 436 case StaticUseKind.DIRECT_INVOKE: |
| 603 invariant( | 437 invariant( |
| 604 element, 'Direct static use is not supported for resolution.'); | 438 element, 'Direct static use is not supported for resolution.'); |
| 605 break; | 439 break; |
| 606 } | 440 } |
| 607 if (addElement) { | 441 if (addElement) { |
| 608 addToWorkList(element); | 442 addToWorkList(element); |
| 609 } | 443 } |
| 610 } | 444 } |
| 611 | 445 |
| 612 void registerTypeUse(TypeUse typeUse) { | 446 void registerTypeUse(TypeUse typeUse) { |
| 613 DartType type = typeUse.type; | 447 DartType type = typeUse.type; |
| 614 switch (typeUse.kind) { | 448 switch (typeUse.kind) { |
| 615 case TypeUseKind.INSTANTIATION: | 449 case TypeUseKind.INSTANTIATION: |
| 616 registerInstantiatedType(type); | 450 _registerInstantiatedType(type, globalDependency: false); |
| 451 break; |
| 452 case TypeUseKind.MIRROR_INSTANTIATION: |
| 453 _registerInstantiatedType(type, |
| 454 mirrorUsage: true, globalDependency: false); |
| 455 break; |
| 456 case TypeUseKind.NATIVE_INSTANTIATION: |
| 457 _registerInstantiatedType(type, |
| 458 nativeUsage: true, globalDependency: true); |
| 617 break; | 459 break; |
| 618 case TypeUseKind.IS_CHECK: | 460 case TypeUseKind.IS_CHECK: |
| 619 case TypeUseKind.AS_CAST: | 461 case TypeUseKind.AS_CAST: |
| 620 case TypeUseKind.CATCH_TYPE: | 462 case TypeUseKind.CATCH_TYPE: |
| 621 _registerIsCheck(type); | 463 _registerIsCheck(type); |
| 622 break; | 464 break; |
| 623 case TypeUseKind.CHECKED_MODE_CHECK: | 465 case TypeUseKind.CHECKED_MODE_CHECK: |
| 624 if (compiler.options.enableTypeAssertions) { | 466 if (compiler.options.enableTypeAssertions) { |
| 625 _registerIsCheck(type); | 467 _registerIsCheck(type); |
| 626 } | 468 } |
| 627 break; | 469 break; |
| 628 case TypeUseKind.TYPE_LITERAL: | 470 case TypeUseKind.TYPE_LITERAL: |
| 629 break; | 471 break; |
| 630 } | 472 } |
| 631 } | 473 } |
| 632 | 474 |
| 633 void _registerIsCheck(DartType type) { | 475 void _registerIsCheck(DartType type) { |
| 634 type = _universe.registerIsCheck(type, compiler); | 476 type = _universe.registerIsCheck(type, compiler); |
| 635 // Even in checked mode, type annotations for return type and argument | 477 // Even in checked mode, type annotations for return type and argument |
| 636 // types do not imply type checks, so there should never be a check | 478 // types do not imply type checks, so there should never be a check |
| 637 // against the type variable of a typedef. | 479 // against the type variable of a typedef. |
| 638 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); | 480 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
| 639 } | 481 } |
| 640 | 482 |
| 641 void registerCallMethodWithFreeTypeVariables(Element element) { | 483 void registerCallMethodWithFreeTypeVariables(Element element) { |
| 642 compiler.backend.registerCallMethodWithFreeTypeVariables( | 484 compiler.backend.registerCallMethodWithFreeTypeVariables(element, this); |
| 643 element, this, compiler.globalDependencies); | |
| 644 _universe.callMethodsWithFreeTypeVariables.add(element); | 485 _universe.callMethodsWithFreeTypeVariables.add(element); |
| 645 } | 486 } |
| 646 | 487 |
| 647 void registerClosurizedMember(TypedElement element) { | 488 void registerClosurizedMember(TypedElement element) { |
| 648 assert(element.isInstanceMember); | 489 assert(element.isInstanceMember); |
| 649 if (element.computeType(resolution).containsTypeVariables) { | 490 if (element.computeType(resolution).containsTypeVariables) { |
| 650 compiler.backend.registerClosureWithFreeTypeVariables( | 491 compiler.backend.registerClosureWithFreeTypeVariables(element, this); |
| 651 element, this, compiler.globalDependencies); | |
| 652 _universe.closuresWithFreeTypeVariables.add(element); | 492 _universe.closuresWithFreeTypeVariables.add(element); |
| 653 } | 493 } |
| 654 compiler.backend.registerBoundClosure(this); | 494 compiler.backend.registerBoundClosure(this); |
| 655 _universe.closurizedMembers.add(element); | 495 _universe.closurizedMembers.add(element); |
| 656 } | 496 } |
| 657 | 497 |
| 658 void forEach(void f(WorkItem work)) { | 498 void forEach(void f(WorkItem work)) { |
| 659 do { | 499 do { |
| 660 while (queue.isNotEmpty) { | 500 while (queue.isNotEmpty) { |
| 661 // TODO(johnniwinther): Find an optimal process order. | 501 // TODO(johnniwinther): Find an optimal process order. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 return processedElements.contains(element.analyzableElement.declaration); | 539 return processedElements.contains(element.analyzableElement.declaration); |
| 700 } | 540 } |
| 701 | 541 |
| 702 /// Registers [element] as processed by the resolution enqueuer. | 542 /// Registers [element] as processed by the resolution enqueuer. |
| 703 void registerProcessedElement(AstElement element) { | 543 void registerProcessedElement(AstElement element) { |
| 704 processedElements.add(element); | 544 processedElements.add(element); |
| 705 compiler.backend.onElementResolved(element); | 545 compiler.backend.onElementResolved(element); |
| 706 } | 546 } |
| 707 | 547 |
| 708 /** | 548 /** |
| 709 * Decides whether an element should be included to satisfy requirements | |
| 710 * of the mirror system. | |
| 711 * | |
| 712 * During resolution, we have to resort to matching elements against the | |
| 713 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, | |
| 714 * yet. | |
| 715 */ | |
| 716 bool shouldIncludeElementDueToMirrors(Element element, | |
| 717 {bool includedEnclosing}) { | |
| 718 return includedEnclosing || | |
| 719 compiler.backend.requiredByMirrorSystem(element); | |
| 720 } | |
| 721 | |
| 722 /** | |
| 723 * Adds [element] to the work list if it has not already been processed. | 549 * Adds [element] to the work list if it has not already been processed. |
| 724 * | 550 * |
| 725 * Returns [true] if the element was actually added to the queue. | 551 * Returns [true] if the element was actually added to the queue. |
| 726 */ | 552 */ |
| 727 bool internalAddToWorkList(Element element) { | 553 bool internalAddToWorkList(Element element) { |
| 728 if (element.isMalformed) return false; | 554 if (element.isMalformed) return false; |
| 729 | 555 |
| 730 assert(invariant(element, element is AnalyzableElement, | 556 assert(invariant(element, element is AnalyzableElement, |
| 731 message: 'Element $element is not analyzable.')); | 557 message: 'Element $element is not analyzable.')); |
| 732 if (hasBeenProcessed(element)) return false; | 558 if (hasBeenProcessed(element)) return false; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 758 } | 584 } |
| 759 } | 585 } |
| 760 | 586 |
| 761 if (element.isGetter && element.name == Identifiers.runtimeType_) { | 587 if (element.isGetter && element.name == Identifiers.runtimeType_) { |
| 762 // Enable runtime type support if we discover a getter called runtimeType. | 588 // Enable runtime type support if we discover a getter called runtimeType. |
| 763 // We have to enable runtime type before hitting the codegen, so | 589 // We have to enable runtime type before hitting the codegen, so |
| 764 // that constructors know whether they need to generate code for | 590 // that constructors know whether they need to generate code for |
| 765 // runtime type. | 591 // runtime type. |
| 766 compiler.enabledRuntimeType = true; | 592 compiler.enabledRuntimeType = true; |
| 767 // TODO(ahe): Record precise dependency here. | 593 // TODO(ahe): Record precise dependency here. |
| 768 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); | 594 compiler.backend.registerRuntimeType(this); |
| 769 } else if (compiler.commonElements.isFunctionApplyMethod(element)) { | 595 } else if (compiler.commonElements.isFunctionApplyMethod(element)) { |
| 770 compiler.enabledFunctionApply = true; | 596 compiler.enabledFunctionApply = true; |
| 771 } | 597 } |
| 772 | 598 |
| 773 return true; | 599 return true; |
| 774 } | 600 } |
| 775 | 601 |
| 776 void registerNoSuchMethod(Element element) { | 602 void registerNoSuchMethod(Element element) { |
| 777 compiler.backend.registerNoSuchMethod(element); | 603 compiler.backend.registerNoSuchMethod(element); |
| 778 } | 604 } |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 } | 740 } |
| 915 | 741 |
| 916 typedef void _DeferredActionFunction(); | 742 typedef void _DeferredActionFunction(); |
| 917 | 743 |
| 918 class _DeferredAction { | 744 class _DeferredAction { |
| 919 final Element element; | 745 final Element element; |
| 920 final _DeferredActionFunction action; | 746 final _DeferredActionFunction action; |
| 921 | 747 |
| 922 _DeferredAction(this.element, this.action); | 748 _DeferredAction(this.element, this.action); |
| 923 } | 749 } |
| OLD | NEW |