Remove dependency on TypeEnvironment.hierarchy

Change-Id: Ibc675aa37bf1d5f90640b41471d094025ae3da86
Reviewed-on: https://dart-review.googlesource.com/c/88805
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Auto-Submit: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 877ff1f..3343ce2 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -36,7 +36,9 @@
   Map<ir.Expression, ir.DartType> _cache = {};
   Map<ir.Expression, TypeMap> typeMapsForTesting;
 
-  StaticTypeVisitor(ir.TypeEnvironment typeEnvironment)
+  final ir.ClassHierarchy hierarchy;
+
+  StaticTypeVisitor(ir.TypeEnvironment typeEnvironment, this.hierarchy)
       : super(typeEnvironment);
 
   Map<ir.Expression, ir.DartType> get cachedStaticTypes => _cache;
@@ -165,8 +167,8 @@
       ir.PropertyGet node, ir.DartType receiverType) {
     ir.Member interfaceTarget = node.interfaceTarget;
     if (interfaceTarget == null && receiverType is ir.InterfaceType) {
-      interfaceTarget = node.interfaceTarget = typeEnvironment.hierarchy
-          .getInterfaceMember(receiverType.classNode, node.name);
+      interfaceTarget = node.interfaceTarget =
+          hierarchy.getInterfaceMember(receiverType.classNode, node.name);
     }
     if (interfaceTarget != null) {
       ir.Class superclass = interfaceTarget.enclosingClass;
@@ -205,7 +207,7 @@
     ir.DartType receiverType = visitNode(node.receiver);
     ir.DartType valueType = super.visitPropertySet(node);
     if (node.interfaceTarget == null && receiverType is ir.InterfaceType) {
-      node.interfaceTarget = typeEnvironment.hierarchy
+      node.interfaceTarget = hierarchy
           .getInterfaceMember(receiverType.classNode, node.name, setter: true);
     }
     receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
@@ -388,8 +390,8 @@
       interfaceTarget = node.interfaceTarget = objectEquals;
     }
     if (interfaceTarget == null && receiverType is ir.InterfaceType) {
-      ir.Member member = typeEnvironment.hierarchy
-          .getInterfaceMember(receiverType.classNode, node.name);
+      ir.Member member =
+          hierarchy.getInterfaceMember(receiverType.classNode, node.name);
       if (_isApplicable(node.arguments, member)) {
         interfaceTarget = node.interfaceTarget = member;
       }
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 68618f8..33648d8 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -99,6 +99,7 @@
   JsConstantEnvironment _constantEnvironment;
   KernelDartTypes _types;
   ir.TypeEnvironment _typeEnvironment;
+  ir.ClassHierarchy _classHierarchy;
 
   /// Library environment. Used for fast lookup.
   JProgramEnv programEnv;
@@ -1057,12 +1058,18 @@
   ir.TypeEnvironment get typeEnvironment {
     if (_typeEnvironment == null) {
       _typeEnvironment ??= new ir.TypeEnvironment(
-          new ir.CoreTypes(programEnv.mainComponent),
-          new ir.ClassHierarchy(programEnv.mainComponent));
+          new ir.CoreTypes(programEnv.mainComponent), classHierarchy);
     }
     return _typeEnvironment;
   }
 
+  ir.ClassHierarchy get classHierarchy {
+    if (_classHierarchy == null) {
+      _classHierarchy ??= new ir.ClassHierarchy(programEnv.mainComponent);
+    }
+    return _classHierarchy;
+  }
+
   StaticTypeProvider getStaticTypeProvider(MemberEntity member) {
     MemberDefinition memberDefinition = members.getData(member).definition;
     Map<ir.Expression, ir.DartType> cachedStaticTypes;
@@ -1098,8 +1105,7 @@
     return new CachedStaticType(
         // We need a copy of the type environment since the `thisType` field
         // is holds state, making the environment contextually bound.
-        new ir.TypeEnvironment(
-            typeEnvironment.coreTypes, typeEnvironment.hierarchy)
+        new ir.TypeEnvironment(typeEnvironment.coreTypes, classHierarchy)
           ..thisType = thisType,
         cachedStaticTypes);
   }
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 9533b15..a798726 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../constants/values.dart';
@@ -29,8 +30,12 @@
   /// Access to the [DartTypes] object.
   DartTypes get types;
 
+  /// Returns the type environment for the underlying kernel model.
   ir.TypeEnvironment get typeEnvironment;
 
+  /// Returns the class hierarchy for the underlying kernel model.
+  ir.ClassHierarchy get classHierarchy;
+
   /// Returns the [DartType] corresponding to [type].
   DartType getDartType(ir.DartType type);
 
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 6c0a91c..f236a92 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -71,6 +71,7 @@
   KernelConstantEnvironment _constantEnvironment;
   KernelDartTypes _types;
   ir.TypeEnvironment _typeEnvironment;
+  ir.ClassHierarchy _classHierarchy;
 
   /// Library environment. Used for fast lookup.
   KProgramEnv env = new KProgramEnv();
@@ -718,12 +719,18 @@
   ir.TypeEnvironment get typeEnvironment {
     if (_typeEnvironment == null) {
       _typeEnvironment ??= new ir.TypeEnvironment(
-          new ir.CoreTypes(env.mainComponent),
-          new ir.ClassHierarchy(env.mainComponent));
+          new ir.CoreTypes(env.mainComponent), classHierarchy);
     }
     return _typeEnvironment;
   }
 
