OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 ordered_typeset; | 5 library ordered_typeset; |
6 | 6 |
7 import 'common.dart'; | 7 import 'common.dart'; |
8 import 'dart_types.dart'; | 8 import 'dart_types.dart'; |
9 import 'diagnostics/diagnostic_listener.dart' show | 9 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter; |
10 DiagnosticReporter; | 10 import 'elements/elements.dart' show ClassElement; |
11 import 'elements/elements.dart' show | 11 import 'util/util.dart' show Link, LinkBuilder; |
12 ClassElement; | 12 import 'util/util_implementation.dart' show LinkEntry; |
13 import 'util/util.dart' show | |
14 Link, | |
15 LinkBuilder; | |
16 import 'util/util_implementation.dart' show | |
17 LinkEntry; | |
18 | 13 |
19 /** | 14 /** |
20 * An ordered set of the supertypes of a class. The supertypes of a class are | 15 * An ordered set of the supertypes of a class. The supertypes of a class are |
21 * ordered by decreasing hierarchy depth and by the order they are extended, | 16 * ordered by decreasing hierarchy depth and by the order they are extended, |
22 * mixed in, or implemented. | 17 * mixed in, or implemented. |
23 * | 18 * |
24 * For these classes | 19 * For these classes |
25 * | 20 * |
26 * class A {} // Depth = 1. | 21 * class A {} // Depth = 1. |
27 * class B {} // Depth = 1. | 22 * class B {} // Depth = 1. |
28 * class C extends B implements A {} // Depth 2. | 23 * class C extends B implements A {} // Depth 2. |
29 * | 24 * |
30 * the ordered supertypes are | 25 * the ordered supertypes are |
31 * | 26 * |
32 * A: [A, Object] | 27 * A: [A, Object] |
33 * B: [B, Object] | 28 * B: [B, Object] |
34 * C: [C, B, A, Object] | 29 * C: [C, B, A, Object] |
35 */ | 30 */ |
36 class OrderedTypeSet { | 31 class OrderedTypeSet { |
37 final List<Link<DartType>> _levels; | 32 final List<Link<DartType>> _levels; |
38 final Link<DartType> types; | 33 final Link<DartType> types; |
39 final Link<DartType> _supertypes; | 34 final Link<DartType> _supertypes; |
40 | 35 |
41 OrderedTypeSet.internal(List<Link<DartType>> this._levels, | 36 OrderedTypeSet.internal(List<Link<DartType>> this._levels, |
42 Link<DartType> this.types, | 37 Link<DartType> this.types, Link<DartType> this._supertypes); |
43 Link<DartType> this._supertypes); | |
44 | 38 |
45 factory OrderedTypeSet.singleton(DartType type) { | 39 factory OrderedTypeSet.singleton(DartType type) { |
46 Link<DartType> types = | 40 Link<DartType> types = |
47 new LinkEntry<DartType>(type, const Link<DartType>()); | 41 new LinkEntry<DartType>(type, const Link<DartType>()); |
48 List<Link<DartType>> list = new List<Link<DartType>>(1); | 42 List<Link<DartType>> list = new List<Link<DartType>>(1); |
49 list[0] = types; | 43 list[0] = types; |
50 return new OrderedTypeSet.internal(list, types, const Link<DartType>()); | 44 return new OrderedTypeSet.internal(list, types, const Link<DartType>()); |
51 } | 45 } |
52 | 46 |
53 /// Creates a new [OrderedTypeSet] for [type] when it directly extends the | 47 /// Creates a new [OrderedTypeSet] for [type] when it directly extends the |
54 /// class which this set represents. This is for instance used to create the | 48 /// class which this set represents. This is for instance used to create the |
55 /// type set for [ClosureClassElement] which extends [Closure]. | 49 /// type set for [ClosureClassElement] which extends [Closure]. |
56 OrderedTypeSet extendClass(InterfaceType type) { | 50 OrderedTypeSet extendClass(InterfaceType type) { |
57 assert(invariant(type.element, types.head.treatAsRaw, | 51 assert(invariant(type.element, types.head.treatAsRaw, |
58 message: 'Cannot extend generic class ${types.head} using ' | 52 message: 'Cannot extend generic class ${types.head} using ' |
59 'OrderedTypeSet.extendClass')); | 53 'OrderedTypeSet.extendClass')); |
60 Link<DartType> extendedTypes = | 54 Link<DartType> extendedTypes = new LinkEntry<DartType>(type, types); |
61 new LinkEntry<DartType>(type, types); | |
62 List<Link<DartType>> list = new List<Link<DartType>>(levels + 1); | 55 List<Link<DartType>> list = new List<Link<DartType>>(levels + 1); |
63 for (int i = 0; i < levels; i++) { | 56 for (int i = 0; i < levels; i++) { |
64 list[i] = _levels[i]; | 57 list[i] = _levels[i]; |
65 } | 58 } |
66 list[levels] = extendedTypes; | 59 list[levels] = extendedTypes; |
67 return new OrderedTypeSet.internal( | 60 return new OrderedTypeSet.internal( |
68 list, extendedTypes, _supertypes.prepend(types.head)); | 61 list, extendedTypes, _supertypes.prepend(types.head)); |
69 } | 62 } |
70 | 63 |
71 Link<DartType> get supertypes => _supertypes; | 64 Link<DartType> get supertypes => _supertypes; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 final DiagnosticReporter reporter; | 147 final DiagnosticReporter reporter; |
155 final ClassElement cls; | 148 final ClassElement cls; |
156 InterfaceType _objectType; | 149 InterfaceType _objectType; |
157 | 150 |
158 // TODO(johnniwinther): Provide access to `Object` in deserialization and | 151 // TODO(johnniwinther): Provide access to `Object` in deserialization and |
159 // make [objectType] mandatory. | 152 // make [objectType] mandatory. |
160 OrderedTypeSetBuilder(this.cls, {this.reporter, InterfaceType objectType}) | 153 OrderedTypeSetBuilder(this.cls, {this.reporter, InterfaceType objectType}) |
161 : this._objectType = objectType; | 154 : this._objectType = objectType; |
162 | 155 |
163 OrderedTypeSet createOrderedTypeSet( | 156 OrderedTypeSet createOrderedTypeSet( |
164 InterfaceType supertype, | 157 InterfaceType supertype, Link<DartType> interfaces) { |
165 Link<DartType> interfaces) { | |
166 | |
167 if (_objectType == null) { | 158 if (_objectType == null) { |
168 // Find `Object` through in hierarchy. This is used for serialization | 159 // Find `Object` through in hierarchy. This is used for serialization |
169 // where it is assumed that the hierarchy is valid. | 160 // where it is assumed that the hierarchy is valid. |
170 _objectType = supertype; | 161 _objectType = supertype; |
171 while (!_objectType.isObject) { | 162 while (!_objectType.isObject) { |
172 _objectType = _objectType.element.supertype; | 163 _objectType = _objectType.element.supertype; |
173 } | 164 } |
174 } | 165 } |
175 | 166 |
176 // TODO(15296): Collapse these iterations to one when the order is not | 167 // TODO(15296): Collapse these iterations to one when the order is not |
(...skipping 13 matching lines...) Expand all Loading... |
190 | 181 |
191 /** | 182 /** |
192 * Adds [type] and all supertypes of [type] to [allSupertypes] while | 183 * Adds [type] and all supertypes of [type] to [allSupertypes] while |
193 * substituting type variables. | 184 * substituting type variables. |
194 */ | 185 */ |
195 void addAllSupertypes(InterfaceType type) { | 186 void addAllSupertypes(InterfaceType type) { |
196 ClassElement classElement = type.element; | 187 ClassElement classElement = type.element; |
197 Link<DartType> supertypes = classElement.allSupertypes; | 188 Link<DartType> supertypes = classElement.allSupertypes; |
198 assert(invariant(cls, supertypes != null, | 189 assert(invariant(cls, supertypes != null, |
199 message: "Supertypes not computed on $classElement " | 190 message: "Supertypes not computed on $classElement " |
200 "during resolution of $cls")); | 191 "during resolution of $cls")); |
201 while (!supertypes.isEmpty) { | 192 while (!supertypes.isEmpty) { |
202 DartType supertype = supertypes.head; | 193 DartType supertype = supertypes.head; |
203 add(supertype.substByContext(type)); | 194 add(supertype.substByContext(type)); |
204 supertypes = supertypes.tail; | 195 supertypes = supertypes.tail; |
205 } | 196 } |
206 } | 197 } |
207 | 198 |
208 void add(InterfaceType type) { | 199 void add(InterfaceType type) { |
209 if (type.element == cls) { | 200 if (type.element == cls) { |
210 if (type != _objectType) { | 201 if (type != _objectType) { |
211 allSupertypes.addLast(_objectType); | 202 allSupertypes.addLast(_objectType); |
212 } | 203 } |
213 _addAtDepth(type, maxDepth + 1); | 204 _addAtDepth(type, maxDepth + 1); |
214 } else { | 205 } else { |
215 if (type != _objectType) { | 206 if (type != _objectType) { |
216 allSupertypes.addLast(type); | 207 allSupertypes.addLast(type); |
217 } | 208 } |
218 _addAtDepth(type, type.element.hierarchyDepth); | 209 _addAtDepth(type, type.element.hierarchyDepth); |
219 } | 210 } |
220 } | 211 } |
221 | 212 |
222 void _addAtDepth(InterfaceType type, int depth) { | 213 void _addAtDepth(InterfaceType type, int depth) { |
223 LinkEntry<DartType> prev = null; | 214 LinkEntry<DartType> prev = null; |
224 LinkEntry<DartType> link = map[depth]; | 215 LinkEntry<DartType> link = map[depth]; |
225 while (link != null) { | 216 while (link != null) { |
226 DartType existingType = link.head; | 217 DartType existingType = link.head; |
227 if (existingType == type) return; | 218 if (existingType == type) return; |
228 if (existingType.element == type.element) { | 219 if (existingType.element == type.element) { |
229 if (reporter != null) { | 220 if (reporter != null) { |
230 reporter.reportErrorMessage( | 221 reporter.reportErrorMessage(cls, MessageKind.MULTI_INHERITANCE, { |
231 cls, | 222 'thisType': cls.thisType, |
232 MessageKind.MULTI_INHERITANCE, | 223 'firstType': existingType, |
233 {'thisType': cls.thisType, | 224 'secondType': type |
234 'firstType': existingType, | 225 }); |
235 'secondType': type}); | |
236 } else { | 226 } else { |
237 assert(invariant(cls, false, | 227 assert(invariant(cls, false, |
238 message: 'Invalid ordered typeset for $cls')); | 228 message: 'Invalid ordered typeset for $cls')); |
239 } | 229 } |
240 return; | 230 return; |
241 } | 231 } |
242 prev = link; | 232 prev = link; |
243 link = link.tail; | 233 link = link.tail; |
244 } | 234 } |
245 LinkEntry<DartType> next = new LinkEntry<DartType>(type); | 235 LinkEntry<DartType> next = new LinkEntry<DartType>(type); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 while (first.tail != null) { | 279 while (first.tail != null) { |
290 sb.write(', ${first.tail.head}'); | 280 sb.write(', ${first.tail.head}'); |
291 first = first.tail; | 281 first = first.tail; |
292 } | 282 } |
293 } | 283 } |
294 sb.write('\n'); | 284 sb.write('\n'); |
295 } | 285 } |
296 return sb.toString(); | 286 return sb.toString(); |
297 } | 287 } |
298 } | 288 } |
OLD | NEW |