Migration: add the ability to union decorated function types.
Change-Id: Ife92ab951ee0a60edea12c0d1fe4f242135a8ae3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107440
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 5656737..e3f31e6 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -119,7 +119,7 @@
DecoratedType.forImplicitType(parameter.type, graph);
}
}
- return DecoratedType(type, graph.never,
+ return DecoratedType(type, node,
returnType:
returnType ?? DecoratedType.forImplicitType(type.returnType, graph),
namedParameters: namedParameters,
@@ -137,6 +137,9 @@
typeArguments: type.typeArguments
.map((t) => DecoratedType.forImplicitType(t, graph))
.toList());
+ } else if (type is FunctionType) {
+ return DecoratedType.forImplicitFunction(
+ type, NullabilityNode.forInferredType(), graph);
}
// TODO(paulberry)
throw UnimplementedError(
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index cf7d441..f72b3c5 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -1101,9 +1101,8 @@
i++) {
_unionDecoratedTypes(x.typeArguments[i], y.typeArguments[i], origin);
}
- if (x.returnType != null || y.returnType != null) {
- // TODO(paulberry)
- throw UnimplementedError('_unionDecoratedTypes($x, $y, $origin)');
+ if (x.returnType != null && y.returnType != null) {
+ _unionDecoratedTypes(x.returnType, y.returnType, origin);
}
}
}
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 046dcef..a664f07 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2056,6 +2056,17 @@
assertUnion(cType.typeArguments[0].node, cBound.node);
}
+ test_typeName_union_with_bound_function_type() async {
+ await analyze('''
+class C<T extends int Function()> {}
+void f(C c) {}
+''');
+ var cType = decoratedTypeAnnotation('C c');
+ var cBound = decoratedGenericFunctionTypeAnnotation('int Function()');
+ assertUnion(cType.typeArguments[0].node, cBound.node);
+ assertUnion(cType.typeArguments[0].returnType.node, cBound.returnType.node);
+ }
+
test_typeName_union_with_bounds() async {
await analyze('''
class C<T extends Object, U extends Object> {}
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index 055aee1..abca42e 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -403,6 +403,24 @@
expect(decoratedArgType.node, same(always));
}
+ test_interfaceType_generic_instantiate_to_function_type() async {
+ await analyze('''
+class C<T extends int Function()> {}
+void f(C x) {}
+''');
+ var decoratedCType = decoratedTypeAnnotation('C x');
+ expect(decoratedFunctionType('f').positionalParameters[0],
+ same(decoratedCType));
+ expect(decoratedCType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedCType.typeArguments, hasLength(1));
+ var decoratedArgType = decoratedCType.typeArguments[0];
+ expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedArgType.typeArguments, isEmpty);
+ var decoratedArgReturnType = decoratedArgType.returnType;
+ expect(decoratedArgReturnType.node, TypeMatcher<NullabilityNodeMutable>());
+ expect(decoratedArgReturnType.typeArguments, isEmpty);
+ }
+
test_interfaceType_generic_instantiate_to_generic_type() async {
await analyze('''
class C<T> {}