[fasta] Add and use a type-inference-specific interface of BodyBuilder

Change-Id: I04c954c4233cc6c43b1f065be95f587a09ed5003
Reviewed-on: https://dart-review.googlesource.com/56328
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
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 5af746c..4d3404a 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
@@ -14,6 +14,8 @@
 
 import '../scope.dart' show ProblemBuilder, Scope;
 
+import '../type_inference/inference_helper.dart' show InferenceHelper;
+
 import '../type_inference/type_promotion.dart' show TypePromoter;
 
 import 'constness.dart' show Constness;
@@ -43,7 +45,8 @@
         PrefixBuilder,
         TypeDeclarationBuilder;
 
-abstract class ExpressionGeneratorHelper<Expression, Statement, Arguments> {
+abstract class ExpressionGeneratorHelper<Expression, Statement, Arguments>
+    implements InferenceHelper<Expression, Statement, Arguments> {
   LibraryBuilder get library;
 
   Uri get uri;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 2bb3a13..36b98a2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -34,7 +34,7 @@
         InstrumentationValueForTypeArgs;
 
 import '../fasta_codes.dart'
-    show templateCantUseSuperBoundedTypeForInstanceCreation;
+    show noLength, templateCantUseSuperBoundedTypeForInstanceCreation;
 
 import '../problems.dart' show unhandled, unsupported;
 
@@ -42,6 +42,8 @@
 
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 
+import '../type_inference/inference_helper.dart' show InferenceHelper;
+
 import '../type_inference/interface_resolver.dart' show InterfaceResolver;
 
 import '../type_inference/type_inference_engine.dart'
@@ -67,8 +69,6 @@
 
 import 'body_builder.dart' show combineStatements;
 
-import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
-
 import 'kernel_expression_generator.dart' show makeLet;
 
 /// Indicates whether type inference involving conditional expressions should
@@ -618,11 +618,11 @@
     if (inferrer.strongMode &&
         !inferrer.isTopLevel &&
         inferrer.typeSchemaEnvironment.isSuperBounded(inferredType)) {
-      inferrer.helper.deprecated_addCompileTimeError(
-          fileOffset,
+      inferrer.helper.addProblem(
           templateCantUseSuperBoundedTypeForInstanceCreation
-              .withArguments(inferredType)
-              .message);
+              .withArguments(inferredType),
+          fileOffset,
+          noLength);
     }
 
     if (isRedirected(this)) {
@@ -2114,8 +2114,7 @@
   }
 
   @override
-  void inferInitializer(
-      ExpressionGeneratorHelper helper, Initializer initializer) {
+  void inferInitializer(InferenceHelper helper, Initializer initializer) {
     assert(initializer is ShadowInitializer);
     this.helper = helper;
     // Use polymorphic dispatch on [KernelInitializer] to perform whatever
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
new file mode 100644
index 0000000..d7c29df
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' show FunctionType;
+
+import '../fasta_codes.dart' show LocatedMessage, Message;
+
+abstract class InferenceHelper<Expression, Statement, Arguments> {
+  Expression wrapInCompileTimeError(Expression expression, Message message);
+
+  Expression buildCompileTimeError(Message message, int charOffset, int length,
+      {List<LocatedMessage> context});
+
+  LocatedMessage checkArgumentsForType(
+      FunctionType function, Arguments arguments, int offset);
+
+  void addProblem(Message message, int charOffset, int length);
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 7a95703..58c6532 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -62,9 +62,6 @@
 
 import '../fasta_codes.dart';
 
-import '../kernel/expression_generator_helper.dart'
-    show ExpressionGeneratorHelper;
-
 import '../kernel/kernel_expression_generator.dart' show buildIsNull;
 
 import '../kernel/kernel_shadow_ast.dart'
@@ -85,6 +82,8 @@
 
 import '../source/source_loader.dart' show SourceLoader;
 
+import 'inference_helper.dart' show InferenceHelper;
+
 import 'interface_resolver.dart' show ForwardingNode, SyntheticAccessor;
 
 import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
@@ -324,20 +323,18 @@
   Uri get uri;
 
   /// Performs full type inference on the given field initializer.
-  void inferFieldInitializer(ExpressionGeneratorHelper helper,
-      DartType declaredType, Expression initializer);
+  void inferFieldInitializer(
+      InferenceHelper helper, DartType declaredType, Expression initializer);
 
   /// Performs type inference on the given function body.
-  void inferFunctionBody(ExpressionGeneratorHelper helper, DartType returnType,
+  void inferFunctionBody(InferenceHelper helper, DartType returnType,
       AsyncMarker asyncMarker, Statement body);
 
   /// Performs type inference on the given constructor initializer.
-  void inferInitializer(
-      ExpressionGeneratorHelper helper, Initializer initializer);
+  void inferInitializer(InferenceHelper helper, Initializer initializer);
 
   /// Performs type inference on the given metadata annotations.
-  void inferMetadata(
-      ExpressionGeneratorHelper helper, List<Expression> annotations);
+  void inferMetadata(InferenceHelper helper, List<Expression> annotations);
 
   /// Performs type inference on the given metadata annotations keeping the
   /// existing helper if possible.
@@ -345,8 +342,8 @@
 
   /// Performs type inference on the given function parameter initializer
   /// expression.
-  void inferParameterInitializer(ExpressionGeneratorHelper helper,
-      Expression initializer, DartType declaredType);
+  void inferParameterInitializer(
+      InferenceHelper helper, Expression initializer, DartType declaredType);
 }
 
 /// Implementation of [TypeInferrer] which doesn't do any type inference.
@@ -366,27 +363,25 @@
   Uri get uri => null;
 
   @override
-  void inferFieldInitializer(ExpressionGeneratorHelper helper,
-      DartType declaredType, Expression initializer) {}
+  void inferFieldInitializer(
+      InferenceHelper helper, DartType declaredType, Expression initializer) {}
 
   @override
-  void inferFunctionBody(ExpressionGeneratorHelper helper, DartType returnType,
+  void inferFunctionBody(InferenceHelper helper, DartType returnType,
       AsyncMarker asyncMarker, Statement body) {}
 
   @override
-  void inferInitializer(
-      ExpressionGeneratorHelper helper, Initializer initializer) {}
+  void inferInitializer(InferenceHelper helper, Initializer initializer) {}
 
   @override
-  void inferMetadata(
-      ExpressionGeneratorHelper helper, List<Expression> annotations) {}
+  void inferMetadata(InferenceHelper helper, List<Expression> annotations) {}
 
   @override
   void inferMetadataKeepingHelper(List<Expression> annotations) {}
 
   @override
-  void inferParameterInitializer(ExpressionGeneratorHelper helper,
-      Expression initializer, DartType declaredType) {}
+  void inferParameterInitializer(
+      InferenceHelper helper, Expression initializer, DartType declaredType) {}
 }
 
 /// Derived class containing generic implementations of [TypeInferrer].
@@ -424,7 +419,7 @@
 
   final SourceLibraryBuilder library;
 
-  ExpressionGeneratorHelper helper;
+  InferenceHelper helper;
 
   /// Context information for the current closure, or `null` if we are not
   /// inside a closure.
@@ -930,8 +925,8 @@
       Expression expression, DartType typeContext, bool typeNeeded);
 
   @override
-  void inferFieldInitializer(ExpressionGeneratorHelper helper,
-      DartType declaredType, Expression initializer) {
+  void inferFieldInitializer(
+      InferenceHelper helper, DartType declaredType, Expression initializer) {
     assert(closureContext == null);
     this.helper = helper;
     var actualType = inferExpression(
@@ -950,7 +945,7 @@
   DartType inferFieldTopLevel(ShadowField field, bool typeNeeded);
 
   @override
-  void inferFunctionBody(ExpressionGeneratorHelper helper, DartType returnType,
+  void inferFunctionBody(InferenceHelper helper, DartType returnType,
       AsyncMarker asyncMarker, Statement body) {
     assert(closureContext == null);
     this.helper = helper;
@@ -1243,8 +1238,7 @@
   }
 
   @override
-  void inferMetadata(
-      ExpressionGeneratorHelper helper, List<Expression> annotations) {
+  void inferMetadata(InferenceHelper helper, List<Expression> annotations) {
     if (annotations != null) {
       this.helper = helper;
       inferMetadataKeepingHelper(annotations);
@@ -1326,8 +1320,8 @@
   }
 
   @override
-  void inferParameterInitializer(ExpressionGeneratorHelper helper,
-      Expression initializer, DartType declaredType) {
+  void inferParameterInitializer(
+      InferenceHelper helper, Expression initializer, DartType declaredType) {
     assert(closureContext == null);
     this.helper = helper;
     assert(declaredType != null);
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
index bf5d7a9..bece5a7 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
@@ -20,6 +20,7 @@
     return new self::Pair::•<self::Pair::U, self::Pair::T>(this.{self::Pair::u}, this.{self::Pair::t});
 }
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Can't use a super-bounded type for instance creation. Got 'test::Pair<test::Clonable<dynamic>, test::Clonable<dynamic>>'.
+Specify a regular-bounded type instead of the super-bounded type. Note that the latter may be due to type inference.
       new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
                                                                                                              ^"]/* from null */;
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
index bf5d7a9..bece5a7 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
@@ -20,6 +20,7 @@
     return new self::Pair::•<self::Pair::U, self::Pair::T>(this.{self::Pair::u}, this.{self::Pair::t});
 }
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Can't use a super-bounded type for instance creation. Got 'test::Pair<test::Clonable<dynamic>, test::Clonable<dynamic>>'.
+Specify a regular-bounded type instead of the super-bounded type. Note that the latter may be due to type inference.
       new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
                                                                                                              ^"]/* from null */;
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect
index 893b908..682d590 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect
@@ -9,6 +9,7 @@
 }
 static field self::B<core::Comparable<dynamic>> y = new self::B::•<core::Comparable<dynamic>>();
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:11:13: Error: Can't use a super-bounded type for instance creation. Got '#lib1::B<dart.core::Comparable<dynamic>>'.
+Specify a regular-bounded type instead of the super-bounded type. Note that the latter may be due to type inference.
 var y = new B();
             ^"]/* from null */;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
index 893b908..682d590 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
@@ -9,6 +9,7 @@
 }
 static field self::B<core::Comparable<dynamic>> y = new self::B::•<core::Comparable<dynamic>>();
 static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:11:13: Error: Can't use a super-bounded type for instance creation. Got '#lib1::B<dart.core::Comparable<dynamic>>'.
+Specify a regular-bounded type instead of the super-bounded type. Note that the latter may be due to type inference.
 var y = new B();
             ^"]/* from null */;
 static method main() → dynamic {}