| 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 part of universe; | 5 part of universe; |
| 6 | 6 |
| 7 abstract class PartialTypeTree { | 7 abstract class PartialTypeTree { |
| 8 | |
| 9 final Compiler compiler; | 8 final Compiler compiler; |
| 10 PartialTypeTreeNode root; | 9 PartialTypeTreeNode root; |
| 11 | 10 |
| 12 final Map<ClassElement, PartialTypeTreeNode> nodes = | |
| 13 new Map<ClassElement, PartialTypeTreeNode>(); | |
| 14 | |
| 15 // TODO(kasperl): For now, we keep track of whether or not the tree | |
| 16 // contains two classes with a subtype relationship that isn't a | |
| 17 // subclass relationship. | |
| 18 bool containsInterfaceSubtypes = false; | |
| 19 | |
| 20 final Set<ClassElement> unseenInterfaceSubtypes = | |
| 21 new Set<ClassElement>(); | |
| 22 | |
| 23 PartialTypeTree(this.compiler); | 11 PartialTypeTree(this.compiler); |
| 24 | 12 |
| 25 PartialTypeTreeNode newSpecializedNode(ClassElement type); | 13 PartialTypeTreeNode newNode(ClassElement type); |
| 26 | 14 |
| 27 PartialTypeTreeNode newNode(ClassElement type) { | |
| 28 PartialTypeTreeNode node = newSpecializedNode(type); | |
| 29 nodes[type] = node; | |
| 30 if (containsInterfaceSubtypes) return node; | |
| 31 | |
| 32 // Check if the implied interface of the new class is implemented | |
| 33 // by another class that is already in the tree. | |
| 34 if (unseenInterfaceSubtypes.contains(type)) { | |
| 35 containsInterfaceSubtypes = true; | |
| 36 unseenInterfaceSubtypes.clear(); | |
| 37 return node; | |
| 38 } | |
| 39 | |
| 40 // Run through all the implied interfaces the class that we're | |
| 41 // adding implements and see if any of them are already in the | |
| 42 // tree. If so, we have a tree with interface subtypes. If not, | |
| 43 // keep track of them so we can deal with it if the interface is | |
| 44 // added to the tree later. | |
| 45 for (Link link = type.interfaces; !link.isEmpty; link = link.tail) { | |
| 46 InterfaceType superType = link.head; | |
| 47 ClassElement superTypeElement = superType.element; | |
| 48 if (nodes.containsKey(superTypeElement)) { | |
| 49 containsInterfaceSubtypes = true; | |
| 50 unseenInterfaceSubtypes.clear(); | |
| 51 break; | |
| 52 } else { | |
| 53 unseenInterfaceSubtypes.add(superTypeElement); | |
| 54 } | |
| 55 } | |
| 56 return node; | |
| 57 } | |
| 58 | |
| 59 // TODO(kasperl): Move this to the Selector class? | |
| 60 /** | 15 /** |
| 61 * Returns a [ClassElement] that is an upper bound of the receiver type on | 16 * Returns a [ClassElement] that is an upper bound of the receiver type on |
| 62 * [selector]. | 17 * [selector]. |
| 63 */ | 18 */ |
| 19 // TODO(kasperl): Move this to the Selector class? |
| 64 ClassElement selectorType(Selector selector) { | 20 ClassElement selectorType(Selector selector) { |
| 65 // TODO(ngeoffray): Should the tree be specialized with DartType? | 21 // TODO(ngeoffray): Should the tree be specialized with DartType? |
| 66 DartType type = selector.receiverType; | 22 DartType type = selector.receiverType; |
| 67 if (type == null) return compiler.objectClass; | 23 if (type == null) return compiler.objectClass; |
| 68 // TODO(kasperl): Should [dynamic] return Object? | 24 // TODO(kasperl): Should [dynamic] return Object? |
| 69 if (identical(type.kind, TypeKind.MALFORMED_TYPE)) | 25 if (identical(type.kind, TypeKind.MALFORMED_TYPE)) |
| 70 return compiler.objectClass; | 26 return compiler.objectClass; |
| 71 // TODO(johnniwinther): Change to use [DartType.unalias]. | 27 // TODO(johnniwinther): Change to use [DartType.unalias]. |
| 72 if (type.element.isTypedef()) return compiler.functionClass; | 28 if (type.element.isTypedef()) return compiler.functionClass; |
| 73 return type.element; | 29 return type.element; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 bool visitRecursively(bool visit(PartialTypeTreeNode node)) { | 132 bool visitRecursively(bool visit(PartialTypeTreeNode node)) { |
| 177 if (!visit(this)) return false; | 133 if (!visit(this)) return false; |
| 178 for (Link link = children; !link.isEmpty; link = link.tail) { | 134 for (Link link = children; !link.isEmpty; link = link.tail) { |
| 179 PartialTypeTreeNode child = link.head; | 135 PartialTypeTreeNode child = link.head; |
| 180 if (!child.visitRecursively(visit)) return false; | 136 if (!child.visitRecursively(visit)) return false; |
| 181 } | 137 } |
| 182 return true; | 138 return true; |
| 183 } | 139 } |
| 184 | 140 |
| 185 } | 141 } |
| OLD | NEW |