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

Unified Diff: pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart

Issue 2866543002: Implement instantiateToBounds in front_end. (Closed)
Patch Set: Created 3 years, 7 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/front_end/test/fasta/type_inference/type_schema_environment_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index ef01a9f19d18e7a76d8e3867ff4e8ed37f82adca..e8bc2e3518fc7b6b0f58bbbd3837d43aac0e4dce 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -149,6 +149,48 @@ class TypeSchemaEnvironment extends TypeEnvironment {
return const DynamicType();
}
+ /// Given a [DartType] [type], if [type] is an uninstantiated
+ /// parameterized type then instantiate the parameters to their
+ /// bounds. See the issue for the algorithm description.
+ ///
+ /// https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397
+ ///
+ /// TODO(paulberry) Compute lazily and cache.
+ DartType instantiateToBounds(DartType type,
+ {Map<TypeParameter, DartType> knownTypes}) {
+ List<TypeParameter> typeFormals = _typeFormalsAsParameters(type);
+ int count = typeFormals.length;
+ if (count == 0) {
+ return type;
+ }
+ var substitution = <TypeParameter, DartType>{};
+ for (TypeParameter parameter in typeFormals) {
+ // Note: we treat class<T extends Object> as equivalent to class<T>; in
+ // both cases they instantiate to class<dynamic>. See dartbug.com/29561
+ if (_isObjectOrDynamic(parameter.bound)) {
+ substitution[parameter] = const DynamicType();
+ } else {
+ substitution[parameter] = parameter.bound;
+ }
+ }
+ if (knownTypes != null) {
+ type = Substitution.fromMap(knownTypes).substituteType(type);
scheglov 2017/05/04 22:09:20 There is some asymmetry here. This construct also
Paul Berry 2017/05/04 22:14:04 Good point. Switched to substitute() for symmetry
+ }
+ var result = substituteDeep(type, substitution);
+ if (result != null) return result;
+
+ // Instantiation failed due to a circularity.
+ // TODO(paulberry): report the error.
+ // Substitute `dynamic` for all parameters to try to allow compilation to
+ // continue. Note that [substituteDeep] is destructive of the
+ // [substitution] so we create a fresh one.
+ substitution = <TypeParameter, DartType>{};
+ for (TypeParameter parameter in typeFormals) {
+ substitution[parameter] = const DynamicType();
+ }
+ return Substitution.fromMap(substitution).substituteType(type);
+ }
+
@override
bool isBottom(DartType t) {
if (t is UnknownType) {
@@ -397,6 +439,23 @@ class TypeSchemaEnvironment extends TypeEnvironment {
return hierarchy.getClassicLeastUpperBound(type1, type2);
}
+ bool _isObjectOrDynamic(DartType type) =>
+ type is DynamicType ||
+ (type is InterfaceType &&
+ identical(type.classNode, coreTypes.objectClass));
+
+ /// Given a [type], returns the [TypeParameter]s corresponding to its formal
+ /// type parameters (if any).
+ List<TypeParameter> _typeFormalsAsParameters(DartType type) {
+ if (type is TypedefType) {
+ return type.typedefNode.typeParameters;
+ } else if (type is InterfaceType) {
+ return type.classNode.typeParameters;
+ } else {
+ return const [];
+ }
+ }
+
DartType _typeParameterLeastUpperBound(DartType type1, DartType type2) {
// This currently just implements a simple least upper bound to
// handle some common cases. It also avoids some termination issues
« no previous file with comments | « no previous file | pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698