From 6e166a88ecd2425e47fcc7415de8a398929daebb Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 10:05:22 +0800 Subject: [PATCH 01/15] wip --- .../src/mill/bsp/worker/MillBuildServer.scala | 188 +++++++----------- .../mill/bsp/worker/MillJavaBuildServer.scala | 4 +- .../mill/bsp/worker/MillJvmBuildServer.scala | 1 + .../bsp/worker/MillScalaBuildServer.scala | 12 +- bsp/worker/src/mill/bsp/worker/State.scala | 40 ++-- bsp/worker/src/mill/bsp/worker/Utils.scala | 13 +- .../src/mill/runner/MillBuildBootstrap.scala | 9 +- runner/src/mill/runner/RunnerState.scala | 5 +- 8 files changed, 112 insertions(+), 160 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 293cf06b070..4b3b59f8a4f 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -1,64 +1,12 @@ package mill.bsp.worker -import ch.epfl.scala.bsp4j.{ - BuildClient, - BuildServer, - BuildServerCapabilities, - BuildTarget, - BuildTargetCapabilities, - BuildTargetIdentifier, - CleanCacheParams, - CleanCacheResult, - CompileParams, - CompileProvider, - CompileResult, - DebugProvider, - DebugSessionAddress, - DebugSessionParams, - DependencyModule, - DependencyModulesItem, - DependencyModulesParams, - DependencyModulesResult, - DependencySourcesItem, - DependencySourcesParams, - DependencySourcesResult, - InitializeBuildParams, - InitializeBuildResult, - InverseSourcesParams, - InverseSourcesResult, - OutputPathItem, - OutputPathItemKind, - OutputPathsItem, - OutputPathsParams, - OutputPathsResult, - ResourcesItem, - ResourcesParams, - ResourcesResult, - RunParams, - RunProvider, - RunResult, - SourceItem, - SourceItemKind, - SourcesItem, - SourcesParams, - SourcesResult, - StatusCode, - TaskDataKind, - TaskFinishParams, - TaskId, - TaskStartParams, - TestParams, - TestProvider, - TestResult, - TestTask, - WorkspaceBuildTargetsResult -} +import ch.epfl.scala.bsp4j.{BuildClient, BuildServer, BuildServerCapabilities, BuildTarget, BuildTargetCapabilities, BuildTargetIdentifier, CleanCacheParams, CleanCacheResult, CompileParams, CompileProvider, CompileResult, DebugProvider, DebugSessionAddress, DebugSessionParams, DependencyModule, DependencyModulesItem, DependencyModulesParams, DependencyModulesResult, DependencySourcesItem, DependencySourcesParams, DependencySourcesResult, InitializeBuildParams, InitializeBuildResult, InverseSourcesParams, InverseSourcesResult, OutputPathItem, OutputPathItemKind, OutputPathsItem, OutputPathsParams, OutputPathsResult, ResourcesItem, ResourcesParams, ResourcesResult, RunParams, RunProvider, RunResult, SourceItem, SourceItemKind, SourcesItem, SourcesParams, SourcesResult, StatusCode, TaskDataKind, TaskFinishParams, TaskId, TaskStartParams, TestParams, TestProvider, TestResult, TestTask, WorkspaceBuildTargetsResult} import ch.epfl.scala.bsp4j import com.google.gson.JsonObject import mill.T import mill.api.{DummyTestReporter, Result, Strict} import mill.define.Segment.Label -import mill.define.{Args, Discover, ExternalModule, Task} +import mill.define.{Args, BaseModule, Discover, ExternalModule, Task} import mill.eval.Evaluator import mill.main.MainModule import mill.scalalib.{JavaModule, SemanticDbJavaModule, TestModule} @@ -94,14 +42,11 @@ private class MillBuildServer( protected var clientIsIntelliJ = false private[this] var statePromise: Promise[State] = Promise[State]() - var evaluatorOpt: Option[Evaluator] = None - def evaluator = evaluatorOpt.get def updateEvaluator(evaluator: Option[Evaluator]): Unit = { debug(s"Updating Evaluator: $evaluator") if (statePromise.isCompleted) statePromise = Promise[State]() // replace the promise - evaluatorOpt = evaluator - evaluatorOpt.foreach(e => + evaluator.foreach { e => statePromise.success( new State( e.rootModule.millSourcePath, @@ -110,7 +55,7 @@ private class MillBuildServer( e.disableCallgraphInvalidation ) ) - ) + } } def debug(msg: String) = logStream.println(msg) @@ -207,7 +152,7 @@ private class MillBuildServer( "workspaceBuildTargets", targetIds = _.bspModulesById.keySet.toSeq, tasks = { case m: JavaModule => T.task { m.bspBuildTargetData() } } - ) { (state, id, m, bspBuildTargetData) => + ) { (ev, state, id, m, bspBuildTargetData) => val s = m.bspBuildTarget val deps = m match { case jm: JavaModule => @@ -296,7 +241,7 @@ private class MillBuildServer( } } ) { - case (state, id, module, items) => new SourcesItem(id, items.asJava) + case (ev, state, id, module, items) => new SourcesItem(id, items.asJava) } { new SourcesResult(_) } @@ -306,18 +251,23 @@ private class MillBuildServer( override def buildTargetInverseSources(p: InverseSourcesParams) : CompletableFuture[InverseSourcesResult] = { completable(s"buildtargetInverseSources ${p}") { state => - val tasks = state.bspModulesById.iterator.collect { - case (id, m: JavaModule) => + val tasksEvaluators = state.bspModulesById.iterator.collect { + case (id, (m: JavaModule, ev)) => T.task { val src = m.allSourceFiles() val found = src.map(sanitizeUri).contains( p.getTextDocument.getUri ) - if (found) Seq((id)) else Seq() - } + if (found) Seq(id) else Seq() + } -> ev }.toSeq - val ids = evaluator.evalOrThrow()(tasks).flatten + val ids = tasksEvaluators + .groupMap(_._2)(_._1) + .flatMap{case (ev, ts) => ev.evalOrThrow()(ts)} + .flatten + .toSeq + new InverseSourcesResult(ids.asJava) } } @@ -342,7 +292,7 @@ private class MillBuildServer( } } ) { - case (state, id, m: JavaModule, (resolveDepsSources, unmanagedClasspath)) => + case (ev, state, id, m: JavaModule, (resolveDepsSources, unmanagedClasspath)) => val buildSources = if (!m.isInstanceOf[MillBuildRootModule]) Nil else mill.scalalib.Lib @@ -368,6 +318,7 @@ private class MillBuildServer( } ) { case ( + ev, state, id, m: JavaModule, @@ -394,7 +345,7 @@ private class MillBuildServer( case _ => T.task { Nil } } ) { - case (state, id, m, resources) => + case (ev, state, id, m, resources) => val resourcesUrls = resources.map(_.path).filter(os.exists).map(sanitizeUri) new ResourcesItem(id, resourcesUrls.asJava) @@ -408,22 +359,27 @@ private class MillBuildServer( completable(s"buildTargetCompile ${p}") { state => val params = TaskParameters.fromCompileParams(p) val taskId = params.hashCode() - val compileTasks = params.getTargets.distinct.map(state.bspModulesById).map { - case m: SemanticDbJavaModule if clientWantsSemanticDb => m.compiledClassesAndSemanticDbFiles - case m: JavaModule => m.compile - case m => T.task { + val compileTasksEvs = params.getTargets.distinct.map(state.bspModulesById).map { + case (m: SemanticDbJavaModule, ev) if clientWantsSemanticDb => (m.compiledClassesAndSemanticDbFiles, ev) + case (m: JavaModule, ev) => (m.compile, ev) + case (m, ev) => T.task { Result.Failure( s"Don't know how to compile non-Java target ${m.bspBuildTarget.displayName}" ) - } + } -> ev } - val result = evaluator.evaluate( - compileTasks, - Utils.getBspLoggedReporterPool(p.getOriginId, state.bspIdByModule, client), - DummyTestReporter, - new MillBspLogger(client, taskId, evaluator.baseLogger) - ) + val result = compileTasksEvs + .groupMap(_._2)(_._1) + .map { case (ev, ts) => + ev.evaluate( + ts, + Utils.getBspLoggedReporterPool(p.getOriginId, state.bspIdByModule, client), + DummyTestReporter, + new MillBspLogger(client, taskId, ev.baseLogger) + ) + } + .toSeq val compileResult = new CompileResult(Utils.getStatusCode(result)) compileResult.setOriginId(p.getOriginId) compileResult // TODO: See in what form IntelliJ expects data about products of compilation in order to set data field @@ -432,25 +388,25 @@ private class MillBuildServer( override def buildTargetOutputPaths(params: OutputPathsParams) : CompletableFuture[OutputPathsResult] = completable(s"buildTargetOutputPaths ${params}") { state => - val outItems = new OutputPathItem( - // Spec says, a directory must end with a forward slash - sanitizeUri(evaluator.outPath) + "/", - OutputPathItemKind.DIRECTORY - ) - - val extItems = new OutputPathItem( - // Spec says, a directory must end with a forward slash - sanitizeUri(evaluator.externalOutPath) + "/", - OutputPathItemKind.DIRECTORY - ) - val items = for { target <- params.getTargets.asScala - module <- state.bspModulesById.get(target) + (module, ev) <- state.bspModulesById.get(target) } yield { val items = - if (module.millOuterCtx.external) List(extItems) - else List(outItems) + if (module.millOuterCtx.external) List( + new OutputPathItem( + // Spec says, a directory must end with a forward slash + sanitizeUri(ev.externalOutPath) + "/", + OutputPathItemKind.DIRECTORY + ) + ) + else List( + new OutputPathItem( + // Spec says, a directory must end with a forward slash + sanitizeUri(ev.outPath) + "/", + OutputPathItemKind.DIRECTORY + ) + ) new OutputPathsItem(target, items.asJava) } @@ -460,15 +416,16 @@ private class MillBuildServer( override def buildTargetRun(runParams: RunParams): CompletableFuture[RunResult] = completable(s"buildTargetRun ${runParams}") { state => val params = TaskParameters.fromRunParams(runParams) - val module = params.getTargets.map(state.bspModulesById).collectFirst { - case m: JavaModule => m + val (module, ev) = params.getTargets.map(state.bspModulesById).collectFirst { + case (m: JavaModule, ev) => (m, ev) }.get + val args = params.getArguments.getOrElse(Seq.empty[String]) val runTask = module.run(T.task(Args(args))) - val runResult = evaluator.evaluate( + val runResult = ev.evaluate( Strict.Agg(runTask), Utils.getBspLoggedReporterPool(runParams.getOriginId, state.bspIdByModule, client), - logger = new MillBspLogger(client, runTask.hashCode(), evaluator.baseLogger) + logger = new MillBspLogger(client, runTask.hashCode(), ev.baseLogger) ) val response = runResult.results(runTask) match { case _: Result.Success[Any] => new RunResult(StatusCode.OK) @@ -510,7 +467,7 @@ private class MillBuildServer( .filter(millBuildTargetIds.contains) .foldLeft(StatusCode.OK) { (overallStatusCode, targetId) => state.bspModulesById(targetId) match { - case testModule: TestModule => + case (testModule: TestModule, ev) => val testTask = testModule.testLocal(argsMap(targetId.getUri): _*) // notifying the client that the testing of this build target started @@ -529,7 +486,7 @@ private class MillBuildServer( Seq.empty[String] ) - val results = evaluator.evaluate( + val results = ev.evaluate( Strict.Agg(testTask), Utils.getBspLoggedReporterPool( testParams.getOriginId, @@ -537,9 +494,9 @@ private class MillBuildServer( client ), testReporter, - new MillBspLogger(client, testTask.hashCode, evaluator.baseLogger) + new MillBspLogger(client, testTask.hashCode, ev.baseLogger) ) - val statusCode = Utils.getStatusCode(results) + val statusCode = Utils.getStatusCode(Seq(results)) // Notifying the client that the testing of this build target ended val taskFinishParams = @@ -582,16 +539,16 @@ private class MillBuildServer( true )) { case ((msg, cleaned), targetId) => - val module = state.bspModulesById(targetId) + val (module, ev) = state.bspModulesById(targetId) val mainModule = new MainModule { override implicit def millDiscover: Discover[_] = Discover[this.type] } val compileTargetName = (module.millModuleSegments ++ Label("compile")).render debug(s"about to clean: ${compileTargetName}") - val cleanTask = mainModule.clean(evaluator, Seq(compileTargetName): _*) - val cleanResult = evaluator.evaluate( + val cleanTask = mainModule.clean(ev, Seq(compileTargetName): _*) + val cleanResult = ev.evaluate( Strict.Agg(cleanTask), - logger = new MillBspLogger(client, cleanTask.hashCode, evaluator.baseLogger) + logger = new MillBspLogger(client, cleanTask.hashCode, ev.baseLogger) ) if (cleanResult.failing.keyCount > 0) ( msg + s" Target ${compileTargetName} could not be cleaned. See message from mill: \n" + @@ -602,7 +559,7 @@ private class MillBuildServer( false ) else { - val outPaths = evaluator.pathsResolver.resolveDest( + val outPaths = ev.pathsResolver.resolveDest( module.millModuleSegments ++ Label("compile") ) val outPathSeq = Seq(outPaths.dest, outPaths.meta, outPaths.log) @@ -626,14 +583,21 @@ private class MillBuildServer( hint: String, targetIds: State => Seq[BuildTargetIdentifier], tasks: BspModule => Task[W] - )(f: (State, BuildTargetIdentifier, BspModule, W) => T)(agg: java.util.List[T] => V) + )(f: (Evaluator, State, BuildTargetIdentifier, BspModule, W) => T)(agg: java.util.List[T] => V) : CompletableFuture[V] = completable(hint) { state: State => val ids = targetIds(state) - val tasksSeq = ids.map(m => tasks(state.bspModulesById(m))) - val evaluated = evaluator.evalOrThrow()(tasksSeq) - val res = evaluated.zip(ids).map { case (v, i) => f(state, i, state.bspModulesById(i), v) } - agg(res.asJava) + val tasksSeq = ids.map { id => + val (m, ev) = state.bspModulesById(id) + (tasks(m), ev) + } + + val evaluated = tasksSeq + .groupMap(_._2)(_._1) + .map{case (ev, ts) => (ev, ev.evalOrThrow()(ts))} + .map{case (ev, vs) => vs.zip(ids).map { case (v, i) => f(ev, state, i, state.bspModulesById(i)._1, v) }} + + agg(evaluated.flatten.toSeq.asJava) } /** diff --git a/bsp/worker/src/mill/bsp/worker/MillJavaBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillJavaBuildServer.scala index 455ba319f5b..c9873e6c1d5 100644 --- a/bsp/worker/src/mill/bsp/worker/MillJavaBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillJavaBuildServer.scala @@ -29,8 +29,8 @@ private trait MillJavaBuildServer extends JavaBuildServer { this: MillBuildServe T.task { (classesPathTask(), m.javacOptions(), m.bspCompileClasspath()) } } ) { - case (state, id, m: JavaModule, (classesPath, javacOptions, bspCompileClasspath)) => - val pathResolver = evaluator.pathsResolver + case (ev, state, id, m: JavaModule, (classesPath, javacOptions, bspCompileClasspath)) => + val pathResolver = ev.pathsResolver val options = javacOptions val classpath = bspCompileClasspath.map(_.resolve(pathResolver)).map(sanitizeUri) diff --git a/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala index 5accb18cb51..a639aad0d14 100644 --- a/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala @@ -60,6 +60,7 @@ private trait MillJvmBuildServer extends JvmBuildServer { this: MillBuildServer } ) { case ( + ev, state, id, m: JavaModule, diff --git a/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala index c918ea73a94..1fe3dcc1f04 100644 --- a/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala @@ -49,8 +49,8 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer T.task { (Nil, Nil, classesPathTask()) } } ) { - case (state, id, m: JavaModule, (allScalacOptions, bspCompileClsaspath, classesPathTask)) => - val pathResolver = evaluator.pathsResolver + case (ev, state, id, m: JavaModule, (allScalacOptions, bspCompileClsaspath, classesPathTask)) => + val pathResolver = ev.pathsResolver new ScalacOptionsItem( id, allScalacOptions.asJava, @@ -73,7 +73,7 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer T.task((m.zincWorker().worker(), m.compile(), m.forkArgs(), m.forkEnv())) } ) { - case (state, id, m: JavaModule, (worker, compile, forkArgs, forkEnv)) => + case (ev, state, id, m: JavaModule, (worker, compile, forkArgs, forkEnv)) => // We find all main classes, although we could also find only the configured one val mainClasses = worker.discoverMainClasses(compile) // val mainMain = m.mainClass().orElse(if(mainClasses.size == 1) mainClasses.headOption else None) @@ -84,7 +84,7 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer } new ScalaMainClassesItem(id, items.asJava) - case (state, id, _, _) => // no Java module, so no main classes + case (ev, state, id, _, _) => // no Java module, so no main classes new ScalaMainClassesItem(id, Seq.empty[ScalaMainClass].asJava) } { new ScalaMainClassesResult(_) @@ -102,7 +102,7 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer T.task(None) } ) { - case (state, id, m: TestModule, Some((classpath, testFramework, compResult))) => + case (ev, state, id, m: TestModule, Some((classpath, testFramework, compResult))) => val (frameworkName, classFingerprint): (String, Agg[(Class[_], Fingerprint)]) = Jvm.inprocess( classpath.map(_.path), @@ -121,7 +121,7 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer )(new mill.api.Ctx.Home { def home = os.home }) val classes = Seq.from(classFingerprint.map(classF => classF._1.getName.stripSuffix("$"))) new ScalaTestClassesItem(id, classes.asJava, frameworkName) - case (state, id, _, _) => + case (ev, state, id, _, _) => // Not a test module, so no test classes new ScalaTestClassesItem(id, Seq.empty[String].asJava) } { diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index 842c078cc38..0a28341e4b4 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -5,6 +5,7 @@ import mill.runner.MillBuildBootstrap import mill.scalalib.bsp.BspModule import mill.scalalib.internal.{JavaModuleUtils, ModuleUtils} import mill.define.Module +import mill.eval.Evaluator import mill.util.ColorLogger private class State( @@ -13,28 +14,28 @@ private class State( debug: String => Unit, disableCallgraphInvalidation: Boolean ) { - lazy val bspModulesById: Map[BuildTargetIdentifier, BspModule] = { - val modules: Seq[(Module, Seq[Module])] = rootModules - .map(rootModule => (rootModule, JavaModuleUtils.transitiveModules(rootModule))) + lazy val bspModulesById: Map[BuildTargetIdentifier, (BspModule, Evaluator)] = { + val modules: Seq[(Module, Seq[Module], Evaluator)] = evaluators + .map(ev => (ev.rootModule, JavaModuleUtils.transitiveModules(ev.rootModule), ev)) val map = modules - .flatMap { case (rootModule, otherModules) => + .flatMap { case (rootModule, otherModules, eval) => (Seq(rootModule) ++ otherModules).collect { case m: BspModule => val uri = Utils.sanitizeUri( rootModule.millSourcePath / m.millModuleSegments.parts ) - (new BuildTargetIdentifier(uri), m) + (new BuildTargetIdentifier(uri), (m, eval)) } } .toMap - debug(s"BspModules: ${map.mapValues(_.bspDisplayName)}") + debug(s"BspModules: ${map.mapValues(_._1.bspDisplayName)}") map } - lazy val rootModules: Seq[mill.main.RootModule] = { + lazy val evaluators: Seq[mill.eval.Evaluator] = { val evaluated = new mill.runner.MillBuildBootstrap( projectRoot = projectRoot, home = os.home, @@ -49,26 +50,11 @@ private class State( needBuildSc = true ).evaluate() - val rootModules0 = evaluated.result.frames - .flatMap(_.classLoaderOpt) - .zipWithIndex - .map { case (c, i) => - MillBuildBootstrap - .getRootModule(c, i, projectRoot) - .fold(sys.error(_), identity(_)) - } + evaluated.result.frames.map(_.evaluator) + } - val bootstrapModule = evaluated.result.bootstrapModuleOpt.map(m => - MillBuildBootstrap - .getChildRootModule( - m, - evaluated.result.frames.length, - projectRoot - ) - .fold(sys.error(_), identity(_)) - ) + lazy val rootModules = evaluators.map(_.rootModule) - rootModules0 ++ bootstrapModule - } - lazy val bspIdByModule: Map[BspModule, BuildTargetIdentifier] = bspModulesById.map(_.swap) + lazy val bspIdByModule: Map[BspModule, BuildTargetIdentifier] = + bspModulesById.mapValues(_._1).map(_.swap).toMap } diff --git a/bsp/worker/src/mill/bsp/worker/Utils.scala b/bsp/worker/src/mill/bsp/worker/Utils.scala index 9edec117254..176f50db7b7 100644 --- a/bsp/worker/src/mill/bsp/worker/Utils.scala +++ b/bsp/worker/src/mill/bsp/worker/Utils.scala @@ -38,14 +38,11 @@ private object Utils { } // Get the execution status code given the results from Evaluator.evaluate - def getStatusCode(results: Evaluator.Results): StatusCode = { - val statusCodes = results.results.keys.map(task => getStatusCodePerTask(results, task)).toSeq - if (statusCodes.contains(StatusCode.ERROR)) - StatusCode.ERROR - else if (statusCodes.contains(StatusCode.CANCELLED)) - StatusCode.CANCELLED - else - StatusCode.OK + def getStatusCode(resultsLists: Seq[Evaluator.Results]): StatusCode = { + val statusCodes = resultsLists.flatMap(r => r.results.keys.map(task => getStatusCodePerTask(r, task)).toSeq) + if (statusCodes.contains(StatusCode.ERROR)) StatusCode.ERROR + else if (statusCodes.contains(StatusCode.CANCELLED)) StatusCode.CANCELLED + else StatusCode.OK } private[this] def getStatusCodePerTask( diff --git a/runner/src/mill/runner/MillBuildBootstrap.scala b/runner/src/mill/runner/MillBuildBootstrap.scala index 24c770f042b..8fcefddbd95 100644 --- a/runner/src/mill/runner/MillBuildBootstrap.scala +++ b/runner/src/mill/runner/MillBuildBootstrap.scala @@ -193,7 +193,8 @@ class MillBuildBootstrap( Map.empty, Map.empty, None, - Nil + Nil, + evaluator ) nestedState.add(frame = evalState, errorOpt = Some(error)) @@ -242,7 +243,8 @@ class MillBuildBootstrap( scriptImportGraph, methodCodeHashSignatures, Some(classLoader), - runClasspath + runClasspath, + evaluator ) nestedState.add(frame = evalState) @@ -270,7 +272,8 @@ class MillBuildBootstrap( Map.empty, Map.empty, None, - Nil + Nil, + evaluator ) nestedState.add(frame = evalState, errorOpt = evaled.left.toOption) diff --git a/runner/src/mill/runner/RunnerState.scala b/runner/src/mill/runner/RunnerState.scala index 1daff8a28de..8a91535a021 100644 --- a/runner/src/mill/runner/RunnerState.scala +++ b/runner/src/mill/runner/RunnerState.scala @@ -61,7 +61,8 @@ object RunnerState { scriptImportGraph: Map[os.Path, (Int, Seq[os.Path])], methodCodeHashSignatures: Map[String, Int], classLoaderOpt: Option[RunnerState.URLClassLoader], - runClasspath: Seq[PathRef] + runClasspath: Seq[PathRef], + evaluator: Evaluator ) { def loggedData = { @@ -101,7 +102,7 @@ object RunnerState { ) implicit val loggedRw: ReadWriter[Logged] = macroRW - def empty = Frame(Map.empty, Nil, Nil, Map.empty, Map.empty, None, Nil) + def empty = Frame(Map.empty, Nil, Nil, Map.empty, Map.empty, None, Nil, null) } } From 8335da78fdef29d580942f5b8d0bc45e3caafae8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 10:05:46 +0800 Subject: [PATCH 02/15] . --- .../src/mill/bsp/worker/MillBuildServer.scala | 65 +++++++++++++++++-- .../bsp/worker/MillScalaBuildServer.scala | 8 ++- bsp/worker/src/mill/bsp/worker/Utils.scala | 3 +- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 4b3b59f8a4f..ad87c9ac78c 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -1,6 +1,58 @@ package mill.bsp.worker -import ch.epfl.scala.bsp4j.{BuildClient, BuildServer, BuildServerCapabilities, BuildTarget, BuildTargetCapabilities, BuildTargetIdentifier, CleanCacheParams, CleanCacheResult, CompileParams, CompileProvider, CompileResult, DebugProvider, DebugSessionAddress, DebugSessionParams, DependencyModule, DependencyModulesItem, DependencyModulesParams, DependencyModulesResult, DependencySourcesItem, DependencySourcesParams, DependencySourcesResult, InitializeBuildParams, InitializeBuildResult, InverseSourcesParams, InverseSourcesResult, OutputPathItem, OutputPathItemKind, OutputPathsItem, OutputPathsParams, OutputPathsResult, ResourcesItem, ResourcesParams, ResourcesResult, RunParams, RunProvider, RunResult, SourceItem, SourceItemKind, SourcesItem, SourcesParams, SourcesResult, StatusCode, TaskDataKind, TaskFinishParams, TaskId, TaskStartParams, TestParams, TestProvider, TestResult, TestTask, WorkspaceBuildTargetsResult} +import ch.epfl.scala.bsp4j.{ + BuildClient, + BuildServer, + BuildServerCapabilities, + BuildTarget, + BuildTargetCapabilities, + BuildTargetIdentifier, + CleanCacheParams, + CleanCacheResult, + CompileParams, + CompileProvider, + CompileResult, + DebugProvider, + DebugSessionAddress, + DebugSessionParams, + DependencyModule, + DependencyModulesItem, + DependencyModulesParams, + DependencyModulesResult, + DependencySourcesItem, + DependencySourcesParams, + DependencySourcesResult, + InitializeBuildParams, + InitializeBuildResult, + InverseSourcesParams, + InverseSourcesResult, + OutputPathItem, + OutputPathItemKind, + OutputPathsItem, + OutputPathsParams, + OutputPathsResult, + ResourcesItem, + ResourcesParams, + ResourcesResult, + RunParams, + RunProvider, + RunResult, + SourceItem, + SourceItemKind, + SourcesItem, + SourcesParams, + SourcesResult, + StatusCode, + TaskDataKind, + TaskFinishParams, + TaskId, + TaskStartParams, + TestParams, + TestProvider, + TestResult, + TestTask, + WorkspaceBuildTargetsResult +} import ch.epfl.scala.bsp4j import com.google.gson.JsonObject import mill.T @@ -264,7 +316,7 @@ private class MillBuildServer( val ids = tasksEvaluators .groupMap(_._2)(_._1) - .flatMap{case (ev, ts) => ev.evalOrThrow()(ts)} + .flatMap { case (ev, ts) => ev.evalOrThrow()(ts) } .flatten .toSeq @@ -360,7 +412,8 @@ private class MillBuildServer( val params = TaskParameters.fromCompileParams(p) val taskId = params.hashCode() val compileTasksEvs = params.getTargets.distinct.map(state.bspModulesById).map { - case (m: SemanticDbJavaModule, ev) if clientWantsSemanticDb => (m.compiledClassesAndSemanticDbFiles, ev) + case (m: SemanticDbJavaModule, ev) if clientWantsSemanticDb => + (m.compiledClassesAndSemanticDbFiles, ev) case (m: JavaModule, ev) => (m.compile, ev) case (m, ev) => T.task { Result.Failure( @@ -594,8 +647,10 @@ private class MillBuildServer( val evaluated = tasksSeq .groupMap(_._2)(_._1) - .map{case (ev, ts) => (ev, ev.evalOrThrow()(ts))} - .map{case (ev, vs) => vs.zip(ids).map { case (v, i) => f(ev, state, i, state.bspModulesById(i)._1, v) }} + .map { case (ev, ts) => (ev, ev.evalOrThrow()(ts)) } + .map { case (ev, vs) => + vs.zip(ids).map { case (v, i) => f(ev, state, i, state.bspModulesById(i)._1, v) } + } agg(evaluated.flatten.toSeq.asJava) } diff --git a/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala index 1fe3dcc1f04..acfcd45b37a 100644 --- a/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala @@ -49,7 +49,13 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer T.task { (Nil, Nil, classesPathTask()) } } ) { - case (ev, state, id, m: JavaModule, (allScalacOptions, bspCompileClsaspath, classesPathTask)) => + case ( + ev, + state, + id, + m: JavaModule, + (allScalacOptions, bspCompileClsaspath, classesPathTask) + ) => val pathResolver = ev.pathsResolver new ScalacOptionsItem( id, diff --git a/bsp/worker/src/mill/bsp/worker/Utils.scala b/bsp/worker/src/mill/bsp/worker/Utils.scala index 176f50db7b7..42a06af854c 100644 --- a/bsp/worker/src/mill/bsp/worker/Utils.scala +++ b/bsp/worker/src/mill/bsp/worker/Utils.scala @@ -39,7 +39,8 @@ private object Utils { // Get the execution status code given the results from Evaluator.evaluate def getStatusCode(resultsLists: Seq[Evaluator.Results]): StatusCode = { - val statusCodes = resultsLists.flatMap(r => r.results.keys.map(task => getStatusCodePerTask(r, task)).toSeq) + val statusCodes = + resultsLists.flatMap(r => r.results.keys.map(task => getStatusCodePerTask(r, task)).toSeq) if (statusCodes.contains(StatusCode.ERROR)) StatusCode.ERROR else if (statusCodes.contains(StatusCode.CANCELLED)) StatusCode.CANCELLED else StatusCode.OK From 7b9467fe278030ea84d02bf278fca28c9f353d7c Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 10:27:50 +0800 Subject: [PATCH 03/15] wip --- bsp/worker/src/mill/bsp/worker/State.scala | 2 +- example/basic/1-simple-scala/.mill-version | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 example/basic/1-simple-scala/.mill-version diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index 0a28341e4b4..bc6d0c7bb86 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -30,7 +30,7 @@ private class State( } } .toMap - debug(s"BspModules: ${map.mapValues(_._1.bspDisplayName)}") + debug(s"BspModules: ${map.mapValues(_._1.bspDisplayName).toMap}") map } diff --git a/example/basic/1-simple-scala/.mill-version b/example/basic/1-simple-scala/.mill-version new file mode 100644 index 00000000000..6e4c5cf083f --- /dev/null +++ b/example/basic/1-simple-scala/.mill-version @@ -0,0 +1 @@ +/Users/lihaoyi/.cache/mill/download/0.11.1-30-8335da-DIRTYc2c67388 \ No newline at end of file From b237551160378f9ba363dc1978db649519a0cd8b Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:01:19 +0800 Subject: [PATCH 04/15] . --- bsp/worker/src/mill/bsp/worker/MillBuildServer.scala | 8 ++++---- example/basic/1-simple-scala/.mill-version | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index ad87c9ac78c..8ae8ed7884b 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -642,14 +642,14 @@ private class MillBuildServer( val ids = targetIds(state) val tasksSeq = ids.map { id => val (m, ev) = state.bspModulesById(id) - (tasks(m), ev) + (tasks(m), (ev, id)) } val evaluated = tasksSeq .groupMap(_._2)(_._1) - .map { case (ev, ts) => (ev, ev.evalOrThrow()(ts)) } - .map { case (ev, vs) => - vs.zip(ids).map { case (v, i) => f(ev, state, i, state.bspModulesById(i)._1, v) } + .map { case ((ev, id), ts) => + ev.evalOrThrow()(ts) + .map { v => f(ev, state, id, state.bspModulesById(id)._1, v) } } agg(evaluated.flatten.toSeq.asJava) diff --git a/example/basic/1-simple-scala/.mill-version b/example/basic/1-simple-scala/.mill-version index 6e4c5cf083f..6ea4d212771 100644 --- a/example/basic/1-simple-scala/.mill-version +++ b/example/basic/1-simple-scala/.mill-version @@ -1 +1 @@ -/Users/lihaoyi/.cache/mill/download/0.11.1-30-8335da-DIRTYc2c67388 \ No newline at end of file +0.11.1-31-7b9467-DIRTYdeae9bc4 \ No newline at end of file From 913d70a07b61d3e312853500a99dca401fce7245 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:12:05 +0800 Subject: [PATCH 05/15] . --- example/basic/1-simple-scala/.mill-version | 1 - 1 file changed, 1 deletion(-) delete mode 100644 example/basic/1-simple-scala/.mill-version diff --git a/example/basic/1-simple-scala/.mill-version b/example/basic/1-simple-scala/.mill-version deleted file mode 100644 index 6ea4d212771..00000000000 --- a/example/basic/1-simple-scala/.mill-version +++ /dev/null @@ -1 +0,0 @@ -0.11.1-31-7b9467-DIRTYdeae9bc4 \ No newline at end of file From 73a4675c5be25daa654b810379afe7c3ef8e22ce Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:30:45 +0800 Subject: [PATCH 06/15] wip --- bsp/src/mill/bsp/BSP.scala | 4 +-- bsp/src/mill/bsp/BspServerHandle.scala | 2 +- .../src/mill/bsp/worker/BspWorkerImpl.scala | 6 ++-- .../src/mill/bsp/worker/MillBuildServer.scala | 13 +++------ bsp/worker/src/mill/bsp/worker/State.scala | 29 ++----------------- main/eval/src/mill/eval/Evaluator.scala | 1 + main/src/mill/main/TokenReaders.scala | 6 ++++ .../src/mill/runner/MillBuildBootstrap.scala | 6 +++- runner/src/mill/runner/RunnerState.scala | 2 ++ 9 files changed, 26 insertions(+), 43 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 6b7825146cd..86e1aa54004 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -49,9 +49,9 @@ object BSP extends ExternalModule with CoursierModule { * @param ev The Evaluator * @return The server result, indicating if mill should re-run this command or just exit. */ - def startSession(ev: Evaluator): Command[BspServerResult] = T.command { + def startSession(allEvaluators: Seq[Evaluator]): Command[BspServerResult] = T.command { T.log.errorStream.println("BSP/startSession: Starting BSP session") - val res = BspContext.bspServerHandle.runSession(ev) + val res = BspContext.bspServerHandle.runSession(allEvaluators) T.log.errorStream.println(s"BSP/startSession: Finished BSP session, result: ${res}") res } diff --git a/bsp/src/mill/bsp/BspServerHandle.scala b/bsp/src/mill/bsp/BspServerHandle.scala index fd52d799a4e..b818bb22766 100644 --- a/bsp/src/mill/bsp/BspServerHandle.scala +++ b/bsp/src/mill/bsp/BspServerHandle.scala @@ -11,7 +11,7 @@ trait BspServerHandle { * Runs a new session with the given evaluator. This one blocks until the session ends. * @return The reason which the session ended, possibly indictating the wish for restart (e.g. in case of workspace reload). */ - def runSession(evaluator: Evaluator): BspServerResult + def runSession(evaluators: Seq[Evaluator]): BspServerResult /** * The result of the latest started session. Once a new session was started but not finished, this may be [[None]]. diff --git a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala index af2cf803451..c1df1e46a21 100644 --- a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala +++ b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala @@ -18,7 +18,7 @@ private class BspWorkerImpl() extends BspWorker { streams: SystemStreams, logStream: PrintStream, logDir: os.Path, - canReload: Boolean + canReload: Boolean, ): Either[String, BspServerHandle] = { val millServer = @@ -56,9 +56,9 @@ private class BspWorkerImpl() extends BspWorker { val bspServerHandle = new BspServerHandle { private[this] var lastResult0: Option[BspServerResult] = None - override def runSession(evaluator: Evaluator): BspServerResult = { + override def runSession(evaluators: Seq[Evaluator]): BspServerResult = { lastResult0 = None - millServer.updateEvaluator(Option(evaluator)) + millServer.updateEvaluator(Option(evaluators)) val onReload = Promise[BspServerResult]() millServer.onSessionEnd = Some { serverResult => if (!onReload.isCompleted) { diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 8ae8ed7884b..1b972f05dc4 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -95,17 +95,12 @@ private class MillBuildServer( private[this] var statePromise: Promise[State] = Promise[State]() - def updateEvaluator(evaluator: Option[Evaluator]): Unit = { - debug(s"Updating Evaluator: $evaluator") + def updateEvaluator(evaluatorsOpt: Option[Seq[Evaluator]]): Unit = { + debug(s"Updating Evaluator: $evaluatorsOpt") if (statePromise.isCompleted) statePromise = Promise[State]() // replace the promise - evaluator.foreach { e => + evaluatorsOpt.foreach { evaluators => statePromise.success( - new State( - e.rootModule.millSourcePath, - e.baseLogger, - debug, - e.disableCallgraphInvalidation - ) + new State(evaluators, debug) ) } } diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index bc6d0c7bb86..c145b701c59 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -1,19 +1,12 @@ package mill.bsp.worker import ch.epfl.scala.bsp4j.BuildTargetIdentifier -import mill.runner.MillBuildBootstrap import mill.scalalib.bsp.BspModule -import mill.scalalib.internal.{JavaModuleUtils, ModuleUtils} +import mill.scalalib.internal.JavaModuleUtils import mill.define.Module import mill.eval.Evaluator -import mill.util.ColorLogger -private class State( - projectRoot: os.Path, - baseLogger: ColorLogger, - debug: String => Unit, - disableCallgraphInvalidation: Boolean -) { +private class State(evaluators: Seq[Evaluator], debug: String => Unit) { lazy val bspModulesById: Map[BuildTargetIdentifier, (BspModule, Evaluator)] = { val modules: Seq[(Module, Seq[Module], Evaluator)] = evaluators .map(ev => (ev.rootModule, JavaModuleUtils.transitiveModules(ev.rootModule), ev)) @@ -35,24 +28,6 @@ private class State( map } - lazy val evaluators: Seq[mill.eval.Evaluator] = { - val evaluated = new mill.runner.MillBuildBootstrap( - projectRoot = projectRoot, - home = os.home, - keepGoing = false, - imports = Nil, - env = Map.empty, - threadCount = None, - targetsAndParams = Seq("resolve", "_"), - prevRunnerState = mill.runner.RunnerState.empty, - logger = baseLogger, - disableCallgraphInvalidation = disableCallgraphInvalidation, - needBuildSc = true - ).evaluate() - - evaluated.result.frames.map(_.evaluator) - } - lazy val rootModules = evaluators.map(_.rootModule) lazy val bspIdByModule: Map[BspModule, BuildTargetIdentifier] = diff --git a/main/eval/src/mill/eval/Evaluator.scala b/main/eval/src/mill/eval/Evaluator.scala index 6f4618c74dd..a278eeed368 100644 --- a/main/eval/src/mill/eval/Evaluator.scala +++ b/main/eval/src/mill/eval/Evaluator.scala @@ -66,6 +66,7 @@ object Evaluator { // Until we migrate our CLI parsing off of Scopt (so we can pass the BaseModule // in directly) we are forced to pass it in via a ThreadLocal val currentEvaluator = new DynamicVariable[mill.eval.Evaluator](null) + val allEvaluators = new DynamicVariable[Seq[mill.eval.Evaluator]](null) val defaultEnv: Map[String, String] = System.getenv().asScala.toMap diff --git a/main/src/mill/main/TokenReaders.scala b/main/src/mill/main/TokenReaders.scala index 0ad750d8c20..02378170711 100644 --- a/main/src/mill/main/TokenReaders.scala +++ b/main/src/mill/main/TokenReaders.scala @@ -26,6 +26,9 @@ object Tasks { private[mill] class EvaluatorTokenReader[T]() extends mainargs.TokensReader.Constant[Evaluator] { def read(): Either[String, Evaluator] = Right(Evaluator.currentEvaluator.value) } +private[mill] class AllEvaluatorsTokenReader[T]() extends mainargs.TokensReader.Constant[Seq[Evaluator]] { + def read(): Either[String, Seq[Evaluator]] = Right(Evaluator.allEvaluators.value) +} private class LeftoverTaskTokenReader[T](tokensReaderOfT: TokensReader.Leftover[T, _]) extends mainargs.TokensReader.Leftover[Task[T], T] { @@ -38,6 +41,9 @@ object TokenReaders { implicit def millEvaluatorTokenReader[T]: mainargs.TokensReader[Evaluator] = new mill.main.EvaluatorTokenReader[T]() + implicit def millAllEvaluatorsTokenReader[T]: mainargs.TokensReader[Seq[Evaluator]] = + new mill.main.AllEvaluatorsTokenReader[T]() + implicit def millTasksTokenReader[T]: mainargs.TokensReader[Tasks[T]] = new mill.main.Tasks.TokenReader[T]() diff --git a/runner/src/mill/runner/MillBuildBootstrap.scala b/runner/src/mill/runner/MillBuildBootstrap.scala index 8fcefddbd95..6f74871f8ad 100644 --- a/runner/src/mill/runner/MillBuildBootstrap.scala +++ b/runner/src/mill/runner/MillBuildBootstrap.scala @@ -262,8 +262,12 @@ class MillBuildBootstrap( evaluator: Evaluator ): RunnerState = { - val (evaled, evalWatched, moduleWatches) = + val (evaled, evalWatched, moduleWatches) = Evaluator.allEvaluators.withValue( + Seq(Evaluator.currentEvaluator.value) ++ + nestedState.frames.map(_.evaluator) + ) { evaluateWithWatches(rootModule, evaluator, targetsAndParams) + } val evalState = RunnerState.Frame( evaluator.workerCache.toMap, diff --git a/runner/src/mill/runner/RunnerState.scala b/runner/src/mill/runner/RunnerState.scala index 8a91535a021..39b21225224 100644 --- a/runner/src/mill/runner/RunnerState.scala +++ b/runner/src/mill/runner/RunnerState.scala @@ -8,6 +8,8 @@ import mill.api.JsonFormatters._ import mill.eval.Evaluator import mill.main.RootModule +import scala.util.DynamicVariable + /** * This contains a list of frames each representing cached data from a single * level of `build.sc` evaluation: From 29b3826e24c04d291df6de368e8e4bd673456ab3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:31:31 +0800 Subject: [PATCH 07/15] wip --- bsp/worker/src/mill/bsp/worker/State.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index c145b701c59..bedd2d2f9b2 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -23,6 +23,9 @@ private class State(evaluators: Seq[Evaluator], debug: String => Unit) { } } .toMap + debug(s"Reused Evaluators: ${evaluators}") + debug(s"Reused Evaluators outPaths: ${evaluators.map(_.outPath)}") + debug(s"Reused Evaluators rootModule.millSourcePath: ${evaluators.map(_.rootModule.millSourcePath)}") debug(s"BspModules: ${map.mapValues(_._1.bspDisplayName).toMap}") map From 9b2e2dfbb11c6b394a661eea5ddfe50c03ebd45e Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:37:25 +0800 Subject: [PATCH 08/15] . --- example/basic/1-simple-scala/.mill-version | 1 + runner/src/mill/runner/MillBuildBootstrap.scala | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 example/basic/1-simple-scala/.mill-version diff --git a/example/basic/1-simple-scala/.mill-version b/example/basic/1-simple-scala/.mill-version new file mode 100644 index 00000000000..2d68225e13e --- /dev/null +++ b/example/basic/1-simple-scala/.mill-version @@ -0,0 +1 @@ +0.11.1-35-29b382 \ No newline at end of file diff --git a/runner/src/mill/runner/MillBuildBootstrap.scala b/runner/src/mill/runner/MillBuildBootstrap.scala index 6f74871f8ad..e9727f86053 100644 --- a/runner/src/mill/runner/MillBuildBootstrap.scala +++ b/runner/src/mill/runner/MillBuildBootstrap.scala @@ -263,8 +263,7 @@ class MillBuildBootstrap( ): RunnerState = { val (evaled, evalWatched, moduleWatches) = Evaluator.allEvaluators.withValue( - Seq(Evaluator.currentEvaluator.value) ++ - nestedState.frames.map(_.evaluator) + Seq(evaluator) ++ nestedState.frames.map(_.evaluator) ) { evaluateWithWatches(rootModule, evaluator, targetsAndParams) } From 8f4e471899174c61713ae9908ebabfdb2156ce79 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:43:25 +0800 Subject: [PATCH 09/15] . --- example/basic/1-simple-scala/.mill-version | 1 - 1 file changed, 1 deletion(-) delete mode 100644 example/basic/1-simple-scala/.mill-version diff --git a/example/basic/1-simple-scala/.mill-version b/example/basic/1-simple-scala/.mill-version deleted file mode 100644 index 2d68225e13e..00000000000 --- a/example/basic/1-simple-scala/.mill-version +++ /dev/null @@ -1 +0,0 @@ -0.11.1-35-29b382 \ No newline at end of file From 327118ecaafd526da61475731cefcfd6bac1f346 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:48:09 +0800 Subject: [PATCH 10/15] . --- bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala | 2 +- bsp/worker/src/mill/bsp/worker/State.scala | 4 +++- main/src/mill/main/TokenReaders.scala | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala index c1df1e46a21..b48d244a5d1 100644 --- a/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala +++ b/bsp/worker/src/mill/bsp/worker/BspWorkerImpl.scala @@ -18,7 +18,7 @@ private class BspWorkerImpl() extends BspWorker { streams: SystemStreams, logStream: PrintStream, logDir: os.Path, - canReload: Boolean, + canReload: Boolean ): Either[String, BspServerHandle] = { val millServer = diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index bedd2d2f9b2..9e95eb45523 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -25,7 +25,9 @@ private class State(evaluators: Seq[Evaluator], debug: String => Unit) { .toMap debug(s"Reused Evaluators: ${evaluators}") debug(s"Reused Evaluators outPaths: ${evaluators.map(_.outPath)}") - debug(s"Reused Evaluators rootModule.millSourcePath: ${evaluators.map(_.rootModule.millSourcePath)}") + debug( + s"Reused Evaluators rootModule.millSourcePath: ${evaluators.map(_.rootModule.millSourcePath)}" + ) debug(s"BspModules: ${map.mapValues(_._1.bspDisplayName).toMap}") map diff --git a/main/src/mill/main/TokenReaders.scala b/main/src/mill/main/TokenReaders.scala index 02378170711..06cc74e20e9 100644 --- a/main/src/mill/main/TokenReaders.scala +++ b/main/src/mill/main/TokenReaders.scala @@ -26,7 +26,8 @@ object Tasks { private[mill] class EvaluatorTokenReader[T]() extends mainargs.TokensReader.Constant[Evaluator] { def read(): Either[String, Evaluator] = Right(Evaluator.currentEvaluator.value) } -private[mill] class AllEvaluatorsTokenReader[T]() extends mainargs.TokensReader.Constant[Seq[Evaluator]] { +private[mill] class AllEvaluatorsTokenReader[T]() + extends mainargs.TokensReader.Constant[Seq[Evaluator]] { def read(): Either[String, Seq[Evaluator]] = Right(Evaluator.allEvaluators.value) } From 7a50ca47437abf921111e5a755e23e3e79927f0f Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 14 Aug 2023 11:54:48 +0800 Subject: [PATCH 11/15] . --- bsp/worker/src/mill/bsp/worker/State.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index 9e95eb45523..c145b701c59 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -23,11 +23,6 @@ private class State(evaluators: Seq[Evaluator], debug: String => Unit) { } } .toMap - debug(s"Reused Evaluators: ${evaluators}") - debug(s"Reused Evaluators outPaths: ${evaluators.map(_.outPath)}") - debug( - s"Reused Evaluators rootModule.millSourcePath: ${evaluators.map(_.rootModule.millSourcePath)}" - ) debug(s"BspModules: ${map.mapValues(_._1.bspDisplayName).toMap}") map From 987923275761f5d1924aed0bc1c97f7d554b58ea Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 14 Aug 2023 22:21:25 +0800 Subject: [PATCH 12/15] Update RunnerState.scala --- runner/src/mill/runner/RunnerState.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/runner/src/mill/runner/RunnerState.scala b/runner/src/mill/runner/RunnerState.scala index 39b21225224..8a91535a021 100644 --- a/runner/src/mill/runner/RunnerState.scala +++ b/runner/src/mill/runner/RunnerState.scala @@ -8,8 +8,6 @@ import mill.api.JsonFormatters._ import mill.eval.Evaluator import mill.main.RootModule -import scala.util.DynamicVariable - /** * This contains a list of frames each representing cached data from a single * level of `build.sc` evaluation: From 4d10461822be138dbaca9fab28cfd61c776880c3 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 14 Aug 2023 22:21:58 +0800 Subject: [PATCH 13/15] Update State.scala --- bsp/worker/src/mill/bsp/worker/State.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index c145b701c59..d38b14efadb 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -28,7 +28,7 @@ private class State(evaluators: Seq[Evaluator], debug: String => Unit) { map } - lazy val rootModules = evaluators.map(_.rootModule) + lazy val rootModules: Seq[mill.main.RootModule] = evaluators.map(_.rootModule) lazy val bspIdByModule: Map[BspModule, BuildTargetIdentifier] = bspModulesById.mapValues(_._1).map(_.swap).toMap From 3e6da77b10335c963edff08946a90ee6d3436f06 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 14 Aug 2023 22:39:20 +0800 Subject: [PATCH 14/15] Update State.scala --- bsp/worker/src/mill/bsp/worker/State.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/worker/src/mill/bsp/worker/State.scala b/bsp/worker/src/mill/bsp/worker/State.scala index d38b14efadb..cfe83dd737f 100644 --- a/bsp/worker/src/mill/bsp/worker/State.scala +++ b/bsp/worker/src/mill/bsp/worker/State.scala @@ -28,7 +28,7 @@ private class State(evaluators: Seq[Evaluator], debug: String => Unit) { map } - lazy val rootModules: Seq[mill.main.RootModule] = evaluators.map(_.rootModule) + lazy val rootModules: Seq[mill.define.BaseModule] = evaluators.map(_.rootModule) lazy val bspIdByModule: Map[BspModule, BuildTargetIdentifier] = bspModulesById.mapValues(_._1).map(_.swap).toMap From d50239b35eb051c1b3cdb8c294bea91afe98eaeb Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 15 Aug 2023 07:53:28 +0800 Subject: [PATCH 15/15] . --- bsp/src/mill/bsp/BSP.scala | 5 +++-- main/eval/src/mill/eval/Evaluator.scala | 3 ++- main/src/mill/main/TokenReaders.scala | 8 +++++--- runner/src/mill/runner/MillBuildBootstrap.scala | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 86e1aa54004..3442ee7e6af 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -49,9 +49,10 @@ object BSP extends ExternalModule with CoursierModule { * @param ev The Evaluator * @return The server result, indicating if mill should re-run this command or just exit. */ - def startSession(allEvaluators: Seq[Evaluator]): Command[BspServerResult] = T.command { + def startSession(allBootstrapEvaluators: Evaluator.AllBootstrapEvaluators) + : Command[BspServerResult] = T.command { T.log.errorStream.println("BSP/startSession: Starting BSP session") - val res = BspContext.bspServerHandle.runSession(allEvaluators) + val res = BspContext.bspServerHandle.runSession(allBootstrapEvaluators.value) T.log.errorStream.println(s"BSP/startSession: Finished BSP session, result: ${res}") res } diff --git a/main/eval/src/mill/eval/Evaluator.scala b/main/eval/src/mill/eval/Evaluator.scala index a278eeed368..f20156b3083 100644 --- a/main/eval/src/mill/eval/Evaluator.scala +++ b/main/eval/src/mill/eval/Evaluator.scala @@ -66,7 +66,8 @@ object Evaluator { // Until we migrate our CLI parsing off of Scopt (so we can pass the BaseModule // in directly) we are forced to pass it in via a ThreadLocal val currentEvaluator = new DynamicVariable[mill.eval.Evaluator](null) - val allEvaluators = new DynamicVariable[Seq[mill.eval.Evaluator]](null) + val allBootstrapEvaluators = new DynamicVariable[AllBootstrapEvaluators](null) + case class AllBootstrapEvaluators(value: Seq[Evaluator]) val defaultEnv: Map[String, String] = System.getenv().asScala.toMap diff --git a/main/src/mill/main/TokenReaders.scala b/main/src/mill/main/TokenReaders.scala index 06cc74e20e9..72915270827 100644 --- a/main/src/mill/main/TokenReaders.scala +++ b/main/src/mill/main/TokenReaders.scala @@ -27,8 +27,9 @@ private[mill] class EvaluatorTokenReader[T]() extends mainargs.TokensReader.Cons def read(): Either[String, Evaluator] = Right(Evaluator.currentEvaluator.value) } private[mill] class AllEvaluatorsTokenReader[T]() - extends mainargs.TokensReader.Constant[Seq[Evaluator]] { - def read(): Either[String, Seq[Evaluator]] = Right(Evaluator.allEvaluators.value) + extends mainargs.TokensReader.Constant[Evaluator.AllBootstrapEvaluators] { + def read(): Either[String, Evaluator.AllBootstrapEvaluators] = + Right(Evaluator.allBootstrapEvaluators.value) } private class LeftoverTaskTokenReader[T](tokensReaderOfT: TokensReader.Leftover[T, _]) @@ -42,7 +43,8 @@ object TokenReaders { implicit def millEvaluatorTokenReader[T]: mainargs.TokensReader[Evaluator] = new mill.main.EvaluatorTokenReader[T]() - implicit def millAllEvaluatorsTokenReader[T]: mainargs.TokensReader[Seq[Evaluator]] = + implicit def millAllEvaluatorsTokenReader[T] + : mainargs.TokensReader[Evaluator.AllBootstrapEvaluators] = new mill.main.AllEvaluatorsTokenReader[T]() implicit def millTasksTokenReader[T]: mainargs.TokensReader[Tasks[T]] = diff --git a/runner/src/mill/runner/MillBuildBootstrap.scala b/runner/src/mill/runner/MillBuildBootstrap.scala index e9727f86053..b32cc5a6df6 100644 --- a/runner/src/mill/runner/MillBuildBootstrap.scala +++ b/runner/src/mill/runner/MillBuildBootstrap.scala @@ -262,8 +262,8 @@ class MillBuildBootstrap( evaluator: Evaluator ): RunnerState = { - val (evaled, evalWatched, moduleWatches) = Evaluator.allEvaluators.withValue( - Seq(evaluator) ++ nestedState.frames.map(_.evaluator) + val (evaled, evalWatched, moduleWatches) = Evaluator.allBootstrapEvaluators.withValue( + Evaluator.AllBootstrapEvaluators(Seq(evaluator) ++ nestedState.frames.map(_.evaluator)) ) { evaluateWithWatches(rootModule, evaluator, targetsAndParams) }