| 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) {
|
| + // 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;
|
|
|