Replace ClassElement/FunctionTypeAliasElement.instantiateToBounds() with TypeSystem.instantiateToBounds2()

Change-Id: I2b1aacc9d72ab444176a2a0e4d6a44d13780e357
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132804
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov
2020-01-22 18:38:48 +00:00
committed by commit-bot@chromium.org
parent 14cb25d095
commit 0b06a369de
6 changed files with 69 additions and 2 deletions
+7
View File
@@ -1,3 +1,10 @@
## 0.39.5-dev
* Deprecated `ClassElement.instantiateToBounds()` and
`FunctionTypeAliasElement.instantiateToBounds()`. With the null-safety
feature, type arguments derived from type parameter bounds cannot be used as
is, and might require erasing nullability, when the element is instantiated
from a legacy library. Use `TypeSystem.instantiateToBounds2()` instead.
## 0.39.4
* Deprecated `DartType.name`, use `element` or `getDisplayString()` instead.
* Fixed bugs 35108 and 39996.
@@ -232,6 +232,7 @@ abstract class ClassElement
/// Create the [InterfaceType] for this class with type arguments that
/// correspond to the bounds of the type parameters, and the given
/// [nullabilitySuffix].
@Deprecated('Use TypeSystem.instantiateToBounds2() instead')
InterfaceType instantiateToBounds({
@required NullabilitySuffix nullabilitySuffix,
});
@@ -1191,6 +1192,7 @@ abstract class FunctionTypeAliasElement
/// generic function, with type formals. For example, if the typedef is:
/// typedef F<T> = void Function<U>(T, U);
/// then `F<int>` will produce `void Function<U>(int, U)`.
@Deprecated('Use TypeSystem.instantiateToBounds2() instead')
FunctionType instantiateToBounds({
@required NullabilitySuffix nullabilitySuffix,
});
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:meta/meta.dart';
@@ -33,6 +35,17 @@ abstract class TypeSystem {
/// Other type systems may define this operation differently.
DartType flatten(DartType type);
/// Instantiate the given generic element using the type arguments that
/// correspond to the bounds of its type parameters.
///
/// One and only one of [classElement] or [functionTypeAliasElement] must
/// be provided.
DartType instantiateToBounds2({
ClassElement classElement,
FunctionTypeAliasElement functionTypeAliasElement,
@required NullabilitySuffix nullabilitySuffix,
});
/// Return `true` if the [leftType] is assignable to the [rightType].
///
/// For the Dart 2.0 type system, the definition of this relationship is given
@@ -207,6 +207,7 @@ abstract class AbstractClassElementImpl extends ElementImpl
);
}
@Deprecated('Use TypeSystem.instantiateToBounds2() instead')
@override
InterfaceType instantiateToBounds({
@required NullabilitySuffix nullabilitySuffix,
@@ -4785,6 +4786,7 @@ class GenericTypeAliasElementImpl extends ElementImpl
);
}
@Deprecated('Use TypeSystem.instantiateToBounds2() instead')
@override
FunctionType instantiateToBounds({
@required NullabilitySuffix nullabilitySuffix,
@@ -358,13 +358,15 @@ class TypeNameResolver {
return _inferRedirectedConstructor(element);
}
return element.instantiateToBounds(
return typeSystem.instantiateToBounds2(
classElement: element,
nullabilitySuffix: nullability,
);
} else if (element is DynamicElementImpl) {
return DynamicTypeImpl.instance;
} else if (element is FunctionTypeAliasElement) {
return element.instantiateToBounds(
return typeSystem.instantiateToBounds2(
functionTypeAliasElement: element,
nullabilitySuffix: nullability,
);
} else if (element is NeverElementImpl) {
@@ -715,6 +715,31 @@ class Dart2TypeSystem extends TypeSystem {
return instantiateType(type, arguments);
}
@override
DartType instantiateToBounds2({
ClassElement classElement,
FunctionTypeAliasElement functionTypeAliasElement,
@required NullabilitySuffix nullabilitySuffix,
}) {
if (classElement != null) {
var typeParameters = classElement.typeParameters;
var typeArguments = _defaultTypeArguments(typeParameters);
return classElement.instantiate(
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
);
} else if (functionTypeAliasElement != null) {
var typeParameters = functionTypeAliasElement.typeParameters;
var typeArguments = _defaultTypeArguments(typeParameters);
return functionTypeAliasElement.instantiate(
typeArguments: typeArguments,
nullabilitySuffix: nullabilitySuffix,
);
} else {
throw ArgumentError('Missing element');
}
}
/**
* Given uninstantiated [typeFormals], instantiate them to their bounds.
* See the issue for the algorithm description.
@@ -1761,6 +1786,17 @@ class Dart2TypeSystem extends TypeSystem {
return null;
}
List<DartType> _defaultTypeArguments(
List<TypeParameterElement> typeParameters,
) {
return typeParameters.map((typeParameter) {
var typeParameterImpl = typeParameter as TypeParameterElementImpl;
var typeArgument = typeParameterImpl.defaultType;
typeArgument = _toLegacyType(typeArgument);
return typeArgument;
}).toList();
}
/**
* Eliminates type variables from the context [type], replacing them with
* `Null` or `Object` as appropriate.
@@ -2255,6 +2291,11 @@ class Dart2TypeSystem extends TypeSystem {
return false;
}
DartType _toLegacyType(DartType type) {
if (isNonNullableByDefault) return type;
return NullabilityEliminator.perform(typeProvider, type);
}
DartType _typeParameterResolveToObjectBounds(DartType type) {
var element = type.element;
type = type.resolveToBound(typeProvider.objectType);