Report generic instantiation of non-generic getters

Fixes #49145

Change-Id: I3b39e7f1042a43f495db3cbec70ce62bb3ed352b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247300
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index 508dbaa..5e0f754 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -475,6 +475,15 @@
       return;
     }
 
+    if (propertyType != null) {
+      // If the property is unknown, [UNDEFINED_GETTER] is reported elsewhere.
+      // If it is known, we must report the bad type instantiation here.
+      _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
+        function.identifier,
+        [],
+      );
+    }
     function.accept(_resolver);
     node.staticType = DynamicTypeImpl.instance;
   }
@@ -532,12 +541,18 @@
           rawType: functionType,
           name: function.propertyName.name,
         );
-      } else {
-        // The target is known, but the method is not; [UNDEFINED_GETTER] is
-        // reported elsewhere.
-        node.staticType = DynamicTypeImpl.instance;
+        return;
+      } else if (functionType != null) {
+        // If the property is unknown, [UNDEFINED_GETTER] is reported elsewhere.
+        // If it is known, we must report the bad type instantiation here.
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
+          function.propertyName,
+          [],
+        );
       }
 
+      node.staticType = DynamicTypeImpl.instance;
       return;
     }
 
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index 0cb0ce2..dd5da81 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -2036,6 +2036,101 @@
 ''');
   }
 
+  test_instanceGetter_nonGeneric() async {
+    await assertErrorsInCode('''
+abstract class A {
+  List<int> get f;
+}
+
+void foo(A a) {
+  a.f<String>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 61, 1),
+    ]);
+
+    assertResolvedNodeText(findNode.functionReference('f<String>'), r'''
+FunctionReference
+  function: PrefixedIdentifier
+    prefix: SimpleIdentifier
+      token: a
+      staticElement: self::@function::foo::@parameter::a
+      staticType: A
+    period: .
+    identifier: SimpleIdentifier
+      token: f
+      staticElement: self::@class::A::@getter::f
+      staticType: List<int>
+    staticElement: self::@class::A::@getter::f
+    staticType: List<int>
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: String
+          staticElement: dart:core::@class::String
+          staticType: null
+        type: String
+    rightBracket: >
+  staticType: dynamic
+''');
+  }
+
+  test_instanceGetter_nonGeneric_propertyAccess() async {
+    await assertErrorsInCode('''
+abstract class A {
+  B get b;
+}
+
+abstract class B {
+  List<int> get f;
+}
+
+void foo(A a) {
+  a.b.f<String>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 96, 1),
+    ]);
+
+    assertResolvedNodeText(findNode.functionReference('f<String>'), r'''
+FunctionReference
+  function: PropertyAccess
+    target: PrefixedIdentifier
+      prefix: SimpleIdentifier
+        token: a
+        staticElement: self::@function::foo::@parameter::a
+        staticType: A
+      period: .
+      identifier: SimpleIdentifier
+        token: b
+        staticElement: self::@class::A::@getter::b
+        staticType: B
+      staticElement: self::@class::A::@getter::b
+      staticType: B
+    operator: .
+    propertyName: SimpleIdentifier
+      token: f
+      staticElement: self::@class::B::@getter::f
+      staticType: List<int>
+    staticType: List<int>
+  typeArguments: TypeArgumentList
+    leftBracket: <
+    arguments
+      NamedType
+        name: SimpleIdentifier
+          token: String
+          staticElement: dart:core::@class::String
+          staticType: null
+        type: String
+    rightBracket: >
+  staticType: dynamic
+''');
+  }
+
   test_instanceMethod() async {
     await assertNoErrorsInCode('''
 class A {
@@ -2214,7 +2309,7 @@
   }
 
   test_instanceMethod_explicitReceiver_getter_wrongNumberOfTypeArguments() async {
-    await assertNoErrorsInCode(r'''
+    await assertErrorsInCode(r'''
 class A {
   int get foo => 0;
 }
@@ -2223,7 +2318,10 @@
   // Extra `()` to force reading the type.
   ((a).foo<double>);
 }
-''');
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 97, 3),
+    ]);
 
     var reference = findNode.functionReference('foo<double>');
     assertResolvedNodeText(reference, r'''