+  ir.ClassHierarchy get classHierarchy {
+    if (_classHierarchy == null) {
+      _classHierarchy ??= new ir.ClassHierarchy(env.mainComponent);
+    }
+    return _classHierarchy;
+  }
+
   DartType getStaticType(ir.Expression node) {
     ir.TreeNode enclosingClass = node;
     while (enclosingClass != null && enclosingClass is! ir.Class) {
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 6a29c13..664c565 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -42,7 +42,7 @@
       this._options, this.variableScopeModel, this._annotations)
       : this.impactBuilder =
             new ResolutionWorldImpactBuilder('${currentMember}'),
-        super(elementMap.typeEnvironment);
+        super(elementMap.typeEnvironment, elementMap.classHierarchy);
 
   CommonElements get commonElements => elementMap.commonElements;
 
diff --git a/tests/compiler/dart2js/analyses/analysis_helper.dart b/tests/compiler/dart2js/analyses/analysis_helper.dart
index 9e1560e..715352e 100644
--- a/tests/compiler/dart2js/analyses/analysis_helper.dart
+++ b/tests/compiler/dart2js/analyses/analysis_helper.dart
@@ -71,9 +71,11 @@
 class StaticTypeVisitorBase extends StaticTypeVisitor {
   VariableScopeModel variableScopeModel;
 
-  StaticTypeVisitorBase(ir.Component component)
-      : super(new ir.TypeEnvironment(
-            new ir.CoreTypes(component), new ir.ClassHierarchy(component)));
+  StaticTypeVisitorBase(
+      ir.Component component, ir.ClassHierarchy classHierarchy)
+      : super(
+            new ir.TypeEnvironment(new ir.CoreTypes(component), classHierarchy),
+            classHierarchy);
 
   @override
   bool get useAsserts => false;
@@ -132,7 +134,7 @@
 
   DynamicVisitor(this.reporter, this.component, this._allowedListPath,
       this.analyzedUrisFilter)
-      : super(component);
+      : super(component, new ir.ClassHierarchy(component));
 
   void run({bool verbose = false, bool generate = false}) {
     if (!generate && _allowedListPath != null) {
diff --git a/tests/compiler/dart2js/analyses/static_type_visitor_test.dart b/tests/compiler/dart2js/analyses/static_type_visitor_test.dart
index 6d8613f..d546a06 100644
--- a/tests/compiler/dart2js/analyses/static_type_visitor_test.dart
+++ b/tests/compiler/dart2js/analyses/static_type_visitor_test.dart
@@ -31,7 +31,8 @@
 }
 
 class Visitor extends StaticTypeVisitorBase {
-  Visitor(ir.Component component) : super(component);
+  Visitor(ir.Component component)
+      : super(component, new ir.ClassHierarchy(component));
 
   ir.DartType getStaticType(ir.Expression node) {
     if (typeEnvironment == null) {