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

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

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

Powered by Google App Engine
This is Rietveld 408576698