Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.world; | 5 library dart2js.world; |
| 6 | 6 |
| 7 import 'closure.dart' show SynthesizedCallMethodElementX; | 7 import 'closure.dart' show SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show Backend; | 8 import 'common/backend_api.dart' show Backend; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 bool isUsedAsMixin(ClassElement cls); | 160 bool isUsedAsMixin(ClassElement cls); |
| 161 | 161 |
| 162 /// Returns `true` if any live class that mixes in [cls] implements [type]. | 162 /// Returns `true` if any live class that mixes in [cls] implements [type]. |
| 163 bool hasAnySubclassOfMixinUseThatImplements( | 163 bool hasAnySubclassOfMixinUseThatImplements( |
| 164 ClassElement cls, ClassElement type); | 164 ClassElement cls, ClassElement type); |
| 165 | 165 |
| 166 /// Returns `true` if any live class that mixes in [mixin] is also a subclass | 166 /// Returns `true` if any live class that mixes in [mixin] is also a subclass |
| 167 /// of [superclass]. | 167 /// of [superclass]. |
| 168 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin); | 168 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin); |
| 169 | 169 |
| 170 /// Returns `true` if [cls] or any superclass mixes in [mixin]. | |
| 171 bool isSubclassOfMixinOf(ClassElement cls, ClassElement mixin); | |
| 172 | |
| 173 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass | |
| 174 /// of a mixin application of [y]. | |
| 175 bool everySubtypeIsSubclassOrMixinOf(ClassElement x, ClassElement y); | |
| 176 | |
| 170 /// Returns `true` if any subclass of [superclass] implements [type]. | 177 /// Returns `true` if any subclass of [superclass] implements [type]. |
| 171 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); | 178 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); |
| 172 | 179 |
| 173 /// Returns `true` if closed-world assumptions can be made, that is, | 180 /// Returns `true` if closed-world assumptions can be made, that is, |
| 174 /// incremental compilation isn't enabled. | 181 /// incremental compilation isn't enabled. |
| 175 bool get hasClosedWorldAssumption; | 182 bool get hasClosedWorldAssumption; |
| 176 | 183 |
| 177 /// Returns a string representation of the closed world. | 184 /// Returns a string representation of the closed world. |
| 178 /// | 185 /// |
| 179 /// If [cls] is provided, the dump will contain only classes related to [cls]. | 186 /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 return mixinUsesOf(cls) | 504 return mixinUsesOf(cls) |
| 498 .any((use) => hasAnySubclassThatImplements(use, type)); | 505 .any((use) => hasAnySubclassThatImplements(use, type)); |
| 499 } | 506 } |
| 500 | 507 |
| 501 /// Returns `true` if any live class that mixes in [mixin] is also a subclass | 508 /// Returns `true` if any live class that mixes in [mixin] is also a subclass |
| 502 /// of [superclass]. | 509 /// of [superclass]. |
| 503 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin) { | 510 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin) { |
| 504 return mixinUsesOf(mixin).any((each) => each.isSubclassOf(superclass)); | 511 return mixinUsesOf(mixin).any((each) => each.isSubclassOf(superclass)); |
| 505 } | 512 } |
| 506 | 513 |
| 514 /// Returns `true` if [cls] or any superclass mixes in [mixin]. | |
| 515 bool isSubclassOfMixinOf(ClassElement cls, ClassElement mixin) { | |
|
Siggi Cherem (dart-lang)
2016/08/29 19:26:00
nit: _Of_Of confuses me a bit, consider renaming?
sra1
2016/08/29 20:37:18
Johnni - what do you think?
For consistency with
Johnni Winther
2016/08/30 11:36:08
I'd go for 'isSubclassOfMixinUseOf' or maybe `inhe
| |
| 516 if (isUsedAsMixin(mixin)) { | |
| 517 ClassElement current = cls.declaration; | |
| 518 mixin = mixin.declaration; | |
| 519 while (current != null) { | |
| 520 current = current.declaration; | |
| 521 if (current.isMixinApplication) { | |
| 522 MixinApplicationElement application = current; | |
| 523 if (application.mixin.declaration == mixin) return true; | |
| 524 } | |
| 525 current = current.superclass; | |
| 526 } | |
| 527 } | |
| 528 return false; | |
| 529 } | |
| 530 | |
| 531 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass | |
| 532 /// of a mixin application of [y]. | |
| 533 bool everySubtypeIsSubclassOrMixinOf(ClassElement x, ClassElement y) { | |
| 534 x = x.declaration; | |
| 535 y = y.declaration; | |
| 536 Map<ClassElement, bool> secondMap = | |
| 537 _subtypeCoveredByCache[x] ??= <ClassElement, bool>{}; | |
| 538 return secondMap[y] ??= | |
| 539 subtypesOf(x).every( | |
|
Siggi Cherem (dart-lang)
2016/08/29 19:26:01
I wonder how much this affects compile-time.
If i
sra1
2016/08/29 20:37:17
I didn't see any perf issues on Golem.
Two things
| |
| 540 (ClassElement cls) => | |
| 541 isSubclassOf(cls, y) || isSubclassOfMixinOf(cls, y)); | |
| 542 } | |
| 543 | |
| 507 /// Returns `true` if any subclass of [superclass] implements [type]. | 544 /// Returns `true` if any subclass of [superclass] implements [type]. |
| 508 bool hasAnySubclassThatImplements( | 545 bool hasAnySubclassThatImplements( |
| 509 ClassElement superclass, ClassElement type) { | 546 ClassElement superclass, ClassElement type) { |
| 510 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); | 547 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| 511 if (subclasses == null) return false; | 548 if (subclasses == null) return false; |
| 512 return subclasses.contains(type); | 549 return subclasses.contains(type); |
| 513 } | 550 } |
| 514 | 551 |
| 515 final Compiler compiler; | 552 final Compiler compiler; |
| 516 Backend get backend => compiler.backend; | 553 Backend get backend => compiler.backend; |
| 517 final FunctionSet allFunctions; | 554 final FunctionSet allFunctions; |
| 518 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 555 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| 519 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 556 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| 520 | 557 |
| 521 final Set<TypedefElement> allTypedefs = new Set<TypedefElement>(); | 558 final Set<TypedefElement> allTypedefs = new Set<TypedefElement>(); |
| 522 | 559 |
| 523 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = | 560 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| 524 new Map<ClassElement, Set<MixinApplicationElement>>(); | 561 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 525 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; | 562 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; |
| 526 | 563 |
| 527 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = | 564 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = |
| 528 new Map<ClassElement, Set<ClassElement>>(); | 565 new Map<ClassElement, Set<ClassElement>>(); |
| 529 | 566 |
| 530 // We keep track of subtype and subclass relationships in four | 567 // We keep track of subtype and subclass relationships in four |
| 531 // distinct sets to make class hierarchy analysis faster. | 568 // distinct sets to make class hierarchy analysis faster. |
| 532 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = | 569 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = |
| 533 <ClassElement, ClassHierarchyNode>{}; | 570 <ClassElement, ClassHierarchyNode>{}; |
| 534 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; | 571 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; |
| 535 | 572 |
| 573 final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache = | |
| 574 <ClassElement, Map<ClassElement, bool>>{}; | |
| 575 | |
| 536 final Set<Element> sideEffectsFreeElements = new Set<Element>(); | 576 final Set<Element> sideEffectsFreeElements = new Set<Element>(); |
| 537 | 577 |
| 538 final Set<Element> elementsThatCannotThrow = new Set<Element>(); | 578 final Set<Element> elementsThatCannotThrow = new Set<Element>(); |
| 539 | 579 |
| 540 final Set<Element> functionsThatMightBePassedToApply = | 580 final Set<Element> functionsThatMightBePassedToApply = |
| 541 new Set<FunctionElement>(); | 581 new Set<FunctionElement>(); |
| 542 | 582 |
| 543 final Set<Element> alreadyPopulated; | 583 final Set<Element> alreadyPopulated; |
| 544 | 584 |
| 545 bool get isClosed => compiler.phase > Compiler.PHASE_RESOLVING; | 585 bool get isClosed => compiler.phase > Compiler.PHASE_RESOLVING; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 // function expressions's element. | 875 // function expressions's element. |
| 836 // TODO(herhut): Generate classes for function expressions earlier. | 876 // TODO(herhut): Generate classes for function expressions earlier. |
| 837 if (element is SynthesizedCallMethodElementX) { | 877 if (element is SynthesizedCallMethodElementX) { |
| 838 return getMightBePassedToApply(element.expression); | 878 return getMightBePassedToApply(element.expression); |
| 839 } | 879 } |
| 840 return functionsThatMightBePassedToApply.contains(element); | 880 return functionsThatMightBePassedToApply.contains(element); |
| 841 } | 881 } |
| 842 | 882 |
| 843 bool get hasClosedWorldAssumption => !compiler.options.hasIncrementalSupport; | 883 bool get hasClosedWorldAssumption => !compiler.options.hasIncrementalSupport; |
| 844 } | 884 } |
| OLD | NEW |