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

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

Issue 1758913002: Add instantiate method on ParameterizedType and InterfaceType. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments 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 | « pkg/analyzer/lib/dart/element/type.dart ('k') | pkg/analyzer/lib/src/generated/constant.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/type.dart
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 29658fb7126bbf1e96bae0458cb46394d0259cb7..b0851deffbb7c2dc7bc873217db49c7bd8c28cce 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -731,10 +731,7 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
@override
bool isSubtypeOf(DartType type) {
- return relate(
- this,
- type,
- (DartType t, DartType s) => t.isAssignableTo(s),
+ return relate(this, type, (DartType t, DartType s) => t.isAssignableTo(s),
new TypeSystemImpl().instantiateToBounds);
}
@@ -854,56 +851,6 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
}
/**
- * Given two functions [f1] and [f2] where f1 and f2 are known to be
- * generic function types (both have type formals), this checks that they
- * have the same number of formals, and that those formals have bounds
- * (e.g. `<T extends LowerBound>`) that satisfy [relation].
- *
- * The return value will be a new list of fresh type variables, that can be
- * used to instantiate both function types, allowing further comparison.
- * For example, given `<T>T -> T` and `<U>U -> U` we can instantiate them with
- * `F` to get `F -> F` and `F -> F`, which we can see are equal.
- */
- static List<DartType> relateTypeFormals(
- FunctionType f1, FunctionType f2, bool relation(DartType t, DartType s)) {
- List<TypeParameterElement> params1 = f1.typeFormals;
- List<TypeParameterElement> params2 = f2.typeFormals;
- int count = params1.length;
- if (params2.length != count) {
- return null;
- }
- // We build up a substitution matching up the type parameters
- // from the two types, {variablesFresh/variables1} and
- // {variablesFresh/variables2}
- List<DartType> variables1 = <DartType>[];
- List<DartType> variables2 = <DartType>[];
- List<DartType> variablesFresh = <DartType>[];
- for (int i = 0; i < count; i++) {
- TypeParameterElement p1 = params1[i];
- TypeParameterElement p2 = params2[i];
- TypeParameterElementImpl pFresh =
- new TypeParameterElementImpl.synthetic(p2.name);
-
- DartType variable1 = p1.type;
- DartType variable2 = p2.type;
- DartType variableFresh = new TypeParameterTypeImpl(pFresh);
-
- variables1.add(variable1);
- variables2.add(variable2);
- variablesFresh.add(variableFresh);
- DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
- DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
- bound1 = bound1.substitute2(variablesFresh, variables1);
- bound2 = bound2.substitute2(variablesFresh, variables2);
- pFresh.bound = bound2;
- if (!relation(bound2, bound1)) {
- return null;
- }
- }
- return variablesFresh;
- }
-
- /**
* Compares two function types [t] and [s] to see if their corresponding
* parameter types match [parameterRelation] and their return types match
* [returnRelation].
@@ -920,7 +867,6 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
bool parameterRelation(DartType t, DartType s),
FunctionType instantiateToBounds(FunctionType t),
{bool returnRelation(DartType t, DartType s)}) {
-
returnRelation ??= parameterRelation;
// Trivial base cases.
@@ -1024,6 +970,56 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
}
/**
+ * Given two functions [f1] and [f2] where f1 and f2 are known to be
+ * generic function types (both have type formals), this checks that they
+ * have the same number of formals, and that those formals have bounds
+ * (e.g. `<T extends LowerBound>`) that satisfy [relation].
+ *
+ * The return value will be a new list of fresh type variables, that can be
+ * used to instantiate both function types, allowing further comparison.
+ * For example, given `<T>T -> T` and `<U>U -> U` we can instantiate them with
+ * `F` to get `F -> F` and `F -> F`, which we can see are equal.
+ */
+ static List<DartType> relateTypeFormals(
+ FunctionType f1, FunctionType f2, bool relation(DartType t, DartType s)) {
+ List<TypeParameterElement> params1 = f1.typeFormals;
+ List<TypeParameterElement> params2 = f2.typeFormals;
+ int count = params1.length;
+ if (params2.length != count) {
+ return null;
+ }
+ // We build up a substitution matching up the type parameters
+ // from the two types, {variablesFresh/variables1} and
+ // {variablesFresh/variables2}
+ List<DartType> variables1 = <DartType>[];
+ List<DartType> variables2 = <DartType>[];
+ List<DartType> variablesFresh = <DartType>[];
+ for (int i = 0; i < count; i++) {
+ TypeParameterElement p1 = params1[i];
+ TypeParameterElement p2 = params2[i];
+ TypeParameterElementImpl pFresh =
+ new TypeParameterElementImpl.synthetic(p2.name);
+
+ DartType variable1 = p1.type;
+ DartType variable2 = p2.type;
+ DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+ variables1.add(variable1);
+ variables2.add(variable2);
+ variablesFresh.add(variableFresh);
+ DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+ DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+ bound1 = bound1.substitute2(variablesFresh, variables1);
+ bound2 = bound2.substitute2(variablesFresh, variables2);
+ pFresh.bound = bound2;
+ if (!relation(bound2, bound1)) {
+ return null;
+ }
+ }
+ return variablesFresh;
+ }
+
+ /**
* Return `true` if all of the name/type pairs in the first map ([firstTypes])
* are equal to the corresponding name/type pairs in the second map
* ([secondTypes]). The maps are expected to iterate over their entries in the
@@ -1313,6 +1309,10 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
PropertyAccessorMember.from(element.getSetter(setterName), this);
@override
+ InterfaceTypeImpl instantiate(List<DartType> argumentTypes) =>
+ substitute2(argumentTypes, typeArguments);
+
+ @override
bool isDirectSupertypeOf(InterfaceType type) {
InterfaceType i = this;
InterfaceType j = type;
@@ -1732,9 +1732,10 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
return newType;
}
+ @deprecated
@override
InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
- substitute2(argumentTypes, typeArguments);
+ instantiate(argumentTypes);
/**
* Starting from this type, search its class hierarchy for types of the form
@@ -1827,6 +1828,62 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
_computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
/**
+ * If there is a single type which is at least as specific as all of the
+ * types in [types], return it. Otherwise return `null`.
+ */
+ static DartType findMostSpecificType(
+ List<DartType> types, TypeSystem typeSystem) {
+ // The << relation ("more specific than") is a partial ordering on types,
+ // so to find the most specific type of a set, we keep a bucket of the most
+ // specific types seen so far such that no type in the bucket is more
+ // specific than any other type in the bucket.
+ List<DartType> bucket = <DartType>[];
+
+ // Then we consider each type in turn.
+ for (DartType type in types) {
+ // If any existing type in the bucket is more specific than this type,
+ // then we can ignore this type.
+ if (bucket.any((DartType t) => typeSystem.isMoreSpecificThan(t, type))) {
+ continue;
+ }
+ // Otherwise, we need to add this type to the bucket and remove any types
+ // that are less specific than it.
+ bool added = false;
+ int i = 0;
+ while (i < bucket.length) {
+ if (typeSystem.isMoreSpecificThan(type, bucket[i])) {
+ if (added) {
+ if (i < bucket.length - 1) {
+ bucket[i] = bucket.removeLast();
+ } else {
+ bucket.removeLast();
+ }
+ } else {
+ bucket[i] = type;
+ i++;
+ added = true;
+ }
+ } else {
+ i++;
+ }
+ }
+ if (!added) {
+ bucket.add(type);
+ }
+ }
+
+ // Now that we are finished, if there is exactly one type left in the
+ // bucket, it is the most specific type.
+ if (bucket.length == 1) {
+ return bucket[0];
+ }
+
+ // Otherwise, there is no single type that is more specific than the
+ // others.
+ return null;
+ }
+
+ /**
* Returns a "smart" version of the "least upper bound" of the given types.
*
* If these types have the same element and differ only in terms of the type
@@ -1920,62 +1977,6 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
}
/**
- * If there is a single type which is at least as specific as all of the
- * types in [types], return it. Otherwise return `null`.
- */
- static DartType findMostSpecificType(
- List<DartType> types, TypeSystem typeSystem) {
- // The << relation ("more specific than") is a partial ordering on types,
- // so to find the most specific type of a set, we keep a bucket of the most
- // specific types seen so far such that no type in the bucket is more
- // specific than any other type in the bucket.
- List<DartType> bucket = <DartType>[];
-
- // Then we consider each type in turn.
- for (DartType type in types) {
- // If any existing type in the bucket is more specific than this type,
- // then we can ignore this type.
- if (bucket.any((DartType t) => typeSystem.isMoreSpecificThan(t, type))) {
- continue;
- }
- // Otherwise, we need to add this type to the bucket and remove any types
- // that are less specific than it.
- bool added = false;
- int i = 0;
- while (i < bucket.length) {
- if (typeSystem.isMoreSpecificThan(type, bucket[i])) {
- if (added) {
- if (i < bucket.length - 1) {
- bucket[i] = bucket.removeLast();
- } else {
- bucket.removeLast();
- }
- } else {
- bucket[i] = type;
- i++;
- added = true;
- }
- } else {
- i++;
- }
- }
- if (!added) {
- bucket.add(type);
- }
- }
-
- // Now that we are finished, if there is exactly one type left in the
- // bucket, it is the most specific type.
- if (bucket.length == 1) {
- return bucket[0];
- }
-
- // Otherwise, there is no single type that is more specific than the
- // others.
- return null;
- }
-
- /**
* Return the intersection of the [first] and [second] sets of types, where
* intersection is based on the equality of the types themselves.
*/
@@ -2217,6 +2218,9 @@ abstract class TypeImpl implements DartType {
*/
TypeImpl pruned(List<FunctionTypeAliasElement> prune);
+ @override
+ DartType resolveToBound(DartType objectType) => this;
+
/**
* Return the type resulting from substituting the given [argumentTypes] for
* the given [parameterTypes] in this type.
@@ -2232,9 +2236,6 @@ abstract class TypeImpl implements DartType {
[List<FunctionTypeAliasElement> prune]);
@override
- DartType resolveToBound(DartType objectType) => this;
-
- @override
String toString() {
StringBuffer buffer = new StringBuffer();
appendTo(buffer);
@@ -2372,6 +2373,15 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
@override
+ DartType resolveToBound(DartType objectType) {
+ if (element.bound == null) {
+ return objectType;
+ }
+
+ return element.bound.resolveToBound(objectType);
+ }
+
+ @override
DartType substitute2(
List<DartType> argumentTypes, List<DartType> parameterTypes,
[List<FunctionTypeAliasElement> prune]) {
@@ -2400,15 +2410,6 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
}
return types;
}
-
- @override
- DartType resolveToBound(DartType objectType) {
- if (element.bound == null) {
- return objectType;
- }
-
- return element.bound.resolveToBound(objectType);
- }
}
/**
« no previous file with comments | « pkg/analyzer/lib/dart/element/type.dart ('k') | pkg/analyzer/lib/src/generated/constant.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698