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

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

Issue 2813853002: Use entity WorldImpl where possible (Closed)
Patch Set: Created 3 years, 8 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 dart2js.world; 5 library dart2js.world;
6 6
7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX;
8 import 'common/backend_api.dart' show BackendClasses; 8 import 'common/backend_api.dart' show BackendClasses;
9 import 'common.dart'; 9 import 'common.dart';
10 import 'constants/constant_system.dart'; 10 import 'constants/constant_system.dart';
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 390
391 class ClosedWorldImpl implements ClosedWorld, ClosedWorldRefiner { 391 class ClosedWorldImpl implements ClosedWorld, ClosedWorldRefiner {
392 final JavaScriptBackend _backend; 392 final JavaScriptBackend _backend;
393 BackendClasses get backendClasses => _backend.backendClasses; 393 BackendClasses get backendClasses => _backend.backendClasses;
394 InterceptorData get interceptorData => _backend.interceptorData; 394 InterceptorData get interceptorData => _backend.interceptorData;
395 FunctionSet _allFunctions; 395 FunctionSet _allFunctions;
396 396
397 final Iterable<TypedefElement> _allTypedefs; 397 final Iterable<TypedefElement> _allTypedefs;
398 398
399 final Map<ClassEntity, Set<ClassEntity>> _mixinUses; 399 final Map<ClassEntity, Set<ClassEntity>> _mixinUses;
400 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; 400 Map<ClassEntity, List<ClassEntity>> _liveMixinUses;
401 401
402 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; 402 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses;
403 403
404 // We keep track of subtype and subclass relationships in four 404 // We keep track of subtype and subclass relationships in four
405 // distinct sets to make class hierarchy analysis faster. 405 // distinct sets to make class hierarchy analysis faster.
406 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes; 406 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes;
407 final Map<ClassEntity, ClassSet> _classSets; 407 final Map<ClassEntity, ClassSet> _classSets;
408 408
409 final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = 409 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache =
410 <ClassElement, Map<ClassElement, bool>>{}; 410 <ClassEntity, Map<ClassEntity, bool>>{};
411 411
412 final Set<Element> functionsCalledInLoop = new Set<Element>(); 412 final Set<Element> functionsCalledInLoop = new Set<Element>();
413 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); 413 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
414 414
415 final Set<Element> sideEffectsFreeElements = new Set<Element>(); 415 final Set<Element> sideEffectsFreeElements = new Set<Element>();
416 416
417 final Set<Element> elementsThatCannotThrow = new Set<Element>(); 417 final Set<Element> elementsThatCannotThrow = new Set<Element>();
418 418
419 final Set<Element> functionsThatMightBePassedToApply = 419 final Set<Element> functionsThatMightBePassedToApply =
420 new Set<FunctionElement>(); 420 new Set<FunctionElement>();
421 421
422 CommonMasks _commonMasks; 422 CommonMasks _commonMasks;
423 423
424 final CommonElements commonElements; 424 final CommonElements commonElements;
425 425
426 final ResolutionWorldBuilder _resolverWorld; 426 final ResolutionWorldBuilder _resolverWorld;
427 427
428 bool get isClosed => true;
429
430 ClosedWorldImpl( 428 ClosedWorldImpl(
431 {JavaScriptBackend backend, 429 {JavaScriptBackend backend,
432 this.commonElements, 430 this.commonElements,
433 ResolutionWorldBuilder resolutionWorldBuilder, 431 ResolutionWorldBuilder resolutionWorldBuilder,
434 FunctionSetBuilder functionSetBuilder, 432 FunctionSetBuilder functionSetBuilder,
435 Iterable<TypedefElement> allTypedefs, 433 Iterable<TypedefElement> allTypedefs,
436 Map<ClassEntity, Set<ClassEntity>> mixinUses, 434 Map<ClassEntity, Set<ClassEntity>> mixinUses,
437 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, 435 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
438 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, 436 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
439 Map<ClassEntity, ClassSet> classSets}) 437 Map<ClassEntity, ClassSet> classSets})
440 : this._backend = backend, 438 : this._backend = backend,
441 this._resolverWorld = resolutionWorldBuilder, 439 this._resolverWorld = resolutionWorldBuilder,
442 this._allTypedefs = allTypedefs, 440 this._allTypedefs = allTypedefs,
443 this._mixinUses = mixinUses, 441 this._mixinUses = mixinUses,
444 this._typesImplementedBySubclasses = typesImplementedBySubclasses, 442 this._typesImplementedBySubclasses = typesImplementedBySubclasses,
445 this._classHierarchyNodes = classHierarchyNodes, 443 this._classHierarchyNodes = classHierarchyNodes,
446 this._classSets = classSets { 444 this._classSets = classSets {
447 _commonMasks = new CommonMasks(this); 445 _commonMasks = new CommonMasks(this);
448 _allFunctions = functionSetBuilder.close(this); 446 _allFunctions = functionSetBuilder.close(this);
449 } 447 }
450 448
451 NativeData get nativeData => _backend.nativeData; 449 NativeData get nativeData => _backend.nativeData;
452 450
453 @override 451 @override
454 ClosedWorld get closedWorld => this; 452 ClosedWorld get closedWorld => this;
455 453
456 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the 454 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
457 /// `FlatTypeMask.flags` property. 455 /// `FlatTypeMask.flags` property.
458 final List<Map<ClassElement, TypeMask>> _canonicalizedTypeMasks = 456 final List<Map<ClassEntity, TypeMask>> _canonicalizedTypeMasks =
459 new List<Map<ClassElement, TypeMask>>.filled(8, null); 457 new List<Map<ClassEntity, TypeMask>>.filled(8, null);
460 458
461 FunctionSet get allFunctions => _allFunctions; 459 FunctionSet get allFunctions => _allFunctions;
462 460
463 CommonMasks get commonMasks { 461 CommonMasks get commonMasks {
464 assert(isClosed);
465 return _commonMasks; 462 return _commonMasks;
466 } 463 }
467 464
468 ConstantSystem get constantSystem => _backend.constantSystem; 465 ConstantSystem get constantSystem => _backend.constantSystem;
469 466
470 TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { 467 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) {
471 Map<ClassElement, TypeMask> cachedMasks = 468 Map<ClassEntity, TypeMask> cachedMasks =
472 _canonicalizedTypeMasks[flags] ??= <ClassElement, TypeMask>{}; 469 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{};
473 return cachedMasks.putIfAbsent(base, createMask); 470 return cachedMasks.putIfAbsent(base, createMask);
474 } 471 }
475 472
473 bool _checkClass(ClassElement cls) => cls.isDeclaration;
474
476 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { 475 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
477 return invariant(cls, cls.isDeclaration, 476 return invariant(cls, cls.isDeclaration,
478 message: '$cls must be the declaration.') && 477 message: '$cls must be the declaration.') &&
479 invariant(cls, cls.isResolved, 478 invariant(cls, cls.isResolved,
480 message: 479 message:
481 '$cls must be resolved.') /* && 480 '$cls must be resolved.') /* &&
482 // TODO(johnniwinther): Reinsert this or similar invariant. 481 // TODO(johnniwinther): Reinsert this or similar invariant.
483 (!mustBeInstantiated || 482 (!mustBeInstantiated ||
484 invariant(cls, isInstantiated(cls), 483 invariant(cls, isInstantiated(cls),
485 message: '$cls is not instantiated.'))*/ 484 message: '$cls is not instantiated.'))*/
486 ; 485 ;
487 } 486 }
488 487
489 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an 488 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
490 /// instance of [y]. 489 /// instance of [y].
491 bool isSubtypeOf(ClassElement x, ClassElement y) { 490 bool isSubtypeOf(ClassElement x, ClassElement y) {
492 assert(isClosed);
493 assert(checkInvariants(x)); 491 assert(checkInvariants(x));
494 assert(checkInvariants(y, mustBeInstantiated: false)); 492 assert(checkInvariants(y, mustBeInstantiated: false));
495 493
496 if (y == commonElements.objectClass) return true; 494 if (y == commonElements.objectClass) return true;
497 if (x == commonElements.objectClass) return false; 495 if (x == commonElements.objectClass) return false;
498 if (x.asInstanceOf(y) != null) return true; 496 if (x.asInstanceOf(y) != null) return true;
499 if (y != commonElements.functionClass) return false; 497 if (y != commonElements.functionClass) return false;
500 return x.callType != null; 498 return x.callType != null;
501 } 499 }
502 500
503 /// Return `true` if [x] is a (non-strict) subclass of [y]. 501 /// Return `true` if [x] is a (non-strict) subclass of [y].
504 bool isSubclassOf(ClassElement x, ClassElement y) { 502 bool isSubclassOf(ClassElement x, ClassElement y) {
505 assert(isClosed);
506 assert(checkInvariants(x)); 503 assert(checkInvariants(x));
507 assert(checkInvariants(y)); 504 assert(checkInvariants(y));
508 505
509 if (y == commonElements.objectClass) return true; 506 if (y == commonElements.objectClass) return true;
510 if (x == commonElements.objectClass) return false; 507 if (x == commonElements.objectClass) return false;
511 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { 508 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) {
512 if (x == y) return true; 509 if (x == y) return true;
513 x = x.superclass; 510 x = x.superclass;
514 } 511 }
515 return false; 512 return false;
516 } 513 }
517 514
518 @override 515 @override
519 bool isInstantiated(ClassElement cls) { 516 bool isInstantiated(ClassEntity cls) {
520 assert(isClosed); 517 assert(_checkClass(cls));
521 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 518 ClassHierarchyNode node = _classHierarchyNodes[cls];
522 return node != null && node.isInstantiated; 519 return node != null && node.isInstantiated;
523 } 520 }
524 521
525 @override 522 @override
526 bool isDirectlyInstantiated(ClassElement cls) { 523 bool isDirectlyInstantiated(ClassEntity cls) {
527 assert(isClosed); 524 assert(_checkClass(cls));
528 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 525 ClassHierarchyNode node = _classHierarchyNodes[cls];
529 return node != null && node.isDirectlyInstantiated; 526 return node != null && node.isDirectlyInstantiated;
530 } 527 }
531 528
532 @override 529 @override
533 bool isAbstractlyInstantiated(ClassElement cls) { 530 bool isAbstractlyInstantiated(ClassEntity cls) {
534 assert(isClosed); 531 assert(_checkClass(cls));
535 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 532 ClassHierarchyNode node = _classHierarchyNodes[cls];
536 return node != null && node.isAbstractlyInstantiated; 533 return node != null && node.isAbstractlyInstantiated;
537 } 534 }
538 535
539 @override 536 @override
540 bool isExplicitlyInstantiated(ClassElement cls) { 537 bool isExplicitlyInstantiated(ClassEntity cls) {
541 assert(isClosed); 538 assert(_checkClass(cls));
542 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 539 ClassHierarchyNode node = _classHierarchyNodes[cls];
543 return node != null && node.isExplicitlyInstantiated; 540 return node != null && node.isExplicitlyInstantiated;
544 } 541 }
545 542
546 @override 543 @override
547 bool isIndirectlyInstantiated(ClassElement cls) { 544 bool isIndirectlyInstantiated(ClassEntity cls) {
548 assert(isClosed); 545 assert(_checkClass(cls));
549 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 546 ClassHierarchyNode node = _classHierarchyNodes[cls];
550 return node != null && node.isIndirectlyInstantiated; 547 return node != null && node.isIndirectlyInstantiated;
551 } 548 }
552 549
553 @override 550 @override
554 bool isAbstract(ClassElement cls) => cls.isAbstract; 551 bool isAbstract(ClassEntity cls) => cls.isAbstract;
555 552
556 /// Returns `true` if [cls] is implemented by an instantiated class. 553 /// Returns `true` if [cls] is implemented by an instantiated class.
557 bool isImplemented(ClassElement cls) { 554 bool isImplemented(ClassEntity cls) {
558 assert(isClosed);
559 return _resolverWorld.isImplemented(cls); 555 return _resolverWorld.isImplemented(cls);
560 } 556 }
561 557
562 /// Returns an iterable over the directly instantiated classes that extend 558 /// Returns an iterable over the directly instantiated classes that extend
563 /// [cls] possibly including [cls] itself, if it is live. 559 /// [cls] possibly including [cls] itself, if it is live.
564 Iterable<ClassElement> subclassesOf(ClassElement cls) { 560 Iterable<ClassEntity> subclassesOf(ClassEntity cls) {
565 assert(isClosed); 561 assert(_checkClass(cls));
566 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; 562 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls];
567 if (hierarchy == null) return const <ClassElement>[]; 563 if (hierarchy == null) return const <ClassEntity>[];
568 return hierarchy 564 return hierarchy
569 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); 565 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
570 } 566 }
571 567
572 /// Returns an iterable over the directly instantiated classes that extend 568 /// Returns an iterable over the directly instantiated classes that extend
573 /// [cls] _not_ including [cls] itself. 569 /// [cls] _not_ including [cls] itself.
574 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) { 570 Iterable<ClassEntity> strictSubclassesOf(ClassEntity cls) {
575 assert(isClosed); 571 assert(_checkClass(cls));
576 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 572 ClassHierarchyNode subclasses = _classHierarchyNodes[cls];
577 if (subclasses == null) return const <ClassElement>[]; 573 if (subclasses == null) return const <ClassEntity>[];
578 return subclasses.subclassesByMask( 574 return subclasses.subclassesByMask(
579 ClassHierarchyNode.EXPLICITLY_INSTANTIATED, 575 ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
580 strict: true); 576 strict: true);
581 } 577 }
582 578
583 /// Returns the number of live classes that extend [cls] _not_ 579 /// Returns the number of live classes that extend [cls] _not_
584 /// including [cls] itself. 580 /// including [cls] itself.
585 int strictSubclassCount(ClassElement cls) { 581 int strictSubclassCount(ClassEntity cls) {
586 assert(isClosed); 582 assert(_checkClass(cls));
587 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 583 ClassHierarchyNode subclasses = _classHierarchyNodes[cls];
588 if (subclasses == null) return 0; 584 if (subclasses == null) return 0;
589 return subclasses.instantiatedSubclassCount; 585 return subclasses.instantiatedSubclassCount;
590 } 586 }
591 587
592 /// Applies [f] to each live class that extend [cls] _not_ including [cls] 588 /// Applies [f] to each live class that extend [cls] _not_ including [cls]
593 /// itself. 589 /// itself.
594 void forEachStrictSubclassOf( 590 void forEachStrictSubclassOf(
595 ClassElement cls, IterationStep f(ClassElement cls)) { 591 ClassEntity cls, IterationStep f(ClassEntity cls)) {
596 assert(isClosed); 592 assert(_checkClass(cls));
597 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 593 ClassHierarchyNode subclasses = _classHierarchyNodes[cls];
598 if (subclasses == null) return; 594 if (subclasses == null) return;
599 subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, 595 subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
600 strict: true); 596 strict: true);
601 } 597 }
602 598
603 /// Returns `true` if [predicate] applies to any live class that extend [cls] 599 /// Returns `true` if [predicate] applies to any live class that extend [cls]
604 /// _not_ including [cls] itself. 600 /// _not_ including [cls] itself.
605 bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) { 601 bool anyStrictSubclassOf(ClassEntity cls, bool predicate(ClassEntity cls)) {
606 assert(isClosed); 602 assert(_checkClass(cls));
607 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 603 ClassHierarchyNode subclasses = _classHierarchyNodes[cls];
608 if (subclasses == null) return false; 604 if (subclasses == null) return false;
609 return subclasses.anySubclass( 605 return subclasses.anySubclass(
610 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, 606 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
611 strict: true); 607 strict: true);
612 } 608 }
613 609
614 /// Returns an iterable over the directly instantiated that implement [cls] 610 /// Returns an iterable over the directly instantiated that implement [cls]
615 /// possibly including [cls] itself, if it is live. 611 /// possibly including [cls] itself, if it is live.
616 Iterable<ClassElement> subtypesOf(ClassElement cls) { 612 Iterable<ClassEntity> subtypesOf(ClassEntity cls) {
617 assert(isClosed); 613 assert(_checkClass(cls));
618 ClassSet classSet = _classSets[cls.declaration]; 614 ClassSet classSet = _classSets[cls];
619 if (classSet == null) { 615 if (classSet == null) {
620 return const <ClassElement>[]; 616 return const <ClassEntity>[];
621 } else { 617 } else {
622 return classSet 618 return classSet
623 .subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); 619 .subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
624 } 620 }
625 } 621 }
626 622
627 /// Returns an iterable over the directly instantiated that implement [cls] 623 /// Returns an iterable over the directly instantiated that implement [cls]
628 /// _not_ including [cls]. 624 /// _not_ including [cls].
629 Iterable<ClassElement> strictSubtypesOf(ClassElement cls) { 625 Iterable<ClassEntity> strictSubtypesOf(ClassEntity cls) {
630 assert(isClosed); 626 assert(_checkClass(cls));
631 ClassSet classSet = _classSets[cls.declaration]; 627 ClassSet classSet = _classSets[cls];
632 if (classSet == null) { 628 if (classSet == null) {
633 return const <ClassElement>[]; 629 return const <ClassEntity>[];
634 } else { 630 } else {
635 return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED, 631 return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
636 strict: true); 632 strict: true);
637 } 633 }
638 } 634 }
639 635
640 /// Returns the number of live classes that implement [cls] _not_ 636 /// Returns the number of live classes that implement [cls] _not_
641 /// including [cls] itself. 637 /// including [cls] itself.
642 int strictSubtypeCount(ClassElement cls) { 638 int strictSubtypeCount(ClassEntity cls) {
643 assert(isClosed); 639 assert(_checkClass(cls));
644 ClassSet classSet = _classSets[cls.declaration]; 640 ClassSet classSet = _classSets[cls];
645 if (classSet == null) return 0; 641 if (classSet == null) return 0;
646 return classSet.instantiatedSubtypeCount; 642 return classSet.instantiatedSubtypeCount;
647 } 643 }
648 644
649 /// Applies [f] to each live class that implements [cls] _not_ including [cls] 645 /// Applies [f] to each live class that implements [cls] _not_ including [cls]
650 /// itself. 646 /// itself.
651 void forEachStrictSubtypeOf( 647 void forEachStrictSubtypeOf(
652 ClassElement cls, IterationStep f(ClassElement cls)) { 648 ClassEntity cls, IterationStep f(ClassEntity cls)) {
653 assert(isClosed); 649 assert(_checkClass(cls));
654 ClassSet classSet = _classSets[cls.declaration]; 650 ClassSet classSet = _classSets[cls];
655 if (classSet == null) return; 651 if (classSet == null) return;
656 classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, 652 classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
657 strict: true); 653 strict: true);
658 } 654 }
659 655
660 /// Returns `true` if [predicate] applies to any live class that extend [cls] 656 /// Returns `true` if [predicate] applies to any live class that extend [cls]
661 /// _not_ including [cls] itself. 657 /// _not_ including [cls] itself.
662 bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) { 658 bool anyStrictSubtypeOf(ClassEntity cls, bool predicate(ClassEntity cls)) {
663 assert(isClosed); 659 assert(_checkClass(cls));
664 ClassSet classSet = _classSets[cls.declaration]; 660 ClassSet classSet = _classSets[cls];
665 if (classSet == null) return false; 661 if (classSet == null) return false;
666 return classSet.anySubtype( 662 return classSet.anySubtype(
667 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, 663 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
668 strict: true); 664 strict: true);
669 } 665 }
670 666
671 /// Returns `true` if [a] and [b] have any known common subtypes. 667 /// Returns `true` if [a] and [b] have any known common subtypes.
672 bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) { 668 bool haveAnyCommonSubtypes(ClassEntity a, ClassEntity b) {
673 assert(isClosed); 669 assert(_checkClass(a));
674 ClassSet classSetA = _classSets[a.declaration]; 670 assert(_checkClass(b));
675 ClassSet classSetB = _classSets[b.declaration]; 671 ClassSet classSetA = _classSets[a];
672 ClassSet classSetB = _classSets[b];
676 if (classSetA == null || classSetB == null) return false; 673 if (classSetA == null || classSetB == null) return false;
677 // TODO(johnniwinther): Implement an optimized query on [ClassSet]. 674 // TODO(johnniwinther): Implement an optimized query on [ClassSet].
678 Set<ClassElement> subtypesOfB = classSetB.subtypes().toSet(); 675 Set<ClassEntity> subtypesOfB = classSetB.subtypes().toSet();
679 for (ClassElement subtypeOfA in classSetA.subtypes()) { 676 for (ClassEntity subtypeOfA in classSetA.subtypes()) {
680 if (subtypesOfB.contains(subtypeOfA)) { 677 if (subtypesOfB.contains(subtypeOfA)) {
681 return true; 678 return true;
682 } 679 }
683 } 680 }
684 return false; 681 return false;
685 } 682 }
686 683
687 /// Returns `true` if any directly instantiated class other than [cls] extends 684 /// Returns `true` if any directly instantiated class other than [cls] extends
688 /// [cls]. 685 /// [cls].
689 bool hasAnyStrictSubclass(ClassElement cls) { 686 bool hasAnyStrictSubclass(ClassEntity cls) {
690 assert(isClosed); 687 assert(_checkClass(cls));
691 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration]; 688 ClassHierarchyNode subclasses = _classHierarchyNodes[cls];
692 if (subclasses == null) return false; 689 if (subclasses == null) return false;
693 return subclasses.isIndirectlyInstantiated; 690 return subclasses.isIndirectlyInstantiated;
694 } 691 }
695 692
696 /// Returns `true` if any directly instantiated class other than [cls] 693 /// Returns `true` if any directly instantiated class other than [cls]
697 /// implements [cls]. 694 /// implements [cls].
698 bool hasAnyStrictSubtype(ClassElement cls) { 695 bool hasAnyStrictSubtype(ClassEntity cls) {
699 return strictSubtypeCount(cls) > 0; 696 return strictSubtypeCount(cls) > 0;
700 } 697 }
701 698
702 /// Returns `true` if all directly instantiated classes that implement [cls] 699 /// Returns `true` if all directly instantiated classes that implement [cls]
703 /// extend it. 700 /// extend it.
704 bool hasOnlySubclasses(ClassElement cls) { 701 bool hasOnlySubclasses(ClassEntity cls) {
705 assert(isClosed); 702 assert(_checkClass(cls));
706 // TODO(johnniwinther): move this to ClassSet? 703 // TODO(johnniwinther): move this to ClassSet?
707 if (cls == commonElements.objectClass) return true; 704 if (cls == commonElements.objectClass) return true;
708 ClassSet classSet = _classSets[cls.declaration]; 705 ClassSet classSet = _classSets[cls];
709 if (classSet == null) { 706 if (classSet == null) {
710 // Vacuously true. 707 // Vacuously true.
711 return true; 708 return true;
712 } 709 }
713 return classSet.hasOnlyInstantiatedSubclasses; 710 return classSet.hasOnlyInstantiatedSubclasses;
714 } 711 }
715 712
716 @override 713 @override
717 ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) { 714 ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls) {
718 assert(isClosed); 715 assert(_checkClass(cls));
719 if (nativeData.isJsInteropClass(cls)) { 716 if (nativeData.isJsInteropClass(cls)) {
720 return _backend.helpers.jsJavaScriptObjectClass; 717 return _backend.helpers.jsJavaScriptObjectClass;
721 } 718 }
722 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; 719 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls];
723 return hierarchy != null 720 return hierarchy != null
724 ? hierarchy.getLubOfInstantiatedSubclasses() 721 ? hierarchy.getLubOfInstantiatedSubclasses()
725 : null; 722 : null;
726 } 723 }
727 724
728 @override 725 @override
729 ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) { 726 ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls) {
730 assert(isClosed); 727 assert(_checkClass(cls));
731 if (nativeData.isJsInteropClass(cls)) { 728 if (nativeData.isJsInteropClass(cls)) {
732 return _backend.helpers.jsJavaScriptObjectClass; 729 return _backend.helpers.jsJavaScriptObjectClass;
733 } 730 }
734 ClassSet classSet = _classSets[cls.declaration]; 731 ClassSet classSet = _classSets[cls];
735 return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null; 732 return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null;
736 } 733 }
737 734
738 /// Returns an iterable over the common supertypes of the [classes]. 735 /// Returns an iterable over the common supertypes of the [classes].
739 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { 736 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
740 assert(isClosed);
741 Iterator<ClassElement> iterator = classes.iterator; 737 Iterator<ClassElement> iterator = classes.iterator;
742 if (!iterator.moveNext()) return const <ClassElement>[]; 738 if (!iterator.moveNext()) return const <ClassElement>[];
743 739
744 ClassElement cls = iterator.current; 740 ClassElement cls = iterator.current;
745 assert(checkInvariants(cls)); 741 assert(checkInvariants(cls));
746 OrderedTypeSet typeSet = cls.allSupertypesAndSelf; 742 OrderedTypeSet typeSet = cls.allSupertypesAndSelf;
747 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); 743 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element);
748 744
749 int depth = typeSet.maxDepth; 745 int depth = typeSet.maxDepth;
750 Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>(); 746 Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>();
(...skipping 19 matching lines...) Expand all
770 if (link.head.asInstanceOf(cls) == null) { 766 if (link.head.asInstanceOf(cls) == null) {
771 continue OUTER; 767 continue OUTER;
772 } 768 }
773 } 769 }
774 commonSupertypes.add(cls); 770 commonSupertypes.add(cls);
775 } 771 }
776 commonSupertypes.add(commonElements.objectClass); 772 commonSupertypes.add(commonElements.objectClass);
777 return commonSupertypes; 773 return commonSupertypes;
778 } 774 }
779 775
780 Iterable<ClassElement> commonSubclasses(ClassElement cls1, ClassQuery query1, 776 Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1,
781 ClassElement cls2, ClassQuery query2) { 777 ClassEntity cls2, ClassQuery query2) {
782 // TODO(johnniwinther): Use [ClassSet] to compute this. 778 // TODO(johnniwinther): Use [ClassSet] to compute this.
783 // Compute the set of classes that are contained in both class subsets. 779 // Compute the set of classes that are contained in both class subsets.
784 Set<ClassEntity> common = 780 Set<ClassEntity> common =
785 _commonContainedClasses(cls1, query1, cls2, query2); 781 _commonContainedClasses(cls1, query1, cls2, query2);
786 if (common == null || common.isEmpty) return const <ClassElement>[]; 782 if (common == null || common.isEmpty) return const <ClassEntity>[];
787 // Narrow down the candidates by only looking at common classes 783 // Narrow down the candidates by only looking at common classes
788 // that do not have a superclass or supertype that will be a 784 // that do not have a superclass or supertype that will be a
789 // better candidate. 785 // better candidate.
790 return common.where((ClassElement each) { 786 return common.where((ClassElement each) {
791 bool containsSuperclass = common.contains(each.supertype.element); 787 bool containsSuperclass = common.contains(each.supertype.element);
792 // If the superclass is also a candidate, then we don't want to 788 // If the superclass is also a candidate, then we don't want to
793 // deal with this class. If we're only looking for a subclass we 789 // deal with this class. If we're only looking for a subclass we
794 // know we don't have to look at the list of interfaces because 790 // know we don't have to look at the list of interfaces because
795 // they can never be in the common set. 791 // they can never be in the common set.
796 if (containsSuperclass || 792 if (containsSuperclass ||
797 query1 == ClassQuery.SUBCLASS || 793 query1 == ClassQuery.SUBCLASS ||
798 query2 == ClassQuery.SUBCLASS) { 794 query2 == ClassQuery.SUBCLASS) {
799 return !containsSuperclass; 795 return !containsSuperclass;
800 } 796 }
801 // Run through the direct supertypes of the class. If the common 797 // Run through the direct supertypes of the class. If the common
802 // set contains the direct supertype of the class, we ignore the 798 // set contains the direct supertype of the class, we ignore the
803 // the class because the supertype is a better candidate. 799 // the class because the supertype is a better candidate.
804 for (Link link = each.interfaces; !link.isEmpty; link = link.tail) { 800 for (Link link = each.interfaces; !link.isEmpty; link = link.tail) {
805 if (common.contains(link.head.element)) return false; 801 if (common.contains(link.head.element)) return false;
806 } 802 }
807 return true; 803 return true;
808 }); 804 });
809 } 805 }
810 806
811 Set<ClassElement> _commonContainedClasses(ClassElement cls1, 807 Set<ClassEntity> _commonContainedClasses(ClassEntity cls1, ClassQuery query1,
812 ClassQuery query1, ClassElement cls2, ClassQuery query2) { 808 ClassEntity cls2, ClassQuery query2) {
813 Iterable<ClassElement> xSubset = _containedSubset(cls1, query1); 809 Iterable<ClassEntity> xSubset = _containedSubset(cls1, query1);
814 if (xSubset == null) return null; 810 if (xSubset == null) return null;
815 Iterable<ClassElement> ySubset = _containedSubset(cls2, query2); 811 Iterable<ClassEntity> ySubset = _containedSubset(cls2, query2);
816 if (ySubset == null) return null; 812 if (ySubset == null) return null;
817 return xSubset.toSet().intersection(ySubset.toSet()); 813 return xSubset.toSet().intersection(ySubset.toSet());
818 } 814 }
819 815
820 Iterable<ClassElement> _containedSubset(ClassElement cls, ClassQuery query) { 816 Iterable<ClassEntity> _containedSubset(ClassEntity cls, ClassQuery query) {
821 switch (query) { 817 switch (query) {
822 case ClassQuery.EXACT: 818 case ClassQuery.EXACT:
823 return null; 819 return null;
824 case ClassQuery.SUBCLASS: 820 case ClassQuery.SUBCLASS:
825 return strictSubclassesOf(cls); 821 return strictSubclassesOf(cls);
826 case ClassQuery.SUBTYPE: 822 case ClassQuery.SUBTYPE:
827 return strictSubtypesOf(cls); 823 return strictSubtypesOf(cls);
828 } 824 }
829 throw new ArgumentError('Unexpected query: $query.'); 825 throw new ArgumentError('Unexpected query: $query.');
830 } 826 }
831 827
832 /// Returns an iterable over the live mixin applications that mixin [cls]. 828 /// Returns an iterable over the live mixin applications that mixin [cls].
833 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { 829 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) {
834 assert(isClosed);
835 if (_liveMixinUses == null) { 830 if (_liveMixinUses == null) {
836 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>(); 831 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>();
837 for (ClassElement mixin in _mixinUses.keys) { 832 for (ClassElement mixin in _mixinUses.keys) {
838 List<MixinApplicationElement> uses = <MixinApplicationElement>[]; 833 List<ClassEntity> uses = <ClassEntity>[];
839 834
840 void addLiveUse(MixinApplicationElement mixinApplication) { 835 void addLiveUse(MixinApplicationElement mixinApplication) {
841 if (isInstantiated(mixinApplication)) { 836 if (isInstantiated(mixinApplication)) {
842 uses.add(mixinApplication); 837 uses.add(mixinApplication);
843 } else if (mixinApplication.isNamedMixinApplication) { 838 } else if (mixinApplication.isNamedMixinApplication) {
844 Set<ClassEntity> next = _mixinUses[mixinApplication]; 839 Set<ClassEntity> next = _mixinUses[mixinApplication];
845 if (next != null) { 840 if (next != null) {
846 next.forEach(addLiveUse); 841 next.forEach(addLiveUse);
847 } 842 }
848 } 843 }
849 } 844 }
850 845
851 _mixinUses[mixin].forEach(addLiveUse); 846 _mixinUses[mixin].forEach(addLiveUse);
852 if (uses.isNotEmpty) { 847 if (uses.isNotEmpty) {
853 _liveMixinUses[mixin] = uses; 848 _liveMixinUses[mixin] = uses;
854 } 849 }
855 } 850 }
856 } 851 }
857 Iterable<MixinApplicationElement> uses = _liveMixinUses[cls]; 852 Iterable<ClassEntity> uses = _liveMixinUses[cls];
858 return uses != null ? uses : const <MixinApplicationElement>[]; 853 return uses != null ? uses : const <ClassEntity>[];
859 } 854 }
860 855
861 /// Returns `true` if [cls] is mixed into a live class. 856 /// Returns `true` if [cls] is mixed into a live class.
862 bool isUsedAsMixin(ClassElement cls) { 857 bool isUsedAsMixin(ClassEntity cls) {
863 assert(isClosed);
864 return !mixinUsesOf(cls).isEmpty; 858 return !mixinUsesOf(cls).isEmpty;
865 } 859 }
866 860
867 /// Returns `true` if any live class that mixes in [cls] implements [type]. 861 /// Returns `true` if any live class that mixes in [cls] implements [type].
868 bool hasAnySubclassOfMixinUseThatImplements( 862 bool hasAnySubclassOfMixinUseThatImplements(
869 ClassElement cls, ClassElement type) { 863 ClassEntity cls, ClassEntity type) {
870 assert(isClosed);
871 return mixinUsesOf(cls) 864 return mixinUsesOf(cls)
872 .any((use) => hasAnySubclassThatImplements(use, type)); 865 .any((use) => hasAnySubclassThatImplements(use, type));
873 } 866 }
874 867
875 /// Returns `true` if any live class that mixes in [mixin] is also a subclass 868 /// Returns `true` if any live class that mixes in [mixin] is also a subclass
876 /// of [superclass]. 869 /// of [superclass].
877 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin) { 870 bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) {
878 assert(isClosed); 871 return mixinUsesOf(mixin).any((ClassElement each) {
879 return mixinUsesOf(mixin).any((each) => each.isSubclassOf(superclass)); 872 return each.isSubclassOf(superclass);
873 });
880 } 874 }
881 875
882 /// Returns `true` if [cls] or any superclass mixes in [mixin]. 876 /// Returns `true` if [cls] or any superclass mixes in [mixin].
883 bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin) { 877 bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) {
884 assert(isClosed); 878 assert(_checkClass(cls));
885 assert(cls.isDeclaration); 879 assert(_checkClass(mixin));
886 assert(mixin.isDeclaration);
887 if (isUsedAsMixin(mixin)) { 880 if (isUsedAsMixin(mixin)) {
888 ClassElement current = cls; 881 ClassElement current = cls;
889 while (current != null) { 882 while (current != null) {
890 if (current.isMixinApplication) { 883 if (current.isMixinApplication) {
891 MixinApplicationElement application = current; 884 MixinApplicationElement application = current;
892 if (application.mixin == mixin) return true; 885 if (application.mixin == mixin) return true;
893 } 886 }
894 current = current.superclass; 887 current = current.superclass;
895 } 888 }
896 } 889 }
897 return false; 890 return false;
898 } 891 }
899 892
900 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass 893 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass
901 /// of a mixin application of [y]. 894 /// of a mixin application of [y].
902 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y) { 895 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y) {
903 assert(isClosed); 896 assert(_checkClass(x));
904 assert(x.isDeclaration); 897 assert(_checkClass(y));
905 assert(y.isDeclaration); 898 Map<ClassEntity, bool> secondMap =
906 Map<ClassElement, bool> secondMap = 899 _subtypeCoveredByCache[x] ??= <ClassEntity, bool>{};
907 _subtypeCoveredByCache[x] ??= <ClassElement, bool>{}; 900 return secondMap[y] ??= subtypesOf(x).every((ClassEntity cls) =>
908 return secondMap[y] ??= subtypesOf(x).every((ClassElement cls) =>
909 isSubclassOf(cls, y) || isSubclassOfMixinUseOf(cls, y)); 901 isSubclassOf(cls, y) || isSubclassOfMixinUseOf(cls, y));
910 } 902 }
911 903
912 /// Returns `true` if any subclass of [superclass] implements [type]. 904 /// Returns `true` if any subclass of [superclass] implements [type].
913 bool hasAnySubclassThatImplements( 905 bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type) {
914 ClassElement superclass, ClassElement type) { 906 assert(_checkClass(superclass));
915 assert(isClosed); 907 Set<ClassEntity> subclasses = _typesImplementedBySubclasses[superclass];
916
917 Set<ClassEntity> subclasses =
918 _typesImplementedBySubclasses[superclass.declaration];
919 if (subclasses == null) return false; 908 if (subclasses == null) return false;
920 return subclasses.contains(type); 909 return subclasses.contains(type);
921 } 910 }
922 911
923 @override 912 @override
924 bool hasElementIn(ClassElement cls, Selector selector, Element element) { 913 bool hasElementIn(ClassEntity cls, Selector selector, Element element) {
925 // Use [:implementation:] of [element] 914 // Use [:implementation:] of [element]
926 // because our function set only stores declarations. 915 // because our function set only stores declarations.
927 Element result = findMatchIn(cls, selector); 916 Element result = findMatchIn(cls, selector);
928 return result == null 917 return result == null
929 ? false 918 ? false
930 : result.implementation == element.implementation; 919 : result.implementation == element.implementation;
931 } 920 }
932 921
933 MemberElement findMatchIn(ClassElement cls, Selector selector, 922 MemberElement findMatchIn(ClassElement cls, Selector selector,
934 {ClassElement stopAtSuperclass}) { 923 {ClassElement stopAtSuperclass}) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 } 989 }
1001 return false; 990 return false;
1002 } 991 }
1003 } 992 }
1004 993
1005 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies 994 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
1006 /// of known classes. 995 /// of known classes.
1007 /// 996 ///
1008 /// This method is only provided for testing. For queries on classes, use the 997 /// This method is only provided for testing. For queries on classes, use the
1009 /// methods defined in [ClosedWorld]. 998 /// methods defined in [ClosedWorld].
1010 ClassHierarchyNode getClassHierarchyNode(ClassElement cls) { 999 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls) {
1011 return _classHierarchyNodes[cls.declaration]; 1000 assert(_checkClass(cls));
1001 return _classHierarchyNodes[cls];
1012 } 1002 }
1013 1003
1014 /// Returns [ClassSet] for [cls] used to model the extends and implements 1004 /// Returns [ClassSet] for [cls] used to model the extends and implements
1015 /// relations of known classes. 1005 /// relations of known classes.
1016 /// 1006 ///
1017 /// This method is only provided for testing. For queries on classes, use the 1007 /// This method is only provided for testing. For queries on classes, use the
1018 /// methods defined in [ClosedWorld]. 1008 /// methods defined in [ClosedWorld].
1019 ClassSet getClassSet(ClassElement cls) { 1009 ClassSet getClassSet(ClassEntity cls) {
1020 return _classSets[cls.declaration]; 1010 assert(_checkClass(cls));
1011 return _classSets[cls];
1021 } 1012 }
1022 1013
1023 void registerClosureClass(ClosureClassElement cls) { 1014 void registerClosureClass(ClosureClassElement cls) {
1024 ClassHierarchyNode parentNode = getClassHierarchyNode(cls.superclass); 1015 ClassHierarchyNode parentNode = getClassHierarchyNode(cls.superclass);
1025 ClassHierarchyNode node = _classHierarchyNodes[cls] = 1016 ClassHierarchyNode node = _classHierarchyNodes[cls] =
1026 new ClassHierarchyNode(parentNode, cls, cls.hierarchyDepth); 1017 new ClassHierarchyNode(parentNode, cls, cls.hierarchyDepth);
1027 for (ResolutionInterfaceType type in cls.allSupertypes) { 1018 for (ResolutionInterfaceType type in cls.allSupertypes) {
1028 ClassSet subtypeSet = getClassSet(type.element); 1019 ClassSet subtypeSet = getClassSet(type.element);
1029 subtypeSet.addSubtype(node); 1020 subtypeSet.addSubtype(node);
1030 } 1021 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { 1056 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) {
1066 return allFunctions.filter(selector, mask).any((each) => each.isGetter); 1057 return allFunctions.filter(selector, mask).any((each) => each.isGetter);
1067 } 1058 }
1068 1059
1069 FieldElement locateSingleField(Selector selector, TypeMask mask) { 1060 FieldElement locateSingleField(Selector selector, TypeMask mask) {
1070 Element result = locateSingleElement(selector, mask); 1061 Element result = locateSingleElement(selector, mask);
1071 return (result != null && result.isField) ? result : null; 1062 return (result != null && result.isField) ? result : null;
1072 } 1063 }
1073 1064
1074 MemberElement locateSingleElement(Selector selector, TypeMask mask) { 1065 MemberElement locateSingleElement(Selector selector, TypeMask mask) {
1075 assert(isClosed);
1076 mask ??= commonMasks.dynamicType; 1066 mask ??= commonMasks.dynamicType;
1077 return mask.locateSingleElement(selector, this); 1067 return mask.locateSingleElement(selector, this);
1078 } 1068 }
1079 1069
1080 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { 1070 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
1081 assert(isClosed);
1082 bool canReachAll = true; 1071 bool canReachAll = true;
1083 if (mask != null) { 1072 if (mask != null) {
1084 canReachAll = _backend.backendUsage.isInvokeOnUsed && 1073 canReachAll = _backend.backendUsage.isInvokeOnUsed &&
1085 mask.needsNoSuchMethodHandling(selector, this); 1074 mask.needsNoSuchMethodHandling(selector, this);
1086 } 1075 }
1087 return canReachAll ? commonMasks.dynamicType : mask; 1076 return canReachAll ? commonMasks.dynamicType : mask;
1088 } 1077 }
1089 1078
1090 void addFunctionCalledInLoop(Element element) { 1079 void addFunctionCalledInLoop(Element element) {
1091 functionsCalledInLoop.add(element.declaration); 1080 functionsCalledInLoop.add(element.declaration);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 return getMightBePassedToApply(element.expression); 1180 return getMightBePassedToApply(element.expression);
1192 } 1181 }
1193 return functionsThatMightBePassedToApply.contains(element); 1182 return functionsThatMightBePassedToApply.contains(element);
1194 } 1183 }
1195 1184
1196 @override 1185 @override
1197 bool getCurrentlyKnownMightBePassedToApply(Element element) { 1186 bool getCurrentlyKnownMightBePassedToApply(Element element) {
1198 return getMightBePassedToApply(element); 1187 return getMightBePassedToApply(element);
1199 } 1188 }
1200 } 1189 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/class_set.dart ('k') | tests/compiler/dart2js/kernel/closed_world2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698