Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BSP: implement buildTarget/OutputPaths request #2110

Merged
merged 6 commits into from
Nov 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions bsp/src/mill/bsp/BspCompileProblemReporter.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package mill.bsp

import java.io.File
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger}

import ch.epfl.scala.bsp4j._
import ch.epfl.scala.{bsp4j => bsp}
import mill.api.{CompileProblemReporter, Problem}
import scala.collection.JavaConverters._
import os.Path

import java.io.File
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger}
import scala.collection.concurrent
import scala.jdk.CollectionConverters._
import scala.language.implicitConversions

import os.Path

/**
* Specialized reporter that sends compilation diagnostics
* for each problem it logs, either as information, warning or
Expand Down
24 changes: 21 additions & 3 deletions bsp/src/mill/bsp/BspTestReporter.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
package mill.bsp

import java.io.{PrintWriter, StringWriter}

import ch.epfl.scala.bsp4j._
import ch.epfl.scala.bsp4j.{
BuildClient,
BuildTargetIdentifier,
StatusCode,
TaskDataKind,
TaskFinishParams,
TaskId,
TaskStartParams,
TestFinish,
TestReport,
TestStart,
TestStatus
}
import mill.api.TestReporter
import sbt.testing._
import sbt.testing.{
Event,
NestedSuiteSelector,
NestedTestSelector,
SuiteSelector,
TestSelector,
TestWildcardSelector
}

/**
* Context class for BSP, specialized for sending `task-start` and
Expand Down
74 changes: 43 additions & 31 deletions bsp/src/mill/bsp/MillBuildServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import ch.epfl.scala.bsp4j.{
InitializeBuildResult,
InverseSourcesParams,
InverseSourcesResult,
OutputPathItem,
OutputPathItemKind,
OutputPathsItem,
OutputPathsParams,
OutputPathsResult,
ResourcesItem,
ResourcesParams,
ResourcesResult,
Expand Down Expand Up @@ -178,14 +183,6 @@ class MillBuildServer(

// TODO: scan BspModules and infer their capabilities

// if (request.getRootUri != bspIdByModule(millBuildTarget).getUri) {
// log.debug(
// s"Workspace root differs from mill build root! Requested root: ${request.getRootUri} Mill root: ${millBuildTarget.buildTargetId.getUri}"
// )
// }

// val moduleBspInfo = bspModulesById.values.map(_.bspBuildTarget).toSeq

val clientCaps = request.getCapabilities().getLanguageIds().asScala

// val compileLangs = moduleBspInfo.filter(_.canCompile).flatMap(_.languageIds).distinct.filter(
Expand All @@ -206,21 +203,20 @@ class MillBuildServer(

val supportedLangs = Seq("java", "scala").asJava
val capabilities = new BuildServerCapabilities

capabilities.setBuildTargetChangedProvider(false)
capabilities.setCanReload(canReload)
capabilities.setCompileProvider(new CompileProvider(supportedLangs))
capabilities.setRunProvider(new RunProvider(supportedLangs))
capabilities.setTestProvider(new TestProvider(supportedLangs))
capabilities.setDebugProvider(new DebugProvider(Seq().asJava))
capabilities.setDependencySourcesProvider(true)

capabilities.setDependencyModulesProvider(true)
capabilities.setDependencySourcesProvider(true)
capabilities.setInverseSourcesProvider(true)
capabilities.setResourcesProvider(true)
capabilities.setBuildTargetChangedProvider(
false
)
capabilities.setCanReload(canReload)
capabilities.setJvmRunEnvironmentProvider(true)
capabilities.setJvmTestEnvironmentProvider(true)
capabilities.setOutputPathsProvider(true)
capabilities.setResourcesProvider(true)
capabilities.setRunProvider(new RunProvider(supportedLangs))
capabilities.setTestProvider(new TestProvider(supportedLangs))

request.getDisplayName match {
case "IntelliJ-BSP" => clientIsIntelliJ = true
Expand Down Expand Up @@ -362,13 +358,6 @@ class MillBuildServer(
sources.setRoots(Seq(sanitizeUri(evaluator.rootModule.millSourcePath)).asJava)
sources
}
// case (id, `millBuildTarget`) =>
// T.task {
// new SourcesItem(
// id,
// Seq(sourceItem(evaluator.rootModule.millSourcePath / "build.sc", false)).asJava
// )
// }
case (id, module: JavaModule) =>
T.task {
val items = module.sources().map(p => sourceItem(p.path, false)) ++
Expand Down Expand Up @@ -412,13 +401,6 @@ class MillBuildServer(
targetIds = p.getTargets.asScala.toSeq,
agg = (items: Seq[DependencySourcesItem]) => new DependencySourcesResult(items.asJava)
) {
// case (id, `millBuildTarget`) =>
// T.task {
// new DependencySourcesItem(
// id,
// ModuleUtils.getMillBuildClasspath(evaluator, sources = true).asJava
// )
// }
case (id, m: JavaModule) =>
T.task {
val sources = m.resolveDeps(
Expand Down Expand Up @@ -500,6 +482,36 @@ class MillBuildServer(
compileResult // TODO: See in what form IntelliJ expects data about products of compilation in order to set data field
}

override def buildTargetOutputPaths(params: OutputPathsParams)
: CompletableFuture[OutputPathsResult] =
completable(s"buildTargetOutputPaths ${params}") { state =>
import state._

val outItems = new OutputPathItem(
// Spec says, a directory must end with a forward slash
sanitizeUri.apply(evaluator.outPath) + "/",
OutputPathItemKind.DIRECTORY
)

val extItems = new OutputPathItem(
// Spec says, a directory must end with a forward slash
sanitizeUri.apply(evaluator.externalOutPath) + "/",
OutputPathItemKind.DIRECTORY
)

val items = for {
target <- params.getTargets.asScala
module <- bspModulesById.get(target)
} yield {
val items =
if (module.millOuterCtx.external) List(extItems)
else List(outItems)
new OutputPathsItem(target, items.asJava)
}

new OutputPathsResult(items.asJava)
}

override def buildTargetRun(runParams: RunParams): CompletableFuture[RunResult] =
completable(s"buildTargetRun ${runParams}") { state =>
import state._
Expand Down
2 changes: 1 addition & 1 deletion bsp/src/mill/bsp/TaskParameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package mill.bsp

import ch.epfl.scala.bsp4j.{BuildTargetIdentifier, CompileParams, RunParams, TestParams}

import scala.collection.JavaConverters._
import scala.jdk.CollectionConverters._

/**
* Common trait to represent BSP request parameters that
Expand Down
3 changes: 1 addition & 2 deletions bsp/src/mill/bsp/Utils.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package mill.bsp

import ch.epfl.scala.bsp4j.{BuildClient, BuildTargetIdentifier, StatusCode, TaskId}
import mill._
import mill.api.CompileProblemReporter
import mill.api.Result.{Skipped, Success}
import mill.api.{CompileProblemReporter}
import mill.eval.Evaluator
import mill.scalalib.JavaModule
import mill.scalalib.bsp.BspModule
Expand Down
2 changes: 1 addition & 1 deletion build.sc
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ object Deps {
val utest = ivy"com.lihaoyi::utest:0.7.11"
val windowsAnsi = ivy"io.github.alexarchambault.windows-ansi:windows-ansi:0.0.4"
val zinc = ivy"org.scala-sbt::zinc:1.8.0"
val bsp = ivy"ch.epfl.scala:bsp4j:2.1.0-M1"
val bsp = ivy"ch.epfl.scala:bsp4j:2.1.0-M3"
val fansi = ivy"com.lihaoyi::fansi:0.4.0"
val jarjarabrams = ivy"com.eed3si9n.jarjarabrams::jarjar-abrams-core:1.8.1"
val requests = ivy"com.lihaoyi::requests:0.7.1"
Expand Down