Store resolution for abstract class constructor invocation.

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: I8973a93550cb7718070a478c26747c88176f60f7
Reviewed-on: https://dart-review.googlesource.com/64160
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
index 3c88c1a..9d1f172 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -971,20 +971,6 @@
   @override
   @failingTest
   @potentialAnalyzerProblem
-  test_newWithAbstractClass() async {
-    return super.test_newWithAbstractClass_generic();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_newWithAbstractClass_generic() async {
-    return super.test_newWithAbstractClass_generic();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
   test_newWithInvalidTypeParameters() async {
     return super.test_newWithInvalidTypeParameters();
   }
diff --git a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
index 411efa9..174f423 100644
--- a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
@@ -37,20 +37,6 @@
 
   @override
   @failingTest
-  test_async_star_method_propagation() async {
-    // Bad state: No type information for Stream at 124
-    await super.test_async_star_method_propagation();
-  }
-
-  @override
-  @failingTest
-  test_async_star_propagation() async {
-    // Bad state: No type information for Stream at 105
-    await super.test_async_star_propagation();
-  }
-
-  @override
-  @failingTest
   test_constrainedByBounds2() async {
     // Expected: InterfaceTypeImpl:<int>
     await super.test_constrainedByBounds2();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 692e703..d0951ad 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2971,6 +2971,74 @@
     assertType(aRef, 'int');
   }
 
+  test_invalid_instanceCreation_abstract() async {
+    addTestFile(r'''
+abstract class C<T> {
+  C(T a);
+  C.named(T a);
+  C.named2();
+}
+var a = 0;
+var b = true;
+main() {
+  new C(a);
+  new C.named(b);
+  new C<double>.named2();
+}
+''');
+    await resolveTestFile();
+    expect(result.errors, isNotEmpty);
+
+    var c = findElement.class_('C');
+
+    {
+      var creation = findNode.instanceCreation('new C(a)');
+      assertType(creation, 'C<int>');
+
+      ConstructorName constructorName = creation.constructorName;
+      expect(constructorName.name, isNull);
+
+      TypeName type = constructorName.type;
+      expect(type.typeArguments, isNull);
+      assertElement(type.name, c);
+      assertType(type.name, useCFE ? 'C<int>' : 'C<dynamic>');
+
+      SimpleIdentifier aRef = creation.argumentList.arguments[0];
+      assertElement(aRef, findElement.topGet('a'));
+      assertType(aRef, 'int');
+    }
+
+    {
+      var creation = findNode.instanceCreation('new C.named(b)');
+      assertType(creation, 'C<bool>');
+
+      ConstructorName constructorName = creation.constructorName;
+      expect(constructorName.name.name, 'named');
+
+      TypeName type = constructorName.type;
+      expect(type.typeArguments, isNull);
+      assertElement(type.name, c);
+      assertType(type.name, useCFE ? 'C<bool>' : 'C<dynamic>');
+
+      SimpleIdentifier bRef = creation.argumentList.arguments[0];
+      assertElement(bRef, findElement.topGet('b'));
+      assertType(bRef, 'bool');
+    }
+
+    {
+      var creation = findNode.instanceCreation('new C<double>.named2()');
+      assertType(creation, 'C<double>');
+
+      ConstructorName constructorName = creation.constructorName;
+      expect(constructorName.name.name, 'named2');
+
+      TypeName type = constructorName.type;
+      assertTypeArguments(type.typeArguments, [doubleType]);
+      assertElement(type.name, c);
+      assertType(type.name, 'C<double>');
+    }
+  }
+
   test_invalid_methodInvocation_simpleIdentifier() async {
     addTestFile(r'''
 int foo = 0;
@@ -7552,6 +7620,15 @@
 
   CompilationUnitElement get unitElement => result.unit.element;
 
+  ClassElement class_(String name) {
+    for (var class_ in unitElement.types) {
+      if (class_.name == name) {
+        return class_;
+      }
+    }
+    fail('Not found class: $name');
+  }
+
   FieldElement field(String name) {
     for (var type in unitElement.types) {
       for (var field in type.fields) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index ddbf2dd..f9430d9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2966,13 +2966,17 @@
         // Not found. Reported below.
       } else if (b.isConstructor) {
         if (type.isAbstract) {
-          return new SyntheticExpressionJudgment(evaluateArgumentsBefore(
-              arguments,
-              buildAbstractClassInstantiationError(
-                  fasta.templateAbstractClassInstantiation
-                      .withArguments(type.name),
-                  type.name,
-                  nameToken.charOffset)));
+          return new InvalidConstructorInvocationJudgment(
+              evaluateArgumentsBefore(
+                  arguments,
+                  buildAbstractClassInstantiationError(
+                      fasta.templateAbstractClassInstantiation
+                          .withArguments(type.name),
+                      type.name,
+                      nameToken.charOffset)),
+              target,
+              arguments)
+            ..fileOffset = charOffset;
         }
       }
       if (target is Constructor ||
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index b54ec64..b3c17bb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -2819,19 +2819,22 @@
       kernel.Expression desugared, this.constructor, this.arguments)
       : super(desugared);
 
+  ArgumentsJudgment get argumentJudgments => arguments;
+
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
       Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
-    for (var argument in arguments.positional) {
-      inferrer.inferExpression(factory, argument, const UnknownType(), true);
-    }
-    for (var argument in arguments.named) {
-      inferrer.inferExpression(
-          factory, argument.value, const UnknownType(), true);
-    }
-    inferredType = constructor.enclosingClass.rawType;
+    var calleeType = constructor.function.functionType;
+    var inferenceResult = inferrer.inferInvocation(
+        factory,
+        typeContext,
+        fileOffset,
+        calleeType,
+        computeConstructorReturnType(constructor),
+        argumentJudgments);
+    this.inferredType = inferenceResult.type;
     inferrer.listener.constructorInvocation(
         this, arguments.fileOffset, constructor, inferredType);
     return super.infer(inferrer, factory, typeContext);