| 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 |