Handle ClassTypeAlias without valid Function.

R=brianwilkerson@google.com

Change-Id: Ibc160658b75f7d5a450548e12aa5dc96be674f06
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101072
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index cfba6f6..003f614 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -194,12 +194,17 @@
     }
   }
 
-  FunctionType _getRawFunctionType(GenericTypeAliasElementImpl element) {
+  DartType _getRawFunctionType(GenericTypeAliasElementImpl element) {
     // If the element is not being linked, there is no reason (or a way,
     // because the linked node might be read only partially) to go through
     // its node - all its types have already been built.
     if (!element.linkedContext.isLinking) {
-      return element.function.type;
+      var function = element.function;
+      if (function != null) {
+        return function.type;
+      } else {
+        return _dynamicType;
+      }
     }
 
     var typedefNode = element.linkedNode;
@@ -211,11 +216,15 @@
       );
     } else if (typedefNode is GenericTypeAlias) {
       var functionNode = typedefNode.functionType;
-      return _buildFunctionType(
-        functionNode.typeParameters,
-        functionNode.returnType,
-        functionNode.parameters,
-      );
+      if (functionNode != null) {
+        return _buildFunctionType(
+          functionNode.typeParameters,
+          functionNode.returnType,
+          functionNode.parameters,
+        );
+      } else {
+        return _dynamicType;
+      }
     } else {
       throw StateError('(${element.runtimeType}) $element');
     }
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index b9ca8f2..cc26161 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -4358,6 +4358,16 @@
 ''');
   }
 
+  test_typedef_not_function() async {
+    newFile('/test/lib/a.dart', content: '''
+typedef F = int;
+''');
+    await assertNoErrorsInCode('''
+import 'a.dart';
+F f;
+''');
+  }
+
   test_typePromotion_booleanAnd_useInRight() async {
     await assertNoErrorsInCode(r'''
 main(Object p) {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index ed7fc0e..3731fcb 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -358,10 +358,15 @@
 
       buffer.write(' = ');
 
-      writeType(e.function.returnType);
-      buffer.write(' Function');
-      writeTypeParameterElements(e.function.typeParameters);
-      writeParameterElements(e.function.parameters);
+      var function = e.function;
+      if (function != null) {
+        writeType(function.returnType);
+        buffer.write(' Function');
+        writeTypeParameterElements(function.typeParameters);
+        writeParameterElements(function.parameters);
+      } else {
+        buffer.write('<null>');
+      }
     } else {
       buffer.write('typedef ');
       writeType2(e.returnType);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 8f9c7ff..17febed 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9466,6 +9466,17 @@
 ''');
   }
 
+  test_typedef_generic_invalid() async {
+    var library = await checkLibrary('''
+typedef F = int;
+F f;
+''');
+    checkElementText(library, r'''
+typedef F = <null>;
+dynamic f;
+''');
+  }
+
   test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
     // F is considered "not simply bounded" because it expands to a type that
     // refers to C, which is not simply bounded.