Move InferredData to GlobalTypeInferenceResults

- and make a pure GlobalTypeInferenceResults interface to prepare for (de)serialization.

Change-Id: I3c2f5f43d686c0d247c611185730134394d86844
Reviewed-on: https://dart-review.googlesource.com/63946
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 4a5d8de..e16eb6f 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -402,7 +402,8 @@
         onProgress: showCodegenProgress);
     codegenEnqueuer.logSummary(reporter.log);
 
-    int programSize = backend.assembleProgram(closedWorld);
+    int programSize = backend.assembleProgram(
+        closedWorld, globalInferenceResults.inferredData);
 
     if (options.dumpInfo) {
       dumpInfoTask.reportSize(programSize);
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index c118ad5..385a7ab 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -292,7 +292,8 @@
     String returnType = '${functionType.returnType}';
 
     String inferredReturnType = '${_resultOfMember(function).returnType}';
-    String sideEffects = '${compiler.globalInference.inferredData
+    String sideEffects = '${compiler
+        .globalInference.resultsForTesting.inferredData
         .getSideEffectsOfElement(function)}';
 
     int inlinedCount = compiler.dumpInfoTask.inlineCount[function];
diff --git a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
index 00c111e..eccd514 100644
--- a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
@@ -61,34 +61,6 @@
         _compiler.backendStrategy.sorter,
         _inferredDataBuilder);
   }
-
-  @override
-  GlobalTypeInferenceResults createResults() {
-    return new KernelGlobalTypeInferenceResults(this, closedWorld);
-  }
-}
-
-class KernelGlobalTypeInferenceResults extends GlobalTypeInferenceResults {
-  KernelGlobalTypeInferenceResults(
-      TypesInferrer inferrer, JClosedWorld closedWorld)
-      : super(inferrer, closedWorld);
-
-  GlobalTypeInferenceMemberResult createMemberResult(
-      TypeGraphInferrer inferrer, MemberEntity member,
-      {bool isJsInterop: false}) {
-    return new GlobalTypeInferenceMemberResultImpl(
-        member,
-        // We store data in the context of the enclosing method, even
-        // for closure elements.
-        inferrer.inferrer.lookupDataOfMember(member),
-        inferrer,
-        isJsInterop);
-  }
-
-  GlobalTypeInferenceParameterResult createParameterResult(
-      TypeGraphInferrer inferrer, Local parameter) {
-    return new GlobalTypeInferenceParameterResultImpl(parameter, inferrer);
-  }
 }
 
 class KernelInferrerEngine extends InferrerEngineImpl {
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 5129e61..87f2fc6 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -738,8 +738,8 @@
   }
 
   /// Generates the output and returns the total size of the generated code.
-  int assembleProgram(JClosedWorld closedWorld) {
-    int programSize = emitter.assembleProgram(namer, closedWorld);
+  int assembleProgram(JClosedWorld closedWorld, InferredData inferredData) {
+    int programSize = emitter.assembleProgram(namer, closedWorld, inferredData);
     closedWorld.noSuchMethodData.emitDiagnostic(reporter);
     return programSize;
   }
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index c72190e..d51e23b 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -14,6 +14,7 @@
 import '../elements/entities.dart';
 import '../js/js.dart' as jsAst;
 import '../js_backend/js_backend.dart' show JavaScriptBackend, Namer;
+import '../js_backend/inferred_data.dart';
 import '../universe/world_builder.dart' show CodegenWorldBuilder;
 import '../world.dart' show JClosedWorld;
 import 'full_emitter/emitter.dart' as full_js_emitter;
@@ -169,7 +170,8 @@
     });
   }
 
