Chromium Code Reviews| Index: pkg/compiler/lib/src/ordered_typeset.dart |
| diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart |
| index cd6dd0e7dd843a59122de104d240721727ffe71a..d28539b02b9b883f21c5eb3b658b2a83a6186ae9 100644 |
| --- a/pkg/compiler/lib/src/ordered_typeset.dart |
| +++ b/pkg/compiler/lib/src/ordered_typeset.dart |
| @@ -5,9 +5,9 @@ |
| library ordered_typeset; |
| import 'common.dart'; |
| -import 'compiler.dart' show |
| - Compiler; |
| import 'dart_types.dart'; |
| +import 'diagnostics/diagnostic_listener.dart' show |
| + DiagnosticReporter; |
| import 'elements/elements.dart' show |
| ClassElement; |
| import 'util/util.dart' show |
| @@ -151,39 +151,91 @@ class OrderedTypeSetBuilder { |
| LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>(); |
| int maxDepth = -1; |
| + final DiagnosticReporter reporter; |
| final ClassElement cls; |
| + InterfaceType _objectType; |
| - OrderedTypeSetBuilder(this.cls); |
| - void add(Compiler compiler, InterfaceType type) { |
| + OrderedTypeSetBuilder(this.cls, {this.reporter, InterfaceType objectType}) |
| + : this._objectType = objectType; |
| + |
| + OrderedTypeSet createOrderedTypeSet( |
| + InterfaceType supertype, |
| + Link<DartType> interfaces) { |
| + |
| + if (_objectType == null) { |
|
Siggi Cherem (dart-lang)
2016/03/18 20:23:13
it's a bit strange to always recompute object...
Johnni Winther
2016/03/29 08:28:53
Adding a TODO.
|
| + // Find `Object` through in hierarchy. This is used for serialization |
| + // where it is assumed that the hierarchy is valid. |
| + _objectType = supertype; |
| + while (!_objectType.isObject) { |
| + _objectType = _objectType.element.supertype; |
| + } |
| + } |
| + |
| + // TODO(15296): Collapse these iterations to one when the order is not |
| + // needed. |
| + add(supertype); |
| + for (Link<DartType> link = interfaces; !link.isEmpty; link = link.tail) { |
| + add(link.head); |
| + } |
| + |
| + addAllSupertypes(supertype); |
| + for (Link<DartType> link = interfaces; !link.isEmpty; link = link.tail) { |
| + addAllSupertypes(link.head); |
| + } |
| + add(cls.thisType); |
| + return toTypeSet(); |
| + } |
| + |
| + /** |
| + * Adds [type] and all supertypes of [type] to [allSupertypes] while |
| + * substituting type variables. |
| + */ |
| + void addAllSupertypes(InterfaceType type) { |
| + ClassElement classElement = type.element; |
| + Link<DartType> supertypes = classElement.allSupertypes; |
| + assert(invariant(cls, supertypes != null, |
| + message: "Supertypes not computed on $classElement " |
| + "during resolution of $cls")); |
| + while (!supertypes.isEmpty) { |
| + DartType supertype = supertypes.head; |
| + add(supertype.substByContext(type)); |
| + supertypes = supertypes.tail; |
| + } |
| + } |
| + |
| + void add(InterfaceType type) { |
| if (type.element == cls) { |
| - if (type.element != compiler.coreClasses.objectClass) { |
| - allSupertypes.addLast(compiler.coreTypes.objectType); |
| + if (type != _objectType) { |
| + allSupertypes.addLast(_objectType); |
| } |
| - DiagnosticReporter reporter = compiler.reporter; |
| - _addAtDepth(reporter, type, maxDepth + 1); |
| + _addAtDepth(type, maxDepth + 1); |
| } else { |
| - if (type.element != compiler.coreClasses.objectClass) { |
| + if (type != _objectType) { |
| allSupertypes.addLast(type); |
| } |
| - DiagnosticReporter reporter = compiler.reporter; |
| - _addAtDepth(reporter, type, type.element.hierarchyDepth); |
| + _addAtDepth(type, type.element.hierarchyDepth); |
| } |
| } |
| - void _addAtDepth(DiagnosticReporter reporter, InterfaceType type, int depth) { |
| + void _addAtDepth(InterfaceType type, int depth) { |
| LinkEntry<DartType> prev = null; |
| LinkEntry<DartType> link = map[depth]; |
| while (link != null) { |
| DartType existingType = link.head; |
| if (existingType == type) return; |
| if (existingType.element == type.element) { |
| - reporter.reportErrorMessage( |
| - cls, |
| - MessageKind.MULTI_INHERITANCE, |
| - {'thisType': cls.thisType, |
| - 'firstType': existingType, |
| - 'secondType': type}); |
| + if (reporter != null) { |
| + reporter.reportErrorMessage( |
| + cls, |
| + MessageKind.MULTI_INHERITANCE, |
| + {'thisType': cls.thisType, |
| + 'firstType': existingType, |
| + 'secondType': type}); |
| + } else { |
| + assert(invariant(cls, false, |
| + message: 'Invalid ordered typeset for $cls')); |
| + } |
| return; |
| } |
| prev = link; |