Flatten DynamicUse and StaticUse class hierarchies

Change-Id: Ib325425dfab7d7001a1a6133df1d50dddfadcbab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102700
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 36d9600..290c803 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -66,7 +66,8 @@
     }
     for (Selector selector in dynamicUses) {
       assert(selector != null);
-      worldImpactBuilder.registerDynamicUse(new DynamicUse(selector));
+      worldImpactBuilder
+          .registerDynamicUse(new DynamicUse(selector, null, const []));
     }
     for (InterfaceType instantiatedType in instantiatedTypes) {
       worldImpactBuilder
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 6041116..5415e98 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -466,7 +466,7 @@
     Selector selector = new Selector.callClosure(
         0, const <String>[], thisType.typeArguments.length);
     impactBuilder.registerDynamicUse(
-        new ConstrainedDynamicUse(selector, null, thisType.typeArguments));
+        new DynamicUse(selector, null, thisType.typeArguments));
   }
 
   @override
@@ -564,8 +564,8 @@
     // TODO(johnniwinther): Yet, alas, we need the dynamic use for now. Remove
     // this when kernel adds an `isFunctionCall` flag to
     // [ir.MethodInvocation].
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        callStructure.callSelector, null, dartTypeArguments));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(callStructure.callSelector, null, dartTypeArguments));
   }
 
   @override
@@ -579,7 +579,7 @@
     Selector selector = elementMap.getInvocationSelector(
         name, positionalArguments, namedArguments, typeArguments.length);
     List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(selector,
+    impactBuilder.registerDynamicUse(new DynamicUse(selector,
         _computeReceiverConstraint(receiverType, relation), dartTypeArguments));
   }
 
@@ -594,7 +594,7 @@
         namedArguments,
         typeArguments.length);
     List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         callStructure.callSelector,
         _computeReceiverConstraint(receiverType, ClassRelation.subtype),
         dartTypeArguments));
@@ -609,7 +609,7 @@
       List<String> namedArguments,
       List<ir.DartType> typeArguments) {
     List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         elementMap.getInvocationSelector(target.name, positionalArguments,
             namedArguments, typeArguments.length),
         _computeReceiverConstraint(receiverType, relation),
@@ -619,7 +619,7 @@
   @override
   void registerDynamicGet(
       ir.DartType receiverType, ClassRelation relation, ir.Name name) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.getter(elementMap.getName(name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -628,7 +628,7 @@
   @override
   void registerInstanceGet(
       ir.DartType receiverType, ClassRelation relation, ir.Member target) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.getter(elementMap.getName(target.name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -637,7 +637,7 @@
   @override
   void registerDynamicSet(
       ir.DartType receiverType, ClassRelation relation, ir.Name name) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.setter(elementMap.getName(name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -646,7 +646,7 @@
   @override
   void registerInstanceSet(
       ir.DartType receiverType, ClassRelation relation, ir.Member target) {
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+    impactBuilder.registerDynamicUse(new DynamicUse(
         new Selector.setter(elementMap.getName(target.name)),
         _computeReceiverConstraint(receiverType, relation),
         const <DartType>[]));
@@ -744,12 +744,12 @@
     Object receiverConstraint =
         _computeReceiverConstraint(iteratorType, iteratorClassRelation);
     impactBuilder.registerFeature(Feature.SYNC_FOR_IN);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.iterator, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.current, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.moveNext, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.iterator, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.current, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, receiverConstraint, const []));
   }
 
   @override
@@ -758,12 +758,12 @@
     Object receiverConstraint =
         _computeReceiverConstraint(iteratorType, iteratorClassRelation);
     impactBuilder.registerFeature(Feature.ASYNC_FOR_IN);
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.cancel, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.current, receiverConstraint, const []));
-    impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        Selectors.moveNext, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.cancel, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.current, receiverConstraint, const []));
+    impactBuilder.registerDynamicUse(
+        new DynamicUse(Selectors.moveNext, receiverConstraint, const []));
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 86f367a..502ab8e 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -33,8 +33,7 @@
 import '../tracer.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
-import '../universe/use.dart'
-    show ConstantUse, ConstrainedDynamicUse, StaticUse, TypeUse;
+import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
 import '../world.dart' show JClosedWorld;
 import 'codegen_helpers.dart';
 import 'nodes.dart';
@@ -1982,8 +1981,8 @@
       // may know something about the types of closures that need
       // the specific closure call method.
       Selector call = new Selector.callClosureFrom(selector);
-      _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(call, null, node.typeArguments));
+      _registry
+          .registerDynamicUse(new DynamicUse(call, null, node.typeArguments));
     }
     if (target != null) {
       // This is a dynamic invocation which we have found to have a single
@@ -2000,7 +1999,7 @@
       AbstractValue mask =
           getOptimizedSelectorFor(node, selector, node.receiverType);
       _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, mask, node.typeArguments));
