Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Unified Diff: pkg/analyzer/lib/src/dart/element/member.dart

Issue 1685273002: fixes #25740, substitute type parameter bound taking into account outer scope type params (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/type.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 f3689e4dbcbf4106dd7a01bf4194dad3c66b327c..558b5ec160130ed6488711b4b2b6ddd9ad849e26 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -901,6 +901,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(
+ 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.
*/
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/dart/element/type.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698