mirror of https://github.com/sbt/sbt.git
Re-implement BuildServerEvalReporter
This commit is contained in:
parent
d6e1c63f3f
commit
e62984846b
|
|
@ -7,7 +7,6 @@ import dotty.tools.dotc.CompilationUnit
|
|||
import dotty.tools.dotc.core.Contexts.{ atPhase, Context }
|
||||
import dotty.tools.dotc.core.{ Flags, Names, Phases, Symbols, Types }
|
||||
import dotty.tools.dotc.Driver
|
||||
import dotty.tools.dotc.reporting.Reporter
|
||||
import dotty.tools.dotc.Run
|
||||
import dotty.tools.dotc.util.SourceFile
|
||||
import dotty.tools.io.{ PlainDirectory, Directory, VirtualDirectory, VirtualFile }
|
||||
|
|
@ -31,7 +30,7 @@ class Eval(
|
|||
nonCpOptions: Seq[String],
|
||||
classpath: Seq[Path],
|
||||
backingDir: Option[Path],
|
||||
mkReporter: Option[() => Reporter]
|
||||
mkReporter: Option[() => EvalReporter]
|
||||
):
|
||||
import Eval.*
|
||||
|
||||
|
|
@ -46,9 +45,9 @@ class Eval(
|
|||
.map(_.toString)
|
||||
.mkString(":")
|
||||
private lazy val driver: EvalDriver = new EvalDriver
|
||||
private lazy val reporter = mkReporter match
|
||||
case Some(fn) => fn()
|
||||
case None => EvalReporter.store
|
||||
private lazy val reporter: EvalReporter = mkReporter match
|
||||
case Some(f) => f()
|
||||
case None => EvalReporter.store
|
||||
|
||||
final class EvalDriver extends Driver:
|
||||
val compileCtx0 = initCtx.fresh
|
||||
|
|
@ -83,6 +82,7 @@ class Eval(
|
|||
line: Int
|
||||
): EvalResult =
|
||||
val ev = new EvalType[String]:
|
||||
override def sourceName: String = srcName
|
||||
override def makeSource(moduleName: String): SourceFile =
|
||||
val returnType = tpeName match
|
||||
case Some(tpe) => s": $tpe"
|
||||
|
|
@ -148,6 +148,7 @@ class Eval(
|
|||
require(definitions.nonEmpty, "definitions to evaluate cannot be empty.")
|
||||
val extraHash0 = extraHash
|
||||
val ev = new EvalType[Seq[String]]:
|
||||
override def sourceName: String = srcName
|
||||
override def makeSource(moduleName: String): SourceFile =
|
||||
val header =
|
||||
imports.strings.mkString("\n") +
|
||||
|
|
@ -176,7 +177,6 @@ class Eval(
|
|||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING
|
||||
)
|
||||
|
||||
override def extraHash: String = extraHash0
|
||||
|
||||
val inter = evalCommon[Seq[String]](definitions.map(_._1), imports, tpeName = Some(""), ev)
|
||||
|
|
@ -203,13 +203,16 @@ class Eval(
|
|||
val d = digester.digest()
|
||||
val hash = Hash.toHex(d)
|
||||
val moduleName = makeModuleName(hash)
|
||||
val (extra, loader) = backingDir match
|
||||
case Some(backing) if classExists(backing, moduleName) =>
|
||||
val loader = (parent: ClassLoader) =>
|
||||
(new URLClassLoader(Array(backing.toUri.toURL), parent): ClassLoader)
|
||||
val extra = ev.read(cacheFile(backing, moduleName))
|
||||
(extra, loader)
|
||||
case _ => compileAndLoad(ev, moduleName)
|
||||
val (extra, loader) =
|
||||
try
|
||||
backingDir match
|
||||
case Some(backing) if classExists(backing, moduleName) =>
|
||||
val loader = (parent: ClassLoader) =>
|
||||
(new URLClassLoader(Array(backing.toUri.toURL), parent): ClassLoader)
|
||||
val extra = ev.read(cacheFile(backing, moduleName))
|
||||
(extra, loader)
|
||||
case _ => compileAndLoad(ev, moduleName)
|
||||
finally reporter.finalReport(ev.sourceName)
|
||||
val generatedFiles = getGeneratedFiles(moduleName)
|
||||
EvalIntermediate(
|
||||
extra = extra,
|
||||
|
|
@ -277,19 +280,19 @@ object Eval:
|
|||
def apply(): Eval =
|
||||
new Eval(Nil, currentClasspath, None, None)
|
||||
|
||||
def apply(mkReporter: () => Reporter): Eval =
|
||||
def apply(mkReporter: () => EvalReporter): Eval =
|
||||
new Eval(Nil, currentClasspath, None, Some(mkReporter))
|
||||
|
||||
def apply(
|
||||
backingDir: Path,
|
||||
mkReporter: () => Reporter,
|
||||
mkReporter: () => EvalReporter,
|
||||
): Eval =
|
||||
new Eval(Nil, currentClasspath, Some(backingDir), Some(mkReporter))
|
||||
|
||||
def apply(
|
||||
nonCpOptions: Seq[String],
|
||||
backingDir: Path,
|
||||
mkReporter: () => Reporter,
|
||||
mkReporter: () => EvalReporter,
|
||||
): Eval =
|
||||
new Eval(nonCpOptions, currentClasspath, Some(backingDir), Some(mkReporter))
|
||||
|
||||
|
|
@ -326,6 +329,7 @@ object Eval:
|
|||
end EvalSourceFile
|
||||
|
||||
trait EvalType[A]:
|
||||
def sourceName: String
|
||||
def makeSource(moduleName: String): SourceFile
|
||||
|
||||
/** Extracts additional information after the compilation unit is evaluated. */
|
||||
|
|
|
|||
|
|
@ -7,7 +7,14 @@ import dotty.tools.dotc.reporting.Diagnostic
|
|||
import dotty.tools.dotc.reporting.Reporter
|
||||
import dotty.tools.dotc.reporting.StoreReporter
|
||||
|
||||
abstract class EvalReporter extends Reporter
|
||||
abstract class EvalReporter extends Reporter:
|
||||
/**
|
||||
* Send a final report to clear out the outdated diagnostics.
|
||||
* @param sourceName the source path of a build.sbt file
|
||||
*/
|
||||
def finalReport(sourceName: String): Unit
|
||||
|
||||
def log(msg: String): Unit = ()
|
||||
|
||||
object EvalReporter:
|
||||
def console: EvalReporter = ForwardingReporter(ConsoleReporter())
|
||||
|
|
@ -16,4 +23,6 @@ end EvalReporter
|
|||
|
||||
class ForwardingReporter(delegate: Reporter) extends EvalReporter:
|
||||
def doReport(dia: Diagnostic)(using Context): Unit = delegate.doReport(dia)
|
||||
|
||||
def finalReport(sourceName: String): Unit = ()
|
||||
end ForwardingReporter
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import sbt.SlashSyntax0.*
|
|||
import sbt.internal.parser.SbtParser
|
||||
import sbt.io.IO
|
||||
import scala.jdk.CollectionConverters.*
|
||||
import xsbti.PathBasedFile
|
||||
import xsbti.VirtualFile
|
||||
import xsbti.VirtualFileRef
|
||||
|
||||
|
|
@ -151,7 +152,9 @@ private[sbt] object EvaluateConfigurations {
|
|||
): LazyClassLoaded[LoadedSbtFile] = {
|
||||
// TODO - Store the file on the LoadedSbtFile (or the parent dir) so we can accurately do
|
||||
// detection for which project project manipulations should be applied.
|
||||
val name = file.id
|
||||
val name = file match
|
||||
case file: PathBasedFile => file.toPath.toString
|
||||
case file => file.id
|
||||
val parsed = parseConfiguration(file, lines, imports, offset)
|
||||
val (importDefs, definitions) =
|
||||
if (parsed.definitions.isEmpty) (Nil, DefinedSbtValues.empty)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import sbt.internal.inc.{ MappedFileConverter, ScalaInstance, ZincLmUtil, ZincUt
|
|||
import sbt.internal.util.Attributed.data
|
||||
import sbt.internal.util.Types.const
|
||||
import sbt.internal.util.{ Attributed, Settings }
|
||||
import sbt.internal.server.BuildServerEvalReporter
|
||||
import sbt.io.{ GlobFilter, IO, Path }
|
||||
import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyDependencyResolution, IvyPaths }
|
||||
import sbt.librarymanagement.{ Configuration, Configurations, Resolver }
|
||||
|
|
@ -33,7 +34,6 @@ import java.net.URI
|
|||
import java.nio.file.{ Path, Paths }
|
||||
import scala.annotation.{ nowarn, tailrec }
|
||||
import scala.collection.mutable
|
||||
// import scala.tools.nsc.reporters.ConsoleReporter
|
||||
|
||||
private[sbt] object Load {
|
||||
// note that there is State passed in but not pulled out
|
||||
|
|
@ -469,7 +469,7 @@ private[sbt] object Load {
|
|||
nonCpOptions = options,
|
||||
classpath = classpath,
|
||||
backingDir = Option(evalOutputDirectory(base).toPath()),
|
||||
mkReporter = Option(() => (mkReporter(): dotty.tools.dotc.reporting.Reporter)),
|
||||
mkReporter = Option(() => mkReporter()),
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
@ -749,14 +749,10 @@ private[sbt] object Load {
|
|||
|
||||
// NOTE - because we create an eval here, we need a clean-eval later for this URI.
|
||||
lazy val eval = timed("Load.loadUnit: mkEval", log) {
|
||||
def mkReporter() = EvalReporter.console
|
||||
// todo:
|
||||
// def mkReporter(settings: scala.tools.nsc.Settings): EvalReporter =
|
||||
// plugs.pluginData.buildTarget match {
|
||||
// case None => EvalReporter.console // (settings)
|
||||
// case Some(buildTarget) =>
|
||||
// new BuildServerEvalReporter(buildTarget, new ConsoleReporter(settings))
|
||||
// }
|
||||
def mkReporter(): EvalReporter = plugs.pluginData.buildTarget match {
|
||||
case None => EvalReporter.console
|
||||
case Some(buildTarget) => new BuildServerEvalReporter(buildTarget, EvalReporter.console)
|
||||
}
|
||||
mkEval(
|
||||
classpath = plugs.classpath.map(converter.toPath),
|
||||
defDir,
|
||||
|
|
|
|||
|
|
@ -8,35 +8,34 @@
|
|||
package sbt.internal.server
|
||||
|
||||
import dotty.tools.dotc.core.Contexts.Context
|
||||
import dotty.tools.dotc.reporting.{ Diagnostic => ScalaDiagnostic }
|
||||
import dotty.tools.dotc.reporting.Reporter
|
||||
// import sbt.StandardMain.exchange
|
||||
import sbt.internal.ForwardingReporter
|
||||
import dotty.tools.dotc.reporting.{ Diagnostic => ScalaDiagnostic }
|
||||
import dotty.tools.dotc.util.SourcePosition
|
||||
import sbt.StandardMain.exchange
|
||||
import sbt.internal.EvalReporter
|
||||
import sbt.internal.bsp
|
||||
import sbt.internal.bsp.{
|
||||
BuildTargetIdentifier,
|
||||
Diagnostic,
|
||||
// DiagnosticSeverity,
|
||||
// PublishDiagnosticsParams,
|
||||
// Range,
|
||||
// TextDocumentIdentifier
|
||||
}
|
||||
import sbt.internal.bsp.BuildTargetIdentifier
|
||||
import sbt.internal.bsp.Diagnostic
|
||||
import sbt.internal.bsp.DiagnosticSeverity
|
||||
import sbt.internal.bsp.PublishDiagnosticsParams
|
||||
import sbt.internal.bsp.Range
|
||||
import sbt.internal.bsp.TextDocumentIdentifier
|
||||
import sbt.internal.bsp.codec.JsonProtocol._
|
||||
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import scala.collection.mutable
|
||||
|
||||
class BuildServerEvalReporter(buildTarget: BuildTargetIdentifier, delegate: Reporter)
|
||||
extends ForwardingReporter(delegate):
|
||||
extends EvalReporter:
|
||||
private val problemsByFile = mutable.Map[Path, Vector[Diagnostic]]()
|
||||
|
||||
override def doReport(dia: ScalaDiagnostic)(using Context): Unit = {
|
||||
/*
|
||||
for {
|
||||
filePath <- if (pos.source.file.exists) Some(Paths.get(pos.source.file.path)) else None
|
||||
range <- convertToRange(pos)
|
||||
} {
|
||||
val bspSeverity = convertToBsp(severity)
|
||||
val diagnostic = Diagnostic(range, bspSeverity, None, Option("sbt"), msg)
|
||||
if (dia.pos.exists) {
|
||||
val filePath = Paths.get(dia.pos.source.file.path)
|
||||
val range = convertToRange(dia.pos)
|
||||
val bspSeverity = convertToBsp(dia.level)
|
||||
val diagnostic = Diagnostic(range, bspSeverity, None, Option("sbt"), dia.msg.message)
|
||||
problemsByFile(filePath) = problemsByFile.getOrElse(filePath, Vector()) :+ diagnostic
|
||||
val params = PublishDiagnosticsParams(
|
||||
TextDocumentIdentifier(filePath.toUri),
|
||||
|
|
@ -46,51 +45,40 @@ class BuildServerEvalReporter(buildTarget: BuildTargetIdentifier, delegate: Repo
|
|||
reset = false
|
||||
)
|
||||
exchange.notifyEvent("build/publishDiagnostics", params)
|
||||
delegate.doReport(dia)
|
||||
}
|
||||
*/
|
||||
super.doReport(dia)
|
||||
}
|
||||
|
||||
/*
|
||||
def finalReport(sourceName: String): Unit = {
|
||||
override def finalReport(sourceName: String): Unit = {
|
||||
val filePath = Paths.get(sourceName)
|
||||
if (Files.exists(filePath)) {
|
||||
val diagnostics = problemsByFile.getOrElse(filePath, Vector())
|
||||
val params = PublishDiagnosticsParams(
|
||||
textDocument = TextDocumentIdentifier(filePath.toUri),
|
||||
buildTarget,
|
||||
originId = None,
|
||||
diagnostics,
|
||||
reset = true
|
||||
)
|
||||
exchange.notifyEvent("build/publishDiagnostics", params)
|
||||
}
|
||||
val diagnostics = problemsByFile.getOrElse(filePath, Vector())
|
||||
val params = PublishDiagnosticsParams(
|
||||
textDocument = TextDocumentIdentifier(filePath.toUri),
|
||||
buildTarget,
|
||||
originId = None,
|
||||
diagnostics,
|
||||
reset = true
|
||||
)
|
||||
exchange.notifyEvent("build/publishDiagnostics", params)
|
||||
}
|
||||
|
||||
private def convertToBsp(severity: Severity): Option[Long] = {
|
||||
private def convertToBsp(severity: Int): Option[Long] = {
|
||||
val result = severity match {
|
||||
case Reporter.INFO => DiagnosticSeverity.Information
|
||||
case Reporter.WARNING => DiagnosticSeverity.Warning
|
||||
case Reporter.ERROR => DiagnosticSeverity.Error
|
||||
case dotty.tools.dotc.interfaces.Diagnostic.INFO => DiagnosticSeverity.Information
|
||||
case dotty.tools.dotc.interfaces.Diagnostic.WARNING => DiagnosticSeverity.Warning
|
||||
case dotty.tools.dotc.interfaces.Diagnostic.ERROR => DiagnosticSeverity.Error
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
|
||||
private def convertToRange(pos: Position): Option[Range] = {
|
||||
pos match {
|
||||
case _: DefinedPosition =>
|
||||
val startLine = pos.source.offsetToLine(pos.start)
|
||||
val startChar = pos.start - pos.source.lineToOffset(startLine)
|
||||
val endLine = pos.source.offsetToLine(pos.end)
|
||||
val endChar = pos.end - pos.source.lineToOffset(endLine)
|
||||
Some(
|
||||
Range(
|
||||
bsp.Position(startLine.toLong, startChar.toLong),
|
||||
bsp.Position(endLine.toLong, endChar.toLong)
|
||||
)
|
||||
)
|
||||
case _ => None
|
||||
}
|
||||
private def convertToRange(pos: SourcePosition): Range = {
|
||||
val startLine = pos.source.offsetToLine(pos.start)
|
||||
val startChar = pos.start - pos.source.lineToOffset(startLine)
|
||||
val endLine = pos.source.offsetToLine(pos.end)
|
||||
val endChar = pos.end - pos.source.lineToOffset(endLine)
|
||||
Range(
|
||||
bsp.Position(startLine.toLong, startChar.toLong),
|
||||
bsp.Position(endLine.toLong, endChar.toLong)
|
||||
)
|
||||
}
|
||||
*/
|
||||
end BuildServerEvalReporter
|
||||
|
|
|
|||
Loading…
Reference in New Issue