+          new DynamicUse(selector, mask, node.typeArguments));
     }
   }
 
@@ -2016,7 +2015,7 @@
       AbstractValue mask =
           getOptimizedSelectorFor(node, selector, node.receiverType);
       _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, mask, node.typeArguments));
+          new DynamicUse(selector, mask, node.typeArguments));
     }
   }
 
@@ -2034,7 +2033,7 @@
       AbstractValue mask =
           getOptimizedSelectorFor(node, selector, node.receiverType);
       _registry.registerDynamicUse(
-          new ConstrainedDynamicUse(selector, mask, node.typeArguments));
+          new DynamicUse(selector, mask, node.typeArguments));
     }
   }
 
@@ -2069,8 +2068,8 @@
     // TODO(kasperl): If we have a typed selector for the call, we
     // may know something about the types of closures that need
     // the specific closure call method.
-    _registry.registerDynamicUse(
-        new ConstrainedDynamicUse(call, null, node.typeArguments));
+    _registry
+        .registerDynamicUse(new DynamicUse(call, null, node.typeArguments));
   }
 
   @override
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 453f812..8b4c082 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -37,8 +37,17 @@
 /// object on which the property is accessed.
 class DynamicUse {
   final Selector selector;
+  final Object receiverConstraint;
+  final List<DartType> _typeArguments;
 
-  DynamicUse(this.selector);
+  DynamicUse(this.selector, this.receiverConstraint, this._typeArguments) {
+    assert(
+        selector.callStructure.typeArgumentCount ==
+            (_typeArguments?.length ?? 0),
+        "Type argument count mismatch. Selector has "
+        "${selector.callStructure.typeArgumentCount} but "
+        "${_typeArguments?.length ?? 0} were passed.");
+  }
 
   /// Short textual representation use for testing.
   String get shortText {
@@ -71,8 +80,6 @@
     return sb.toString();
   }
 
-  Object get receiverConstraint => null;
-
   DynamicUseKind get kind {
     if (selector.isGetter) {
       return DynamicUseKind.GET;
@@ -83,7 +90,7 @@
     }
   }
 
-  List<DartType> get typeArguments => const <DartType>[];
+  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
 
   @override
   int get hashCode => Hashing.listHash(
@@ -99,48 +106,7 @@
   }
 
   @override
-  String toString() => '$selector,$receiverConstraint';
-}
-
-class GenericDynamicUse extends DynamicUse {
-  final List<DartType> _typeArguments;
-
-  GenericDynamicUse(Selector selector, [this._typeArguments])
-      : super(selector) {
-    assert(
-        selector.callStructure.typeArgumentCount ==
-            (_typeArguments?.length ?? 0),
-        "Type argument count mismatch. Selector has "
-        "${selector.callStructure.typeArgumentCount} but "
-        "${typeArguments?.length ?? 0} were passed.");
-  }
-
-  @override
-  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
-}
-
-/// A dynamic use with a receiver constraint.
-///
-/// This is used in the codegen phase where receivers are constrained to a
-/// type mask or similar.
-class ConstrainedDynamicUse extends DynamicUse {
-  @override
-  final Object receiverConstraint;
-  final List<DartType> _typeArguments;
-
-  ConstrainedDynamicUse(
-      Selector selector, this.receiverConstraint, this._typeArguments)
-      : super(selector) {
-    assert(
-        selector.callStructure.typeArgumentCount ==
-            (_typeArguments?.length ?? 0),
-        "Type argument count mismatch. Selector has "
-        "${selector.callStructure.typeArgumentCount} but "
-        "${_typeArguments?.length ?? 0} were passed.");
-  }
-
-  @override
-  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
+  String toString() => '$selector,$receiverConstraint,$typeArguments';
 }
 
 enum StaticUseKind {
@@ -178,24 +144,36 @@
   final CallStructure callStructure;
   final ImportEntity deferredImport;
   final ConstantValue constant;
+  final List<DartType> typeArguments;
 
   StaticUse.internal(Entity element, this.kind,
       {this.type,
       this.callStructure,
       this.deferredImport,
-      typeArgumentsHash: 0,
+      this.typeArguments,
       this.constant})
       : this.element = element,
         this.hashCode = Hashing.listHash([
           element,
           kind,
           type,
-          typeArgumentsHash,
+          Hashing.listHash(typeArguments),
           callStructure,
           deferredImport,
           constant
         ]);
 
+  bool _checkGenericInvariants() {
+    assert(
+        (callStructure?.typeArgumentCount ?? 0) == (typeArguments?.length ?? 0),
+        failedAt(
+            element,
+            "Type argument count mismatch. Call structure has "
+            "${callStructure?.typeArgumentCount ?? 0} but "
+            "${typeArguments?.length ?? 0} were passed in $this."));
+    return true;
+  }
+
   /// Short textual representation use for testing.
   String get shortText {
     StringBuffer sb = new StringBuffer();
@@ -252,8 +230,6 @@
     return sb.toString();
   }
 
-  List<DartType> get typeArguments => null;
-
   /// Invocation of a static or top-level [element] with the given
   /// [callStructure].
   factory StaticUse.staticInvoke(
@@ -272,8 +248,13 @@
         failedAt(element,
             "Not CallStructure for static invocation of element $element."));
 
-    return new GenericStaticUse(element, StaticUseKind.STATIC_INVOKE,
-        callStructure, typeArguments, deferredImport);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.STATIC_INVOKE,
+        callStructure: callStructure,
+        typeArguments: typeArguments,
+        deferredImport: deferredImport);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Closurization of a static or top-level function [element].
@@ -351,8 +332,11 @@
         callStructure != null,
         failedAt(element,
             "Not CallStructure for super invocation of element $element."));
