Use dynamic type arguments for TypeName without explicit type arguments.

Plus some other fixes for sync/async.

R=brianwilkerson@google.com

Change-Id: I4d21f6557ef009b5218683136443578d1bff0b01
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97721
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 766ca7b..fd5b796 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1061,7 +1061,7 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@typeParameter');
-      var typeParameters = context.getTypeParameters(linkedNode);
+      var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
@@ -9073,7 +9073,7 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@typeParameter');
-      var typeParameters = context.getTypeParameters(linkedNode);
+      var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 980e032..03d7ad0 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -68,6 +68,33 @@
     var reference = rootReference.getChild(uriStr);
     return elementOfReference(reference);
   }
+
+  LinkedNode nodeOfReference(Reference reference) {
+    if (reference.node != null) {
+      return reference.node;
+    }
+
+    var unitRef = reference.parent?.parent;
+    var unitContainer = unitRef?.parent;
+    if (unitContainer?.name == '@unit') {
+      var libraryUriStr = unitContainer.parent.name;
+      var libraryData = libraryMap[libraryUriStr];
+      for (var unitData in libraryData.node.units) {
+        var definingUnitContext = LinkedUnitContext(
+          libraryData.context,
+          TokensContext(unitData.tokens),
+        );
+        _ElementRequest._indexUnitDeclarations(
+          definingUnitContext,
+          unitRef,
+          unitData.node,
+        );
+        return reference.node;
+      }
+    }
+
+    throw UnimplementedError('$reference');
+  }
 }
 
 class _ElementRequest {
@@ -160,7 +187,7 @@
   ClassElementImpl _class(
       CompilationUnitElementImpl unit, Reference reference) {
     if (reference.node == null) {
-      _indexUnitDeclarations(unit);
+      _indexUnitElementDeclarations(unit);
       assert(reference.node != 0, '$reference');
     }
     return reference.element = ClassElementImpl.forLinkedNode(
@@ -234,39 +261,11 @@
     return reference.element;
   }
 
-  void _indexUnitDeclarations(CompilationUnitElementImpl unit) {
-    var context = unit.linkedContext;
+  void _indexUnitElementDeclarations(CompilationUnitElementImpl unit) {
+    var unitContext = unit.linkedContext;
     var unitRef = unit.reference;
-    var classRef = unitRef.getChild('@class');
-    var enumRef = unitRef.getChild('@class');
-    var functionRef = unitRef.getChild('@function');
-    var typeAliasRef = unitRef.getChild('@typeAlias');
-    var variableRef = unitRef.getChild('@variable');
-    for (var declaration in unit.linkedNode.compilationUnit_declarations) {
-      var kind = declaration.kind;
-      if (kind == LinkedNodeKind.classDeclaration ||
-          kind == LinkedNodeKind.classTypeAlias) {
-        var name = context.getUnitMemberName(declaration);
-        classRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.enumDeclaration) {
-        var name = context.getUnitMemberName(declaration);
-        enumRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.functionDeclaration) {
-        var name = context.getUnitMemberName(declaration);
-        functionRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.functionTypeAlias) {
-        var name = context.getUnitMemberName(declaration);
-        typeAliasRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.topLevelVariableDeclaration) {
-        var variables = declaration.topLevelVariableDeclaration_variableList;
-        for (var variable in variables.variableDeclarationList_variables) {
-          var name = context.getSimpleName(variable.variableDeclaration_name);
-          variableRef.getChild(name).node = variable;
-        }
-      } else {
-        throw UnimplementedError('$kind');
-      }
-    }
+    var unitNode = unit.linkedNode;
+    _indexUnitDeclarations(unitContext, unitRef, unitNode);
   }
 
   MethodElementImpl _method(ClassElementImpl enclosing, Reference reference) {
@@ -285,7 +284,7 @@
   GenericTypeAliasElementImpl _typeAlias(
       CompilationUnitElementImpl unit, Reference reference) {
     if (reference.node == null) {
-      _indexUnitDeclarations(unit);
+      _indexUnitElementDeclarations(unit);
       assert(reference.node != 0, '$reference');
     }
     return reference.element = GenericTypeAliasElementImpl.forLinkedNode(
@@ -302,6 +301,44 @@
     assert(reference.element != null);
     return reference.element;
   }
+
+  static void _indexUnitDeclarations(
+    LinkedUnitContext unitContext,
+    Reference unitRef,
+    LinkedNode unitNode,
+  ) {
+    var classRef = unitRef.getChild('@class');
+    var enumRef = unitRef.getChild('@class');
+    var functionRef = unitRef.getChild('@function');
+    var typeAliasRef = unitRef.getChild('@typeAlias');
+    var variableRef = unitRef.getChild('@variable');
+    for (var declaration in unitNode.compilationUnit_declarations) {
+      var kind = declaration.kind;
+      if (kind == LinkedNodeKind.classDeclaration ||
+          kind == LinkedNodeKind.classTypeAlias) {
+        var name = unitContext.getUnitMemberName(declaration);
+        classRef.getChild(name).node = declaration;
+      } else if (kind == LinkedNodeKind.enumDeclaration) {
+        var name = unitContext.getUnitMemberName(declaration);
+        enumRef.getChild(name).node = declaration;
+      } else if (kind == LinkedNodeKind.functionDeclaration) {
+        var name = unitContext.getUnitMemberName(declaration);
+        functionRef.getChild(name).node = declaration;
+      } else if (kind == LinkedNodeKind.functionTypeAlias) {
+        var name = unitContext.getUnitMemberName(declaration);
+        typeAliasRef.getChild(name).node = declaration;
+      } else if (kind == LinkedNodeKind.topLevelVariableDeclaration) {
+        var variables = declaration.topLevelVariableDeclaration_variableList;
+        for (var variable in variables.variableDeclarationList_variables) {
+          var name =
+              unitContext.getSimpleName(variable.variableDeclaration_name);
+          variableRef.getChild(name).node = variable;
+        }
+      } else {
+        throw UnimplementedError('$kind');
+      }
+    }
+  }
 }
 
 class _Library {
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 7e2cdb7..25c0290 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -158,34 +158,6 @@
     }
   }
 
-  List<LinkedNode> getTypeParameters(LinkedNode node) {
-    LinkedNode typeParameterList;
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.classTypeAlias) {
-      typeParameterList = node.classTypeAlias_typeParameters;
-    } else if (kind == LinkedNodeKind.classDeclaration ||
-        kind == LinkedNodeKind.mixinDeclaration) {
-      typeParameterList = node.classOrMixinDeclaration_typeParameters;
-    } else if (kind == LinkedNodeKind.constructorDeclaration) {
-      return const [];
-    } else if (kind == LinkedNodeKind.functionDeclaration) {
-      return getTypeParameters(node.functionDeclaration_functionExpression);
-    } else if (kind == LinkedNodeKind.functionExpression) {
-      typeParameterList = node.functionExpression_typeParameters;
-    } else if (kind == LinkedNodeKind.functionTypeAlias) {
-      typeParameterList = node.functionTypeAlias_typeParameters;
-    } else if (kind == LinkedNodeKind.genericFunctionType) {
-      typeParameterList = node.genericFunctionType_typeParameters;
-    } else if (kind == LinkedNodeKind.genericTypeAlias) {
-      typeParameterList = node.genericTypeAlias_typeParameters;
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      typeParameterList = node.methodDeclaration_typeParameters;
-    } else {
-      throw UnimplementedError('$kind');
-    }
-    return typeParameterList?.typeParameterList_typeParameters;
-  }
-
   String getUnitMemberName(LinkedNode node) {
     return getSimpleName(node.namedCompilationUnitMember_name);
   }
@@ -202,14 +174,18 @@
   bool isAsynchronous(LinkedNode node) {
     LinkedNode body = _getFunctionBody(node);
     if (body.kind == LinkedNodeKind.blockFunctionBody) {
-      return body.blockFunctionBody_keyword != 0;
+      return isAsyncKeyword(body.blockFunctionBody_keyword);
     } else if (body.kind == LinkedNodeKind.emptyFunctionBody) {
       return false;
     } else {
-      return body.expressionFunctionBody_keyword != 0;
+      return isAsyncKeyword(body.expressionFunctionBody_keyword);
     }
   }
 
+  bool isAsyncKeyword(int token) {
+    return tokensContext.type(token) == UnlinkedTokenType.ASYNC;
+  }
+
   bool isConst(LinkedNode node) {
     var kind = node.kind;
     if (kind == LinkedNodeKind.defaultFormalParameter) {
@@ -347,6 +323,10 @@
     throw UnimplementedError('$kind');
   }
 
+  bool isSyncKeyword(int token) {
+    return tokensContext.type(token) == UnlinkedTokenType.SYNC;
+  }
+
   void loadClassMemberReferences(Reference reference) {
     var node = reference.node;
     if (node.kind != LinkedNodeKind.classDeclaration &&
@@ -443,4 +423,32 @@
   bool _isSetToken(int token) {
     return tokensContext.type(token) == UnlinkedTokenType.SET;
   }
+
+  static List<LinkedNode> getTypeParameters(LinkedNode node) {
+    LinkedNode typeParameterList;
+    var kind = node.kind;
+    if (kind == LinkedNodeKind.classTypeAlias) {
+      typeParameterList = node.classTypeAlias_typeParameters;
+    } else if (kind == LinkedNodeKind.classDeclaration ||
+        kind == LinkedNodeKind.mixinDeclaration) {
+      typeParameterList = node.classOrMixinDeclaration_typeParameters;
+    } else if (kind == LinkedNodeKind.constructorDeclaration) {
+      return const [];
+    } else if (kind == LinkedNodeKind.functionDeclaration) {
+      return getTypeParameters(node.functionDeclaration_functionExpression);
+    } else if (kind == LinkedNodeKind.functionExpression) {
+      typeParameterList = node.functionExpression_typeParameters;
+    } else if (kind == LinkedNodeKind.functionTypeAlias) {
+      typeParameterList = node.functionTypeAlias_typeParameters;
+    } else if (kind == LinkedNodeKind.genericFunctionType) {
+      typeParameterList = node.genericFunctionType_typeParameters;
+    } else if (kind == LinkedNodeKind.genericTypeAlias) {
+      typeParameterList = node.genericTypeAlias_typeParameters;
+    } else if (kind == LinkedNodeKind.methodDeclaration) {
+      typeParameterList = node.methodDeclaration_typeParameters;
+    } else {
+      throw UnimplementedError('$kind');
+    }
+    return typeParameterList?.typeParameterList_typeParameters;
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index 21a5e74..60d102d 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -5,6 +5,8 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/reference_resolver.dart';
 
 /// Build types in a [TypesToBuild].
@@ -64,7 +66,7 @@
     var referenceIndex = _typeNameElementIndex(node.typeName_name);
     var reference = bundleContext.referenceOfIndex(referenceIndex);
 
-    var typeArguments = const <LinkedNodeTypeBuilder>[];
+    List<LinkedNodeTypeBuilder> typeArguments;
     var typeArgumentList = node.typeName_typeArguments;
     if (typeArgumentList != null) {
       typeArguments = typeArgumentList.typeArgumentList_arguments
@@ -73,6 +75,15 @@
     }
 
     if (reference.isClass) {
+      // TODO(scheglov) Use instantiate to bounds.
+      var typeParametersLength = _typeParametersLength(reference);
+      if (typeArguments == null ||
+          typeArguments.length != typeParametersLength) {
+        typeArguments = List<LinkedNodeTypeBuilder>.filled(
+          typeParametersLength,
+          _dynamicType,
+        );
+      }
       node.typeName_type = LinkedNodeTypeBuilder(
         kind: LinkedNodeTypeKind.interface,
         interfaceClass: referenceIndex,
@@ -83,6 +94,15 @@
         kind: LinkedNodeTypeKind.dynamic_,
       );
     } else if (reference.isGenericTypeAlias) {
+      // TODO(scheglov) Use instantiate to bounds.
+      var typeParametersLength = _typeParametersLength(reference);
+      if (typeArguments == null ||
+          typeArguments.length != typeParametersLength) {
+        typeArguments = List<LinkedNodeTypeBuilder>.filled(
+          typeParametersLength,
+          _dynamicType,
+        );
+      }
       node.typeName_type = LinkedNodeTypeBuilder(
         kind: LinkedNodeTypeKind.genericTypeAlias,
         genericTypeAliasReference: referenceIndex,
@@ -140,6 +160,11 @@
     }
   }
 
+  int _typeParametersLength(Reference reference) {
+    var node = bundleContext.elementFactory.nodeOfReference(reference);
+    return LinkedUnitContext.getTypeParameters(node)?.length ?? 0;
+  }
+
   static LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) {
     var kind = node.kind;
     if (kind == LinkedNodeKind.genericFunctionType) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 6a7e658..a54e951 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -122,6 +122,8 @@
 class Future<T> {}
 
 class FutureOr<T> {}
+
+class Stream<T> {}
 ''';
 
     var dartMathCode = r'''
@@ -826,18 +828,6 @@
 
   @override
   @failingTest
-  test_function_async() async {
-    await super.test_function_async();
-  }
-
-  @override
-  @failingTest
-  test_function_asyncStar() async {
-    await super.test_function_asyncStar();
-  }
-
-  @override
-  @failingTest
   test_function_entry_point_in_export_hidden() async {
     await super.test_function_entry_point_in_export_hidden();
   }
@@ -1147,24 +1137,6 @@
 
   @override
   @failingTest
-  test_member_function_async() async {
-    await super.test_member_function_async();
-  }
-
-  @override
-  @failingTest
-  test_member_function_asyncStar() async {
-    await super.test_member_function_asyncStar();
-  }
-
-  @override
-  @failingTest
-  test_member_function_syncStar() async {
-    await super.test_member_function_syncStar();
-  }
-
-  @override
-  @failingTest
   test_metadata_constructor_call_named_prefixed() async {
     await super.test_metadata_constructor_call_named_prefixed();
   }
@@ -1353,12 +1325,6 @@
 
   @override
   @failingTest
-  test_type_arguments_implicit() async {
-    await super.test_type_arguments_implicit();
-  }
-
-  @override
-  @failingTest
   test_type_inference_based_on_loadLibrary() async {
     await super.test_type_inference_based_on_loadLibrary();
   }
@@ -1431,12 +1397,6 @@
 
   @override
   @failingTest
-  test_type_reference_to_class_with_type_arguments_implicit() async {
-    await super.test_type_reference_to_class_with_type_arguments_implicit();
-  }
-
-  @override
-  @failingTest
   test_type_reference_to_import() async {
     await super.test_type_reference_to_import();
   }