Analyzer/FE integration of unresolved static method calls.

Change-Id: Ia1e1e29d5b00c8adc6cc34e08158757fc6812759
Reviewed-on: https://dart-review.googlesource.com/63445
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index 9aebb33..01d758e 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -561,7 +561,7 @@
         ? calleeType
         : substitution.substituteType(calleeType.withoutTypeParameters);
     _store(location,
-        invokeType: invokeType,
+        invokeType: invokeType ?? const DynamicType(),
         argumentTypes: expressionArgumentsTypes,
         reference: expressionTarget,
         inferredType: inferredType);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
index 732c694..92509f6 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
@@ -777,13 +777,6 @@
 
   @override
   @failingTest
-  test_undefinedMethod_typeLiteral_conditionalAccess() async {
-    // Bad state: No reference information for A at 18
-    await super.test_undefinedMethod_typeLiteral_conditionalAccess();
-  }
-
-  @override
-  @failingTest
   test_undefinedOperator_indexBoth() async {
     // Expected 1 errors of type StaticTypeWarningCode.UNDEFINED_OPERATOR, found 0
     await super.test_undefinedOperator_indexBoth();
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 67931ff..8e9c9ae 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -1855,20 +1855,6 @@
     return super.test_undefinedSetter();
   }
 
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_undefinedStaticMethodOrGetter_method() async {
-    return super.test_undefinedStaticMethodOrGetter_method();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_undefinedStaticMethodOrGetter_method_inSuperclass() async {
-    return super.test_undefinedStaticMethodOrGetter_method_inSuperclass();
-  }
-
   @failingTest
   @override
   test_useOfVoidResult_assignmentExpression_function() async {
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 aff06a8..c4c8cbd 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -7351,6 +7351,40 @@
     expect(identifier.staticType, isDynamicType);
   }
 
+  test_unresolved_static_call() async {
+    addTestFile('''
+class C {
+  static f() => C.g();
+}
+''');
+    await resolveTestFile();
+    expect(result.errors, isNotEmpty);
+
+    var g = findNode.simple('g()');
+    assertElementNull(g);
+    assertTypeDynamic(g);
+    var invocation = g.parent as MethodInvocation;
+    assertTypeDynamic(invocation);
+    expect(invocation.staticInvokeType, isDynamicType);
+  }
+
+  test_unresolved_static_call_same_name_as_type_param() async {
+    addTestFile('''
+class C<T> {
+  static f() => C.T();
+}
+''');
+    await resolveTestFile();
+    expect(result.errors, isNotEmpty);
+
+    var t = findNode.simple('T()');
+    assertElementNull(t);
+    assertTypeDynamic(t);
+    var invocation = t.parent as MethodInvocation;
+    assertTypeDynamic(invocation);
+    expect(invocation.staticInvokeType, isDynamicType);
+  }
+
   /// Assert that the [argument] is associated with the [expectedParameter],
   /// if [useCFE] is `null`. If the [argument] is a [NamedExpression],
   /// the name must be resolved to the parameter in both cases.
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 394dfb6..5715911 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2899,11 +2899,12 @@
       nameToken = nameToken.next.next;
     }
 
-    return new SyntheticExpressionJudgment(throwNoSuchMethodError(
+    return new UnresolvedTargetInvocation(throwNoSuchMethodError(
         forest.literalNull(null)..fileOffset = charOffset,
         errorName,
         arguments,
-        nameToken.charOffset));
+        nameToken.charOffset))
+      ..fileOffset = arguments.fileOffset;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index cd6ab94..e51a0bf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -107,6 +107,7 @@
         SwitchCaseJudgment,
         SwitchStatementJudgment,
         SyntheticExpressionJudgment,
+        UnresolvedTargetInvocation,
         UnresolvedVariableGetJudgment,
         UnresolvedVariableAssignmentJudgment,
         VariableAssignmentJudgment,
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 563d0e48..5c10b3b 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
@@ -3549,6 +3549,23 @@
       variable._isLocalFunction;
 }
 
+/// Synthetic judgment class representing an attempt to invoke an unresolved
+/// target.
+class UnresolvedTargetInvocation extends SyntheticExpressionJudgment {
+  UnresolvedTargetInvocation(kernel.Expression desugared) : super(desugared);
+
+  @override
+  Expression infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory,
+      DartType typeContext) {
+    var result = super.infer(inferrer, factory, typeContext);
+    inferrer.listener.staticInvocation(
+        this, fileOffset, null, null, null, null, inferredType);
+    return result;
+  }
+}
+
 /// Synthetic judgment class representing an attempt to assign to an unresolved
 /// variable.
 class UnresolvedVariableAssignmentJudgment extends SyntheticExpressionJudgment {