Index: pkg/analyzer/lib/src/dart/element/type.dart |
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart |
index 8d6aec0a5357e32d1dfde221bcc0d193a0b417d7..22a247ab3bfa0a509ded516f0a674157829c7ce6 100644 |
--- a/pkg/analyzer/lib/src/dart/element/type.dart |
+++ b/pkg/analyzer/lib/src/dart/element/type.dart |
@@ -927,6 +927,39 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType { |
} |
/** |
+ * Given a generic function type [g] and an instantiated function type [f], |
+ * find a list of type arguments TArgs such that `g<TArgs> == f`, |
+ * and return TArgs. |
+ * |
+ * This function must be called with type [f] that was instantiated from [g]. |
+ */ |
+ static Iterable<DartType> recoverTypeArguments( |
Jennifer Messerly
2016/06/22 23:58:06
Moved from DDC:
https://github.com/dart-lang/dev_
|
+ FunctionType g, FunctionType f) { |
+ // TODO(jmesserly): perhaps a better design here would be: instead of |
+ // recording staticInvokeType on InvocationExpression, we could record the |
+ // instantiated type arguments, that way we wouldn't need to recover them. |
+ // |
+ // For now though, this is a pretty quick operation. |
+ assert(identical(g.element, f.element)); |
+ assert(g.typeFormals.isNotEmpty && f.typeFormals.isEmpty); |
+ assert(g.typeFormals.length + g.typeArguments.length == |
+ f.typeArguments.length); |
+ |
+ // Instantiation in Analyzer works like this: |
+ // Given: |
+ // {U/T} <S> T -> S |
+ // Where {U/T} represents the typeArguments (U) and typeParameters (T) list, |
+ // and <S> represents the typeFormals. |
+ // |
+ // Now instantiate([V]), and the result should be: |
+ // {U/T, V/S} T -> S. |
+ // |
+ // Therefore, we can recover the typeArguments from our instantiated |
+ // function. |
+ return f.typeArguments.skip(g.typeArguments.length); |
+ } |
+ |
+ /** |
* Compares two function types [t] and [s] to see if their corresponding |
* parameter types match [parameterRelation] and their return types match |
* [returnRelation]. |