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 universe; | 5 library universe; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import '../cache_strategy.dart'; | 9 import '../cache_strategy.dart'; |
10 import '../common.dart'; | 10 import '../common.dart'; |
11 import '../common/backend_api.dart' show Backend; | 11 import '../common/backend_api.dart' show Backend; |
12 import '../common/resolution.dart' show Resolution; | 12 import '../common/resolution.dart' show Resolution; |
13 import '../compiler.dart' show Compiler; | 13 import '../compiler.dart' show Compiler; |
14 import '../core_types.dart' show CoreClasses; | 14 import '../core_types.dart' show CoreClasses; |
15 import '../dart_types.dart'; | 15 import '../dart_types.dart'; |
16 import '../elements/elements.dart'; | 16 import '../elements/elements.dart'; |
17 import '../types/masks.dart' show CommonMasks; | |
18 import '../universe/class_set.dart' show Instantiation; | 17 import '../universe/class_set.dart' show Instantiation; |
19 import '../util/enumset.dart'; | |
20 import '../util/util.dart'; | 18 import '../util/util.dart'; |
21 import '../world.dart' show World, ClosedWorld, OpenWorld, WorldImpl; | 19 import '../world.dart' show World, ClosedWorld, OpenWorld, WorldImpl; |
22 import 'selector.dart' show Selector; | 20 import 'selector.dart' show Selector; |
23 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; | 21 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; |
24 | 22 |
25 /// The known constraint on receiver for a dynamic call site. | 23 /// The known constraint on receiver for a dynamic call site. |
26 /// | 24 /// |
27 /// This can for instance be used to constrain this dynamic call to `foo` to | 25 /// This can for instance be used to constrain this dynamic call to `foo` to |
28 /// 'receivers of the exact instance `Bar`': | 26 /// 'receivers of the exact instance `Bar`': |
29 /// | 27 /// |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 | 155 |
158 /// Returns `true` if [cls] is considered to be implemented by an | 156 /// Returns `true` if [cls] is considered to be implemented by an |
159 /// instantiated class, either directly, through subclasses or through | 157 /// instantiated class, either directly, through subclasses or through |
160 /// subtypes. The latter case only contains spurious information from | 158 /// subtypes. The latter case only contains spurious information from |
161 /// instantiations through factory constructors and mixins. | 159 /// instantiations through factory constructors and mixins. |
162 bool isImplemented(ClassElement cls); | 160 bool isImplemented(ClassElement cls); |
163 | 161 |
164 /// Set of all fields that are statically known to be written to. | 162 /// Set of all fields that are statically known to be written to. |
165 Iterable<Element> get fieldSetters; | 163 Iterable<Element> get fieldSetters; |
166 | 164 |
167 /// Call [f] for all directly or abstractly instantiated classes. | 165 /// Call [f] for all classes with instantiated types. This includes the |
168 void forEachInstantiatedClass( | 166 /// directly and abstractly instantiated classes but also classes whose type |
169 f(ClassElement cls, EnumSet<Instantiation> instantiations)); | 167 /// arguments are used in live factory constructors. |
| 168 void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)); |
170 | 169 |
171 /// `true` of `Object.runtimeType` is supported. | 170 /// `true` of `Object.runtimeType` is supported. |
172 bool get hasRuntimeTypeSupport; | 171 bool get hasRuntimeTypeSupport; |
173 | 172 |
174 /// `true` of use of the `dart:isolate` library is supported. | 173 /// `true` of use of the `dart:isolate` library is supported. |
175 bool get hasIsolateSupport; | 174 bool get hasIsolateSupport; |
176 | 175 |
177 /// `true` of `Function.apply` is supported. | 176 /// `true` of `Function.apply` is supported. |
178 bool get hasFunctionApplySupport; | 177 bool get hasFunctionApplySupport; |
179 | 178 |
180 /// The [OpenWorld] being created by this world builder. | 179 /// The [OpenWorld] being created by this world builder. |
181 // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder]. | 180 // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder]. |
182 OpenWorld get openWorld; | 181 OpenWorld get openWorld; |
183 } | 182 } |
184 | 183 |
| 184 /// The type and kind of an instantiation registered through |
| 185 /// `ResolutionWorldBuilder.registerTypeInstantiation`. |
| 186 class Instance { |
| 187 final InterfaceType type; |
| 188 final Instantiation kind; |
| 189 final bool isRedirection; |
| 190 |
| 191 Instance(this.type, this.kind, {this.isRedirection: false}); |
| 192 |
| 193 int get hashCode { |
| 194 return Hashing.objectHash( |
| 195 type, Hashing.objectHash(kind, Hashing.objectHash(isRedirection))); |
| 196 } |
| 197 |
| 198 bool operator ==(other) { |
| 199 if (identical(this, other)) return true; |
| 200 if (other is! Instance) return false; |
| 201 return type == other.type && |
| 202 kind == other.kind && |
| 203 isRedirection == other.isRedirection; |
| 204 } |
| 205 |
| 206 String toString() { |
| 207 StringBuffer sb = new StringBuffer(); |
| 208 sb.write(type); |
| 209 if (kind == Instantiation.DIRECTLY_INSTANTIATED) { |
| 210 sb.write(' directly'); |
| 211 } else if (kind == Instantiation.ABSTRACTLY_INSTANTIATED) { |
| 212 sb.write(' abstractly'); |
| 213 } else if (kind == Instantiation.UNINSTANTIATED) { |
| 214 sb.write(' none'); |
| 215 } |
| 216 if (isRedirection) { |
| 217 sb.write(' redirect'); |
| 218 } |
| 219 return sb.toString(); |
| 220 } |
| 221 } |
| 222 |
| 223 /// Information about instantiations of a class. |
| 224 class InstantiationInfo { |
| 225 /// A map from constructor of the class to their instantiated types. |
| 226 /// |
| 227 /// For instance |
| 228 /// |
| 229 /// import 'dart:html'; |
| 230 /// |
| 231 /// abstract class AbstractClass<S> { |
| 232 /// factory AbstractClass.a() = Class<S>.a; |
| 233 /// factory AbstractClass.b() => new Class<S>.b(); |
| 234 /// } |
| 235 /// class Class<T> implements AbstractClass<T> { |
| 236 /// Class.a(); |
| 237 /// Class.b(); |
| 238 /// factory Class.c() = Class.b<T>; |
| 239 /// } |
| 240 /// |
| 241 /// |
| 242 /// main() { |
| 243 /// new Class.a(); |
| 244 /// new Class<int>.a(); |
| 245 /// new Class<String>.b(); |
| 246 /// new Class<num>.c(); |
| 247 /// new AbstractClass<double>.a(); |
| 248 /// new AbstractClass<bool>.b(); |
| 249 /// new DivElement(); // native instantiation |
| 250 /// } |
| 251 /// |
| 252 /// will generate the mappings |
| 253 /// |
| 254 /// AbstractClass: { |
| 255 /// AbstractClass.a: { |
| 256 /// AbstractClass<double> none, // from `new AbstractClass<double>.a()` |
| 257 /// }, |
| 258 /// AbstractClass.b: { |
| 259 /// AbstractClass<bool> none, // from `new AbstractClass<bool>.b()` |
| 260 /// }, |
| 261 /// }, |
| 262 /// Class: { |
| 263 /// Class.a: { |
| 264 /// Class directly, // from `new Class.a()` |
| 265 /// Class<int> directly, // from `new Class<int>.a()` |
| 266 /// Class<S> directly redirect, // from `factory AbstractClass.a` |
| 267 /// }, |
| 268 /// Class.b: { |
| 269 /// Class<String> directly, // from `new Class<String>.b()` |
| 270 /// Class<T> directly redirect, // from `factory Class.c` |
| 271 /// Class<S> directly, // from `factory AbstractClass.b` |
| 272 /// }, |
| 273 /// Class.c: { |
| 274 /// Class<num> directly, // from `new Class<num>.c()` |
| 275 /// }, |
| 276 /// }, |
| 277 /// DivElement: { |
| 278 /// DivElement: { |
| 279 /// DivElement abstractly, // from `new DivElement()` |
| 280 /// }, |
| 281 /// } |
| 282 /// |
| 283 /// If the constructor is unknown, for instance for native or mirror usage, |
| 284 /// `null` is used as key. |
| 285 Map<ConstructorElement, Set<Instance>> instantiationMap; |
| 286 |
| 287 /// Register [type] as the instantiation [kind] using [constructor]. |
| 288 void addInstantiation( |
| 289 ConstructorElement constructor, InterfaceType type, Instantiation kind, |
| 290 {bool isRedirection: false}) { |
| 291 instantiationMap ??= <ConstructorElement, Set<Instance>>{}; |
| 292 instantiationMap |
| 293 .putIfAbsent(constructor, () => new Set<Instance>()) |
| 294 .add(new Instance(type, kind, isRedirection: isRedirection)); |
| 295 switch (kind) { |
| 296 case Instantiation.DIRECTLY_INSTANTIATED: |
| 297 isDirectlyInstantiated = true; |
| 298 break; |
| 299 case Instantiation.ABSTRACTLY_INSTANTIATED: |
| 300 isAbstractlyInstantiated = true; |
| 301 break; |
| 302 case Instantiation.UNINSTANTIATED: |
| 303 break; |
| 304 default: |
| 305 throw new StateError("Instantiation $kind is not allowed."); |
| 306 } |
| 307 } |
| 308 |
| 309 /// `true` if the class is either directly or abstractly instantiated. |
| 310 bool get hasInstantiation => |
| 311 isDirectlyInstantiated || isAbstractlyInstantiated; |
| 312 |
| 313 /// `true` if the class is directly instantiated. |
| 314 bool isDirectlyInstantiated = false; |
| 315 |
| 316 /// `true` if the class is abstractly instantiated. |
| 317 bool isAbstractlyInstantiated = false; |
| 318 |
| 319 String toString() { |
| 320 StringBuffer sb = new StringBuffer(); |
| 321 sb.write('InstantiationInfo['); |
| 322 if (instantiationMap != null) { |
| 323 bool needsComma = false; |
| 324 instantiationMap |
| 325 .forEach((ConstructorElement constructor, Set<Instance> set) { |
| 326 if (needsComma) { |
| 327 sb.write(', '); |
| 328 } |
| 329 if (constructor != null) { |
| 330 sb.write(constructor); |
| 331 } else { |
| 332 sb.write('<unknown>'); |
| 333 } |
| 334 sb.write(': '); |
| 335 sb.write(set); |
| 336 needsComma = true; |
| 337 }); |
| 338 } |
| 339 sb.write(']'); |
| 340 return sb.toString(); |
| 341 } |
| 342 } |
| 343 |
185 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { | 344 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { |
186 /// The set of all directly instantiated classes, that is, classes with a | 345 /// Instantiation information for all classes with instantiated types. |
187 /// generative constructor that has been called directly and not only through | |
188 /// a super-call. | |
189 /// | 346 /// |
190 /// Invariant: Elements are declaration elements. | 347 /// Invariant: Elements are declaration elements. |
191 // TODO(johnniwinther): [_directlyInstantiatedClasses] and | 348 final Map<ClassElement, InstantiationInfo> _instantiationInfo = |
192 // [_instantiatedTypes] sets should be merged. | 349 <ClassElement, InstantiationInfo>{}; |
193 final Map<ClassElement, EnumSet<Instantiation>> _directlyInstantiatedClasses = | |
194 <ClassElement, EnumSet<Instantiation>>{}; | |
195 | |
196 /// The set of all directly instantiated types, that is, the types of the | |
197 /// directly instantiated classes. | |
198 /// | |
199 /// See [_directlyInstantiatedClasses]. | |
200 final Set<DartType> _instantiatedTypes = new Set<DartType>(); | |
201 | 350 |
202 /// Classes implemented by directly instantiated classes. | 351 /// Classes implemented by directly instantiated classes. |
203 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); | 352 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
204 | 353 |
205 /// The set of all referenced static fields. | 354 /// The set of all referenced static fields. |
206 /// | 355 /// |
207 /// Invariant: Elements are declaration elements. | 356 /// Invariant: Elements are declaration elements. |
208 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | 357 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); |
209 | 358 |
210 /** | 359 /** |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy); | 414 _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy); |
266 } | 415 } |
267 | 416 |
268 OpenWorld get openWorld => _openWorld; | 417 OpenWorld get openWorld => _openWorld; |
269 | 418 |
270 /// All directly instantiated classes, that is, classes with a generative | 419 /// All directly instantiated classes, that is, classes with a generative |
271 /// constructor that has been called directly and not only through a | 420 /// constructor that has been called directly and not only through a |
272 /// super-call. | 421 /// super-call. |
273 // TODO(johnniwinther): Improve semantic precision. | 422 // TODO(johnniwinther): Improve semantic precision. |
274 Iterable<ClassElement> get directlyInstantiatedClasses { | 423 Iterable<ClassElement> get directlyInstantiatedClasses { |
275 return _directlyInstantiatedClasses.keys; | 424 Set<ClassElement> classes = new Set<ClassElement>(); |
| 425 _instantiationInfo.forEach((ClassElement cls, InstantiationInfo info) { |
| 426 if (info.hasInstantiation) { |
| 427 classes.add(cls); |
| 428 } |
| 429 }); |
| 430 return classes; |
276 } | 431 } |
277 | 432 |
278 /// All directly instantiated types, that is, the types of the directly | 433 /// All directly instantiated types, that is, the types of the directly |
279 /// instantiated classes. | 434 /// instantiated classes. |
280 /// | 435 /// |
281 /// See [directlyInstantiatedClasses]. | 436 /// See [directlyInstantiatedClasses]. |
282 // TODO(johnniwinther): Improve semantic precision. | 437 // TODO(johnniwinther): Improve semantic precision. |
283 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; | 438 Iterable<DartType> get instantiatedTypes { |
| 439 Set<InterfaceType> types = new Set<InterfaceType>(); |
| 440 _instantiationInfo.forEach((_, InstantiationInfo info) { |
| 441 if (info.instantiationMap != null) { |
| 442 for (Set<Instance> instances in info.instantiationMap.values) { |
| 443 for (Instance instance in instances) { |
| 444 types.add(instance.type); |
| 445 } |
| 446 } |
| 447 } |
| 448 }); |
| 449 return types; |
| 450 } |
284 | 451 |
285 /// Returns `true` if [cls] is considered to be implemented by an | 452 /// Returns `true` if [cls] is considered to be implemented by an |
286 /// instantiated class, either directly, through subclasses or through | 453 /// instantiated class, either directly, through subclasses or through |
287 /// subtypes. The latter case only contains spurious information from | 454 /// subtypes. The latter case only contains spurious information from |
288 /// instantiations through factory constructors and mixins. | 455 /// instantiations through factory constructors and mixins. |
289 // TODO(johnniwinther): Improve semantic precision. | 456 // TODO(johnniwinther): Improve semantic precision. |
290 bool isImplemented(ClassElement cls) { | 457 bool isImplemented(ClassElement cls) { |
291 return _implementedClasses.contains(cls.declaration); | 458 return _implementedClasses.contains(cls.declaration); |
292 } | 459 } |
293 | 460 |
294 /// Register [type] as (directly) instantiated. | 461 /// Register [type] as (directly) instantiated. |
295 /// | 462 /// |
296 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 463 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
297 // TODO(johnniwinther): Fully enforce the separation between exact, through | 464 // TODO(johnniwinther): Fully enforce the separation between exact, through |
298 // subclass and through subtype instantiated types/classes. | 465 // subclass and through subtype instantiated types/classes. |
299 // TODO(johnniwinther): Support unknown type arguments for generic types. | 466 // TODO(johnniwinther): Support unknown type arguments for generic types. |
300 void registerTypeInstantiation(InterfaceType type, | 467 void registerTypeInstantiation(InterfaceType type, |
301 {bool byMirrors: false, | 468 {ConstructorElement constructor, |
| 469 bool byMirrors: false, |
302 bool isNative: false, | 470 bool isNative: false, |
| 471 bool isRedirection: false, |
303 void onImplemented(ClassElement cls)}) { | 472 void onImplemented(ClassElement cls)}) { |
304 _instantiatedTypes.add(type); | |
305 ClassElement cls = type.element; | 473 ClassElement cls = type.element; |
| 474 InstantiationInfo info = |
| 475 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo()); |
| 476 Instantiation kind = Instantiation.UNINSTANTIATED; |
306 if (!cls.isAbstract | 477 if (!cls.isAbstract |
307 // We can't use the closed-world assumption with native abstract | 478 // We can't use the closed-world assumption with native abstract |
308 // classes; a native abstract class may have non-abstract subclasses | 479 // classes; a native abstract class may have non-abstract subclasses |
309 // not declared to the program. Instances of these classes are | 480 // not declared to the program. Instances of these classes are |
310 // indistinguishable from the abstract class. | 481 // indistinguishable from the abstract class. |
311 || | 482 || |
312 isNative | 483 isNative |
313 // Likewise, if this registration comes from the mirror system, | 484 // Likewise, if this registration comes from the mirror system, |
314 // all bets are off. | 485 // all bets are off. |
315 // TODO(herhut): Track classes required by mirrors seperately. | 486 // TODO(herhut): Track classes required by mirrors seperately. |
316 || | 487 || |
317 byMirrors) { | 488 byMirrors) { |
318 EnumSet<Instantiation> instantiations = _directlyInstantiatedClasses | |
319 .putIfAbsent(cls, () => new EnumSet<Instantiation>()); | |
320 if (isNative || byMirrors) { | 489 if (isNative || byMirrors) { |
321 instantiations.add(Instantiation.ABSTRACTLY_INSTANTIATED); | 490 kind = Instantiation.ABSTRACTLY_INSTANTIATED; |
322 } else { | 491 } else { |
323 instantiations.add(Instantiation.DIRECTLY_INSTANTIATED); | 492 kind = Instantiation.DIRECTLY_INSTANTIATED; |
324 } | 493 } |
325 } | 494 } |
| 495 info.addInstantiation(constructor, type, kind, |
| 496 isRedirection: isRedirection); |
326 | 497 |
327 // TODO(johnniwinther): Replace this by separate more specific mappings that | 498 // TODO(johnniwinther): Use [_instantiationInfo] to compute this information |
328 // include the type arguments. | 499 // instead. |
329 if (_implementedClasses.add(cls)) { | 500 if (_implementedClasses.add(cls)) { |
330 onImplemented(cls); | 501 onImplemented(cls); |
331 cls.allSupertypes.forEach((InterfaceType supertype) { | 502 cls.allSupertypes.forEach((InterfaceType supertype) { |
332 if (_implementedClasses.add(supertype.element)) { | 503 if (_implementedClasses.add(supertype.element)) { |
333 onImplemented(supertype.element); | 504 onImplemented(supertype.element); |
334 } | 505 } |
335 }); | 506 }); |
336 } | 507 } |
337 } | 508 } |
338 | 509 |
339 @override | 510 @override |
340 void forEachInstantiatedClass( | 511 void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)) { |
341 f(ClassElement cls, EnumSet<Instantiation> instantiations)) { | 512 _instantiationInfo.forEach(f); |
342 _directlyInstantiatedClasses.forEach(f); | |
343 } | 513 } |
344 | 514 |
345 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 515 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
346 Element member, OpenWorld world) { | 516 Element member, OpenWorld world) { |
347 if (selectors == null) return false; | 517 if (selectors == null) return false; |
348 for (Selector selector in selectors.keys) { | 518 for (Selector selector in selectors.keys) { |
349 if (selector.appliesUnnamed(member)) { | 519 if (selector.appliesUnnamed(member)) { |
350 SelectorConstraints masks = selectors[selector]; | 520 SelectorConstraints masks = selectors[selector]; |
351 if (masks.applies(member, selector, world)) { | 521 if (masks.applies(member, selector, world)) { |
352 return true; | 522 return true; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 fieldSetters.add(element); | 585 fieldSetters.add(element); |
416 break; | 586 break; |
417 case StaticUseKind.SUPER_TEAR_OFF: | 587 case StaticUseKind.SUPER_TEAR_OFF: |
418 methodsNeedingSuperGetter.add(element); | 588 methodsNeedingSuperGetter.add(element); |
419 break; | 589 break; |
420 case StaticUseKind.GENERAL: | 590 case StaticUseKind.GENERAL: |
421 case StaticUseKind.STATIC_TEAR_OFF: | 591 case StaticUseKind.STATIC_TEAR_OFF: |
422 case StaticUseKind.FIELD_GET: | 592 case StaticUseKind.FIELD_GET: |
423 case StaticUseKind.CONSTRUCTOR_INVOKE: | 593 case StaticUseKind.CONSTRUCTOR_INVOKE: |
424 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 594 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 595 case StaticUseKind.REDIRECTION: |
425 break; | 596 break; |
426 case StaticUseKind.CLOSURE: | 597 case StaticUseKind.CLOSURE: |
427 allClosures.add(element); | 598 allClosures.add(element); |
428 break; | 599 break; |
429 case StaticUseKind.DIRECT_INVOKE: | 600 case StaticUseKind.DIRECT_INVOKE: |
430 invariant( | 601 invariant( |
431 element, 'Direct static use is not supported for resolution.'); | 602 element, 'Direct static use is not supported for resolution.'); |
432 break; | 603 break; |
433 } | 604 } |
434 } | 605 } |
435 | 606 |
436 void forgetElement(Element element, Compiler compiler) { | 607 void forgetElement(Element element, Compiler compiler) { |
437 allClosures.remove(element); | 608 allClosures.remove(element); |
438 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); | 609 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); |
439 closurizedMembers.remove(element); | 610 closurizedMembers.remove(element); |
440 fieldSetters.remove(element); | 611 fieldSetters.remove(element); |
441 _directlyInstantiatedClasses.remove(element); | 612 _instantiationInfo.remove(element); |
442 if (element is ClassElement) { | |
443 assert(invariant(element, element.thisType.isRaw, | |
444 message: 'Generic classes not supported (${element.thisType}).')); | |
445 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | |
446 } | |
447 } | 613 } |
448 | 614 |
449 // TODO(ahe): Replace this method with something that is O(1), for example, | 615 // TODO(ahe): Replace this method with something that is O(1), for example, |
450 // by using a map. | 616 // by using a map. |
451 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 617 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
452 // Return new list to guard against concurrent modifications. | 618 // Return new list to guard against concurrent modifications. |
453 return new List<LocalFunctionElement>.from( | 619 return new List<LocalFunctionElement>.from( |
454 allClosures.where((LocalFunctionElement closure) { | 620 allClosures.where((LocalFunctionElement closure) { |
455 return closure.executableContext == element; | 621 return closure.executableContext == element; |
456 })); | 622 })); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 case StaticUseKind.SUPER_TEAR_OFF: | 860 case StaticUseKind.SUPER_TEAR_OFF: |
695 methodsNeedingSuperGetter.add(element); | 861 methodsNeedingSuperGetter.add(element); |
696 break; | 862 break; |
697 case StaticUseKind.SUPER_FIELD_SET: | 863 case StaticUseKind.SUPER_FIELD_SET: |
698 case StaticUseKind.FIELD_SET: | 864 case StaticUseKind.FIELD_SET: |
699 case StaticUseKind.GENERAL: | 865 case StaticUseKind.GENERAL: |
700 case StaticUseKind.CLOSURE: | 866 case StaticUseKind.CLOSURE: |
701 case StaticUseKind.FIELD_GET: | 867 case StaticUseKind.FIELD_GET: |
702 case StaticUseKind.CONSTRUCTOR_INVOKE: | 868 case StaticUseKind.CONSTRUCTOR_INVOKE: |
703 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 869 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 870 case StaticUseKind.REDIRECTION: |
704 case StaticUseKind.DIRECT_INVOKE: | 871 case StaticUseKind.DIRECT_INVOKE: |
705 break; | 872 break; |
706 } | 873 } |
707 } | 874 } |
708 | 875 |
709 void forgetElement(Element element, Compiler compiler) { | 876 void forgetElement(Element element, Compiler compiler) { |
710 _directlyInstantiatedClasses.remove(element); | 877 _directlyInstantiatedClasses.remove(element); |
711 if (element is ClassElement) { | 878 if (element is ClassElement) { |
712 assert(invariant(element, element.thisType.isRaw, | 879 assert(invariant(element, element.thisType.isRaw, |
713 message: 'Generic classes not supported (${element.thisType}).')); | 880 message: 'Generic classes not supported (${element.thisType}).')); |
714 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | 881 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); |
715 } | 882 } |
716 } | 883 } |
717 } | 884 } |
OLD | NEW |