API changes to incremental compiler to support modular compilation

Change-Id: I2b86eefaebbeb0ede06ed2e433868585c3df2461
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/95780
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index 9ff093c..ce04a71 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -19,11 +19,12 @@
 
 abstract class IncrementalKernelGenerator {
   factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint,
-      [Uri initializeFromDillUri]) {
+      [Uri initializeFromDillUri, bool outlineOnly]) {
     return new IncrementalCompiler(
         new CompilerContext(
             new ProcessedOptions(options: options, inputs: [entryPoint])),
-        initializeFromDillUri);
+        initializeFromDillUri,
+        outlineOnly);
   }
 
   /// Initialize the incremental compiler from a component.
@@ -31,11 +32,13 @@
   /// Notice that the component has to include the platform, and that no other
   /// platform will be loaded.
   factory IncrementalKernelGenerator.fromComponent(
-      CompilerOptions options, Uri entryPoint, Component component) {
+      CompilerOptions options, Uri entryPoint, Component component,
+      [bool outlineOnly]) {
     return new IncrementalCompiler.fromComponent(
         new CompilerContext(
             new ProcessedOptions(options: options, inputs: [entryPoint])),
-        component);
+        component,
+        outlineOnly);
   }
 
   /// Returns a component whose libraries are the recompiled libraries,
@@ -47,6 +50,26 @@
   /// next call to [computeDelta]).
   void invalidate(Uri uri);
 
+  /// Invalidate all libraries that were build from source.
+  ///
+  /// This is equivalent to a number of calls to [invalidate]: One for each URI
+  /// that happens to have been read from source.
+  /// Said another way, this invalidates everything not loaded from dill
+  /// (at startup) or via [setModulesToLoadOnNextComputeDelta].
+  void invalidateAllSources();
+
+  /// Set the given [components] as components to load on the next iteration
+  /// of [computeDelta].
+  ///
+  /// If specified, all libraries not compiled from source and not included in
+  /// these components will be invalidated and the libraries inside these
+  /// components will be loaded instead.
+  ///
+  /// Useful for, for instance, modular compilation, where modules
+  /// (created externally) via this functionality can be added, changed or
+  /// removed.
+  void setModulesToLoadOnNextComputeDelta(List<Component> components);
+
   /// Compile [expression] as an [Expression]. A function returning that
   /// expression is compiled.
   ///
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index a8245b2..9db66d0 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -84,6 +84,8 @@
 
   final Ticker ticker;
 
+  final bool outlineOnly;
+
   Set<Uri> invalidatedUris = new Set<Uri>();
 
   DillTarget dillLoadedData;
@@ -96,17 +98,22 @@
   bool hasToCheckPackageUris = false;
   Map<Uri, List<DiagnosticMessageFromJson>> remainingComponentProblems =
       new Map<Uri, List<DiagnosticMessageFromJson>>();
+  List<Component> modulesToLoad;
 
   KernelTarget userCode;
 
   IncrementalCompiler.fromComponent(
-      this.context, Component this.componentToInitializeFrom)
+      this.context, Component this.componentToInitializeFrom,
+      [bool outlineOnly])
       : ticker = context.options.ticker,
-        initializeFromDillUri = null;
+        initializeFromDillUri = null,
+        this.outlineOnly = outlineOnly ?? false;
 
-  IncrementalCompiler(this.context, [this.initializeFromDillUri])
+  IncrementalCompiler(this.context,
+      [this.initializeFromDillUri, bool outlineOnly])
       : ticker = context.options.ticker,
-        componentToInitializeFrom = null;
+        componentToInitializeFrom = null,
+        this.outlineOnly = outlineOnly ?? false;
 
   @override
   Future<Component> computeDelta(
@@ -315,6 +322,18 @@
     });
   }
 
+  /// Internal method.
+  void invalidateNotKeptUserBuilders(Set<Uri> invalidatedUris) {
+    throw UnimplementedError("Not implemented yet.");
+  }
+
+  /// Internal method.
+  Future loadEnsureLoadedComponents(
+      Set<Uri> reusedLibraryUris, List<LibraryBuilder> reusedLibraries) async {
+    throw UnimplementedError("Not implemented yet.");
+  }
+
+  /// Internal method.
   void reissueLibraryProblems(
       Set<Library> allLibraries, List<Library> compiledLibraries) {
     // The newly-compiled libraries have issued problems already. Re-issue
@@ -331,6 +350,7 @@
     }
   }
 
+  /// Internal method.
   /// Re-issue problems on the component and return the filtered list.
   List<String> reissueComponentProblems(Component componentWithDill) {
     // These problems have already been reported.
@@ -364,6 +384,7 @@
     return new List<String>.from(issuedProblems);
   }
 
+  /// Internal method.
   Uri getPartFileUri(
       Uri parentFileUri, LibraryPart part, UriTranslator uriTranslator) {
     Uri fileUri = parentFileUri.resolve(part.partUri);
@@ -376,6 +397,7 @@
     return fileUri;
   }
 
+  /// Internal method.
   /// Compute the transitive closure.
   ///
   /// As a side-effect, this also cleans-up now-unreferenced builders as well as
@@ -448,6 +470,7 @@
     return result;
   }
 
+  /// Internal method.
   void removeLibraryFromRemainingComponentProblems(
       Library lib, UriTranslator uriTranslator) {
     remainingComponentProblems.remove(lib.fileUri);
@@ -458,6 +481,7 @@
     }
   }
 
+  /// Internal method.
   int prepareSummary(List<int> summaryBytes, UriTranslator uriTranslator,
       CompilerContext c, IncrementalCompilerData data) {
     dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
@@ -475,6 +499,7 @@
     return bytesLength;
   }
 
+  /// Internal method.
   // This procedure will try to load the dill file and will crash if it cannot.
   Future<int> initializeFromDill(UriTranslator uriTranslator, CompilerContext c,
       IncrementalCompilerData data) async {
@@ -515,6 +540,7 @@
     return bytesLength;
   }
 
+  /// Internal method.
   void saveComponentProblems(IncrementalCompilerData data) {
     if (data.component.problemsAsJson != null) {
       for (String jsonString in data.component.problemsAsJson) {
@@ -528,6 +554,7 @@
     }
   }
 
+  /// Internal method.
   // This procedure will set up compiler from [componentToInitializeFrom].
   void initializeFromComponent(UriTranslator uriTranslator, CompilerContext c,
       IncrementalCompilerData data) {
@@ -559,6 +586,7 @@
     ticker.logMs("Ran initializeFromComponent");
   }
 
+  /// Internal method.
   void appendLibraries(IncrementalCompilerData data, int bytesLength) {
     if (data.component != null) {
       dillLoadedData.loader
@@ -673,6 +701,7 @@
     });
   }
 
+  /// Internal method.
   List<LibraryBuilder> computeReusedLibraries(
       Set<Uri> invalidatedUris, UriTranslator uriTranslator,
       {Set<LibraryBuilder> notReused}) {
@@ -796,7 +825,20 @@
     invalidatedUris.add(uri);
   }
 
+  @override
+  void invalidateAllSources() {
+    throw UnimplementedError("Not implemented yet.");
+  }
+
+  @override
+  void setModulesToLoadOnNextComputeDelta(List<Component> components) {
+    throw UnimplementedError("Not implemented yet.");
+  }
+
+  /// Internal method.
   void recordInvalidatedImportUrisForTesting(List<Uri> uris) {}
+
+  /// Internal method.
   void recordTemporaryFileForTesting(Uri uri) {}
 }