Add message for missing type arguments

This message is ignored by default and Fasta uses this internally
to help migrate to Dart 2 and type errors in analyzer integration
at compile-time.

Change-Id: Ie0def14f09eb387fdae0486cd7a4bbed2536c64d
Reviewed-on: https://dart-review.googlesource.com/60427
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index f430cfc..4cf8c2a 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -4,12 +4,17 @@
 
 library fasta.named_type_builder;
 
-import '../fasta_codes.dart' show Message, templateTypeArgumentMismatch;
+import '../fasta_codes.dart'
+    show
+        Message,
+        templateMissingExplicitTypeArguments,
+        templateTypeArgumentMismatch;
 
 import 'builder.dart'
     show
         Declaration,
         InvalidTypeBuilder,
+        LibraryBuilder,
         PrefixBuilder,
         QualifiedName,
         Scope,
@@ -34,7 +39,8 @@
   }
 
   @override
-  void resolveIn(Scope scope, int charOffset, Uri fileUri) {
+  void resolveIn(
+      Scope scope, int charOffset, Uri fileUri, LibraryBuilder library) {
     if (declaration != null) return;
     final name = this.name;
     Declaration member;
@@ -48,6 +54,14 @@
     }
     if (member is TypeDeclarationBuilder) {
       declaration = member.origin;
+      if (arguments == null && declaration.typeVariablesCount != 0) {
+        library.addProblem(
+            templateMissingExplicitTypeArguments
+                .withArguments(declaration.typeVariablesCount),
+            charOffset,
+            "$name".length,
+            fileUri);
+      }
       return;
     }
     declaration = buildInvalidType(charOffset, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index 0b2d80a..ee13b6f 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -10,7 +10,8 @@
 abstract class TypeBuilder {
   const TypeBuilder();
 
-  void resolveIn(Scope scope, int charOffset, Uri fileUri) {}
+  void resolveIn(
+      Scope scope, int charOffset, Uri fileUri, LibraryBuilder library) {}
 
   /// See `UnresolvedType.checkType`.
   void check(int charOffset, Uri fileUri) {}
diff --git a/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart b/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart
index 392e15e..7c5004a 100644
--- a/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart
+++ b/pkg/front_end/lib/src/fasta/builder/unresolved_type.dart
@@ -4,7 +4,7 @@
 
 library fasta.unresolved_type;
 
-import 'builder.dart' show Scope, TypeBuilder;
+import 'builder.dart' show LibraryBuilder, Scope, TypeBuilder;
 
 /// A wrapper around a type that is yet to be resolved.
 class UnresolvedType<T extends TypeBuilder> {
@@ -14,7 +14,8 @@
 
   UnresolvedType(this.builder, this.charOffset, this.fileUri);
 
-  void resolveIn(Scope scope) => builder.resolveIn(scope, charOffset, fileUri);
+  void resolveIn(Scope scope, LibraryBuilder library) =>
+      builder.resolveIn(scope, charOffset, fileUri, library);
 
   /// Performs checks on the type after it's resolved.
   void checkType() => builder.check(charOffset, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index a76cf2f..e4aecb4 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -4012,6 +4012,26 @@
         r"""Try adding the name of the type of the variable or the keyword 'var'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(int count)>
+    templateMissingExplicitTypeArguments =
+    const Template<Message Function(int count)>(
+        messageTemplate: r"""No type arguments provided, #count possible.""",
+        withArguments: _withArgumentsMissingExplicitTypeArguments);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(int count)> codeMissingExplicitTypeArguments =
+    const Code<Message Function(int count)>(
+        "MissingExplicitTypeArguments", templateMissingExplicitTypeArguments,
+        severity: Severity.ignored);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsMissingExplicitTypeArguments(int count) {
+  return new Message(codeMissingExplicitTypeArguments,
+      message: """No type arguments provided, ${count} possible.""",
+      arguments: {'count': count});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMissingExponent = messageMissingExponent;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
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 25b70b1..503f139 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -3694,7 +3694,7 @@
     // [ClassMemberParser] is not used to build the type variables for the local
     // function.  See the comment above.
     for (UnresolvedType t in library.types) {
-      t.resolveIn(scope);
+      t.resolveIn(scope, library);
     }
     library.types.clear();
   }
@@ -3755,8 +3755,8 @@
             library.loader.target.objectClassBuilder);
         for (int i = 0; i < typeVariables.length; ++i) {
           typeVariables[i].defaultType = calculatedBounds[i];
-          typeVariables[i].defaultType.resolveIn(
-              scope, typeVariables[i].charOffset, typeVariables[i].fileUri);
+          typeVariables[i].defaultType.resolveIn(scope,
+              typeVariables[i].charOffset, typeVariables[i].fileUri, library);
           typeVariables[i].finish(
               library,
               library.loader.target.objectClassBuilder,
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index a7228a9..5b8bd85 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -15,6 +15,7 @@
         messageInvalidInitializer,
         templateDeferredTypeAnnotation,
         templateIntegerLiteralIsOutOfRange,
+        templateMissingExplicitTypeArguments,
         templateNotAType,
         templateUnresolvedPrefixInTypeAnnotation;
 
@@ -632,6 +633,12 @@
         // as a recovery node once the IR can represent it (Issue #29840).
         arguments = null;
       }
+    } else if (declaration.typeVariablesCount != 0) {
+      helper.addProblem(
+          templateMissingExplicitTypeArguments
+              .withArguments(declaration.typeVariablesCount),
+          offsetForToken(token),
+          lengthForToken(token));
     }
 
     DartType type;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 5351b10..3589b1c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -22,7 +22,7 @@
 
 import 'forest.dart' show Forest;
 
-import 'kernel_builder.dart' show PrefixBuilder;
+import 'kernel_builder.dart' show KernelTypeBuilder, PrefixBuilder;
 
 import 'kernel_ast_api.dart'
     show
@@ -130,7 +130,7 @@
       Member interfaceTarget});
 
   Expression buildConstructorInvocation(
-      TypeDeclarationBuilder type,
+      TypeDeclarationBuilder<KernelTypeBuilder, DartType> type,
       Token nameToken,
       Arguments arguments,
       String name,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
index 5c4c3d9..0964665 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
@@ -230,10 +230,12 @@
   @override
   Class build(KernelLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary) {
     cls.isEnum = true;
-    intType.resolveIn(coreLibrary.scope, charOffset, fileUri);
-    stringType.resolveIn(coreLibrary.scope, charOffset, fileUri);
-    objectType.resolveIn(coreLibrary.scope, charOffset, fileUri);
-    listType.resolveIn(coreLibrary.scope, charOffset, fileUri);
+    intType.resolveIn(coreLibrary.scope, charOffset, fileUri, libraryBuilder);
+    stringType.resolveIn(
+        coreLibrary.scope, charOffset, fileUri, libraryBuilder);
+    objectType.resolveIn(
+        coreLibrary.scope, charOffset, fileUri, libraryBuilder);
+    listType.resolveIn(coreLibrary.scope, charOffset, fileUri, libraryBuilder);
 
     KernelFieldBuilder indexFieldBuilder = this["index"];
     Field indexField = indexFieldBuilder.build(libraryBuilder);
diff --git a/pkg/front_end/lib/src/fasta/rewrite_severity.dart b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
index 5238c7d..9298669 100644
--- a/pkg/front_end/lib/src/fasta/rewrite_severity.dart
+++ b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
@@ -8,36 +8,120 @@
 
 Severity rewriteSeverity(
     Severity severity, msg.Code<Object> code, Uri fileUri) {
-  if (severity == Severity.ignored &&
-      fileUri.path.contains("/pkg/front_end/lib/src/fasta/")) {
-    String path = fileUri.path;
-    if (code == msg.codeUseOfDeprecatedIdentifier) {
-      // TODO(ahe): Remove the exceptions below.
-      // We plan to remove all uses of deprecated identifiers from Fasta. The
-      // strategy is to remove files from the list below one by one. To get
-      // started on cleaning up a given file, simply remove it from the list
-      // below and compile Fasta with itself to get a list of remaining call
-      // sites.
-      if (path.endsWith("/command_line_reporting.dart")) return severity;
-      if (path.endsWith("/deprecated_problems.dart")) return severity;
-      if (path.endsWith("/kernel/body_builder.dart")) return severity;
-      if (path.endsWith("/kernel/expression_generator.dart")) return severity;
-      if (path.endsWith("/kernel/kernel_expression_generator.dart"))
+  if (severity != Severity.ignored) return severity;
+  String path = fileUri.path;
+  const String fastaPath = "/pkg/front_end/lib/src/fasta/";
+  int index = path.indexOf(fastaPath);
+  if (index == -1) return severity;
+  if (code == msg.codeUseOfDeprecatedIdentifier) {
+    // TODO(ahe): Remove the exceptions below.
+    // We plan to remove all uses of deprecated identifiers from Fasta. The
+    // strategy is to remove files from the list below one by one. To get
+    // started on cleaning up a given file, simply remove it from the list
+    // below and compile Fasta with itself to get a list of remaining call
+    // sites.
+    switch (path.substring(fastaPath.length + index)) {
+      case "command_line_reporting.dart":
+      case "deprecated_problems.dart":
+      case "kernel/body_builder.dart":
+      case "kernel/expression_generator.dart":
+      case "kernel/kernel_expression_generator.dart":
+      case "kernel/kernel_expression_generator_impl.dart":
+      case "kernel/kernel_procedure_builder.dart":
+      case "kernel/kernel_target.dart":
+      case "kernel/kernel_type_variable_builder.dart":
+      case "quote.dart":
+      case "source/diet_listener.dart":
+      case "source/source_library_builder.dart":
+      case "source/source_loader.dart":
+      case "source/stack_listener.dart":
         return severity;
-      if (path.endsWith("/kernel/kernel_expression_generator_impl.dart"))
-        return severity;
-      if (path.endsWith("/kernel/kernel_procedure_builder.dart"))
-        return severity;
-      if (path.endsWith("/kernel/kernel_target.dart")) return severity;
-      if (path.endsWith("/kernel/kernel_type_variable_builder.dart"))
-        return severity;
-      if (path.endsWith("/quote.dart")) return severity;
-      if (path.endsWith("/source/diet_listener.dart")) return severity;
-      if (path.endsWith("/source/source_library_builder.dart")) return severity;
-      if (path.endsWith("/source/source_loader.dart")) return severity;
-      if (path.endsWith("/source/stack_listener.dart")) return severity;
     }
-    return Severity.error;
+  } else if (code == msg.codeMissingExplicitTypeArguments) {
+    // TODO(ahe): Remove the exceptions below.
+    // We're not sure if we want to require that all types have explicit type
+    // arguments in Fasta. Regardles, the strategy is to remove files from the
+    // list below one by one. To get started on cleaning up a given file,
+    // simply remove it from the list below and compile Fasta with itself to
+    // get a list of remaining call sites.
+    switch (path.substring(fastaPath.length + index)) {
+      case "builder/builtin_type_builder.dart":
+      case "builder/class_builder.dart":
+      case "builder/constructor_reference_builder.dart":
+      case "builder/dynamic_type_builder.dart":
+      case "builder/field_builder.dart":
+      case "builder/formal_parameter_builder.dart":
+      case "builder/function_type_alias_builder.dart":
+      case "builder/function_type_builder.dart":
+      case "builder/library_builder.dart":
+      case "builder/member_builder.dart":
+      case "builder/metadata_builder.dart":
+      case "builder/mixin_application_builder.dart":
+      case "builder/named_type_builder.dart":
+      case "builder/prefix_builder.dart":
+      case "builder/procedure_builder.dart":
+      case "builder/type_builder.dart":
+      case "builder/type_declaration_builder.dart":
+      case "builder/type_variable_builder.dart":
+      case "builder/unresolved_type.dart":
+      case "builder/void_type_builder.dart":
+      case "builder_graph.dart":
+      case "compiler_context.dart":
+      case "dill/dill_class_builder.dart":
+      case "dill/dill_library_builder.dart":
+      case "dill/dill_loader.dart":
+      case "dill/dill_target.dart":
+      case "dill/dill_typedef_builder.dart":
+      case "export.dart":
+      case "fasta_codes.dart":
+      case "import.dart":
+      case "incremental_compiler.dart":
+      case "kernel/body_builder.dart":
+      case "kernel/expression_generator.dart":
+      case "kernel/expression_generator_helper.dart":
+      case "kernel/fangorn.dart":
+      case "kernel/forest.dart":
+      case "kernel/kernel_class_builder.dart":
+      case "kernel/kernel_enum_builder.dart":
+      case "kernel/kernel_expression_generator.dart":
+      case "kernel/kernel_expression_generator_impl.dart":
+      case "kernel/kernel_field_builder.dart":
+      case "kernel/kernel_formal_parameter_builder.dart":
+      case "kernel/kernel_function_type_alias_builder.dart":
+      case "kernel/kernel_function_type_builder.dart":
+      case "kernel/kernel_invalid_type_builder.dart":
+      case "kernel/kernel_library_builder.dart":
+      case "kernel/kernel_mixin_application_builder.dart":
+      case "kernel/kernel_named_type_builder.dart":
+      case "kernel/kernel_prefix_builder.dart":
+      case "kernel/kernel_procedure_builder.dart":
+      case "kernel/kernel_shadow_ast.dart":
+      case "kernel/kernel_target.dart":
+      case "kernel/kernel_type_builder.dart":
+      case "kernel/kernel_type_variable_builder.dart":
+      case "kernel/load_library_builder.dart":
+      case "kernel/metadata_collector.dart":
+      case "kernel/type_algorithms.dart":
+      case "kernel/verifier.dart":
+      case "loader.dart":
+      case "scanner/error_token.dart":
+      case "scanner/recover.dart":
+      case "scope.dart":
+      case "source/diet_listener.dart":
+      case "source/outline_builder.dart":
+      case "source/source_class_builder.dart":
+      case "source/source_library_builder.dart":
+      case "source/source_loader.dart":
+      case "source/stack_listener.dart":
+      case "target_implementation.dart":
+      case "type_inference/interface_resolver.dart":
+      case "type_inference/type_inference_engine.dart":
+      case "type_inference/type_inferrer.dart":
+      case "type_inference/type_schema.dart":
+      case "util/link.dart":
+      case "util/link_implementation.dart":
+        return severity;
+    }
   }
-  return severity;
+  return Severity.error;
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 9b5db36..99631ab 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -712,7 +712,7 @@
   int resolveTypes() {
     int typeCount = types.length;
     for (UnresolvedType<T> t in types) {
-      t.resolveIn(scope);
+      t.resolveIn(scope, this);
       if (loader.target.strongMode) {
         t.checkType();
       } else {
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index df83d386..11bcacc 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2299,3 +2299,7 @@
   severity: WARNING
   frontendInternal: true
   external: test/incremental_load_from_invalid_dill_test.dart
+
+MissingExplicitTypeArguments:
+  template: "No type arguments provided, #count possible."
+  severity: IGNORED