| 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 'cache_strategy.dart'; | 9 import 'cache_strategy.dart'; |
| 10 import 'common/backend_api.dart' show Backend; | 10 import 'common/backend_api.dart' show Backend; |
| 11 import 'common/names.dart' show Identifiers; | 11 import 'common/names.dart' show Identifiers; |
| 12 import 'common/resolution.dart' show Resolution, ResolutionWorkItem; | 12 import 'common/resolution.dart' show Resolution, ResolutionWorkItem; |
| 13 import 'common/tasks.dart' show CompilerTask; | 13 import 'common/tasks.dart' show CompilerTask; |
| 14 import 'common/work.dart' show WorkItem; | 14 import 'common/work.dart' show WorkItem; |
| 15 import 'common.dart'; | 15 import 'common.dart'; |
| 16 import 'compiler.dart' show Compiler, GlobalDependencyRegistry; | 16 import 'compiler.dart' show Compiler, GlobalDependencyRegistry; |
| 17 import 'core_types.dart' show CommonElements; | 17 import 'core_types.dart' show CommonElements; |
| 18 import 'options.dart'; | 18 import 'options.dart'; |
| 19 import 'dart_types.dart' show DartType, InterfaceType; | 19 import 'dart_types.dart' show DartType, InterfaceType; |
| 20 import 'elements/elements.dart' | 20 import 'elements/elements.dart' |
| 21 show | 21 show |
| 22 AnalyzableElement, | 22 AnalyzableElement, |
| 23 AstElement, | 23 AstElement, |
| 24 ClassElement, | 24 ClassElement, |
| 25 ConstructorElement, | 25 ConstructorElement, |
| 26 Element, | 26 Element, |
| 27 Entity, | 27 Entity, |
| 28 FunctionElement, | |
| 29 LibraryElement, | 28 LibraryElement, |
| 30 LocalFunctionElement, | 29 LocalFunctionElement, |
| 31 TypedElement; | 30 MemberElement; |
| 31 import 'elements/entities.dart'; |
| 32 import 'native/native.dart' as native; | 32 import 'native/native.dart' as native; |
| 33 import 'types/types.dart' show TypeMaskStrategy; | 33 import 'types/types.dart' show TypeMaskStrategy; |
| 34 import 'universe/selector.dart' show Selector; | |
| 35 import 'universe/world_builder.dart'; | 34 import 'universe/world_builder.dart'; |
| 36 import 'universe/use.dart' | 35 import 'universe/use.dart' |
| 37 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; | 36 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
| 38 import 'universe/world_impact.dart' | 37 import 'universe/world_impact.dart' |
| 39 show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor; | 38 show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor; |
| 39 import 'util/enumset.dart'; |
| 40 import 'util/util.dart' show Setlet; | 40 import 'util/util.dart' show Setlet; |
| 41 import 'world.dart' show OpenWorld; | 41 import 'world.dart' show OpenWorld; |
| 42 | 42 |
| 43 class EnqueueTask extends CompilerTask { | 43 class EnqueueTask extends CompilerTask { |
| 44 ResolutionEnqueuer _resolution; | 44 ResolutionEnqueuer _resolution; |
| 45 Enqueuer _codegen; | 45 Enqueuer _codegen; |
| 46 final Compiler compiler; | 46 final Compiler compiler; |
| 47 | 47 |
| 48 String get name => 'Enqueue'; | 48 String get name => 'Enqueue'; |
| 49 | 49 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 bool isProcessed(Element member); | 115 bool isProcessed(Element member); |
| 116 | 116 |
| 117 Iterable<Entity> get processedEntities; | 117 Iterable<Entity> get processedEntities; |
| 118 | 118 |
| 119 Iterable<ClassElement> get processedClasses; | 119 Iterable<ClassElement> get processedClasses; |
| 120 } | 120 } |
| 121 | 121 |
| 122 abstract class EnqueuerImpl extends Enqueuer { | 122 abstract class EnqueuerImpl extends Enqueuer { |
| 123 CompilerTask get task; | 123 CompilerTask get task; |
| 124 EnqueuerStrategy get strategy; | 124 EnqueuerStrategy get strategy; |
| 125 void processInstantiatedClassMember(ClassElement cls, Element member); | 125 void checkClass(ClassElement cls); |
| 126 void processStaticUse(StaticUse staticUse); | 126 void processStaticUse(StaticUse staticUse); |
| 127 void processTypeUse(TypeUse typeUse); | 127 void processTypeUse(TypeUse typeUse); |
| 128 void processDynamicUse(DynamicUse dynamicUse); | 128 void processDynamicUse(DynamicUse dynamicUse); |
| 129 } | 129 } |
| 130 | 130 |
| 131 /// [Enqueuer] which is specific to resolution. | 131 /// [Enqueuer] which is specific to resolution. |
| 132 class ResolutionEnqueuer extends EnqueuerImpl { | 132 class ResolutionEnqueuer extends EnqueuerImpl { |
| 133 static const ImpactUseCase IMPACT_USE = | 133 static const ImpactUseCase IMPACT_USE = |
| 134 const ImpactUseCase('ResolutionEnqueuer'); | 134 const ImpactUseCase('ResolutionEnqueuer'); |
| 135 | 135 |
| 136 final CompilerTask task; | 136 final CompilerTask task; |
| 137 final String name; | 137 final String name; |
| 138 final Resolution _resolution; | 138 final Resolution _resolution; |
| 139 final CompilerOptions _options; | 139 final CompilerOptions _options; |
| 140 final Backend backend; | 140 final Backend backend; |
| 141 final GlobalDependencyRegistry _globalDependencies; | 141 final GlobalDependencyRegistry _globalDependencies; |
| 142 final CommonElements _commonElements; | 142 final CommonElements _commonElements; |
| 143 final native.NativeEnqueuer nativeEnqueuer; | 143 final native.NativeEnqueuer nativeEnqueuer; |
| 144 | 144 |
| 145 final EnqueuerStrategy strategy; | 145 final EnqueuerStrategy strategy; |
| 146 final Map<String, Set<Element>> _instanceMembersByName = | |
| 147 new Map<String, Set<Element>>(); | |
| 148 final Map<String, Set<Element>> _instanceFunctionsByName = | |
| 149 new Map<String, Set<Element>>(); | |
| 150 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); | 146 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); |
| 151 Set<ClassElement> _recentClasses = new Setlet<ClassElement>(); | 147 Set<ClassElement> _recentClasses = new Setlet<ClassElement>(); |
| 152 final ResolutionWorldBuilderImpl _universe; | 148 final ResolutionWorldBuilderImpl _universe; |
| 153 | 149 |
| 154 bool queueIsClosed = false; | 150 bool queueIsClosed = false; |
| 155 | 151 |
| 156 WorldImpactVisitor _impactVisitor; | 152 WorldImpactVisitor _impactVisitor; |
| 157 | 153 |
| 158 /// All declaration elements that have been processed by the resolver. | 154 /// All declaration elements that have been processed by the resolver. |
| 159 final Set<AstElement> processedElements = new Set<AstElement>(); | 155 final Set<AstElement> processedElements = new Set<AstElement>(); |
| 160 | 156 |
| 161 final Queue<WorkItem> _queue = new Queue<WorkItem>(); | 157 final Queue<WorkItem> _queue = new Queue<WorkItem>(); |
| 162 | 158 |
| 163 /// Queue of deferred resolution actions to execute when the resolution queue | 159 /// Queue of deferred resolution actions to execute when the resolution queue |
| 164 /// has been emptied. | 160 /// has been emptied. |
| 165 final Queue<_DeferredAction> _deferredQueue = new Queue<_DeferredAction>(); | 161 final Queue<_DeferredAction> _deferredQueue = new Queue<_DeferredAction>(); |
| 166 | 162 |
| 167 ResolutionEnqueuer( | 163 ResolutionEnqueuer( |
| 168 this.task, | 164 this.task, |
| 169 this._options, | 165 this._options, |
| 170 this._resolution, | 166 Resolution resolution, |
| 171 this.strategy, | 167 this.strategy, |
| 172 this._globalDependencies, | 168 this._globalDependencies, |
| 173 Backend backend, | 169 Backend backend, |
| 174 CommonElements commonElements, | 170 this._commonElements, |
| 175 CacheStrategy cacheStrategy, | 171 CacheStrategy cacheStrategy, |
| 176 [this.name = 'resolution enqueuer']) | 172 [this.name = 'resolution enqueuer']) |
| 177 : this.backend = backend, | 173 : this.backend = backend, |
| 178 this._commonElements = commonElements, | 174 this._resolution = resolution, |
| 179 this.nativeEnqueuer = backend.nativeResolutionEnqueuer(), | 175 this.nativeEnqueuer = backend.nativeResolutionEnqueuer(), |
| 180 _universe = new ResolutionWorldBuilderImpl( | 176 _universe = new ResolutionWorldBuilderImpl( |
| 181 backend, commonElements, cacheStrategy, const TypeMaskStrategy()) { | 177 backend, resolution, cacheStrategy, const TypeMaskStrategy()) { |
| 182 _impactVisitor = new EnqueuerImplImpactVisitor(this); | 178 _impactVisitor = new EnqueuerImplImpactVisitor(this); |
| 183 } | 179 } |
| 184 | 180 |
| 185 ResolutionWorldBuilder get universe => _universe; | 181 ResolutionWorldBuilder get universe => _universe; |
| 186 | 182 |
| 187 OpenWorld get _openWorld => universe.openWorld; | 183 OpenWorld get _openWorld => universe.openWorld; |
| 188 | 184 |
| 189 bool get queueIsEmpty => _queue.isEmpty; | 185 bool get queueIsEmpty => _queue.isEmpty; |
| 190 | 186 |
| 191 DiagnosticReporter get _reporter => _resolution.reporter; | 187 DiagnosticReporter get _reporter => _resolution.reporter; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (!cls.isAbstract || isNative || mirrorUsage) { | 222 if (!cls.isAbstract || isNative || mirrorUsage) { |
| 227 _processInstantiatedClass(cls); | 223 _processInstantiatedClass(cls); |
| 228 } | 224 } |
| 229 }); | 225 }); |
| 230 } | 226 } |
| 231 | 227 |
| 232 bool checkNoEnqueuedInvokedInstanceMethods() { | 228 bool checkNoEnqueuedInvokedInstanceMethods() { |
| 233 return strategy.checkEnqueuerConsistency(this); | 229 return strategy.checkEnqueuerConsistency(this); |
| 234 } | 230 } |
| 235 | 231 |
| 236 void processInstantiatedClassMember(ClassElement cls, Element member) { | 232 void checkClass(ClassElement cls) { |
| 237 assert(invariant(member, member.isDeclaration)); | 233 _processClassMembers(cls, |
| 238 if (isProcessed(member)) return; | 234 (MemberElement member, EnumSet<MemberUse> useSet) { |
| 239 if (!member.isInstanceMember) return; | 235 if (useSet.isNotEmpty) { |
| 240 String memberName = member.name; | 236 _reporter.internalError(member, |
| 237 'Unenqueued use of $member: ${useSet.iterable(MemberUse.values)}'); |
| 238 } |
| 239 }); |
| 240 } |
| 241 | 241 |
| 242 if (member.isField) { | 242 /// Callback for applying the first seen use of a [member]. |
| 243 // The obvious thing to test here would be "member.isNative", | 243 void _applyFirstUse(MemberElement member, EnumSet<MemberUse> useSet) { |
| 244 // however, that only works after metadata has been parsed/analyzed, | 244 ClassElement cls = member.enclosingClass; |
| 245 // and that may not have happened yet. | 245 if (member.isFunction) { |
| 246 // So instead we use the enclosing class, which we know have had | 246 MemberElement function = member; |
| 247 // its metadata parsed and analyzed. | |
| 248 // Note: this assumes that there are no non-native fields on native | |
| 249 // classes, which may not be the case when a native class is subclassed. | |
| 250 if (backend.isNative(cls)) { | |
| 251 _openWorld.registerUsedElement(member); | |
| 252 if (_universe.hasInvokedGetter(member, _openWorld) || | |
| 253 _universe.hasInvocation(member, _openWorld)) { | |
| 254 _addToWorkList(member); | |
| 255 return; | |
| 256 } | |
| 257 if (_universe.hasInvokedSetter(member, _openWorld)) { | |
| 258 _addToWorkList(member); | |
| 259 return; | |
| 260 } | |
| 261 // Native fields need to go into instanceMembersByName as they | |
| 262 // are virtual instantiation points and escape points. | |
| 263 } else { | |
| 264 // All field initializers must be resolved as they could | |
| 265 // have an observable side-effect (and cannot be tree-shaken | |
| 266 // away). | |
| 267 _addToWorkList(member); | |
| 268 return; | |
| 269 } | |
| 270 } else if (member.isFunction) { | |
| 271 FunctionElement function = member; | |
| 272 function.computeType(_resolution); | |
| 273 if (function.name == Identifiers.noSuchMethod_) { | 247 if (function.name == Identifiers.noSuchMethod_) { |
| 274 _registerNoSuchMethod(function); | 248 _registerNoSuchMethod(function); |
| 275 } | 249 } |
| 276 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { | 250 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { |
| 277 _registerCallMethodWithFreeTypeVariables(function); | 251 _registerCallMethodWithFreeTypeVariables(function); |
| 278 } | 252 } |
| 279 // If there is a property access with the same name as a method we | |
| 280 // need to emit the method. | |
| 281 if (_universe.hasInvokedGetter(function, _openWorld)) { | |
| 282 _registerClosurizedMember(function); | |
| 283 _addToWorkList(function); | |
| 284 return; | |
| 285 } | |
| 286 // Store the member in [instanceFunctionsByName] to catch | |
| 287 // getters on the function. | |
| 288 _instanceFunctionsByName | |
| 289 .putIfAbsent(memberName, () => new Set<Element>()) | |
| 290 .add(member); | |
| 291 if (_universe.hasInvocation(function, _openWorld)) { | |
| 292 _addToWorkList(function); | |
| 293 return; | |
| 294 } | |
| 295 } else if (member.isGetter) { | |
| 296 FunctionElement getter = member; | |
| 297 getter.computeType(_resolution); | |
| 298 if (_universe.hasInvokedGetter(getter, _openWorld)) { | |
| 299 _addToWorkList(getter); | |
| 300 return; | |
| 301 } | |
| 302 // We don't know what selectors the returned closure accepts. If | |
| 303 // the set contains any selector we have to assume that it matches. | |
| 304 if (_universe.hasInvocation(getter, _openWorld)) { | |
| 305 _addToWorkList(getter); | |
| 306 return; | |
| 307 } | |
| 308 } else if (member.isSetter) { | |
| 309 FunctionElement setter = member; | |
| 310 setter.computeType(_resolution); | |
| 311 if (_universe.hasInvokedSetter(setter, _openWorld)) { | |
| 312 _addToWorkList(setter); | |
| 313 return; | |
| 314 } | |
| 315 } | 253 } |
| 316 | 254 _applyUse(member, useSet); |
| 317 // The element is not yet used. Add it to the list of instance | |
| 318 // members to still be processed. | |
| 319 _instanceMembersByName | |
| 320 .putIfAbsent(memberName, () => new Set<Element>()) | |
| 321 .add(member); | |
| 322 } | 255 } |
| 323 | 256 |
| 257 /// Callback for applying the use of a [member]. |
| 258 void _applyUse(Entity member, EnumSet<MemberUse> useSet) { |
| 259 if (useSet.contains(MemberUse.NORMAL)) { |
| 260 _addToWorkList(member); |
| 261 } |
| 262 if (useSet.contains(MemberUse.CLOSURIZE)) { |
| 263 _registerClosurizedMember(member); |
| 264 } |
| 265 } |
| 266 |
| 267 /// TODO(johnniwinther): Move this to [ResolutionWorldBuilderImpl]. |
| 324 void _processInstantiatedClass(ClassElement cls) { | 268 void _processInstantiatedClass(ClassElement cls) { |
| 325 task.measure(() { | 269 task.measure(() { |
| 326 if (_processedClasses.contains(cls)) return; | 270 if (_processedClasses.contains(cls)) return; |
| 327 // The class must be resolved to compute the set of all | 271 // The class must be resolved to compute the set of all |
| 328 // supertypes. | 272 // supertypes. |
| 329 cls.ensureResolved(_resolution); | 273 cls.ensureResolved(_resolution); |
| 330 | 274 |
| 331 void processClass(ClassElement superclass) { | 275 void processClass(ClassElement superclass) { |
| 332 if (_processedClasses.contains(superclass)) return; | 276 if (_processedClasses.contains(superclass)) return; |
| 333 | 277 |
| 334 _processedClasses.add(superclass); | 278 _processedClasses.add(superclass); |
| 335 _recentClasses.add(superclass); | 279 _recentClasses.add(superclass); |
| 336 superclass.ensureResolved(_resolution); | 280 superclass.ensureResolved(_resolution); |
| 337 superclass.implementation.forEachMember(processInstantiatedClassMember); | 281 _processClassMembers(superclass, _applyFirstUse); |
| 338 _resolution.ensureClassMembers(superclass); | 282 _resolution.ensureClassMembers(superclass); |
| 339 // We only tell the backend once that [superclass] was instantiated, so | 283 // We only tell the backend once that [superclass] was instantiated, so |
| 340 // any additional dependencies must be treated as global | 284 // any additional dependencies must be treated as global |
| 341 // dependencies. | 285 // dependencies. |
| 342 applyImpact( | 286 applyImpact( |
| 343 backend.registerInstantiatedClass(superclass, forResolution: true)); | 287 backend.registerInstantiatedClass(superclass, forResolution: true)); |
| 344 } | 288 } |
| 345 | 289 |
| 346 ClassElement superclass = cls; | 290 ClassElement superclass = cls; |
| 347 while (superclass != null) { | 291 while (superclass != null) { |
| 348 processClass(superclass); | 292 processClass(superclass); |
| 349 superclass = superclass.superclass; | 293 superclass = superclass.superclass; |
| 350 } | 294 } |
| 351 }); | 295 }); |
| 352 } | 296 } |
| 353 | 297 |
| 298 /// TODO(johnniwinther): Move this to [ResolutionWorldBuilderImpl]. |
| 299 void _processClassMembers(ClassElement cls, MemberUsed memberUsed) { |
| 300 cls.implementation.forEachMember((ClassElement cls, MemberElement member) { |
| 301 _universe.processInstantiatedClassMember(cls, member, memberUsed); |
| 302 }); |
| 303 } |
| 304 |
| 354 void processDynamicUse(DynamicUse dynamicUse) { | 305 void processDynamicUse(DynamicUse dynamicUse) { |
| 355 task.measure(() { | 306 task.measure(() { |
| 356 if (_universe.registerDynamicUse(dynamicUse)) { | 307 _universe.registerDynamicUse(dynamicUse, _applyUse); |
| 357 _handleUnseenSelector(dynamicUse); | |
| 358 } | |
| 359 }); | 308 }); |
| 360 } | 309 } |
| 361 | 310 |
| 362 void _processSet( | |
| 363 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { | |
| 364 Set<Element> members = map[memberName]; | |
| 365 if (members == null) return; | |
| 366 // [f] might add elements to [: map[memberName] :] during the loop below | |
| 367 // so we create a new list for [: map[memberName] :] and prepend the | |
| 368 // [remaining] members after the loop. | |
| 369 map[memberName] = new Set<Element>(); | |
| 370 Set<Element> remaining = new Set<Element>(); | |
| 371 for (Element member in members) { | |
| 372 if (!f(member)) remaining.add(member); | |
| 373 } | |
| 374 map[memberName].addAll(remaining); | |
| 375 } | |
| 376 | |
| 377 void _processInstanceMembers(String n, bool f(Element e)) { | |
| 378 _processSet(_instanceMembersByName, n, f); | |
| 379 } | |
| 380 | |
| 381 void _processInstanceFunctions(String n, bool f(Element e)) { | |
| 382 _processSet(_instanceFunctionsByName, n, f); | |
| 383 } | |
| 384 | |
| 385 void _handleUnseenSelector(DynamicUse dynamicUse) { | |
| 386 Selector selector = dynamicUse.selector; | |
| 387 String methodName = selector.name; | |
| 388 _processInstanceMembers(methodName, (Element member) { | |
| 389 if (dynamicUse.appliesUnnamed(member, _openWorld)) { | |
| 390 if (member.isFunction && selector.isGetter) { | |
| 391 _registerClosurizedMember(member); | |
| 392 } | |
| 393 _addToWorkList(member); | |
| 394 return true; | |
| 395 } | |
| 396 return false; | |
| 397 }); | |
| 398 if (selector.isGetter) { | |
| 399 _processInstanceFunctions(methodName, (Element member) { | |
| 400 if (dynamicUse.appliesUnnamed(member, _openWorld)) { | |
| 401 _registerClosurizedMember(member); | |
| 402 return true; | |
| 403 } | |
| 404 return false; | |
| 405 }); | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 void processStaticUse(StaticUse staticUse) { | 311 void processStaticUse(StaticUse staticUse) { |
| 410 Element element = staticUse.element; | 312 Element element = staticUse.element; |
| 411 assert(invariant(element, element.isDeclaration, | 313 assert(invariant(element, element.isDeclaration, |
| 412 message: "Element ${element} is not the declaration.")); | 314 message: "Element ${element} is not the declaration.")); |
| 413 _universe.registerStaticUse(staticUse); | 315 _universe.registerStaticUse(staticUse); |
| 414 applyImpact(backend.registerStaticUse(element, forResolution: true)); | 316 applyImpact(backend.registerStaticUse(element, forResolution: true)); |
| 415 bool addElement = true; | 317 bool addElement = true; |
| 416 switch (staticUse.kind) { | 318 switch (staticUse.kind) { |
| 417 case StaticUseKind.STATIC_TEAR_OFF: | 319 case StaticUseKind.STATIC_TEAR_OFF: |
| 418 applyImpact(backend.registerGetOfStaticFunction()); | 320 applyImpact(backend.registerGetOfStaticFunction()); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 // against the type variable of a typedef. | 394 // against the type variable of a typedef. |
| 493 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); | 395 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
| 494 } | 396 } |
| 495 | 397 |
| 496 void _registerCallMethodWithFreeTypeVariables(Element element) { | 398 void _registerCallMethodWithFreeTypeVariables(Element element) { |
| 497 applyImpact(backend.registerCallMethodWithFreeTypeVariables(element, | 399 applyImpact(backend.registerCallMethodWithFreeTypeVariables(element, |
| 498 forResolution: true)); | 400 forResolution: true)); |
| 499 _universe.callMethodsWithFreeTypeVariables.add(element); | 401 _universe.callMethodsWithFreeTypeVariables.add(element); |
| 500 } | 402 } |
| 501 | 403 |
| 502 void _registerClosurizedMember(TypedElement element) { | 404 void _registerClosurizedMember(MemberElement element) { |
| 503 assert(element.isInstanceMember); | 405 assert(element.isInstanceMember); |
| 504 if (element.computeType(_resolution).containsTypeVariables) { | 406 if (element.type.containsTypeVariables) { |
| 505 applyImpact(backend.registerClosureWithFreeTypeVariables(element, | 407 applyImpact(backend.registerClosureWithFreeTypeVariables(element, |
| 506 forResolution: true)); | 408 forResolution: true)); |
| 507 _universe.closuresWithFreeTypeVariables.add(element); | 409 _universe.closuresWithFreeTypeVariables.add(element); |
| 508 } | 410 } |
| 509 applyImpact(backend.registerBoundClosure()); | 411 applyImpact(backend.registerBoundClosure()); |
| 510 _universe.closurizedMembers.add(element); | 412 _universe.closurizedMembers.add(element); |
| 511 } | 413 } |
| 512 | 414 |
| 513 void forEach(void f(WorkItem work)) { | 415 void forEach(void f(WorkItem work)) { |
| 514 do { | 416 do { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 void _emptyDeferredQueue() { | 551 void _emptyDeferredQueue() { |
| 650 while (!_deferredQueue.isEmpty) { | 552 while (!_deferredQueue.isEmpty) { |
| 651 _DeferredAction task = _deferredQueue.removeFirst(); | 553 _DeferredAction task = _deferredQueue.removeFirst(); |
| 652 _reporter.withCurrentElement(task.element, task.action); | 554 _reporter.withCurrentElement(task.element, task.action); |
| 653 } | 555 } |
| 654 } | 556 } |
| 655 | 557 |
| 656 void forgetElement(Element element, Compiler compiler) { | 558 void forgetElement(Element element, Compiler compiler) { |
| 657 _universe.forgetElement(element, compiler); | 559 _universe.forgetElement(element, compiler); |
| 658 _processedClasses.remove(element); | 560 _processedClasses.remove(element); |
| 659 _instanceMembersByName[element.name]?.remove(element); | |
| 660 _instanceFunctionsByName[element.name]?.remove(element); | |
| 661 processedElements.remove(element); | 561 processedElements.remove(element); |
| 662 } | 562 } |
| 663 } | 563 } |
| 664 | 564 |
| 665 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 565 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
| 666 Set<Element> set = map[element.name]; | 566 Set<Element> set = map[element.name]; |
| 667 if (set == null) return; | 567 if (set == null) return; |
| 668 set.remove(element); | 568 set.remove(element); |
| 669 } | 569 } |
| 670 | 570 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 | 621 |
| 722 /// Check enqueuer consistency after the queue has been closed. | 622 /// Check enqueuer consistency after the queue has been closed. |
| 723 bool checkEnqueuerConsistency(EnqueuerImpl enqueuer) { | 623 bool checkEnqueuerConsistency(EnqueuerImpl enqueuer) { |
| 724 enqueuer.task.measure(() { | 624 enqueuer.task.measure(() { |
| 725 // Run through the classes and see if we need to enqueue more methods. | 625 // Run through the classes and see if we need to enqueue more methods. |
| 726 for (ClassElement classElement | 626 for (ClassElement classElement |
| 727 in enqueuer.universe.directlyInstantiatedClasses) { | 627 in enqueuer.universe.directlyInstantiatedClasses) { |
| 728 for (ClassElement currentClass = classElement; | 628 for (ClassElement currentClass = classElement; |
| 729 currentClass != null; | 629 currentClass != null; |
| 730 currentClass = currentClass.superclass) { | 630 currentClass = currentClass.superclass) { |
| 731 currentClass.implementation | 631 enqueuer.checkClass(currentClass); |
| 732 .forEachMember(enqueuer.processInstantiatedClassMember); | |
| 733 } | 632 } |
| 734 } | 633 } |
| 735 }); | 634 }); |
| 736 return true; | 635 return true; |
| 737 } | 636 } |
| 738 } | 637 } |
| 739 | 638 |
| 740 class EnqueuerImplImpactVisitor implements WorldImpactVisitor { | 639 class EnqueuerImplImpactVisitor implements WorldImpactVisitor { |
| 741 final EnqueuerImpl enqueuer; | 640 final EnqueuerImpl enqueuer; |
| 742 | 641 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 759 } | 658 } |
| 760 | 659 |
| 761 typedef void _DeferredActionFunction(); | 660 typedef void _DeferredActionFunction(); |
| 762 | 661 |
| 763 class _DeferredAction { | 662 class _DeferredAction { |
| 764 final Element element; | 663 final Element element; |
| 765 final _DeferredActionFunction action; | 664 final _DeferredActionFunction action; |
| 766 | 665 |
| 767 _DeferredAction(this.element, this.action); | 666 _DeferredAction(this.element, this.action); |
| 768 } | 667 } |
| OLD | NEW |