diff options
-rw-r--r-- | .bsp/mill-bsp.json | 1 | ||||
-rw-r--r-- | contrib/bsp/src/mill/contrib/MainMillBuildServer.scala | 40 | ||||
-rw-r--r-- | contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala | 14 | ||||
-rw-r--r-- | contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala | 33 | ||||
-rw-r--r-- | contrib/bsp/src/mill/contrib/bsp/TaskParameters.scala | 97 | ||||
-rw-r--r-- | main/api/src/mill/api/Ctx.scala | 3 | ||||
-rw-r--r-- | main/core/src/eval/Evaluator.scala | 26 | ||||
-rw-r--r-- | scalalib/src/JavaModule.scala | 2 | ||||
-rw-r--r-- | scalalib/src/ScalaModule.scala | 2 | ||||
-rw-r--r-- | scratch/build.sc | 14 |
10 files changed, 185 insertions, 47 deletions
diff --git a/.bsp/mill-bsp.json b/.bsp/mill-bsp.json new file mode 100644 index 00000000..0c4587f9 --- /dev/null +++ b/.bsp/mill-bsp.json @@ -0,0 +1 @@ +{"name":"mill-bsp","argv":["/home/alexandra/mill-release", "-i", "mill.contrib.MainMillBuildServer/startServer"],"version":"1.0.0","bspVersion":"2.0.0-M4","languages":["scala","java"]} diff --git a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala index 7caaf5d3..b9e8ee8a 100644 --- a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala +++ b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala @@ -7,7 +7,7 @@ import java.nio.file.FileAlreadyExistsException import java.util.concurrent.{CancellationException, CompletableFuture, ExecutorService, Executors, Future} import upickle.default._ -import ch.epfl.scala.bsp4j.{BspConnectionDetails, BuildClient, DidChangeBuildTarget, LogMessageParams, PublishDiagnosticsParams, ScalaTestClassesParams, ShowMessageParams, TaskFinishParams, TaskProgressParams, TaskStartParams, WorkspaceBuildTargetsResult} +import ch.epfl.scala.bsp4j.{BspConnectionDetails, BuildClient, CompileParams, DidChangeBuildTarget, LogMessageParams, PublishDiagnosticsParams, ScalaTestClassesParams, ShowMessageParams, TaskFinishParams, TaskProgressParams, TaskStartParams, WorkspaceBuildTargetsResult} import mill._ import mill.api.Strict import mill.contrib.bsp.{BspLoggedReporter, MillBuildServer, ModuleUtils} @@ -120,8 +120,9 @@ object MainMillBuildServer extends ExternalModule { * server */ def startServer(ev: Evaluator): Command[Unit] = T.command { - - val millServer = new mill.contrib.bsp.MillBuildServer(ev, bspVersion, version, languages) + val eval = new Evaluator(ev.home, ev.outPath, ev.externalOutPath, ev.rootModule, ev.log, ev.classLoaderSig, + ev.workerCache, ev.env, false) + val millServer = new mill.contrib.bsp.MillBuildServer(eval, bspVersion, version, languages) val executor = Executors.newCachedThreadPool() val stdin = System.in @@ -152,14 +153,26 @@ object MainMillBuildServer extends ExternalModule { } def experiment(ev: Evaluator): Command[Unit] = T.command { - val millServer = new mill.contrib.bsp.MillBuildServer(ev, bspVersion, version, languages) + val eval = new Evaluator(ev.home, ev.outPath, ev.externalOutPath, ev.rootModule, ev.log, ev.classLoaderSig, + ev.workerCache, ev.env, false) + val millServer = new mill.contrib.bsp.MillBuildServer(eval, bspVersion, version, languages) val client = new BuildClient { var diagnostics = List.empty[PublishDiagnosticsParams] - override def onBuildShowMessage(params: ShowMessageParams): Unit = ??? - override def onBuildLogMessage(params: LogMessageParams): Unit = ??? - override def onBuildTaskStart(params: TaskStartParams): Unit = ??? - override def onBuildTaskProgress(params: TaskProgressParams): Unit = ??? - override def onBuildTaskFinish(params: TaskFinishParams): Unit = ??? + override def onBuildShowMessage(params: ShowMessageParams): Unit = { + + } + override def onBuildLogMessage(params: LogMessageParams): Unit = { + + } + override def onBuildTaskStart(params: TaskStartParams): Unit = { + + } + override def onBuildTaskProgress(params: TaskProgressParams): Unit = { + + } + override def onBuildTaskFinish(params: TaskFinishParams): Unit = { + + } override def onBuildPublishDiagnostics( params: PublishDiagnosticsParams ): Unit = { @@ -168,12 +181,11 @@ object MainMillBuildServer extends ExternalModule { override def onBuildTargetDidChange(params: DidChangeBuildTarget): Unit = ??? } + millServer.client = client for (module <- millServer.millModules) { - ev.evaluate(Strict.Agg(module.compile), Option(new BspLoggedReporter(client, - millServer.moduleToTargetId(module), - Option.empty[String], - 10, millServer.getCompilationLogger))) - //println("Diagnostics: " + client.diagnostics) + if (millServer.moduleToTarget(module).getDisplayName == "random") { + println(millServer.buildTargetCompile(new CompileParams(List(millServer.moduleToTargetId(module)).asJava)).get) + } } } diff --git a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala index 5c7d5e5d..6d92cd16 100644 --- a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala +++ b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala @@ -24,6 +24,7 @@ class BspLoggedReporter(client: bsp.BuildClient, } override def logInfo(problem: Problem): Unit = { + logger.info("Problem: " + problem.toString) client.onBuildPublishDiagnostics(getDiagnostics(problem, targetId, compilationOriginId)) super.logInfo(problem) } @@ -33,12 +34,10 @@ class BspLoggedReporter(client: bsp.BuildClient, super.logWarning(problem) } + //TODO: document that if the problem is a general information without a text document + // associated to it, then the document field of the diagnostic is set to the uri of the target def getDiagnostics(problem: Problem, targetId: bsp.BuildTargetIdentifier, originId: Option[String]): bsp.PublishDiagnosticsParams = { - println("Line: " + problem.position.line) - println("Offset: " + problem.position.offset) - println("pointer: " + problem.position.pointer) - println("pointer space: " + problem.position.pointerSpace) val sourceFile = problem.position().sourceFile().asScala val start = new bsp.Position( problem.position.startLine.asScala.getOrElse(problem.position.line.asScala.getOrElse(0)), @@ -55,9 +54,12 @@ class BspLoggedReporter(client: bsp.BuildClient, case Severity.Warn => bsp.DiagnosticSeverity.WARNING } ) - + val textDocument = sourceFile.getOrElse(None) match { + case None => targetId.getUri + case f: File => f.toPath.toUri.toString + } val params = new bsp.PublishDiagnosticsParams( - new bsp.TextDocumentIdentifier(sourceFile.getOrElse(new File(targetId.getUri)).toPath.toAbsolutePath.toUri.toString), + new bsp.TextDocumentIdentifier(textDocument), targetId, List(diagnostic).asJava, true) if (originId.nonEmpty) { params.setOriginId(originId.get) } diff --git a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala index 3a694599..b4635558 100644 --- a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala +++ b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala @@ -235,9 +235,17 @@ class MillBuildServer(evaluator: Evaluator, } } + def getArguments(params: CompileParams) : Option[Seq[String]] = { + try { + Option(params.getArguments.asScala) + } catch { + case e: Exception => Option.empty[Seq[String]] + } + } + def getCompilationLogger: ManagedLogger = { val consoleAppender = MainAppender.defaultScreen(ConsoleOut.printStreamOut( - mill.util.DummyLogger.outputStream + System.out )) val l = LogExchange.logger("Hello") LogExchange.unbindLoggerAppenders("Hello") @@ -250,13 +258,12 @@ class MillBuildServer(evaluator: Evaluator, override def buildTargetCompile(compileParams: CompileParams): CompletableFuture[CompileResult] = { def getCompileResult: CompileResult = { - + val params = TaskParameters.fromCompileParams(compileParams) var numFailures = 0 var compileTime = 0 - for (targetId <- compileParams.getTargets.asScala) { + for (targetId <- params.getTargets) { if (moduleToTarget(targetIdToModule(targetId)).getCapabilities.getCanCompile) { val millModule = targetIdToModule(targetId) - //millModule.javacOptions = compileParams.getArguments.asScala val compileTask = millModule.compile // send notification to client that compilation of this target started @@ -271,7 +278,8 @@ class MillBuildServer(evaluator: Evaluator, Option(new BspLoggedReporter(client, targetId, getOriginId(compileParams), - 10, getCompilationLogger))) + 10, getCompilationLogger)), + params.getArguments.getOrElse(Seq.empty[String])) val endTime = System.currentTimeMillis() compileTime += result.timings.map(timingTuple => timingTuple._2).sum @@ -312,16 +320,13 @@ class MillBuildServer(evaluator: Evaluator, override def buildTargetRun(runParams: RunParams): CompletableFuture[RunResult] = { def getRunResult: RunResult = { - val module = targetIdToModule(runParams.getTarget) - val args = runParams.getArguments -// val runResult = runParams.getData() match { -// case d: ScalaMainClass => millEvaluator.evaluate(Strict.Agg(module.runMain(d.getClass, d.getArguments.asScala))) -// case default => millEvaluator.evaluate(Strict.Agg(module.run(args.asScala.mkString(" ")))) -// } - val runResult = millEvaluator.evaluate(Strict.Agg(module.run(args.asScala.mkString(" "))), + val params = TaskParameters.fromRunParams(runParams) + val module = targetIdToModule(params.getTargets.head) + val args = params.getArguments.getOrElse(Seq.empty[String]) + val runResult = millEvaluator.evaluate(Strict.Agg(module.run(args.mkString(" "))), Option(new BspLoggedReporter(client, - runParams.getTarget, - Option.empty[String], + params.getTargets.head, + params.getOriginId, 10, getCompilationLogger))) if (runResult.failing.keyCount > 0) { new RunResult(StatusCode.ERROR) diff --git a/contrib/bsp/src/mill/contrib/bsp/TaskParameters.scala b/contrib/bsp/src/mill/contrib/bsp/TaskParameters.scala new file mode 100644 index 00000000..b020b498 --- /dev/null +++ b/contrib/bsp/src/mill/contrib/bsp/TaskParameters.scala @@ -0,0 +1,97 @@ +package mill.contrib.bsp +import java.util + +import scala.collection.JavaConverters._ +import scala.compat.java8.OptionConverters._ +import ch.epfl.scala.bsp4j.{BuildTargetIdentifier, CompileParams, RunParams, TestParams} + +trait Parameters { + def getTargets: List[BuildTargetIdentifier] + + def getArguments: Option[Seq[String]] + + def getOriginId: Option[String] +} + +case class CParams(compileParams: CompileParams) extends Parameters { + + override def getTargets: List[BuildTargetIdentifier] = { + compileParams.getTargets.asScala.toList + } + + override def getArguments: Option[Seq[String]] = { + try { + Option(compileParams.getArguments.asScala) + }catch { + case e: Exception => Option.empty[Seq[String]] + } + } + + override def getOriginId: Option[String] = { + try { + Option(compileParams.getOriginId) + }catch { + case e: Exception => Option.empty[String] + } + } + +} +case class RParams(runParams: RunParams) extends Parameters { + + override def getTargets: List[BuildTargetIdentifier] = { + List(runParams.getTarget) + } + + override def getArguments: Option[Seq[String]] = { + try { + Option(runParams.getArguments.asScala) + }catch { + case e: Exception => Option.empty[Seq[String]] + } + } + + override def getOriginId: Option[String] = { + try { + Option(runParams.getOriginId) + }catch { + case e: Exception => Option.empty[String] + } + } + +} +case class TParams(testParams: TestParams) extends Parameters { + + override def getTargets: List[BuildTargetIdentifier] = { + testParams.getTargets.asScala.toList + } + + override def getArguments: Option[Seq[String]] = { + try { + Option(testParams.getArguments.asScala) + }catch { + case e: Exception => Option.empty[Seq[String]] + } + } + + override def getOriginId: Option[String] = { + try { + Option(testParams.getOriginId) + }catch { + case e: Exception => Option.empty[String] + } + } +} + +object TaskParameters { + def fromCompileParams(compileParams: CompileParams): Parameters = { + CParams(compileParams) + } + + def fromRunParams(runParams: RunParams): Parameters = { + RParams(runParams) + } + + def fromTestParams(testParams: TestParams): Parameters = { + TParams(testParams) + } +}
\ No newline at end of file diff --git a/main/api/src/mill/api/Ctx.scala b/main/api/src/mill/api/Ctx.scala index 7d081d6a..0799d887 100644 --- a/main/api/src/mill/api/Ctx.scala +++ b/main/api/src/mill/api/Ctx.scala @@ -61,7 +61,8 @@ class Ctx( val log: Logger, val home: os.Path, val env: Map[String, String], - val reporter: Option[ManagedLoggedReporter] + val reporter: Option[ManagedLoggedReporter], + val compileArguments: Seq[String] = Seq.empty[String] ) extends Ctx.Dest with Ctx.Log diff --git a/main/core/src/eval/Evaluator.scala b/main/core/src/eval/Evaluator.scala index 99befd0d..55802546 100644 --- a/main/core/src/eval/Evaluator.scala +++ b/main/core/src/eval/Evaluator.scala @@ -12,7 +12,7 @@ import mill.api.Result.{Aborted, OuterStack, Success} import mill.util import mill.util._ import mill.api.Strict.Agg -import sbt.internal.inc.ManagedLoggedReporter +import sbt.internal.inc.{CompilerArguments, ManagedLoggedReporter} import sbt.internal.util.{ConsoleOut, MainAppender} import sbt.util.LogExchange @@ -42,9 +42,11 @@ case class Evaluator(home: os.Path, val classLoaderSignHash = classLoaderSig.hashCode() - def evaluate(goals: Agg[Task[_]], reporter: Option[ManagedLoggedReporter] = Option.empty[ManagedLoggedReporter]): Evaluator.Results = { + def evaluate(goals: Agg[Task[_]], + reporter: Option[ManagedLoggedReporter] = Option.empty[ManagedLoggedReporter], + compileArguments: Seq[String] = Seq.empty[String]): Evaluator.Results = { os.makeDir.all(outPath) - + println("Reporter: " + reporter) val (sortedGroups, transitive) = Evaluator.plan(rootModule, goals) val evaluated = new Agg.Mutable[Task[_]] @@ -69,7 +71,8 @@ case class Evaluator(home: os.Path, group, results, counterMsg, - reporter + reporter, + compileArguments ) someTaskFailed = someTaskFailed || newResults.exists(task => !task._2.isInstanceOf[Success[_]]) @@ -115,7 +118,8 @@ case class Evaluator(home: os.Path, group: Agg[Task[_]], results: collection.Map[Task[_], Result[(Any, Int)]], counterMsg: String, - reporter: Option[ManagedLoggedReporter] + reporter: Option[ManagedLoggedReporter], + compilerArguments: Seq[String] ): (collection.Map[Task[_], Result[(Any, Int)]], Seq[Task[_]], Boolean) = { val externalInputsHash = scala.util.hashing.MurmurHash3.orderedHash( @@ -138,7 +142,8 @@ case class Evaluator(home: os.Path, paths = None, maybeTargetLabel = None, counterMsg = counterMsg, - reporter + reporter, + compilerArguments ) (newResults, newEvaluated, false) case Right(labelledNamedTask) => @@ -191,7 +196,8 @@ case class Evaluator(home: os.Path, paths = Some(paths), maybeTargetLabel = Some(msgParts.mkString), counterMsg = counterMsg, - reporter + reporter, + compilerArguments ) newResults(labelledNamedTask.task) match{ @@ -266,7 +272,8 @@ case class Evaluator(home: os.Path, paths: Option[Evaluator.Paths], maybeTargetLabel: Option[String], counterMsg: String, - reporter: Option[ManagedLoggedReporter]): (mutable.LinkedHashMap[Task[_], Result[(Any, Int)]], mutable.Buffer[Task[_]]) = { + reporter: Option[ManagedLoggedReporter], + compileArguments: Seq[String]): (mutable.LinkedHashMap[Task[_], Result[(Any, Int)]], mutable.Buffer[Task[_]]) = { val newEvaluated = mutable.Buffer.empty[Task[_]] @@ -327,7 +334,8 @@ case class Evaluator(home: os.Path, multiLogger, home, env, - reporter //new ManagedLoggedReporter(10, logger) + reporter, + compileArguments//new ManagedLoggedReporter(10, logger) ) val out = System.out val in = System.in diff --git a/scalalib/src/JavaModule.scala b/scalalib/src/JavaModule.scala index e6c47324..941f82e7 100644 --- a/scalalib/src/JavaModule.scala +++ b/scalalib/src/JavaModule.scala @@ -221,7 +221,7 @@ trait JavaModule extends mill.Module with TaskModule with GenIdeaModule { outer upstreamCompileOutput(), allSourceFiles().map(_.path), compileClasspath().map(_.path), - javacOptions(), + javacOptions() ++ T.ctx.compileArguments, T.ctx().reporter ) } diff --git a/scalalib/src/ScalaModule.scala b/scalalib/src/ScalaModule.scala index 5c7a4c97..0c3684c6 100644 --- a/scalalib/src/ScalaModule.scala +++ b/scalalib/src/ScalaModule.scala @@ -140,7 +140,7 @@ trait ScalaModule extends JavaModule { outer => javacOptions(), scalaVersion(), scalaOrganization(), - scalacOptions(), + scalacOptions() ++ T.ctx.compileArguments, scalaCompilerClasspath().map(_.path), scalacPluginClasspath().map(_.path), T.ctx().reporter diff --git a/scratch/build.sc b/scratch/build.sc index c36b554f..85228a20 100644 --- a/scratch/build.sc +++ b/scratch/build.sc @@ -1,5 +1,5 @@ import mill._, scalalib._ -//import $ivy.`com.lihaoyi::mill-contrib-bsp:0.4.1-7-be21ae-DIRTY1fe41d7a` +//import $ivy.`com.lihaoyi::mill-contrib-bsp:0.4.1-16-c95bc4-DIRTYd5dc7fa5` object mill_exercise extends ScalaModule { def scalaVersion = "2.12.8" @@ -28,3 +28,15 @@ object mill_exercise extends ScalaModule { def testFrameworks = Seq("org.scalatest.tools.Framework") } } + +object random extends SbtModule { + + def scalacOptions = Seq( + //"-Ywarn-unused", + "-Ylog-classpath" + ) + + def scalaVersion = "2.12.8" + + def ivyDeps = Agg(ivy"ch.epfl.scala:bsp4j:2.0.0-M3") +} |