package mb.p_raffrayi;

import org.metaborg.util.functions.Function1;
import org.metaborg.util.functions.Function2;
import org.metaborg.util.future.CompletableFuture;
import org.metaborg.util.future.IFuture;

import mb.scopegraph.oopsla20.diff.BiMap;

public interface IIncrementalTypeCheckerContext<S, L, D, R> extends ITypeCheckerContext<S, L, D> {

    /**
     * Runs a given local type checker incrementally. The boolean argument indicates whether the type checker was
     * restarted (true) or started because there was no earlier result (false). If the result could be reused, the
     * callback is not invoked at all.
     */
    <Q> IFuture<R> runIncremental(Function1<Boolean, IFuture<Q>> runLocalTypeChecker, Function1<R, Q> extractLocal,
            Function2<Q, BiMap.Immutable<S>, Q> patch, Function2<Q, Throwable, IFuture<R>> combine);

    default <Q> IFuture<R> runIncremental(Function1<Boolean, IFuture<Q>> runLocalTypeChecker, Function1<R, Q> extractLocal,
            Function2<Q, Throwable, IFuture<R>> combine) {
        return this.runIncremental(runLocalTypeChecker, extractLocal, (x, p) -> x, combine);
    }

    default IFuture<R> runIncremental(Function1<Boolean, IFuture<R>> runLocalTypeChecker) {
        return this.runIncremental(runLocalTypeChecker, x -> x, CompletableFuture::completed);
    }


}

@@ -411,74 +411,1439 @@
 ly. 
-The boolean argument indicates whether the type checker was%0A     *
+When a type-checker uses incrementality, it should be implemented%0A     * in the following way: First, it should synchronously create all shared scopes, and start all its subunits. After%0A     * that, %7B@link runIncremental%7D should be called with the appropriate callbacks.%0A     *%0A     * The callbacks are designed in such a way that the initial result of a particular type checker can be reused%0A     * whenever the unit itself was not required to (re)start. This holds regardless of the state of its subunits. We%0A     * assume that the type-checker result %7B@link R%7D is an aggregation of the local result %7B@link Q%7D of the type-checker%0A     * and the results of its subunits. we allow to split these values with %7B@code extractLocal%7D, and later to be%0A     * recombined with either updated or fresh results using %7B@code combine%7D.%0A     *%0A     * @implSpec In summary, when the type-checker result can be reused with patches %7B@code p%7D,%0A     *           %7B@code combine(patch(extractLocal(previousResult), p), null)%7D is used to obtain the updated result.%0A     *           Otherwise, %7B@code combine(runLocalTypeChecker(restarted), null)%7D is used to compute the new result.%0A     *%0A     * @param %3CQ%3E%0A     *            The type of the local type-checker result%0A     *%0A     * @param runLocalTypeChecker%0A     *            The callback that should start the type checker. The boolean argument indicates whether the type%0A     *            checker was
  res
@@ -1925,16 +1925,34 @@
 e result
+%0A     *           
  could b
@@ -1964,23 +1964,16 @@
 sed, the
-%0A     *
  callbac
@@ -1995,16 +1995,697 @@
 d at all
+. Instead, the %7B@code patch%7D callback will be%0A     *            invoked to update it.%0A     *%0A     * @param extractLocal%0A     *            Callback that should extract the local type-checker result %7B@link Q%7D from an aggregated result%0A     *            %7B@link R%7D%0A     *%0A     * @param patch%0A     *            Callback that should update a previous result with the supplied scope patches.%0A     *%0A     * @param combine%0A     *            Callback that should combine the local result (which is either fresh or updated from a previous run)%0A     *            with the results of its sub-units. The futures of this subunit should be captured in the callback%0A     *            implementation
 .%0A     *
@@ -2904,16 +2904,117 @@
 bine);%0A%0A
+    /**%0A     * Default %7B@link runIncremental%7D implementation that applies no scope patching.%0A     */%0A
     defa
@@ -3090,32 +3090,44 @@
 ocalTypeChecker,
+%0A           
  Function1%3CR, Q%3E
@@ -3136,36 +3136,24 @@
 xtractLocal,
-%0A           
  Function2%3CQ
@@ -3288,16 +3288,148 @@
 %0A    %7D%0A%0A
+    /**%0A     * Default %7B@link runIncremental%7D implementation that applies no scope patching nor subunit result aggregation.%0A     */%0A
     defa
@@ -3614,11 +3614,10 @@
 %0A    %7D%0A%0A
-%0A
 %7D%0A

Document incremental type-checker context.