Rework BuildServerReporter

Make it stop blinking
Use `reset` field to reduce verbosity
This commit is contained in:
adpi2 2020-07-13 12:56:02 +02:00
parent 8bd43a9fa3
commit 6c694fb04d
2 changed files with 59 additions and 85 deletions

View File

@ -1880,16 +1880,13 @@ object Defaults extends BuildCommon {
val compilers: Compilers = ci.compilers
val i = ci.withCompilers(onArgs(compilers))
try {
val prev = i.previousResult
prev.analysis.toOption map { analysis =>
i.setup.reporter match {
case r: BuildServerReporter =>
r.resetPrevious(analysis)
case _ => ()
}
}
incCompiler.compile(i, s.log)
} finally x.close() // workaround for #937
} finally {
i.setup.reporter match {
case r: BuildServerReporter => r.sendFinalReport()
}
x.close() // workaround for #937
}
}
def compileIncSetupTask = Def.task {
val converter = fileConverter.value
@ -1949,7 +1946,7 @@ object Defaults extends BuildCommon {
maxErrors.value,
streams.value.log,
foldMappers(sourcePositionMappers.value),
fileConverter.value
sources.value
)
},
compileInputs := {

View File

@ -7,12 +7,13 @@
package sbt.internal.server
import java.io.File
import sbt.StandardMain
import sbt.internal.bsp._
import sbt.internal.inc.ManagedLoggedReporter
import sbt.internal.util.ManagedLogger
import xsbti.compile.CompileAnalysis
import xsbti.{ BasicVirtualFileRef, FileConverter, Problem, Severity, Position => XPosition }
import xsbti.{ Problem, Severity, Position => XPosition }
import scala.collection.mutable
@ -28,97 +29,72 @@ class BuildServerReporter(
maximumErrors: Int,
logger: ManagedLogger,
sourcePositionMapper: XPosition => XPosition = identity[XPosition],
converter: FileConverter
sources: Seq[File]
) extends ManagedLoggedReporter(maximumErrors, logger, sourcePositionMapper) {
import sbt.internal.bsp.codec.JsonProtocol._
import sbt.internal.inc.JavaInterfaceUtil._
import scala.collection.JavaConverters._
private lazy val exchange = StandardMain.exchange
private val problemsByFile = mutable.Map[File, Vector[Diagnostic]]()
lazy val exchange = StandardMain.exchange
private[sbt] lazy val problemsByFile = new mutable.HashMap[String, mutable.ListBuffer[Problem]]
override def reset(): Unit = {
super.reset()
problemsByFile.clear()
}
override def log(problem: Problem): Unit = {
val pos = problem.position
pos.sourcePath().toOption foreach { sourcePath =>
problemsByFile.get(sourcePath) match {
case Some(xs: mutable.ListBuffer[Problem]) => problemsByFile(sourcePath) = xs :+ problem
case _ => problemsByFile(sourcePath) = mutable.ListBuffer(problem)
}
}
super.log(problem)
}
override def logError(problem: Problem): Unit = {
aggregateProblems(problem)
// console channel can keep using the xsbi.Problem
super.logError(problem)
}
override def logWarning(problem: Problem): Unit = {
aggregateProblems(problem)
// console channel can keep using the xsbi.Problem
super.logWarning(problem)
}
override def logInfo(problem: Problem): Unit = {
aggregateProblems(problem)
// console channel can keep using the xsbi.Problem
super.logInfo(problem)
}
private[sbt] def resetPrevious(analysis: CompileAnalysis): Unit = {
val files = analysis.readSourceInfos.getAllSourceInfos.keySet.asScala
files foreach { file =>
private[sbt] def sendFinalReport(): Unit = {
for (source <- sources) {
val diagnostics = problemsByFile.getOrElse(source, Vector())
val params = PublishDiagnosticsParams(
TextDocumentIdentifier(converter.toPath(file).toUri),
TextDocumentIdentifier(source.toURI),
buildTarget,
None,
diagnostics = Vector(),
originId = None,
diagnostics,
reset = true
)
exchange.notifyEvent("build/publishDiagnostics", params)
}
}
private[sbt] def aggregateProblems(problem: Problem): Unit = {
val pos = problem.position
pos.sourcePath().toOption foreach { sourcePath: String =>
problemsByFile.get(sourcePath) match {
case Some(xs: mutable.ListBuffer[Problem]) =>
val diagnostics = toDiagnostics(xs)
val absolutePath = converter.toPath(new BasicVirtualFileRef(sourcePath) {})
val params = PublishDiagnosticsParams(
TextDocumentIdentifier(absolutePath.toUri),
buildTarget,
originId = None,
diagnostics,
reset = true
)
exchange.notifyEvent("build/publishDiagnostics", params)
case _ =>
}
override def logError(problem: Problem): Unit = {
publishDiagnostic(problem)
// console channel can keep using the xsbi.Problem
super.logError(problem)
}
override def logWarning(problem: Problem): Unit = {
publishDiagnostic(problem)
// console channel can keep using the xsbi.Problem
super.logWarning(problem)
}
override def logInfo(problem: Problem): Unit = {
publishDiagnostic(problem)
// console channel can keep using the xsbi.Problem
super.logInfo(problem)
}
private def publishDiagnostic(problem: Problem): Unit = {
for {
source <- problem.position.sourceFile.toOption
diagnostic <- toDiagnostic(problem)
} {
problemsByFile(source) = problemsByFile.getOrElse(source, Vector()) :+ diagnostic
val params = PublishDiagnosticsParams(
TextDocumentIdentifier(source.toURI),
buildTarget,
originId = None,
Vector(diagnostic),
reset = false
)
exchange.notifyEvent("build/publishDiagnostics", params)
}
}
private[sbt] def toDiagnostics(ps: Seq[Problem]): Vector[Diagnostic] = {
private def toDiagnostic(problem: Problem): Option[Diagnostic] = {
val pos = problem.position
for {
problem <- ps.toVector
pos = problem.position
line0 <- pos.line.toOption.toVector
pointer0 <- pos.pointer.toOption.toVector
line <- pos.line.toOption.map(_.toLong - 1L)
pointer <- pos.pointer.toOption.map(_.toLong)
} yield {
val line = line0.toLong - 1L
val pointer = pointer0.toLong
val range = (
pos.startLine.toOption,
pos.startColumn.toOption,
@ -130,6 +106,7 @@ class BuildServerReporter(
case _ =>
Range(Position(line, pointer), Position(line, pointer + 1))
}
Diagnostic(
range,
Option(toDiagnosticSeverity(problem.severity)),