Use Zinc analysis in BuildServerReporter

This commit is contained in:
Adrien Piquerez 2020-10-08 11:31:59 +02:00
parent 93ad022dca
commit efb8bc4ec0
3 changed files with 63 additions and 22 deletions

View File

@ -2113,10 +2113,13 @@ object Defaults extends BuildCommon {
val result0 = incCompiler val result0 = incCompiler
.asInstanceOf[sbt.internal.inc.IncrementalCompilerImpl] .asInstanceOf[sbt.internal.inc.IncrementalCompilerImpl]
.compileAllJava(in, s.log) .compileAllJava(in, s.log)
reporter.sendSuccessReport(result0.analysis())
result0.withHasModified(result0.hasModified || r.hasModified) result0.withHasModified(result0.hasModified || r.hasModified)
} else r } else r
} finally { } catch {
reporter.sendFinalReport() case NonFatal(e) =>
reporter.sendFailureReport(in.options.sources)
throw e
} }
} }
private[this] def compileIncrementalTaskImpl( private[this] def compileIncrementalTaskImpl(
@ -2137,14 +2140,19 @@ object Defaults extends BuildCommon {
val compilers: Compilers = ci.compilers val compilers: Compilers = ci.compilers
val i = ci.withCompilers(onArgs(compilers)) val i = ci.withCompilers(onArgs(compilers))
try { try {
incCompiler.compile(i, s.log) val result = incCompiler.compile(i, s.log)
reporter.sendSuccessReport(result.getAnalysis)
result
} catch { } catch {
case e: Throwable if !promise.isCompleted => case e: Throwable =>
if (!promise.isCompleted) {
promise.failure(e) promise.failure(e)
ConcurrentRestrictions.cancelAllSentinels() ConcurrentRestrictions.cancelAllSentinels()
}
reporter.sendFailureReport(ci.options.sources)
throw e throw e
} finally { } finally {
reporter.sendFinalReport()
x.close() // workaround for #937 x.close() // workaround for #937
} }
} }

View File

@ -201,11 +201,11 @@ object BuildServerProtocol {
bspScalaMainClassesItem := scalaMainClassesTask.value, bspScalaMainClassesItem := scalaMainClassesTask.value,
Keys.compile / bspReporter := { Keys.compile / bspReporter := {
val targetId = bspTargetIdentifier.value val targetId = bspTargetIdentifier.value
val converter = fileConverter.value
val underlying = (Keys.compile / compilerReporter).value val underlying = (Keys.compile / compilerReporter).value
val logger = streams.value.log val logger = streams.value.log
val srcs = sources.value
if (bspEnabled.value) { if (bspEnabled.value) {
new BuildServerReporterImpl(targetId, logger, underlying, srcs) new BuildServerReporterImpl(targetId, converter, logger, underlying)
} else { } else {
new BuildServerForwarder(logger, underlying) new BuildServerForwarder(logger, underlying)
} }

View File

@ -7,13 +7,21 @@
package sbt.internal.server package sbt.internal.server
import java.io.File
import sbt.StandardMain import sbt.StandardMain
import sbt.internal.bsp._ import sbt.internal.bsp._
import sbt.internal.util.ManagedLogger import sbt.internal.util.ManagedLogger
import xsbti.{ Problem, Reporter, Severity, Position => XPosition } import xsbti.compile.CompileAnalysis
import xsbti.{
FileConverter,
Problem,
Reporter,
Severity,
VirtualFile,
VirtualFileRef,
Position => XPosition
}
import scala.collection.JavaConverters._
import scala.collection.mutable import scala.collection.mutable
sealed trait BuildServerReporter extends Reporter { sealed trait BuildServerReporter extends Reporter {
@ -25,7 +33,9 @@ sealed trait BuildServerReporter extends Reporter {
protected def publishDiagnostic(problem: Problem): Unit protected def publishDiagnostic(problem: Problem): Unit
def sendFinalReport(): Unit def sendSuccessReport(analysis: CompileAnalysis): Unit
def sendFailureReport(sources: Array[VirtualFile]): Unit
override def reset(): Unit = underlying.reset() override def reset(): Unit = underlying.reset()
@ -51,21 +61,40 @@ sealed trait BuildServerReporter extends Reporter {
final class BuildServerReporterImpl( final class BuildServerReporterImpl(
buildTarget: BuildTargetIdentifier, buildTarget: BuildTargetIdentifier,
converter: FileConverter,
protected override val logger: ManagedLogger, protected override val logger: ManagedLogger,
protected override val underlying: Reporter, protected override val underlying: Reporter
sources: Seq[File]
) extends BuildServerReporter { ) extends BuildServerReporter {
import sbt.internal.bsp.codec.JsonProtocol._ import sbt.internal.bsp.codec.JsonProtocol._
import sbt.internal.inc.JavaInterfaceUtil._ import sbt.internal.inc.JavaInterfaceUtil._
private lazy val exchange = StandardMain.exchange private lazy val exchange = StandardMain.exchange
private val problemsByFile = mutable.Map[File, Vector[Diagnostic]]() private val problemsByFile = mutable.Map[VirtualFileRef, Vector[Diagnostic]]()
override def sendFinalReport(): Unit = { override def sendSuccessReport(analysis: CompileAnalysis): Unit = {
for (source <- sources) { for {
val diagnostics = problemsByFile.getOrElse(source, Vector()) (source, infos) <- analysis.readSourceInfos.getAllSourceInfos.asScala
} {
val filePath = converter.toPath(source)
val diagnostics = infos.getReportedProblems.toSeq.flatMap(toDiagnostic)
val params = PublishDiagnosticsParams( val params = PublishDiagnosticsParams(
TextDocumentIdentifier(source.toURI), textDocument = TextDocumentIdentifier(filePath.toUri),
buildTarget,
originId = None,
diagnostics.toVector,
reset = true
)
exchange.notifyEvent("build/publishDiagnostics", params)
}
}
override def sendFailureReport(sources: Array[VirtualFile]): Unit = {
for (source <- sources) {
val ref = VirtualFileRef.of(source.id())
val diagnostics = problemsByFile.getOrElse(ref, Vector())
val filePath = converter.toPath(source)
val params = PublishDiagnosticsParams(
textDocument = TextDocumentIdentifier(filePath.toUri),
buildTarget, buildTarget,
originId = None, originId = None,
diagnostics, diagnostics,
@ -77,10 +106,12 @@ final class BuildServerReporterImpl(
protected override def publishDiagnostic(problem: Problem): Unit = { protected override def publishDiagnostic(problem: Problem): Unit = {
for { for {
path <- problem.position().sourcePath.toOption
source <- problem.position.sourceFile.toOption source <- problem.position.sourceFile.toOption
diagnostic <- toDiagnostic(problem) diagnostic <- toDiagnostic(problem)
} { } {
problemsByFile(source) = problemsByFile.getOrElse(source, Vector()) :+ diagnostic val fileId = VirtualFileRef.of(path)
problemsByFile(fileId) = problemsByFile.getOrElse(fileId, Vector()) :+ diagnostic
val params = PublishDiagnosticsParams( val params = PublishDiagnosticsParams(
TextDocumentIdentifier(source.toURI), TextDocumentIdentifier(source.toURI),
buildTarget, buildTarget,
@ -132,7 +163,9 @@ final class BuildServerForwarder(
protected override val underlying: Reporter protected override val underlying: Reporter
) extends BuildServerReporter { ) extends BuildServerReporter {
override def sendFinalReport(): Unit = () override def sendSuccessReport(analysis: CompileAnalysis): Unit = ()
override def sendFailureReport(sources: Array[VirtualFile]): Unit = ()
protected override def publishDiagnostic(problem: Problem): Unit = () protected override def publishDiagnostic(problem: Problem): Unit = ()
} }