Move more parts of impact builder to ir/impact.dart

Change-Id: I64ef1add990548208f2eda28c8486d88f00504a3
Reviewed-on: https://dart-review.googlesource.com/c/88950
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index d63d791..99a364b 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -285,4 +285,93 @@
       ir.RedirectingInitializer node, ArgumentTypes argumentTypes) {
     registerRedirectingInitializer(node.target, node.arguments);
   }
+
+  void registerParameterCheck(ir.DartType type);
+
+  @override
+  void handleParameter(ir.VariableDeclaration parameter) {
+    registerParameterCheck(parameter.type);
+  }
+
+  @override
+  void handleSignature(ir.FunctionNode node) {
+    for (ir.TypeParameter parameter in node.typeParameters) {
+      registerParameterCheck(parameter.bound);
+    }
+  }
+
+  void registerLazyField();
+
+  @override
+  void handleField(ir.Field field) {
+    registerParameterCheck(field.type);
+    if (field.initializer != null) {
+      if (!field.isInstanceMember &&
+          !field.isConst &&
+          field.initializer is! ir.NullLiteral) {
+        registerLazyField();
+      }
+    } else {
+      registerNullLiteral();
+    }
+  }
+
+  @override
+  void handleProcedure(ir.Procedure procedure) {
+    handleAsyncMarker(procedure.function);
+  }
+
+  void registerNew(ir.Member constructor, ir.InterfaceType type,
+      ir.Arguments arguments, ir.LibraryDependency import,
+      {bool isConst});
+
+  @override
+  void handleConstructorInvocation(ir.ConstructorInvocation node,
+      ArgumentTypes argumentTypes, ir.DartType resultType) {
+    registerNew(node.target, node.constructedType, node.arguments,
+        getDeferredImport(node),
+        isConst: node.isConst);
+  }
+
+  void registerStaticInvocation(
+      ir.Procedure target, ir.Arguments arguments, ir.LibraryDependency import);
+
+  @override
+  void handleStaticInvocation(ir.StaticInvocation node,
+      ArgumentTypes argumentTypes, ir.DartType returnType) {
+    if (node.target.kind == ir.ProcedureKind.Factory) {
+      // TODO(johnniwinther): We should not mark the type as instantiated but
+      // rather follow the type arguments directly.
+      //
+      // Consider this:
+      //
+      //    abstract class A<T> {
+      //      factory A.regular() => new B<T>();
+      //      factory A.redirect() = B<T>;
+      //    }
+      //
+      //    class B<T> implements A<T> {}
+      //
+      //    main() {
+      //      print(new A<int>.regular() is B<int>);
+      //      print(new A<String>.redirect() is B<String>);
+      //    }
+      //
+      // To track that B is actually instantiated as B<int> and B<String> we
+      // need to follow the type arguments passed to A.regular and A.redirect
+      // to B. Currently, we only do this soundly if we register A<int> and
+      // A<String> as instantiated. We should instead register that A.T is
+      // instantiated as int and String.
+      registerNew(
+          node.target,
+          new ir.InterfaceType(
+              node.target.enclosingClass, node.arguments.types),
+          node.arguments,
+          getDeferredImport(node),
+          isConst: node.isConst);
+    } else {
+      registerStaticInvocation(
+          node.target, node.arguments, getDeferredImport(node));
+    }
+  }
 }
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index c570bbd..de88b6f 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -54,22 +54,12 @@
   bool get inferEffectivelyFinalVariableTypes =>
       !_annotations.contains(PragmaAnnotation.disableFinal);
 