-    return new GenericStaticUse(
-        element, StaticUseKind.SUPER_INVOKE, callStructure, typeArguments);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.SUPER_INVOKE,
+        callStructure: callStructure, typeArguments: typeArguments);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Read access of a super field or getter [element].
@@ -449,8 +433,11 @@
             "Direct invoke element $element must be an instance member."));
     assert(element.isFunction,
         failedAt(element, "Direct invoke element $element must be a method."));
-    return new GenericStaticUse(
-        element, StaticUseKind.DIRECT_INVOKE, callStructure, typeArguments);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.DIRECT_INVOKE,
+        callStructure: callStructure, typeArguments: typeArguments);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Direct read access of a field or getter [element].
@@ -584,8 +571,11 @@
   /// [callStructure] and [typeArguments].
   factory StaticUse.closureCall(Local element, CallStructure callStructure,
       List<DartType> typeArguments) {
-    return new GenericStaticUse(
-        element, StaticUseKind.CLOSURE_CALL, callStructure, typeArguments);
+    StaticUse staticUse = new StaticUse.internal(
+        element, StaticUseKind.CLOSURE_CALL,
+        callStructure: callStructure, typeArguments: typeArguments);
+    assert(staticUse._checkGenericInvariants());
+    return staticUse;
   }
 
   /// Read of a call [method] on a closureClass.
@@ -610,7 +600,8 @@
   /// Inlining of [element].
   factory StaticUse.methodInlining(
       FunctionEntity element, List<DartType> typeArguments) {
-    return new GenericStaticUse.methodInlining(element, typeArguments);
+    return new StaticUse.internal(element, StaticUseKind.INLINING,
+        typeArguments: typeArguments);
   }
 
   @override
@@ -631,31 +622,6 @@
       'StaticUse($element,$kind,$type,$typeArguments,$callStructure)';
 }
 
-class GenericStaticUse extends StaticUse {
-  @override
-  final List<DartType> typeArguments;
-
-  GenericStaticUse(Entity entity, StaticUseKind kind,
-      CallStructure callStructure, this.typeArguments,
-      [ImportEntity deferredImport])
-      : super.internal(entity, kind,
-            callStructure: callStructure,
-            deferredImport: deferredImport,
-            typeArgumentsHash: Hashing.listHash(typeArguments)) {
-    assert(
-        (callStructure?.typeArgumentCount ?? 0) == (typeArguments?.length ?? 0),
-        failedAt(
-            element,
-            "Type argument count mismatch. Call structure has "
-            "${callStructure?.typeArgumentCount ?? 0} but "
-            "${typeArguments?.length ?? 0} were passed in $this."));
-  }
-
-  GenericStaticUse.methodInlining(FunctionEntity entity, this.typeArguments)
-      : super.internal(entity, StaticUseKind.INLINING,
-            typeArgumentsHash: Hashing.listHash(typeArguments));
-}
-
 enum TypeUseKind {
   IS_CHECK,
   AS_CAST,
diff --git a/tests/compiler/dart2js/model/enqueuer_test.dart b/tests/compiler/dart2js/model/enqueuer_test.dart
index 3417206..e792a10 100644
--- a/tests/compiler/dart2js/model/enqueuer_test.dart
+++ b/tests/compiler/dart2js/model/enqueuer_test.dart
@@ -195,8 +195,8 @@
         new Name(methodName, elementEnvironment.mainLibrary),
         CallStructure.NO_ARGS);
     WorldImpact impact = new WorldImpactBuilderImpl()
-      ..registerDynamicUse(new ConstrainedDynamicUse(
-          selector, createConstraint(cls), const <DartType>[]));
+      ..registerDynamicUse(
+          new DynamicUse(selector, createConstraint(cls), const <DartType>[]));
     enqueuer.applyImpact(impact);
   }