| 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 | 7 import 'closure.dart' show |
| 8 SynthesizedCallMethodElementX; | 8 SynthesizedCallMethodElementX; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'common/backend_api.dart' show | 10 import 'common/backend_api.dart' show |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 | 55 |
| 56 /// The [ClassElement] for the [int] class defined in 'dart:core'. | 56 /// The [ClassElement] for the [int] class defined in 'dart:core'. |
| 57 ClassElement get intClass; | 57 ClassElement get intClass; |
| 58 | 58 |
| 59 /// The [ClassElement] for the [double] class defined in 'dart:core'. | 59 /// The [ClassElement] for the [double] class defined in 'dart:core'. |
| 60 ClassElement get doubleClass; | 60 ClassElement get doubleClass; |
| 61 | 61 |
| 62 /// The [ClassElement] for the [String] class defined in 'dart:core'. | 62 /// The [ClassElement] for the [String] class defined in 'dart:core'. |
| 63 ClassElement get stringClass; | 63 ClassElement get stringClass; |
| 64 | 64 |
| 65 /// Returns `true` if [cls] is instantiated. | 65 /// Returns `true` if [cls] is either directly or indirectly instantiated. |
| 66 bool isInstantiated(ClassElement cls); | 66 bool isInstantiated(ClassElement cls); |
| 67 | 67 |
| 68 /// Returns `true` if [cls] is directly instantiated. |
| 69 bool isDirectlyInstantiated(ClassElement cls); |
| 70 |
| 71 /// Returns `true` if [cls] is indirectly instantiated, that is through a |
| 72 /// subclass. |
| 73 bool isIndirectlyInstantiated(ClassElement cls); |
| 74 |
| 68 /// Returns `true` if [cls] is implemented by an instantiated class. | 75 /// Returns `true` if [cls] is implemented by an instantiated class. |
| 69 bool isImplemented(ClassElement cls); | 76 bool isImplemented(ClassElement cls); |
| 70 | 77 |
| 71 /// Returns `true` if the class world is closed. | 78 /// Returns `true` if the class world is closed. |
| 72 bool get isClosed; | 79 bool get isClosed; |
| 73 | 80 |
| 74 /// Return `true` if [x] is a subclass of [y]. | 81 /// Return `true` if [x] is a subclass of [y]. |
| 75 bool isSubclassOf(ClassElement x, ClassElement y); | 82 bool isSubclassOf(ClassElement x, ClassElement y); |
| 76 | 83 |
| 77 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an | 84 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an |
| (...skipping 21 matching lines...) Expand all Loading... |
| 99 | 106 |
| 100 /// Returns `true` if any live class other than [cls] extends [cls]. | 107 /// Returns `true` if any live class other than [cls] extends [cls]. |
| 101 bool hasAnyStrictSubclass(ClassElement cls); | 108 bool hasAnyStrictSubclass(ClassElement cls); |
| 102 | 109 |
| 103 /// Returns `true` if any live class other than [cls] implements [cls]. | 110 /// Returns `true` if any live class other than [cls] implements [cls]. |
| 104 bool hasAnyStrictSubtype(ClassElement cls); | 111 bool hasAnyStrictSubtype(ClassElement cls); |
| 105 | 112 |
| 106 /// Returns `true` if all live classes that implement [cls] extend it. | 113 /// Returns `true` if all live classes that implement [cls] extend it. |
| 107 bool hasOnlySubclasses(ClassElement cls); | 114 bool hasOnlySubclasses(ClassElement cls); |
| 108 | 115 |
| 116 /// Returns the most specific subclass of [cls] (including [cls]) that is |
| 117 /// directly instantiated or a superclass of all directly instantiated |
| 118 /// subclasses. If [cls] is not instantiated, `null` is returned. |
| 119 ClassElement getLeastUpperInstantiatedSubclass(ClassElement cls); |
| 120 |
| 121 /// Returns the most specific subtype of [cls] (including [cls]) that is |
| 122 /// directly instantiated or a superclass of all directly instantiated |
| 123 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. |
| 124 ClassElement getLeastUpperInstantiatedSubtype(ClassElement cls); |
| 125 |
| 109 /// Returns an iterable over the common supertypes of the [classes]. | 126 /// Returns an iterable over the common supertypes of the [classes]. |
| 110 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes); | 127 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes); |
| 111 | 128 |
| 112 /// Returns an iterable over the live mixin applications that mixin [cls]. | 129 /// Returns an iterable over the live mixin applications that mixin [cls]. |
| 113 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls); | 130 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls); |
| 114 | 131 |
| 115 /// Returns `true` if [cls] is mixed into a live class. | 132 /// Returns `true` if [cls] is mixed into a live class. |
| 116 bool isUsedAsMixin(ClassElement cls); | 133 bool isUsedAsMixin(ClassElement cls); |
| 117 | 134 |
| 118 /// Returns `true` if any live class that mixes in [cls] implements [type]. | 135 /// Returns `true` if any live class that mixes in [cls] implements [type]. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 | 200 |
| 184 if (y == objectClass) return true; | 201 if (y == objectClass) return true; |
| 185 if (x == objectClass) return false; | 202 if (x == objectClass) return false; |
| 186 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { | 203 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { |
| 187 if (x == y) return true; | 204 if (x == y) return true; |
| 188 x = x.superclass; | 205 x = x.superclass; |
| 189 } | 206 } |
| 190 return false; | 207 return false; |
| 191 } | 208 } |
| 192 | 209 |
| 193 /// Returns `true` if [cls] is instantiated either directly or through a | 210 @override |
| 194 /// subclass. | |
| 195 bool isInstantiated(ClassElement cls) { | 211 bool isInstantiated(ClassElement cls) { |
| 196 return compiler.resolverWorld.isInstantiated(cls); | 212 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| 213 return node != null && node.isInstantiated; |
| 214 } |
| 215 |
| 216 @override |
| 217 bool isDirectlyInstantiated(ClassElement cls) { |
| 218 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| 219 return node != null && node.isDirectlyInstantiated; |
| 220 } |
| 221 |
| 222 @override |
| 223 bool isIndirectlyInstantiated(ClassElement cls) { |
| 224 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; |
| 225 return node != null && node.isIndirectlyInstantiated; |
| 197 } | 226 } |
| 198 | 227 |
| 199 /// Returns `true` if [cls] is implemented by an instantiated class. | 228 /// Returns `true` if [cls] is implemented by an instantiated class. |
| 200 bool isImplemented(ClassElement cls) { | 229 bool isImplemented(ClassElement cls) { |
| 201 return compiler.resolverWorld.isImplemented(cls); | 230 return compiler.resolverWorld.isImplemented(cls); |
| 202 } | 231 } |
| 203 | 232 |
| 204 /// Returns an iterable over the directly instantiated classes that extend | 233 /// Returns an iterable over the directly instantiated classes that extend |
| 205 /// [cls] possibly including [cls] itself, if it is live. | 234 /// [cls] possibly including [cls] itself, if it is live. |
| 206 Iterable<ClassElement> subclassesOf(ClassElement cls) { | 235 Iterable<ClassElement> subclassesOf(ClassElement cls) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 | 309 |
| 281 /// Returns `true` if all directly instantiated classes that implement [cls] | 310 /// Returns `true` if all directly instantiated classes that implement [cls] |
| 282 /// extend it. | 311 /// extend it. |
| 283 bool hasOnlySubclasses(ClassElement cls) { | 312 bool hasOnlySubclasses(ClassElement cls) { |
| 284 Iterable<ClassElement> subtypes = strictSubtypesOf(cls); | 313 Iterable<ClassElement> subtypes = strictSubtypesOf(cls); |
| 285 if (subtypes == null) return true; | 314 if (subtypes == null) return true; |
| 286 Iterable<ClassElement> subclasses = strictSubclassesOf(cls); | 315 Iterable<ClassElement> subclasses = strictSubclassesOf(cls); |
| 287 return subclasses != null && (subclasses.length == subtypes.length); | 316 return subclasses != null && (subclasses.length == subtypes.length); |
| 288 } | 317 } |
| 289 | 318 |
| 319 @override |
| 320 ClassElement getLeastUpperInstantiatedSubclass(ClassElement cls) { |
| 321 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; |
| 322 return hierarchy != null |
| 323 ? hierarchy.getLeastUpperInstantiatedSubclass() : null; |
| 324 } |
| 325 |
| 326 @override |
| 327 ClassElement getLeastUpperInstantiatedSubtype(ClassElement cls) { |
| 328 ClassSet classSet = _classSets[cls.declaration]; |
| 329 return classSet != null |
| 330 ? classSet.getLeastUpperInstantiatedSubtype() : null; |
| 331 } |
| 332 |
| 290 /// Returns an iterable over the common supertypes of the [classes]. | 333 /// Returns an iterable over the common supertypes of the [classes]. |
| 291 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { | 334 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { |
| 292 Iterator<ClassElement> iterator = classes.iterator; | 335 Iterator<ClassElement> iterator = classes.iterator; |
| 293 if (!iterator.moveNext()) return const <ClassElement>[]; | 336 if (!iterator.moveNext()) return const <ClassElement>[]; |
| 294 | 337 |
| 295 ClassElement cls = iterator.current; | 338 ClassElement cls = iterator.current; |
| 296 assert(checkInvariants(cls)); | 339 assert(checkInvariants(cls)); |
| 297 OrderedTypeSet typeSet = cls.allSupertypesAndSelf; | 340 OrderedTypeSet typeSet = cls.allSupertypesAndSelf; |
| 298 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); | 341 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); |
| 299 | 342 |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 }); | 535 }); |
| 493 } | 536 } |
| 494 | 537 |
| 495 void populate() { | 538 void populate() { |
| 496 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` | 539 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
| 497 /// properties of the [ClassHierarchyNode] for [cls]. | 540 /// properties of the [ClassHierarchyNode] for [cls]. |
| 498 void updateClassHierarchyNodeForClass( | 541 void updateClassHierarchyNodeForClass( |
| 499 ClassElement cls, | 542 ClassElement cls, |
| 500 {bool directlyInstantiated: false, | 543 {bool directlyInstantiated: false, |
| 501 bool indirectlyInstantiated: false}) { | 544 bool indirectlyInstantiated: false}) { |
| 502 assert(!directlyInstantiated || isInstantiated(cls)); | |
| 503 ClassHierarchyNode node = getClassHierarchyNode(cls); | 545 ClassHierarchyNode node = getClassHierarchyNode(cls); |
| 504 bool changed = false; | 546 bool changed = false; |
| 505 if (directlyInstantiated && !node.isDirectlyInstantiated) { | 547 if (directlyInstantiated && !node.isDirectlyInstantiated) { |
| 506 node.isDirectlyInstantiated = true; | 548 node.isDirectlyInstantiated = true; |
| 507 changed = true; | 549 changed = true; |
| 508 } | 550 } |
| 509 if (indirectlyInstantiated && !node.isIndirectlyInstantiated) { | 551 if (indirectlyInstantiated && !node.isIndirectlyInstantiated) { |
| 510 node.isIndirectlyInstantiated = true; | 552 node.isIndirectlyInstantiated = true; |
| 511 changed = true; | 553 changed = true; |
| 512 } | 554 } |
| 513 if (changed && cls.superclass != null) { | 555 if (changed && cls.superclass != null) { |
| 514 updateClassHierarchyNodeForClass( | 556 updateClassHierarchyNodeForClass( |
| 515 cls.superclass, indirectlyInstantiated: true); | 557 cls.superclass, indirectlyInstantiated: true); |
| 516 } | 558 } |
| 559 // Ensure that classes implicitly implementing `Function` are in its |
| 560 // subtype set. |
| 561 if (cls != coreClasses.functionClass && |
| 562 cls.implementsFunction(compiler)) { |
| 563 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); |
| 564 subtypeSet.addSubtype(node); |
| 565 } |
| 517 } | 566 } |
| 518 | 567 |
| 519 void addSubtypes(ClassElement cls) { | 568 void addSubtypes(ClassElement cls) { |
| 520 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) { | 569 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) { |
| 521 return; | 570 return; |
| 522 } | 571 } |
| 523 assert(cls.isDeclaration); | 572 assert(cls.isDeclaration); |
| 524 if (!cls.isResolved) { | 573 if (!cls.isResolved) { |
| 525 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); | 574 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); |
| 526 } | 575 } |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 // function expressions's element. | 745 // function expressions's element. |
| 697 // TODO(herhut): Generate classes for function expressions earlier. | 746 // TODO(herhut): Generate classes for function expressions earlier. |
| 698 if (element is SynthesizedCallMethodElementX) { | 747 if (element is SynthesizedCallMethodElementX) { |
| 699 return getMightBePassedToApply(element.expression); | 748 return getMightBePassedToApply(element.expression); |
| 700 } | 749 } |
| 701 return functionsThatMightBePassedToApply.contains(element); | 750 return functionsThatMightBePassedToApply.contains(element); |
| 702 } | 751 } |
| 703 | 752 |
| 704 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; | 753 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; |
| 705 } | 754 } |
| OLD | NEW |