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 {}