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 |