-  int assembleProgram(Namer namer, JClosedWorld closedWorld) {
+  int assembleProgram(
+      Namer namer, JClosedWorld closedWorld, InferredData inferredData) {
     return measure(() {
       _finalizeRti();
       ProgramBuilder programBuilder = new ProgramBuilder(
@@ -199,7 +201,7 @@
           this,
           closedWorld,
           closedWorld.allocatorAnalysis,
-          compiler.globalInference.inferredData,
+          inferredData,
           backend.sourceInformationStrategy,
           compiler.backendStrategy.sorter,
           typeTestRegistry.rtiNeededClasses,
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 63525f5..f3900d0 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -92,7 +92,7 @@
 
   JsInteropAnalysis get jsInteropAnalysis => backend.jsInteropAnalysis;
 
-  InferredData get inferredData => compiler.globalInference.inferredData;
+  InferredData get inferredData => globalInferenceResults.inferredData;
 
   DeferredLoadTask get deferredLoadTask => compiler.deferredLoadTask;
 
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index 4780546..89c5b8c 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -180,68 +180,30 @@
   void clear();
   bool isMemberCalledOnce(MemberEntity element);
   bool isFixedArrayCheckedForGrowable(ir.Node node);
-  GlobalTypeInferenceResults createResults();
 }
 
 /// Results produced by the global type-inference algorithm.
 ///
 /// All queries in this class may contain results that assume whole-program
-/// closed-world semantics. Any [TypeMask] for an element or node that we return
-/// was inferred to be a "guaranteed type", that means, it is a type that we
-/// can prove to be correct for all executions of the program.
+/// closed-world semantics. Any [AbstractValue] for an element or node that we
+/// return was inferred to be a "guaranteed type", that means, it is a type that
+/// we can prove to be correct for all executions of the program.
 abstract class GlobalTypeInferenceResults {
-  // TODO(sigmund): store relevant data & drop reference to inference engine.
-  final TypeGraphInferrer _inferrer;
-  final JClosedWorld closedWorld;
-  final Map<MemberEntity, GlobalTypeInferenceMemberResult> _memberResults =
-      <MemberEntity, GlobalTypeInferenceMemberResult>{};
-  final Map<Local, GlobalTypeInferenceParameterResult> _parameterResults =
-      <Local, GlobalTypeInferenceParameterResult>{};
+  JClosedWorld get closedWorld;
 
-  GlobalTypeInferenceResults(this._inferrer, this.closedWorld);
+  InferredData get inferredData;
 
-  /// Create the [GlobalTypeInferenceMemberResult] object for [member].
-  GlobalTypeInferenceMemberResult createMemberResult(
-      TypeGraphInferrer inferrer, MemberEntity member,
-      {bool isJsInterop: false});
+  GlobalTypeInferenceMemberResult resultOfMember(MemberEntity member);
 
-  /// Create the [GlobalTypeInferenceParameterResult] object for [parameter].
-  GlobalTypeInferenceParameterResult createParameterResult(
-      TypeGraphInferrer inferrer, Local parameter);
-
-  // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an
-  // error to query for results that don't exist.
-  GlobalTypeInferenceMemberResult resultOfMember(MemberEntity member) {
-    assert(
-        member is! ConstructorBodyEntity,
-        failedAt(
-            member,
-            "unexpected input: ConstructorBodyElements are created"
-            " after global type inference, no data is avaiable for them."));
-
-    bool isJsInterop = closedWorld.nativeData.isJsInteropMember(member);
-    return _memberResults.putIfAbsent(member,
-        () => createMemberResult(_inferrer, member, isJsInterop: isJsInterop));
-  }
-
-  // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an
-  // error to query for results that don't exist.
-  GlobalTypeInferenceElementResult resultOfParameter(Local parameter) {
-    return _parameterResults.putIfAbsent(
-        parameter, () => createParameterResult(_inferrer, parameter));
-  }
+  GlobalTypeInferenceElementResult resultOfParameter(Local parameter);
 
   /// Returns the type of a [selector] when applied to a receiver with the given
   /// type [mask].
-  AbstractValue typeOfSelector(Selector selector, AbstractValue mask) =>
-      _inferrer.getTypeOfSelector(selector, mask);
+  AbstractValue typeOfSelector(Selector selector, AbstractValue mask);
 
   /// Returns whether a fixed-length constructor call goes through a growable
   /// check.
-  // TODO(sigmund): move into the result of the element containing such
-  // constructor call.
-  bool isFixedArrayCheckedForGrowable(ir.Node ctorCall) =>
-      _inferrer.isFixedArrayCheckedForGrowable(ctorCall);
+  bool isFixedArrayCheckedForGrowable(ir.Node node);
 }
 
 /// Global analysis that infers concrete types.
@@ -257,8 +219,6 @@
 
   GlobalTypeInferenceResults resultsForTesting;
 
-  InferredData inferredData;
-
   GlobalTypeInferenceTask(Compiler compiler)
       : compiler = compiler,
         super(compiler.measurer);
@@ -272,12 +232,82 @@
           disableTypeInference: compiler.disableTypeInference);
       typesInferrerInternal.analyzeMain(mainElement);
       typesInferrerInternal.clear();
-      GlobalTypeInferenceResults results =
-          typesInferrerInternal.createResults();
+
+      GlobalTypeInferenceResultsImpl results =
+          new GlobalTypeInferenceResultsImpl(
+              typesInferrerInternal, closedWorld);
       closedWorld.noSuchMethodData.categorizeComplexImplementations(results);
-      inferredData = inferredDataBuilder.close(closedWorld);
+      results.inferredData = inferredDataBuilder.close(closedWorld);
       resultsForTesting = results;
       return results;
     });
   }
 }
