summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandra Dima <alexandra.dima@jetbrains.com>2019-07-22 10:44:50 +0200
committerSamvel Abrahamyan <samvel1024@gmail.com>2019-10-12 14:33:07 +0200
commitb5347266ee73d62659d01bdfe2d3444680a98747 (patch)
tree0e7452f50e574c50c953c7c93fcc359748cb742b
parent2e37532d915d54f61bc645faa6b0c73f29c5d9ea (diff)
downloadmill-b5347266ee73d62659d01bdfe2d3444680a98747.tar.gz
mill-b5347266ee73d62659d01bdfe2d3444680a98747.tar.bz2
mill-b5347266ee73d62659d01bdfe2d3444680a98747.zip
Modified the compilation diagnostics reporter to send not only the currently generated diagnostic, but also all of the past diagnostics discovered for a certain source file. This will be compatible with the idea that each set of diagnostics for a certain file invalidates all other diagnostics received in the past.
-rw-r--r--contrib/bsp/src/mill/contrib/MainMillBuildServer.scala22
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala65
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala17
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala61
-rw-r--r--scalalib/src/JavaModule.scala2
5 files changed, 95 insertions, 72 deletions
diff --git a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala
index 24adaf1d..ba1dbcec 100644
--- a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala
+++ b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala
@@ -7,10 +7,11 @@ import java.nio.file.FileAlreadyExistsException
import java.util.concurrent.{CancellationException, CompletableFuture, ExecutorService, Executors, Future}
import upickle.default._
-import ch.epfl.scala.bsp4j.{BspConnectionDetails, BuildClient, CleanCacheParams, CompileParams, DidChangeBuildTarget, LogMessageParams, PublishDiagnosticsParams, ScalaTestClassesParams, ShowMessageParams, TaskFinishParams, TaskProgressParams, TaskStartParams, TestParams, WorkspaceBuildTargetsResult}
+import ch.epfl.scala.bsp4j.{BspConnectionDetails, BuildClient, BuildTargetIdentifier, CleanCacheParams, CompileParams, CompileTask, DidChangeBuildTarget, LogMessageParams, PublishDiagnosticsParams, ScalaTestClassesParams, ScalacOptionsParams, ShowMessageParams, SourcesParams, TaskFinishParams, TaskProgressParams, TaskStartParams, TestParams, WorkspaceBuildTargetsResult}
import mill._
-import mill.api.Strict
-import mill.contrib.bsp.{BspLoggedReporter, MillBuildServer, ModuleUtils}
+import mill.api.Result.{Aborted, Skipped}
+import mill.api.{BspContext, Result, Strict}
+import mill.contrib.bsp.{BspLoggedReporter, MillBspLogger, MillBuildServer, ModuleUtils, TaskParameters}
import mill.define.{Command, Discover, ExternalModule, Target, Task}
import mill.eval.Evaluator
import mill.scalalib._
@@ -172,23 +173,24 @@ object MainMillBuildServer extends ExternalModule {
}
override def onBuildTaskFinish(params: TaskFinishParams): Unit = {
- println("Task Finish: " + params)
+ //println("Task Finish: " + params)
}
override def onBuildPublishDiagnostics(
params: PublishDiagnosticsParams
): Unit = {
- diagnostics ++= List(params)
+ println("Diagnostics: " + params)
}
override def onBuildTargetDidChange(params: DidChangeBuildTarget): Unit =
???
}
millServer.client = client
millServer.initialized = true
- println(millServer.buildTargetCleanCache(
- new CleanCacheParams(millServer.millModules.map(m => millServer.moduleToTargetId(m)).asJava)).get)
- println(millServer.buildTargetCompile(
- new CompileParams(millServer.millModules.map(m => millServer.moduleToTargetId(m)).asJava)).get)
- println("Diagnostics: " + client.diagnostics)
+ val compileParams = new CompileParams(millServer.moduleCodeToTargetId.values.
+ filter(t => millServer.targetIdToModule(t) != millServer.rootModule).toList.asJava)
+ val pool = millServer.getBspLoggedReporterPool(TaskParameters.fromCompileParams(compileParams), (t) => s"Started compiling target: $t",
+ "compile-task", (targetId: BuildTargetIdentifier) => new CompileTask(targetId))
+ println(millServer.buildTargetCleanCache(new CleanCacheParams(millServer.moduleCodeToTargetId.values.toList.asJava)).get)
+ println(millServer.buildTargetCompile(compileParams).get)
}
/**
diff --git a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
index 8ab17d7e..8e537fb8 100644
--- a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
+++ b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
@@ -1,16 +1,19 @@
package mill.contrib.bsp
import java.io.File
+import java.util.concurrent.{ConcurrentHashMap, ConcurrentMap}
-import ch.epfl.scala.bsp4j.{BuildServer, BuildTargetIdentifier, CompileReport, InverseSourcesParams, ScalaBuildServer, StatusCode, TaskFinishParams, TaskId, TextDocumentIdentifier}
+import ch.epfl.scala.bsp4j.{BuildServer, BuildTargetIdentifier, CompileReport, Diagnostic, InverseSourcesParams, ScalaBuildServer, StatusCode, TaskFinishParams, TaskId, TextDocumentIdentifier}
import ch.epfl.scala.{bsp4j => bsp}
import mill.api.BspContext
+import org.eclipse.lsp4j.PublishDiagnosticsParams
import sbt.internal.inc.ManagedLoggedReporter
import sbt.internal.inc.schema.Position
import sbt.internal.util.ManagedLogger
import xsbti.{Problem, Severity}
import scala.collection.JavaConverters._
+import scala.collection.concurrent
import scala.compat.java8.OptionConverters._
import scala.io.Source
@@ -24,6 +27,8 @@ class BspLoggedReporter(client: bsp.BuildClient,
var errors = 0
var warnings = 0
var infos = 0
+ var diagnosticMap: concurrent.Map[TextDocumentIdentifier, bsp.PublishDiagnosticsParams] =
+ new ConcurrentHashMap[TextDocumentIdentifier, bsp.PublishDiagnosticsParams]().asScala
override def logError(problem: Problem): Unit = {
client.onBuildPublishDiagnostics(getDiagnostics(problem, targetId, compilationOriginId))
@@ -61,31 +66,20 @@ class BspLoggedReporter(client: bsp.BuildClient,
// 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 = {
+ val diagnostic = getSingleDiagnostic(problem)
val sourceFile = problem.position().sourceFile().asScala
- val start = new bsp.Position(
- problem.position.startLine.asScala.getOrElse(problem.position.line.asScala.getOrElse(0)),
- problem.position.startOffset.asScala.getOrElse(problem.position.offset.asScala.getOrElse(0)))
- val end = new bsp.Position(
- problem.position.endLine.asScala.getOrElse(problem.position.line.asScala.getOrElse(0)),
- problem.position.endOffset.asScala.getOrElse(problem.position.offset.asScala.getOrElse(0)))
- val diagnostic = new bsp.Diagnostic(new bsp.Range(start, end), problem.message)
- diagnostic.setCode(problem.position.lineContent)
- diagnostic.setSource("compiler from mill")
- diagnostic.setSeverity( problem.severity match {
- case Severity.Info => bsp.DiagnosticSeverity.INFORMATION
- case Severity.Error => bsp.DiagnosticSeverity.ERROR
- case Severity.Warn => bsp.DiagnosticSeverity.WARNING
- }
- )
- val textDocument = sourceFile.getOrElse(None) match {
+ val textDocument = new TextDocumentIdentifier(
+ sourceFile.getOrElse(None) match {
case None => targetId.getUri
case f: File => f.toPath.toUri.toString
- }
- val params = new bsp.PublishDiagnosticsParams(
- new bsp.TextDocumentIdentifier(textDocument),
- targetId, List(diagnostic).asJava, true)
+ })
+ val params = new bsp.PublishDiagnosticsParams(textDocument,
+ targetId,
+ appendDiagnostics(textDocument, diagnostic).asJava
+ , true)
if (originId.nonEmpty) { params.setOriginId(originId.get) }
+ diagnosticMap.put(textDocument, params)
params
}
@@ -93,6 +87,35 @@ class BspLoggedReporter(client: bsp.BuildClient,
if (errors > 0) StatusCode.ERROR else StatusCode.OK
}
+ private[this] def appendDiagnostics(textDocument: TextDocumentIdentifier,
+ currentDiagnostic: Diagnostic): List[Diagnostic] = {
+ diagnosticMap.getOrElse(textDocument, new bsp.PublishDiagnosticsParams(
+ textDocument,
+ targetId,
+ List.empty[Diagnostic].asJava, true)).getDiagnostics.asScala.toList ++
+ List(currentDiagnostic)
+ }
+
+ private[this] def getSingleDiagnostic(problem: Problem): Diagnostic ={
+
+ val start = new bsp.Position(
+ problem.position.startLine.asScala.getOrElse(problem.position.line.asScala.getOrElse(0)),
+ problem.position.startOffset.asScala.getOrElse(problem.position.offset.asScala.getOrElse(0)))
+ val end = new bsp.Position(
+ problem.position.endLine.asScala.getOrElse(problem.position.line.asScala.getOrElse(0)),
+ problem.position.endOffset.asScala.getOrElse(problem.position.offset.asScala.getOrElse(0)))
+ val diagnostic = new bsp.Diagnostic(new bsp.Range(start, end), problem.message)
+ diagnostic.setCode(problem.position.lineContent)
+ diagnostic.setSource("compiler from mill")
+ diagnostic.setSeverity( problem.severity match {
+ case Severity.Info => bsp.DiagnosticSeverity.INFORMATION
+ case Severity.Error => bsp.DiagnosticSeverity.ERROR
+ case Severity.Warn => bsp.DiagnosticSeverity.WARNING
+ }
+ )
+ diagnostic
+ }
+
private[this] def getErrorCode(file: Option[File], start: bsp.Position, end: bsp.Position, position: xsbti.Position): String = {
file match {
case None => position.lineContent
diff --git a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala
index 2c25a9fc..1666ed60 100644
--- a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala
+++ b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala
@@ -18,8 +18,6 @@ import sbt.internal.inc._
import xsbti.{Position, Problem, Severity}
import xsbti.compile.{AnalysisContents, AnalysisStore, FileAnalysisStore}
import xsbti.compile.analysis.SourceInfo
-
-import scala.collection.mutable.Map
import mill.api.Result.{Failing, Failure, Success}
import scala.collection.JavaConverters._
@@ -46,6 +44,7 @@ class MillBuildServer(evaluator: Evaluator,
val millServerVersion: String = serverVersion
var cancelator: () => Unit = () => ()
var millEvaluator: Evaluator = evaluator
+ var rootModule: JavaModule = ModuleUtils.getRootJavaModule(evaluator.rootModule)
var millModules: Seq[JavaModule] = getMillModules(millEvaluator)
var client: BuildClient = _
var moduleToTargetId: Predef.Map[JavaModule, BuildTargetIdentifier] = ModuleUtils.getModuleTargetIdMap(
@@ -54,7 +53,7 @@ class MillBuildServer(evaluator: Evaluator,
)
var targetIdToModule: Predef.Map[BuildTargetIdentifier, JavaModule] = targetToModule(moduleToTargetId)
var moduleToTarget: Predef.Map[JavaModule, BuildTarget] =
- ModuleUtils.millModulesToBspTargets(millModules, evaluator, List("scala", "java"))
+ ModuleUtils.millModulesToBspTargets(millModules, rootModule, evaluator, List("scala", "java"))
var moduleCodeToTargetId: Predef.Map[Int, BuildTargetIdentifier] =
for ( (targetId, module) <- targetIdToModule ) yield (targetId, module.hashCode()).swap
@@ -247,14 +246,13 @@ class MillBuildServer(evaluator: Evaluator,
l
}
- private[this] def getBspLoggedReporterPool(params: Parameters, taskStartMessage: String => String,
+ def getBspLoggedReporterPool(params: Parameters, taskStartMessage: String => String,
taskStartDataKind: String, taskStartData: BuildTargetIdentifier => Object):
Int => Option[ManagedLoggedReporter] = {
(int: Int) =>
- val targetId = moduleCodeToTargetId(int)
- val taskId = new TaskId(targetIdToModule(targetId).compile.hashCode.toString)
if (moduleCodeToTargetId.contains(int)) {
- println("Module: " + int)
+ val targetId = moduleCodeToTargetId(int)
+ val taskId = new TaskId(targetIdToModule(targetId).compile.hashCode.toString)
val taskStartParams = new TaskStartParams(taskId)
taskStartParams.setEventTime(System.currentTimeMillis())
taskStartParams.setData(taskStartData(targetId))
@@ -526,14 +524,15 @@ class MillBuildServer(evaluator: Evaluator,
ev.rootModule.millInternal.segmentsToModules.values.
collect {
case m: scalalib.JavaModule => m
- }.toSeq
+ }.toSeq ++ Seq(rootModule)
}
private[this] def recomputeTargets(): Unit = {
+ rootModule = ModuleUtils.getRootJavaModule(millEvaluator.rootModule)
millModules = getMillModules(millEvaluator)
moduleToTargetId = ModuleUtils.getModuleTargetIdMap(millModules, millEvaluator)
targetIdToModule = targetToModule(moduleToTargetId)
- moduleToTarget = ModuleUtils.millModulesToBspTargets(millModules, evaluator, List("scala", "java"))
+ moduleToTarget = ModuleUtils.millModulesToBspTargets(millModules, rootModule, evaluator, List("scala", "java"))
}
private[this] def handleExceptions[T, V](serverMethod: T => V, input: T): CompletableFuture[V] = {
diff --git a/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala b/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala
index d0db5fd0..36415c5f 100644
--- a/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala
+++ b/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala
@@ -31,40 +31,42 @@ object ModuleUtils {
dummyModule, DummyLogger)
def millModulesToBspTargets(modules: Seq[JavaModule],
+ rootModule: JavaModule,
evaluator: Evaluator,
supportedLanguages: List[String]): Predef.Map[JavaModule, BuildTarget] = {
val moduleIdMap = getModuleTargetIdMap(modules, evaluator)
- val rootModule = getRootJavaModule(evaluator.rootModule)
- var moduleToTarget = Predef.Map[JavaModule, BuildTarget](
- rootModule -> getRootTarget(rootModule, evaluator)
- )
+ var moduleToTarget = Predef.Map[JavaModule, BuildTarget]()
for ( module <- modules ) {
- val dataBuildTarget = computeScalaBuildTarget(module, evaluator)
- val capabilities = getModuleCapabilities(module, evaluator)
- val buildTargetTag: List[String] = module match {
- case m: TestModule => List(BuildTargetTag.TEST)
- case m: JavaModule => List(BuildTargetTag.LIBRARY, BuildTargetTag.APPLICATION)
+ if (module == rootModule) {
+ moduleToTarget ++= Map(module -> getRootTarget(module, evaluator))
+ } else {
+ val dataBuildTarget = computeScalaBuildTarget(module, evaluator)
+ val capabilities = getModuleCapabilities(module, evaluator)
+ val buildTargetTag: List[String] = module match {
+ case m: TestModule => List(BuildTargetTag.TEST)
+ case m: JavaModule => List(BuildTargetTag.LIBRARY, BuildTargetTag.APPLICATION)
+ }
+
+ val dependencies = module match {
+ case m: JavaModule => m.moduleDeps.map(dep => moduleIdMap(dep)).toList.asJava
+ }
+
+ val buildTarget = new BuildTarget(moduleIdMap(module),
+ buildTargetTag.asJava,
+ supportedLanguages.asJava,
+ dependencies,
+ capabilities)
+ if (module.isInstanceOf[ScalaModule]) {
+ buildTarget.setDataKind("scala")
+ }
+ buildTarget.setData(dataBuildTarget)
+ buildTarget.setDisplayName(moduleName(module.millModuleSegments))
+ buildTarget.setBaseDirectory(module.intellijModulePath.toNIO.toAbsolutePath.toUri.toString)
+
+ if (!moduleToTarget.contains(module)) moduleToTarget ++= Map(module -> buildTarget)
}
-
- val dependencies = module match {
- case m: JavaModule => m.moduleDeps.map(dep => moduleIdMap(dep)).toList.asJava
- }
-
- val buildTarget = new BuildTarget(moduleIdMap(module),
- buildTargetTag.asJava,
- supportedLanguages.asJava,
- dependencies,
- capabilities)
- if (module.isInstanceOf[ScalaModule]) {
- buildTarget.setDataKind("scala")
- }
- buildTarget.setData(dataBuildTarget)
- buildTarget.setDisplayName(moduleName(module.millModuleSegments))
- buildTarget.setBaseDirectory(module.intellijModulePath.toNIO.toAbsolutePath.toUri.toString)
-
- if (!moduleToTarget.contains(module)) moduleToTarget ++= Map(module -> buildTarget)
}
moduleToTarget
@@ -168,10 +170,7 @@ object ModuleUtils {
}
def getModuleTargetIdMap(modules: Seq[JavaModule], evaluator:Evaluator): Predef.Map[JavaModule, BuildTargetIdentifier] = {
- var moduleToTarget = Map[JavaModule, BuildTargetIdentifier](
- getRootJavaModule(evaluator.rootModule) -> new BuildTargetIdentifier(evaluator.rootModule.millSourcePath.
- toNIO.toAbsolutePath.toUri.toString)
- )
+ var moduleToTarget = Map[JavaModule, BuildTargetIdentifier]()
for ( module <- modules ) {
moduleToTarget ++= Map(module -> new BuildTargetIdentifier(
diff --git a/scalalib/src/JavaModule.scala b/scalalib/src/JavaModule.scala
index 822d7985..5405828f 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() ++ T.ctx.bsp.args,
+ javacOptions() ++ T.ctx().bsp.args,
T.ctx().reporter(hashCode)
)
}