| Index: pkg/analyzer/lib/src/generated/type_system.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
|
| index 940ee83c5ef5dffe18db9aee9a9083c89518fb2c..ff70e899be87bccc9ba815f3379da9b8c0c10d17 100644
|
| --- a/pkg/analyzer/lib/src/generated/type_system.dart
|
| +++ b/pkg/analyzer/lib/src/generated/type_system.dart
|
| @@ -24,8 +24,6 @@ typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
|
| class StrongTypeSystemImpl extends TypeSystem {
|
| final _specTypeSystem = new TypeSystemImpl();
|
|
|
| - StrongTypeSystemImpl();
|
| -
|
| bool anyParameterType(FunctionType ft, bool predicate(DartType t)) {
|
| return ft.parameters.any((p) => predicate(p.type));
|
| }
|
| @@ -509,6 +507,47 @@ abstract class TypeSystem {
|
| bool isSubtypeOf(DartType leftType, DartType rightType);
|
|
|
| /**
|
| + * Searches the superinterfaces of [type] for implementations of [genericType]
|
| + * and returns the most specific type argument used for that generic type.
|
| + *
|
| + * For example, given [type] `List<int>` and [genericType] `Iterable<T>`,
|
| + * returns [int].
|
| + *
|
| + * Returns `null` if [type] does not implement [genericType].
|
| + */
|
| + // TODO(jmesserly): this is very similar to code used for flattening futures.
|
| + // The only difference is, because of a lack of TypeProvider, the other method
|
| + // has to match the Future type by its name and library. Here was are passed
|
| + // in the correct type.
|
| + DartType mostSpecificTypeArgument(DartType type, DartType genericType) {
|
| + if (type is! InterfaceType) return null;
|
| +
|
| + // Walk the superinterface hierarchy looking for [genericType].
|
| + List<DartType> candidates = <DartType>[];
|
| + HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
|
| + void recurse(InterfaceTypeImpl interface) {
|
| + if (interface.element == genericType.element &&
|
| + interface.typeArguments.isNotEmpty) {
|
| + candidates.add(interface.typeArguments[0]);
|
| + }
|
| + if (visitedClasses.add(interface.element)) {
|
| + if (interface.superclass != null) {
|
| + recurse(interface.superclass);
|
| + }
|
| + interface.mixins.forEach(recurse);
|
| + interface.interfaces.forEach(recurse);
|
| + visitedClasses.remove(interface.element);
|
| + }
|
| + }
|
| +
|
| + recurse(type);
|
| +
|
| + // Since the interface may be implemented multiple times with different
|
| + // type arguments, choose the best one.
|
| + return InterfaceTypeImpl.findMostSpecificType(candidates, this);
|
| + }
|
| +
|
| + /**
|
| * Given a [DartType] type, return the [TypeParameterElement]s corresponding
|
| * to its formal type parameters (if any).
|
| *
|
|
|