Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: pkg/compiler/lib/src/universe/universe.dart

Issue 2318593003: Split Universe into ResolutionUniverse and CodegenUniverse (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 '../common.dart'; 9 import '../common.dart';
10 import '../compiler.dart' show Compiler; 10 import '../compiler.dart' show Compiler;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 /// Create a [UniverseSelectorConstraints] to represent the global receiver 100 /// Create a [UniverseSelectorConstraints] to represent the global receiver
101 /// constraints for dynamic call sites with [selector]. 101 /// constraints for dynamic call sites with [selector].
102 UniverseSelectorConstraints createSelectorConstraints(Selector selector); 102 UniverseSelectorConstraints createSelectorConstraints(Selector selector);
103 } 103 }
104 104
105 /// The [Universe] is an auxiliary class used in the process of computing the 105 /// The [Universe] is an auxiliary class used in the process of computing the
106 /// [ClassWorld]. The concepts here and in [ClassWorld] are very similar -- in 106 /// [ClassWorld]. The concepts here and in [ClassWorld] are very similar -- in
107 /// the same way that the "universe expands" you can think of this as a mutable 107 /// the same way that the "universe expands" you can think of this as a mutable
108 /// world that is expanding as we visit and discover parts of the program. 108 /// world that is expanding as we visit and discover parts of the program.
109 /// TODO(sigmund): rename to "growing/expanding/mutable world"? 109 /// TODO(sigmund): rename to "growing/expanding/mutable world"?
110 class Universe { 110 abstract class Universe {
111 /// All directly instantiated classes, that is, classes with a generative
112 /// constructor that has been called directly and not only through a
113 /// super-call.
114 // TODO(johnniwinther): Improve semantic precision.
115 Iterable<ClassElement> get directlyInstantiatedClasses;
116
117 /// All types that are checked either through is, as or checked mode checks.
118 Iterable<DartType> get isChecks;
119
120 /// Registers that [type] is checked in this universe. The unaliased type is
121 /// returned.
122 DartType registerIsCheck(DartType type, Compiler compiler);
123
124 /// All directly instantiated types, that is, the types of the directly
125 /// instantiated classes.
126 // TODO(johnniwinther): Improve semantic precision.
127 Iterable<DartType> get instantiatedTypes;
128
129 /// Returns `true` if [member] is invoked as a setter.
130 bool hasInvokedSetter(Element member, World world);
131 }
132
133 abstract class ResolutionUniverse implements Universe {
134 /// Set of (live) local functions (closures) whose signatures reference type
135 /// variables.
136 ///
137 /// A live function is one whose enclosing member function has been enqueued.
138 Set<Element> get closuresWithFreeTypeVariables;
Harry Terkelsen 2016/09/19 18:07:10 how come some of these collections are sets and so
Johnni Winther 2016/09/21 09:13:04 This is added to from the outside. Will be changed
139
140 /// Set of (live) `call` methods whose signatures reference type variables.
141 ///
142 /// A live `call` method is one whose enclosing class has been instantiated.
143 Iterable<Element> get callMethodsWithFreeTypeVariables;
144
145 /// Set of all closures in the program. Used by the mirror tracking system
146 /// to find all live closure instances.
147 Iterable<LocalFunctionElement> get allClosures;
148
149 /// Set of methods in instantiated classes that are potentially closurized.
150 Iterable<Element> get closurizedMembers;
151
152 /// Returns `true` if [cls] is considered to be implemented by an
153 /// instantiated class, either directly, through subclasses or through
154 /// subtypes. The latter case only contains spurious information from
155 /// instantiations through factory constructors and mixins.
156 // TODO(johnniwinther): Improve semantic precision.
Siggi Cherem (dart-lang) 2016/09/06 17:57:43 remove TODO (it's already in the impl class below)
Johnni Winther 2016/09/21 09:13:04 Done.
157 bool isImplemented(ClassElement cls);
158
159 /// Set of all fields that are statically known to be written to.
160 Iterable<Element> get fieldSetters;
161 }
162
163 class ResolutionUniverseImpl implements ResolutionUniverse {
111 /// The set of all directly instantiated classes, that is, classes with a 164 /// The set of all directly instantiated classes, that is, classes with a
112 /// generative constructor that has been called directly and not only through 165 /// generative constructor that has been called directly and not only through
113 /// a super-call. 166 /// a super-call.
114 /// 167 ///
115 /// Invariant: Elements are declaration elements. 168 /// Invariant: Elements are declaration elements.
116 // TODO(johnniwinther): [_directlyInstantiatedClasses] and 169 // TODO(johnniwinther): [_directlyInstantiatedClasses] and
117 // [_instantiatedTypes] sets should be merged. 170 // [_instantiatedTypes] sets should be merged.
118 final Set<ClassElement> _directlyInstantiatedClasses = 171 final Set<ClassElement> _directlyInstantiatedClasses =
119 new Set<ClassElement>(); 172 new Set<ClassElement>();
120 173
121 /// The set of all directly instantiated types, that is, the types of the 174 /// The set of all directly instantiated types, that is, the types of the
122 /// directly instantiated classes. 175 /// directly instantiated classes.
123 /// 176 ///
124 /// See [_directlyInstantiatedClasses]. 177 /// See [_directlyInstantiatedClasses].
125 final Set<DartType> _instantiatedTypes = new Set<DartType>(); 178 final Set<DartType> _instantiatedTypes = new Set<DartType>();
126 179
127 /// Classes implemented by directly instantiated classes. 180 /// Classes implemented by directly instantiated classes.
128 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); 181 final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
129 182
130 /// The set of all referenced static fields. 183 /// The set of all referenced static fields.
131 /// 184 ///
132 /// Invariant: Elements are declaration elements. 185 /// Invariant: Elements are declaration elements.
133 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); 186 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
134 187
135 /** 188 /**
136 * Documentation wanted -- johnniwinther 189 * Documentation wanted -- johnniwinther
137 * 190 *
138 * Invariant: Elements are declaration elements. 191 * Invariant: Elements are declaration elements.
139 */ 192 */
140 final Set<FunctionElement> staticFunctionsNeedingGetter =
141 new Set<FunctionElement>();
142 final Set<FunctionElement> methodsNeedingSuperGetter = 193 final Set<FunctionElement> methodsNeedingSuperGetter =
143 new Set<FunctionElement>(); 194 new Set<FunctionElement>();
144 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = 195 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
145 <String, Map<Selector, SelectorConstraints>>{}; 196 <String, Map<Selector, SelectorConstraints>>{};
146 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = 197 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
147 <String, Map<Selector, SelectorConstraints>>{}; 198 <String, Map<Selector, SelectorConstraints>>{};
148 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = 199 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
149 <String, Map<Selector, SelectorConstraints>>{}; 200 <String, Map<Selector, SelectorConstraints>>{};
150 201
151 /** 202 /// Fields set.
152 * Fields accessed. Currently only the codegen knows this
153 * information. The resolver is too conservative when seeing a
154 * getter and only registers an invoked getter.
155 */
156 final Set<Element> fieldGetters = new Set<Element>();
157
158 /**
159 * Fields set. See comment in [fieldGetters].
160 */
161 final Set<Element> fieldSetters = new Set<Element>(); 203 final Set<Element> fieldSetters = new Set<Element>();
162 final Set<DartType> isChecks = new Set<DartType>(); 204 final Set<DartType> isChecks = new Set<DartType>();
163 205
164 /** 206 /**
165 * Set of (live) [:call:] methods whose signatures reference type variables. 207 * Set of (live) [:call:] methods whose signatures reference type variables.
166 * 208 *
167 * A live [:call:] method is one whose enclosing class has been instantiated. 209 * A live [:call:] method is one whose enclosing class has been instantiated.
168 */ 210 */
169 final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>(); 211 final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>();
170 212
(...skipping 12 matching lines...) Expand all
183 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>(); 225 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
184 226
185 /** 227 /**
186 * Set of methods in instantiated classes that are potentially 228 * Set of methods in instantiated classes that are potentially
187 * closurized. 229 * closurized.
188 */ 230 */
189 final Set<Element> closurizedMembers = new Set<Element>(); 231 final Set<Element> closurizedMembers = new Set<Element>();
190 232
191 final SelectorConstraintsStrategy selectorConstraintsStrategy; 233 final SelectorConstraintsStrategy selectorConstraintsStrategy;
192 234
193 Universe(this.selectorConstraintsStrategy); 235 ResolutionUniverseImpl(this.selectorConstraintsStrategy);
194 236
195 /// All directly instantiated classes, that is, classes with a generative 237 /// All directly instantiated classes, that is, classes with a generative
196 /// constructor that has been called directly and not only through a 238 /// constructor that has been called directly and not only through a
197 /// super-call. 239 /// super-call.
198 // TODO(johnniwinther): Improve semantic precision. 240 // TODO(johnniwinther): Improve semantic precision.
199 Iterable<ClassElement> get directlyInstantiatedClasses { 241 Iterable<ClassElement> get directlyInstantiatedClasses {
200 return _directlyInstantiatedClasses; 242 return _directlyInstantiatedClasses;
201 } 243 }
202 244
203 /// All directly instantiated types, that is, the types of the directly 245 /// All directly instantiated types, that is, the types of the directly
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 ReceiverConstraint mask = dynamicUse.mask; 342 ReceiverConstraint mask = dynamicUse.mask;
301 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( 343 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
302 name, () => new Maplet<Selector, SelectorConstraints>()); 344 name, () => new Maplet<Selector, SelectorConstraints>());
303 UniverseSelectorConstraints constraints = 345 UniverseSelectorConstraints constraints =
304 selectors.putIfAbsent(selector, () { 346 selectors.putIfAbsent(selector, () {
305 return selectorConstraintsStrategy.createSelectorConstraints(selector); 347 return selectorConstraintsStrategy.createSelectorConstraints(selector);
306 }); 348 });
307 return constraints.addReceiverConstraint(mask); 349 return constraints.addReceiverConstraint(mask);
308 } 350 }
309 351
352 DartType registerIsCheck(DartType type, Compiler compiler) {
353 type.computeUnaliased(compiler.resolution);
354 type = type.unaliased;
355 // Even in checked mode, type annotations for return type and argument
356 // types do not imply type checks, so there should never be a check
357 // against the type variable of a typedef.
358 isChecks.add(type);
359 return type;
360 }
361
362 void registerStaticUse(StaticUse staticUse) {
363 Element element = staticUse.element;
364 if (Elements.isStaticOrTopLevel(element) && element.isField) {
365 allReferencedStaticFields.add(element);
366 }
367 switch (staticUse.kind) {
368 case StaticUseKind.SUPER_FIELD_SET:
369 case StaticUseKind.FIELD_SET:
370 fieldSetters.add(element);
371 break;
372 case StaticUseKind.SUPER_TEAR_OFF:
373 methodsNeedingSuperGetter.add(element);
374 break;
375 case StaticUseKind.GENERAL:
376 case StaticUseKind.STATIC_TEAR_OFF:
377 case StaticUseKind.FIELD_GET:
378 break;
379 case StaticUseKind.CLOSURE:
380 allClosures.add(element);
381 break;
382 }
383 }
384
385 void forgetElement(Element element, Compiler compiler) {
386 allClosures.remove(element);
387 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
388 closurizedMembers.remove(element);
389 fieldSetters.remove(element);
390 _directlyInstantiatedClasses.remove(element);
391 if (element is ClassElement) {
392 assert(invariant(element, element.thisType.isRaw,
393 message: 'Generic classes not supported (${element.thisType}).'));
394 _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
395 }
396 }
397
398 // TODO(ahe): Replace this method with something that is O(1), for example,
399 // by using a map.
400 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
401 // Return new list to guard against concurrent modifications.
402 return new List<LocalFunctionElement>.from(
403 allClosures.where((LocalFunctionElement closure) {
404 return closure.executableContext == element;
405 }));
406 }
407 }
408
409 abstract class CodegenUniverse implements Universe {
Harry Terkelsen 2016/09/19 18:07:10 add dartdoc for this class
Johnni Winther 2016/09/21 09:13:04 Done.
410 void forEachInvokedName(
411 f(String name, Map<Selector, SelectorConstraints> selectors));
412
413 void forEachInvokedGetter(
414 f(String name, Map<Selector, SelectorConstraints> selectors));
415
416 void forEachInvokedSetter(
417 f(String name, Map<Selector, SelectorConstraints> selectors));
418
419 bool hasInvokedGetter(Element member, World world);
420
421 Map<Selector, SelectorConstraints> invocationsByName(String name);
422
423 Map<Selector, SelectorConstraints> getterInvocationsByName(String name);
424
425 Map<Selector, SelectorConstraints> setterInvocationsByName(String name);
426
427 Iterable<FunctionElement> get staticFunctionsNeedingGetter;
428 Iterable<FunctionElement> get methodsNeedingSuperGetter;
429
430 /// The set of all referenced static fields.
431 ///
432 /// Invariant: Elements are declaration elements.
433 Iterable<FieldElement> get allReferencedStaticFields;
434 }
435
436 class CodegenUniverseImpl implements CodegenUniverse {
437 /// The set of all directly instantiated classes, that is, classes with a
438 /// generative constructor that has been called directly and not only through
439 /// a super-call.
440 ///
441 /// Invariant: Elements are declaration elements.
442 // TODO(johnniwinther): [_directlyInstantiatedClasses] and
443 // [_instantiatedTypes] sets should be merged.
444 final Set<ClassElement> _directlyInstantiatedClasses =
445 new Set<ClassElement>();
446
447 /// The set of all directly instantiated types, that is, the types of the
448 /// directly instantiated classes.
449 ///
450 /// See [_directlyInstantiatedClasses].
451 final Set<DartType> _instantiatedTypes = new Set<DartType>();
452
453 /// Classes implemented by directly instantiated classes.
454 final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
455
456 /// The set of all referenced static fields.
457 ///
458 /// Invariant: Elements are declaration elements.
459 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
460
461 /**
462 * Documentation wanted -- johnniwinther
463 *
464 * Invariant: Elements are declaration elements.
465 */
466 final Set<FunctionElement> staticFunctionsNeedingGetter =
467 new Set<FunctionElement>();
468 final Set<FunctionElement> methodsNeedingSuperGetter =
469 new Set<FunctionElement>();
470 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
471 <String, Map<Selector, SelectorConstraints>>{};
472 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
473 <String, Map<Selector, SelectorConstraints>>{};
474 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
475 <String, Map<Selector, SelectorConstraints>>{};
476
477 final Set<DartType> isChecks = new Set<DartType>();
478
479 final SelectorConstraintsStrategy selectorConstraintsStrategy;
480
481 CodegenUniverseImpl(this.selectorConstraintsStrategy);
482
483 /// All directly instantiated classes, that is, classes with a generative
484 /// constructor that has been called directly and not only through a
485 /// super-call.
486 // TODO(johnniwinther): Improve semantic precision.
487 Iterable<ClassElement> get directlyInstantiatedClasses {
488 return _directlyInstantiatedClasses;
489 }
490
491 /// All directly instantiated types, that is, the types of the directly
492 /// instantiated classes.
493 ///
494 /// See [directlyInstantiatedClasses].
495 // TODO(johnniwinther): Improve semantic precision.
496 Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
497
498 /// Register [type] as (directly) instantiated.
499 ///
500 /// If [byMirrors] is `true`, the instantiation is through mirrors.
501 // TODO(johnniwinther): Fully enforce the separation between exact, through
502 // subclass and through subtype instantiated types/classes.
503 // TODO(johnniwinther): Support unknown type arguments for generic types.
504 void registerTypeInstantiation(InterfaceType type,
Siggi Cherem (dart-lang) 2016/09/06 17:57:43 should some of this shared code be in a shared sup
Harry Terkelsen 2016/09/19 18:07:10 I would suggest 'UniverseBase'
Johnni Winther 2016/09/21 09:13:04 I'll wait with that until the unification of world
505 {bool byMirrors: false,
506 bool isNative: false,
507 void onImplemented(ClassElement cls)}) {
508 _instantiatedTypes.add(type);
509 ClassElement cls = type.element;
510 if (!cls.isAbstract
511 // We can't use the closed-world assumption with native abstract
512 // classes; a native abstract class may have non-abstract subclasses
513 // not declared to the program. Instances of these classes are
514 // indistinguishable from the abstract class.
515 ||
516 isNative
517 // Likewise, if this registration comes from the mirror system,
518 // all bets are off.
519 // TODO(herhut): Track classes required by mirrors seperately.
520 ||
521 byMirrors) {
522 _directlyInstantiatedClasses.add(cls);
523 }
524
525 // TODO(johnniwinther): Replace this by separate more specific mappings that
526 // include the type arguments.
527 if (_implementedClasses.add(cls)) {
528 onImplemented(cls);
529 cls.allSupertypes.forEach((InterfaceType supertype) {
530 if (_implementedClasses.add(supertype.element)) {
531 onImplemented(supertype.element);
532 }
533 });
534 }
535 }
536
537 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
538 Element member, World world) {
539 if (selectors == null) return false;
540 for (Selector selector in selectors.keys) {
541 if (selector.appliesUnnamed(member, world)) {
542 SelectorConstraints masks = selectors[selector];
543 if (masks.applies(member, selector, world)) {
544 return true;
545 }
546 }
547 }
548 return false;
549 }
550
551 bool hasInvocation(Element member, World world) {
552 return _hasMatchingSelector(_invokedNames[member.name], member, world);
553 }
554
555 bool hasInvokedGetter(Element member, World world) {
556 return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
557 member.isFunction && methodsNeedingSuperGetter.contains(member);
558 }
559
560 bool hasInvokedSetter(Element member, World world) {
561 return _hasMatchingSelector(_invokedSetters[member.name], member, world);
562 }
563
564 bool registerDynamicUse(DynamicUse dynamicUse) {
565 switch (dynamicUse.kind) {
566 case DynamicUseKind.INVOKE:
567 return _registerNewSelector(dynamicUse, _invokedNames);
568 case DynamicUseKind.GET:
569 return _registerNewSelector(dynamicUse, _invokedGetters);
570 case DynamicUseKind.SET:
571 return _registerNewSelector(dynamicUse, _invokedSetters);
572 }
573 }
574
575 bool _registerNewSelector(DynamicUse dynamicUse,
576 Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
577 Selector selector = dynamicUse.selector;
578 String name = selector.name;
579 ReceiverConstraint mask = dynamicUse.mask;
580 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
581 name, () => new Maplet<Selector, SelectorConstraints>());
582 UniverseSelectorConstraints constraints =
583 selectors.putIfAbsent(selector, () {
584 return selectorConstraintsStrategy.createSelectorConstraints(selector);
585 });
586 return constraints.addReceiverConstraint(mask);
587 }
588
310 Map<Selector, SelectorConstraints> _asUnmodifiable( 589 Map<Selector, SelectorConstraints> _asUnmodifiable(
311 Map<Selector, SelectorConstraints> map) { 590 Map<Selector, SelectorConstraints> map) {
312 if (map == null) return null; 591 if (map == null) return null;
313 return new UnmodifiableMapView(map); 592 return new UnmodifiableMapView(map);
314 } 593 }
315 594
316 Map<Selector, SelectorConstraints> invocationsByName(String name) { 595 Map<Selector, SelectorConstraints> invocationsByName(String name) {
317 return _asUnmodifiable(_invokedNames[name]); 596 return _asUnmodifiable(_invokedNames[name]);
318 } 597 }
319 598
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 631
353 void registerStaticUse(StaticUse staticUse) { 632 void registerStaticUse(StaticUse staticUse) {
354 Element element = staticUse.element; 633 Element element = staticUse.element;
355 if (Elements.isStaticOrTopLevel(element) && element.isField) { 634 if (Elements.isStaticOrTopLevel(element) && element.isField) {
356 allReferencedStaticFields.add(element); 635 allReferencedStaticFields.add(element);
357 } 636 }
358 switch (staticUse.kind) { 637 switch (staticUse.kind) {
359 case StaticUseKind.STATIC_TEAR_OFF: 638 case StaticUseKind.STATIC_TEAR_OFF:
360 staticFunctionsNeedingGetter.add(element); 639 staticFunctionsNeedingGetter.add(element);
361 break; 640 break;
362 case StaticUseKind.FIELD_GET:
363 fieldGetters.add(element);
364 break;
365 case StaticUseKind.SUPER_FIELD_SET:
366 case StaticUseKind.FIELD_SET:
367 fieldSetters.add(element);
368 break;
369 case StaticUseKind.SUPER_TEAR_OFF: 641 case StaticUseKind.SUPER_TEAR_OFF:
370 methodsNeedingSuperGetter.add(element); 642 methodsNeedingSuperGetter.add(element);
371 break; 643 break;
644 case StaticUseKind.SUPER_FIELD_SET:
645 case StaticUseKind.FIELD_SET:
372 case StaticUseKind.GENERAL: 646 case StaticUseKind.GENERAL:
373 break;
374 case StaticUseKind.CLOSURE: 647 case StaticUseKind.CLOSURE:
375 allClosures.add(element); 648 case StaticUseKind.FIELD_GET:
376 break; 649 break;
377 } 650 }
378 } 651 }
379 652
380 void forgetElement(Element element, Compiler compiler) { 653 void forgetElement(Element element, Compiler compiler) {
381 allClosures.remove(element);
382 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
383 closurizedMembers.remove(element);
384 fieldSetters.remove(element);
385 fieldGetters.remove(element);
386 _directlyInstantiatedClasses.remove(element); 654 _directlyInstantiatedClasses.remove(element);
387 if (element is ClassElement) { 655 if (element is ClassElement) {
388 assert(invariant(element, element.thisType.isRaw, 656 assert(invariant(element, element.thisType.isRaw,
389 message: 'Generic classes not supported (${element.thisType}).')); 657 message: 'Generic classes not supported (${element.thisType}).'));
390 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); 658 _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
391 } 659 }
392 } 660 }
393
394 // TODO(ahe): Replace this method with something that is O(1), for example,
395 // by using a map.
396 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
397 // Return new list to guard against concurrent modifications.
398 return new List<LocalFunctionElement>.from(
399 allClosures.where((LocalFunctionElement closure) {
400 return closure.executableContext == element;
401 }));
402 }
403 } 661 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698