summaryrefslogtreecommitdiff
path: root/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala')
-rw-r--r--contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala65
1 files changed, 44 insertions, 21 deletions
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