+
+class GlobalTypeInferenceResultsImpl implements GlobalTypeInferenceResults {
+  final JClosedWorld closedWorld;
+  InferredData inferredData;
+  final TypeGraphInferrer _inferrer;
+  // TODO(sigmund): store relevant data & drop reference to inference engine.
+  final Map<MemberEntity, GlobalTypeInferenceMemberResult> _memberResults =
+      <MemberEntity, GlobalTypeInferenceMemberResult>{};
+  final Map<Local, GlobalTypeInferenceParameterResult> _parameterResults =
+      <Local, GlobalTypeInferenceParameterResult>{};
+
+  GlobalTypeInferenceResultsImpl(this._inferrer, this.closedWorld);
+
+  GlobalTypeInferenceMemberResult _createMemberResult(
+      TypeGraphInferrer inferrer, MemberEntity member,
+      {bool isJsInterop: false}) {
+    return new GlobalTypeInferenceMemberResultImpl(
+        member,
+        // We store data in the context of the enclosing method, even
+        // for closure elements.
+        inferrer.inferrer.lookupDataOfMember(member),
+        inferrer,
+        isJsInterop);
+  }
+
+  GlobalTypeInferenceParameterResult _createParameterResult(
+      TypeGraphInferrer inferrer, Local parameter) {
+    return new GlobalTypeInferenceParameterResultImpl(parameter, inferrer);
+  }
+
+  // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an
+  // error to query for results that don't exist.
+  @override
+  GlobalTypeInferenceMemberResult resultOfMember(MemberEntity member) {
+    assert(
+        member is! ConstructorBodyEntity,
+        failedAt(
+            member,
+            "unexpected input: ConstructorBodyElements are created"
+            " after global type inference, no data is avaiable for them."));
+
+    bool isJsInterop = closedWorld.nativeData.isJsInteropMember(member);
+    return _memberResults.putIfAbsent(member,
+        () => _createMemberResult(_inferrer, member, isJsInterop: isJsInterop));
+  }
+
+  // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an
+  // error to query for results that don't exist.
+  @override
+  GlobalTypeInferenceElementResult resultOfParameter(Local parameter) {
+    return _parameterResults.putIfAbsent(
+        parameter, () => _createParameterResult(_inferrer, parameter));
+  }
+
+  /// Returns the type of a [selector] when applied to a receiver with the given
+  /// type [mask].
+  @override
+  AbstractValue typeOfSelector(Selector selector, AbstractValue mask) =>
+      _inferrer.getTypeOfSelector(selector, mask);
+
+  /// Returns whether a fixed-length constructor call goes through a growable
+  /// check.
+  // TODO(sigmund): move into the result of the element containing such
+  // constructor call.
+  @override
+  bool isFixedArrayCheckedForGrowable(ir.Node ctorCall) =>
+      _inferrer.isFixedArrayCheckedForGrowable(ctorCall);
+}
diff --git a/tests/compiler/dart2js/inference/inference_data_test.dart b/tests/compiler/dart2js/inference/inference_data_test.dart
index a1cf219..436126a 100644
--- a/tests/compiler/dart2js/inference/inference_data_test.dart
+++ b/tests/compiler/dart2js/inference/inference_data_test.dart
@@ -51,7 +51,7 @@
             elementMap,
             compiler.backendClosedWorldForTesting,
             backendStrategy.closureDataLookup,
-            compiler.globalInference.inferredData)
+            compiler.globalInference.resultsForTesting.inferredData)
         .run(definition.node);
   }
 }
diff --git a/tests/compiler/dart2js/inference/side_effects_test.dart b/tests/compiler/dart2js/inference/side_effects_test.dart
index b0e0948..d97b477 100644
--- a/tests/compiler/dart2js/inference/side_effects_test.dart
+++ b/tests/compiler/dart2js/inference/side_effects_test.dart
@@ -47,7 +47,7 @@
             elementMap,
             compiler.backendClosedWorldForTesting,
             backendStrategy.closureDataLookup,
-            compiler.globalInference.inferredData)
+            compiler.globalInference.resultsForTesting.inferredData)
         .run(definition.node);
   }
 }