diff --git a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala index 1e890f59bda..3a21d7b1e46 100644 --- a/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillBuildServer.scala @@ -100,6 +100,9 @@ private class MillBuildServer( protected var clientWantsSemanticDb = false protected var clientIsIntelliJ = false + /** `true` when client and server support the `JvmCompileClasspathProvider`` request. */ + protected var enableJvmCompileClasspathProvider = false + private[this] var statePromise: Promise[State] = Promise[State]() def updateEvaluator(evaluatorsOpt: Option[Seq[Evaluator]]): Unit = { @@ -120,6 +123,9 @@ private class MillBuildServer( : CompletableFuture[InitializeBuildResult] = completableNoState(s"buildInitialize ${request}", checkInitialized = false) { + val clientCapabilities = request.getCapabilities() + enableJvmCompileClasspathProvider = clientCapabilities.getJvmCompileClasspathReceiver + // TODO: scan BspModules and infer their capabilities val supportedLangs = Seq("java", "scala").asJava @@ -132,6 +138,7 @@ private class MillBuildServer( capabilities.setDependencyModulesProvider(true) capabilities.setDependencySourcesProvider(true) capabilities.setInverseSourcesProvider(true) + capabilities.setJvmCompileClasspathProvider(enableJvmCompileClasspathProvider) capabilities.setJvmRunEnvironmentProvider(true) capabilities.setJvmTestEnvironmentProvider(true) capabilities.setOutputPathsProvider(true) diff --git a/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala index 79c574ea020..b358ddcc28e 100644 --- a/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillJvmBuildServer.scala @@ -3,6 +3,9 @@ package mill.bsp.worker import ch.epfl.scala.bsp4j.{ BuildTargetIdentifier, JvmBuildServer, + JvmCompileClasspathItem, + JvmCompileClasspathParams, + JvmCompileClasspathResult, JvmEnvironmentItem, JvmMainClass, JvmRunEnvironmentParams, @@ -22,7 +25,7 @@ private trait MillJvmBuildServer extends JvmBuildServer { this: MillBuildServer override def buildTargetJvmRunEnvironment(params: JvmRunEnvironmentParams) : CompletableFuture[JvmRunEnvironmentResult] = { jvmRunTestEnvironment( - s"jvmRunEnvironment ${params}", + s"buildTarget/jvmRunEnvironment ${params}", params.getTargets.asScala.toSeq, new JvmRunEnvironmentResult(_) ) @@ -31,7 +34,7 @@ private trait MillJvmBuildServer extends JvmBuildServer { this: MillBuildServer override def buildTargetJvmTestEnvironment(params: JvmTestEnvironmentParams) : CompletableFuture[JvmTestEnvironmentResult] = { jvmRunTestEnvironment( - s"jvmTestEnvironment ${params}", + s"buildTarget/jvmTestEnvironment ${params}", params.getTargets.asScala.toSeq, new JvmTestEnvironmentResult(_) ) @@ -41,7 +44,7 @@ private trait MillJvmBuildServer extends JvmBuildServer { this: MillBuildServer name: String, targetIds: Seq[BuildTargetIdentifier], agg: java.util.List[JvmEnvironmentItem] => V - ) = { + ): CompletableFuture[V] = { completableTasks( name, targetIds = _ => targetIds, @@ -65,7 +68,7 @@ private trait MillJvmBuildServer extends JvmBuildServer { this: MillBuildServer ev, state, id, - m: JavaModule, + _: JavaModule, (runClasspath, forkArgs, forkWorkingDir, forkEnv, mainClass, zincWorker, compile) ) => val classpath = runClasspath.map(_.path).map(sanitizeUri) @@ -84,4 +87,26 @@ private trait MillJvmBuildServer extends JvmBuildServer { this: MillBuildServer agg } } + + override def buildTargetJvmCompileClasspath(params: JvmCompileClasspathParams) + : CompletableFuture[JvmCompileClasspathResult] = + completableTasks( + hint = "buildTarget/jvmCompileClasspath", + targetIds = _ => params.getTargets.asScala.toSeq, + tasks = { + case m: JavaModule => m.bspCompileClasspath + } + ) { + case (ev, _, id, _: JavaModule, compileClasspath) => + val pathResolver = ev.pathsResolver + + new JvmCompileClasspathItem( + id, + compileClasspath.iterator + .map(_.resolve(pathResolver)) + .map(sanitizeUri).toSeq.asJava + ) + } { + new JvmCompileClasspathResult(_) + } } diff --git a/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala b/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala index 454ad9927b8..2f9610dbe68 100644 --- a/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala +++ b/bsp/worker/src/mill/bsp/worker/MillScalaBuildServer.scala @@ -16,7 +16,7 @@ import ch.epfl.scala.bsp4j.{ import mill.{Agg, T} import mill.bsp.worker.Utils.sanitizeUri import mill.util.Jvm -import mill.scalalib.{JavaModule, ScalaModule, SemanticDbJavaModule, TestModule} +import mill.scalalib.{JavaModule, ScalaModule, TestModule, UnresolvedPath} import mill.testrunner.{Framework, TestRunnerUtils} import sbt.testing.Fingerprint @@ -29,25 +29,33 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer override def buildTargetScalacOptions(p: ScalacOptionsParams) : CompletableFuture[ScalacOptionsResult] = completableTasks( - hint = s"buildTargetScalacOptions ${p}", + hint = s"buildTarget/scalacOptions ${p}", targetIds = _ => p.getTargets.asScala.toSeq, tasks = { - case m: ScalaModule => - val classesPathTask = m match { - case sem: SemanticDbJavaModule if clientWantsSemanticDb => - sem.bspCompiledClassesAndSemanticDbFiles - case _ => m.bspCompileClassesPath + case m: JavaModule => + val scalacOptionsTask = m match { + case m: ScalaModule => m.allScalacOptions + case _ => T.task { Seq.empty[String] } } - T.task((m.allScalacOptions(), m.bspCompileClasspath(), classesPathTask())) + val compileClasspathTask = + if (enableJvmCompileClasspathProvider) { + // We have a dedicated request for it + T.task { Agg.empty[UnresolvedPath] } + } else { + m.bspCompileClasspath + } - case m: JavaModule => - val classesPathTask = m match { - case sem: SemanticDbJavaModule if clientWantsSemanticDb => - sem.bspCompiledClassesAndSemanticDbFiles - case _ => m.bspCompileClassesPath + val classesPathTask = + if (clientWantsSemanticDb) { + m.bspCompiledClassesAndSemanticDbFiles + } else { + m.bspCompileClassesPath + } + + T.task { + (scalacOptionsTask(), compileClasspathTask(), classesPathTask()) } - T.task { (Nil, Nil, classesPathTask()) } } ) { // We ignore all non-JavaModule @@ -56,13 +64,13 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer state, id, m: JavaModule, - (allScalacOptions, bspCompileClsaspath, classesPathTask) + (allScalacOptions, compileClasspath, classesPathTask) ) => val pathResolver = ev.pathsResolver new ScalacOptionsItem( id, allScalacOptions.asJava, - bspCompileClsaspath.iterator + compileClasspath.iterator .map(_.resolve(pathResolver)) .map(sanitizeUri).toSeq.asJava, sanitizeUri(classesPathTask.resolve(pathResolver)) @@ -74,7 +82,7 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer override def buildTargetScalaMainClasses(p: ScalaMainClassesParams) : CompletableFuture[ScalaMainClassesResult] = completableTasks( - hint = "buildTargetScalaMainClasses", + hint = "buildTarget/scalaMainClasses", targetIds = _ => p.getTargets.asScala.toSeq, tasks = { case m: JavaModule => T.task((m.zincWorker().worker(), m.compile(), m.forkArgs(), m.forkEnv())) @@ -100,7 +108,7 @@ private trait MillScalaBuildServer extends ScalaBuildServer { this: MillBuildSer override def buildTargetScalaTestClasses(p: ScalaTestClassesParams) : CompletableFuture[ScalaTestClassesResult] = completableTasks( - s"buildTargetScalaTestClasses ${p}", + s"buildTarget/scalaTestClasses ${p}", targetIds = _ => p.getTargets.asScala.toSeq, tasks = { case m: TestModule => diff --git a/build.sc b/build.sc index 89c5579f13e..1aee81222ac 100644 --- a/build.sc +++ b/build.sc @@ -184,7 +184,7 @@ object Deps { val windowsAnsi = ivy"io.github.alexarchambault.windows-ansi:windows-ansi:0.0.5" val zinc = ivy"org.scala-sbt::zinc:1.9.6" // keep in sync with doc/antora/antory.yml - val bsp4j = ivy"ch.epfl.scala:bsp4j:2.2.0-M1" + val bsp4j = ivy"ch.epfl.scala:bsp4j:2.2.0-M2" val fansi = ivy"com.lihaoyi::fansi:0.4.0" val jarjarabrams = ivy"com.eed3si9n.jarjarabrams::jarjar-abrams-core:1.14.0" val requests = ivy"com.lihaoyi::requests:0.8.0"