| 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 27510764a1a7f91eb95df17dfebc5fb17e401dd0..06be4dba32a3df6e7deafcf8b7ef4df3142ad786 100644
|
| --- a/pkg/analyzer/lib/src/dart/element/member.dart
|
| +++ b/pkg/analyzer/lib/src/dart/element/member.dart
|
| @@ -908,13 +908,11 @@ class PropertyAccessorMember extends ExecutableMember
|
| * [FunctionType.returnType], and [ParameterMember].
|
| */
|
| class TypeParameterMember extends Member implements TypeParameterElement {
|
| - @override
|
| - final DartType bound;
|
| -
|
| + DartType _bound;
|
| DartType _type;
|
|
|
| TypeParameterMember(
|
| - TypeParameterElement baseElement, DartType definingType, this.bound)
|
| + TypeParameterElement baseElement, DartType definingType, this._bound)
|
| : super(baseElement, definingType) {
|
| _type = new TypeParameterTypeImpl(this);
|
| }
|
| @@ -924,6 +922,9 @@ class TypeParameterMember extends Member implements TypeParameterElement {
|
| super.baseElement as TypeParameterElement;
|
|
|
| @override
|
| + DartType get bound => _bound;
|
| +
|
| + @override
|
| Element get enclosingElement => baseElement.enclosingElement;
|
|
|
| @override
|
| @@ -943,19 +944,41 @@ class TypeParameterMember extends Member implements TypeParameterElement {
|
| * the given parameter. Return the member that was created, or the base
|
| * parameter if no member was created.
|
| */
|
| - static TypeParameterElement from(
|
| - TypeParameterElement parameter, ParameterizedType definingType) {
|
| - if (parameter?.bound == null || definingType.typeArguments.isEmpty) {
|
| - return parameter;
|
| - }
|
| -
|
| - DartType bound = parameter.bound;
|
| + static List<TypeParameterElement> from(
|
| + List<TypeParameterElement> formals, FunctionType definingType) {
|
| List<DartType> argumentTypes = definingType.typeArguments;
|
| + if (argumentTypes.isEmpty) {
|
| + return formals;
|
| + }
|
| List<DartType> parameterTypes =
|
| TypeParameterTypeImpl.getTypes(definingType.typeParameters);
|
| - DartType substitutedBound =
|
| - bound.substitute2(argumentTypes, parameterTypes);
|
| - return new TypeParameterMember(parameter, definingType, substitutedBound);
|
| +
|
| + // Create type formals with specialized bounds.
|
| + // For example `<U extends T>` where T comes from an outer scope.
|
| + var results = formals.toList(growable: false);
|
| + for (int i = 0; i < results.length; i++) {
|
| + var formal = results[i];
|
| + DartType bound = formal?.bound;
|
| + if (bound != null) {
|
| + // substitute type arguments from the function.
|
| + bound = bound.substitute2(argumentTypes, parameterTypes);
|
| + results[i] = new TypeParameterMember(formal, definingType, bound);
|
| + }
|
| + }
|
| + List<TypeParameterType> formalTypes =
|
| + TypeParameterTypeImpl.getTypes(formals);
|
| + for (var formal in results) {
|
| + if (formal is TypeParameterMember) {
|
| + // Recursive bounds are allowed too, so make sure these are updated
|
| + // to refer to any new TypeParameterMember we just made, rather than
|
| + // the original type parameter
|
| + // TODO(jmesserly): this is required so substituting for the
|
| + // type formal will work. Investigate if there's a better solution.
|
| + formal._bound = formal.bound
|
| + .substitute2(TypeParameterTypeImpl.getTypes(results), formalTypes);
|
| + }
|
| + }
|
| + return results;
|
| }
|
| }
|
|
|
|
|