Index: pkg/analyzer/lib/src/dart/element/member.dart |
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart |
index 57cbcb91d44f57a45c2e3d724f8121d0f185176d..35062911f0a1a9118d9bfb0b544f22dc85075b54 100644 |
--- a/pkg/analyzer/lib/src/dart/element/member.dart |
+++ b/pkg/analyzer/lib/src/dart/element/member.dart |
@@ -898,6 +898,68 @@ class PropertyAccessorMember extends ExecutableMember |
} |
/** |
+ * A type parameter defined inside of another parameterized type, where the |
+ * values of the enclosing type parameters are known. |
+ * |
+ * For example: |
+ * |
+ * class C<T> { |
+ * S m<S extends T>(S s); |
+ * } |
+ * |
+ * If we have `C<num>.m` and we ask for the type parameter "S", we should get |
+ * `<S extends num>` instead of `<S extends T>`. This is how the parameter |
+ * and return types work, see: [FunctionType.parameters], |
+ * [FunctionType.returnType], and [ParameterMember]. |
+ */ |
+class TypeParameterMember extends Member implements TypeParameterElement { |
+ @override |
+ final DartType bound; |
+ |
+ TypeParameterMember( |
+ TypeParameterElement baseElement, DartType definingType, this.bound) |
+ : super(baseElement, definingType); |
+ |
+ @override |
+ TypeParameterElement get baseElement => |
+ super.baseElement as TypeParameterElement; |
+ |
+ @override |
+ Element get enclosingElement => baseElement.enclosingElement; |
+ |
+ @override |
+ TypeParameterType get type => baseElement.type; |
+ |
+ @override |
+ accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this); |
+ |
+ /** |
+ * If the given [parameter]'s type is different when any type parameters from |
+ * the defining type's declaration are replaced with the actual type |
+ * arguments from the [definingType], create a parameter member representing |
+ * the given parameter. Return the member that was created, or the base |
+ * parameter if no member was created. |
+ */ |
+ static TypeParameterElement from( |
Brian Wilkerson
2016/02/10 22:55:46
nit: I think our sorter sorts static methods to th
Jennifer Messerly
2016/02/11 20:13:16
Hmmm. It seems to think the file is already sorted
|
+ TypeParameterElement parameter, ParameterizedType definingType) { |
+ if (parameter?.bound == null || definingType.typeArguments.isEmpty) { |
+ return parameter; |
+ } |
+ |
+ DartType bound = parameter.bound; |
+ List<DartType> argumentTypes = definingType.typeArguments; |
+ List<DartType> parameterTypes = |
+ TypeParameterTypeImpl.getTypes(definingType.typeParameters); |
+ DartType substitutedBound = |
+ bound.substitute2(argumentTypes, parameterTypes); |
+ if (bound == substitutedBound) { |
+ return parameter; |
+ } |
+ return new TypeParameterMember(parameter, definingType, substitutedBound); |
+ } |
+} |
+ |
+/** |
* A variable element defined in a parameterized type where the values of the |
* type parameters are known. |
*/ |