-  /// Add a checked-mode type use of [type] if it is not `dynamic`.
-  DartType checkType(ir.DartType irType, TypeUseKind kind) {
+  @override
+  void registerParameterCheck(ir.DartType irType) {
     DartType type = elementMap.getDartType(irType);
-    if (kind != null && !type.isDynamic) {
-      switch (kind) {
-        case TypeUseKind.PARAMETER_CHECK:
-          impactBuilder.registerTypeUse(new TypeUse.parameterCheck(type));
-          break;
-        case TypeUseKind.IMPLICIT_CAST:
-          impactBuilder.registerTypeUse(new TypeUse.implicitCast(type));
-          break;
-        default:
-          throw new UnsupportedError("Unexpected type check kind: $kind");
-      }
+    if (!type.isDynamic) {
+      impactBuilder.registerTypeUse(new TypeUse.parameterCheck(type));
     }
-    return type;
   }
 
   List<DartType> _getTypeArguments(ir.Arguments arguments) {
@@ -77,34 +67,14 @@
     return arguments.types.map(elementMap.getDartType).toList();
   }
 
-  /// Add checked-mode type use for the parameter type and constant for the
-  /// default value of [parameter].
   @override
-  void handleParameter(ir.VariableDeclaration parameter) {
-    checkType(parameter.type, TypeUseKind.PARAMETER_CHECK);
-  }
-
-  /// Add checked-mode type use for parameter and return types, and add
-  /// constants for default values.
-  @override
-  void handleSignature(ir.FunctionNode node) {
-    for (ir.TypeParameter parameter in node.typeParameters) {
-      checkType(parameter.bound, TypeUseKind.PARAMETER_CHECK);
-    }
+  void registerLazyField() {
+    impactBuilder.registerFeature(Feature.LAZY_FIELD);
   }
 
   @override
   void handleField(ir.Field field) {
-    checkType(field.type, TypeUseKind.PARAMETER_CHECK);
-    if (field.initializer != null) {
-      if (!field.isInstanceMember &&
-          !field.isConst &&
-          field.initializer is! ir.NullLiteral) {
-        impactBuilder.registerFeature(Feature.LAZY_FIELD);
-      }
-    } else {
-      impactBuilder.registerConstantLiteral(new NullConstantExpression());
-    }
+    super.handleField(field);
 
     if (field.isInstanceMember &&
         elementMap.isNativeClass(field.enclosingClass)) {
@@ -156,7 +126,8 @@
 
   @override
   void handleProcedure(ir.Procedure procedure) {
-    handleAsyncMarker(procedure.function);
+    super.handleProcedure(procedure);
+
     MemberEntity member = elementMap.getMember(procedure);
     if (procedure.isExternal && !commonElements.isForeignHelper(member)) {
       bool isJsInterop = _nativeBasicData.isJsInteropMember(member);
@@ -216,14 +187,21 @@
   }
 
   @override
-  void handleConstructorInvocation(ir.ConstructorInvocation node,
-      ArgumentTypes argumentTypes, ir.DartType resultType) {
-    handleNew(node, node.target, isConst: node.isConst);
-  }
-
-  void handleNew(ir.InvocationExpression node, ir.Member target,
-      {bool isConst: false}) {
+  void registerNew(ir.Member target, ir.InterfaceType type,
+      ir.Arguments arguments, ir.LibraryDependency import,
+      {bool isConst}) {
     ConstructorEntity constructor = elementMap.getConstructor(target);
+    CallStructure callStructure = elementMap.getCallStructure(arguments);
+    ImportEntity deferredImport = elementMap.getImport(import);
+    impactBuilder.registerStaticUse(isConst
+        ? new StaticUse.constConstructorInvoke(constructor, callStructure,
+            elementMap.getDartType(type), deferredImport)
+        : new StaticUse.typedConstructorInvoke(constructor, callStructure,
+            elementMap.getDartType(type), deferredImport));
+    if (type.typeArguments.any((ir.DartType type) => type is! ir.DynamicType)) {
+      impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
+    }
+
     if (commonElements.isSymbolConstructor(constructor)) {
       impactBuilder.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
     }
@@ -236,21 +214,9 @@
       // return here.
     }
 
-    InterfaceType type = elementMap.createInterfaceType(
-        target.enclosingClass, node.arguments.types);
-    CallStructure callStructure = elementMap.getCallStructure(node.arguments);
-    ImportEntity deferredImport = elementMap.getImport(getDeferredImport(node));
-    impactBuilder.registerStaticUse(isConst
-        ? new StaticUse.constConstructorInvoke(
-            constructor, callStructure, type, deferredImport)
-        : new StaticUse.typedConstructorInvoke(
-            constructor, callStructure, type, deferredImport));
-    if (type.typeArguments.any((DartType type) => !type.isDynamic)) {
-      impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
-    }
     if (isConst && commonElements.isSymbolConstructor(constructor)) {
       ConstantValue value =
-          elementMap.getConstantValue(node.arguments.positional.first);
+          elementMap.getConstantValue(arguments.positional.first);
       if (!value.isString) {
         // TODO(het): Get the actual span for the Symbol constructor argument
         reporter.reportErrorMessage(
@@ -277,47 +243,26 @@
         target, elementMap.getCallStructure(node.arguments)));
   }
 
+  @override
+  void registerStaticInvocation(ir.Procedure procedure, ir.Arguments arguments,
+      ir.LibraryDependency import) {
+    FunctionEntity target = elementMap.getMethod(procedure);
+    CallStructure callStructure = elementMap.getCallStructure(arguments);
+    List<DartType> typeArguments = _getTypeArguments(arguments);
+    if (commonElements.isExtractTypeArguments(target)) {
+      _handleExtractTypeArguments(target, typeArguments, callStructure);
+      return;
+    } else {
+      ImportEntity deferredImport = elementMap.getImport(import);
+      impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+          target, callStructure, typeArguments, deferredImport));
+    }
+  }
+
   void handleStaticInvocation(ir.StaticInvocation node,
       ArgumentTypes argumentTypes, ir.DartType returnType) {
-    if (node.target.kind == ir.ProcedureKind.Factory) {
-      // TODO(johnniwinther): We should not mark the type as instantiated but
-      // rather follow the type arguments directly.
-      //
-      // Consider this:
-      //
-      //    abstract class A<T> {
-      //      factory A.regular() => new B<T>();
-      //      factory A.redirect() = B<T>;
-      //    }
-      //
-      //    class B<T> implements A<T> {}
-      //
-      //    main() {
-      //      print(new A<int>.regular() is B<int>);
-      //      print(new A<String>.redirect() is B<String>);
-      //    }
-      //
-      // To track that B is actually instantiated as B<int> and B<String> we
-      // need to follow the type arguments passed to A.regular and A.redirect
-      // to B. Currently, we only do this soundly if we register A<int> and
-      // A<String> as instantiated. We should instead register that A.T is
-      // instantiated as int and String.
-      handleNew(node, node.target, isConst: node.isConst);
-    } else {
-      FunctionEntity target = elementMap.getMethod(node.target);
-      List<DartType> typeArguments = _getTypeArguments(node.arguments);
-      if (commonElements.isExtractTypeArguments(target)) {
-        _handleExtractTypeArguments(node, target, typeArguments);
-        return;
-      }
-      ImportEntity deferredImport =
-          elementMap.getImport(getDeferredImport(node));
-      impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-          target,
-          elementMap.getCallStructure(node.arguments),
-          typeArguments,
-          deferredImport));
-    }
+    super.handleStaticInvocation(node, argumentTypes, returnType);
+
     switch (elementMap.getForeignKind(node)) {
       case ForeignKind.JS:
         impactBuilder
@@ -343,8 +288,8 @@
     }
   }
 
-  void _handleExtractTypeArguments(ir.StaticInvocation node,
-      FunctionEntity target, List<DartType> typeArguments) {
+  void _handleExtractTypeArguments(FunctionEntity target,
+      List<DartType> typeArguments, CallStructure callStructure) {
     // extractTypeArguments<Map>(obj, fn) has additional impacts:
     //
     //   1. All classes implementing Map need to carry type arguments (similar
@@ -352,8 +297,8 @@
     //
     //   2. There is an invocation of fn with some number of type arguments.
     //
-    impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-        target, elementMap.getCallStructure(node.arguments), typeArguments));
+    impactBuilder.registerStaticUse(
+        new StaticUse.staticInvoke(target, callStructure, typeArguments));
 
     if (typeArguments.length != 1) return;
     DartType matchedType = typeArguments.first;