Skip to content

Commit

Permalink
Replace ClassElement/FunctionTypeAliasElement.instantiateToBounds() w…
Browse files Browse the repository at this point in the history
…ith TypeSystem.instantiateToBounds2()

Change-Id: I2b1aacc9d72ab444176a2a0e4d6a44d13780e357
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132804
Commit-Queue: Konstantin Shcheglov <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
  • Loading branch information
scheglov authored and [email protected] committed Jan 22, 2020
1 parent 14cb25d commit 0b06a36
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 2 deletions.
7 changes: 7 additions & 0 deletions pkg/analyzer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 2 additions & 0 deletions pkg/analyzer/lib/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand Down Expand Up @@ -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,
});
Expand Down
13 changes: 13 additions & 0 deletions pkg/analyzer/lib/dart/element/type_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions pkg/analyzer/lib/src/dart/element/element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ abstract class AbstractClassElementImpl extends ElementImpl
);
}

@Deprecated('Use TypeSystem.instantiateToBounds2() instead')
@override
InterfaceType instantiateToBounds({
@required NullabilitySuffix nullabilitySuffix,
Expand Down Expand Up @@ -4785,6 +4786,7 @@ class GenericTypeAliasElementImpl extends ElementImpl
);
}

@Deprecated('Use TypeSystem.instantiateToBounds2() instead')
@override
FunctionType instantiateToBounds({
@required NullabilitySuffix nullabilitySuffix,
Expand Down
6 changes: 4 additions & 2 deletions pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
41 changes: 41 additions & 0 deletions pkg/analyzer/lib/src/generated/type_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 0b06a36

Please sign in to comment.