Migration: build decorated types for implicit constructors of class type aliases (partial).
This CL addresses implicit constructors without parameters. Implicit
constructors with parameters will take a bit more work to accomplish,
and will be handled in a follow-up CL.
Change-Id: Id12725712198eeeff8e4080e8fa0ca2a1eb46177
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107187
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 6e83905..5605746 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -103,8 +103,23 @@
node.metadata.accept(this);
node.name.accept(this);
node.typeParameters?.accept(this);
- _handleSupertypeClauses(node.declaredElement, node.superclass,
- node.withClause, node.implementsClause, null);
+ var classElement = node.declaredElement;
+ _handleSupertypeClauses(classElement, node.superclass, node.withClause,
+ node.implementsClause, null);
+ for (var constructorElement in classElement.constructors) {
+ assert(constructorElement.isSynthetic);
+ var decoratedReturnType =
+ _createDecoratedTypeForClass(classElement, node);
+ if (constructorElement.parameters.isNotEmpty) {
+ _unimplemented(node,
+ 'Implicit constructor of a mixin application, with parameters');
+ }
+ var functionType = DecoratedType(constructorElement.type, _graph.never,
+ returnType: decoratedReturnType,
+ positionalParameters: [],
+ namedParameters: {});
+ _variables.recordDecoratedElementType(constructorElement, functionType);
+ }
return null;
}
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index 5e2c014..ae63968 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -31,6 +31,33 @@
DecoratedType decoratedTypeParameterBound(String search) => variables
.decoratedElementType(findNode.typeParameter(search).declaredElement);
+ test_class_alias_synthetic_constructors_no_parameters() async {
+ await analyze('''
+class C {
+ C.a();
+ C.b();
+}
+mixin M {}
+class D = C with M;
+''');
+ var constructors = findElement.class_('D').constructors;
+ expect(constructors, hasLength(2));
+ var a = findElement.constructor('a', of: 'D');
+ var aType = variables.decoratedElementType(a);
+ expect(aType.type.toString(), 'D Function()');
+ expect(aType.node, same(never));
+ expect(aType.typeArguments, isEmpty);
+ expect(aType.returnType.type.toString(), 'D');
+ expect(aType.returnType.node, same(never));
+ var b = findElement.constructor('b', of: 'D');
+ var bType = variables.decoratedElementType(b);
+ expect(bType.type.toString(), 'D Function()');
+ expect(bType.node, same(never));
+ expect(bType.typeArguments, isEmpty);
+ expect(bType.returnType.type.toString(), 'D');
+ expect(bType.returnType.node, same(never));
+ }
+
test_class_with_default_constructor() async {
await analyze('''
class C {}