Fix for building named function types.

R=brianwilkerson@google.com

Change-Id: Idc0b192579db4189b0335b44d2468f87701b43fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101005
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
index f1e402e..7688746 100644
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -53,6 +53,9 @@
   LinkedBundleContext.forAst(this.elementFactory, this._references)
       : _bundle = null;
 
+  /// Return `true` if this bundle is being linked.
+  bool get isLinking => _bundle == null;
+
   LinkedLibraryContext addLinkingLibrary(
     String uriStr,
     LinkedNodeLibraryBuilder data,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index dabace1..f8a17c6 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -80,6 +80,9 @@
     return false;
   }
 
+  /// Return `true` if this unit is a part of a bundle that is being linked.
+  bool get isLinking => bundleContext.isLinking;
+
   CompilationUnit get unit => _unit;
 
   CompilationUnit get unit_withDeclarations {
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index 683e7c9..cfba6f6 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -72,27 +72,9 @@
       // Break a possible recursion.
       _type = _dynamicType;
 
+      var rawType = _getRawFunctionType(element);
+
       var parameters = element.typeParameters;
-
-      FunctionType rawType;
-      var typedefNode = (element as ElementImpl).linkedNode;
-      if (typedefNode is FunctionTypeAlias) {
-        rawType = _buildFunctionType(
-          null,
-          typedefNode.returnType,
-          typedefNode.parameters,
-        );
-      } else if (typedefNode is GenericTypeAlias) {
-        var functionNode = typedefNode.functionType;
-        rawType = _buildFunctionType(
-          functionNode.typeParameters,
-          functionNode.returnType,
-          functionNode.parameters,
-        );
-      } else {
-        throw StateError('(${element.runtimeType}) $element');
-      }
-
       if (parameters.isEmpty) {
         _type = rawType;
       } else {
@@ -212,6 +194,33 @@
     }
   }
 
+  FunctionType _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 typedefNode = element.linkedNode;
+    if (typedefNode is FunctionTypeAlias) {
+      return _buildFunctionType(
+        null,
+        typedefNode.returnType,
+        typedefNode.parameters,
+      );
+    } else if (typedefNode is GenericTypeAlias) {
+      var functionNode = typedefNode.functionType;
+      return _buildFunctionType(
+        functionNode.typeParameters,
+        functionNode.returnType,
+        functionNode.parameters,
+      );
+    } else {
+      throw StateError('(${element.runtimeType}) $element');
+    }
+  }
+
   static List<DartType> _listOfDynamic(int length) {
     return List<DartType>.filled(length, _dynamicType);
   }