Add BspCompilationTaskProgress

This commit is contained in:
Adrien Piquerez 2020-05-19 16:57:42 +02:00
parent a31747758c
commit c11ee3269c
15 changed files with 386 additions and 44 deletions

View File

@ -9,7 +9,7 @@ package sbt
import java.io.{ File, PrintWriter }
import java.net.{ URI, URL, URLClassLoader }
import java.nio.file.{ Path => NioPath, Paths }
import java.nio.file.{ Paths, Path => NioPath }
import java.util.Optional
import java.util.concurrent.TimeUnit
@ -43,6 +43,7 @@ import sbt.internal.librarymanagement.mavenint.{
import sbt.internal.librarymanagement.{ CustomHttp => _, _ }
import sbt.internal.nio.{ CheckBuildSources, Globs }
import sbt.internal.server.{
BspCompileTask,
BuildServerProtocol,
BuildServerReporter,
Definition,
@ -644,7 +645,7 @@ object Defaults extends BuildCommon {
compile := compileTask.value,
internalDependencyConfigurations := InternalDependencies.configurations.value,
manipulateBytecode := compileIncremental.value,
compileIncremental := (compileIncrementalTask tag (Tags.Compile, Tags.CPU)).value,
compileIncremental := compileIncrementalTask.tag(Tags.Compile, Tags.CPU).value,
printWarnings := printWarningsTask.value,
compileAnalysisFilename := {
// Here, if the user wants cross-scala-versioning, we also append it
@ -1854,8 +1855,10 @@ object Defaults extends BuildCommon {
analysis
}
def compileIncrementalTask = Def.task {
// TODO - Should readAnalysis + saveAnalysis be scoped by the compile task too?
compileIncrementalTaskImpl(streams.value, (compileInputs in compile).value)
BspCompileTask.compute(bspTargetIdentifier.value, thisProjectRef.value, configuration.value) {
// TODO - Should readAnalysis + saveAnalysis be scoped by the compile task too?
compileIncrementalTaskImpl(streams.value, (compileInputs in compile).value)
}
}
private val incCompiler = ZincUtil.defaultIncrementalCompiler
private[this] def compileIncrementalTaskImpl(s: TaskStreams, ci: Inputs): CompileResult = {

View File

@ -0,0 +1,109 @@
package sbt.internal.server
import sbt._
import sbt.internal.bsp._
import sbt.librarymanagement.Configuration
import sjsonnew.support.scalajson.unsafe.Converter
import xsbti.compile.CompileResult
import xsbti.{ CompileFailed, Problem, Severity }
import scala.util.control.NonFatal
object BspCompileTask {
import sbt.internal.bsp.codec.JsonProtocol._
private lazy val exchange = StandardMain.exchange
def compute(targetId: BuildTargetIdentifier, project: ProjectRef, config: Configuration)(
compile: => CompileResult
): CompileResult = {
val task = BspCompileTask(targetId, project, config)
try {
notifyStart(task)
val result = compile
notifySuccess(task, result)
result
} catch {
case NonFatal(cause) =>
val compileFailed = cause match {
case failed: CompileFailed => Some(failed)
case _ => None
}
notifyFailure(task, compileFailed)
throw cause
}
}
private def apply(
targetId: BuildTargetIdentifier,
project: ProjectRef,
config: Configuration
): BspCompileTask = {
val taskId = TaskId(BuildServerTasks.uniqueId, Vector())
val targetName = BuildTargetName.fromScope(project.project, config.name)
BspCompileTask(targetId, targetName, taskId, System.currentTimeMillis())
}
private def notifyStart(task: BspCompileTask): Unit = {
val message = s"Compiling ${task.targetName}"
val data = Converter.toJsonUnsafe(CompileTask(task.targetId))
val params = TaskStartParams(task.id, task.startTimeMillis, message, "compile-task", data)
exchange.notifyEvent("build/taskStart", params)
}
private def notifySuccess(task: BspCompileTask, result: CompileResult): Unit = {
import collection.JavaConverters._
val endTimeMillis = System.currentTimeMillis()
val elapsedTimeMillis = endTimeMillis - task.startTimeMillis
val problems = result match {
case compileResult: CompileResult =>
val sourceInfos = compileResult.analysis().readSourceInfos().getAllSourceInfos.asScala
sourceInfos.values.flatMap(_.getReportedProblems).toSeq
case _ => Seq()
}
val report = compileReport(problems, task.targetId, elapsedTimeMillis)
val params = TaskFinishParams(
task.id,
endTimeMillis,
s"Compiled ${task.targetName}",
StatusCode.Success,
"compile-report",
Converter.toJsonUnsafe(report)
)
exchange.notifyEvent("build/taskFinish", params)
}
private def notifyFailure(task: BspCompileTask, cause: Option[CompileFailed]): Unit = {
val endTimeMillis = System.currentTimeMillis()
val elapsedTimeMillis = endTimeMillis - task.startTimeMillis
val problems = cause.map(_.problems().toSeq).getOrElse(Seq.empty[Problem])
val report = compileReport(problems, task.targetId, elapsedTimeMillis)
val params = TaskFinishParams(
task.id,
endTimeMillis,
s"Compiled ${task.targetName}",
StatusCode.Error,
"compile-report",
Converter.toJsonUnsafe(report)
)
exchange.notifyEvent("build/taskFinish", params)
}
private def compileReport(
problems: Seq[Problem],
targetId: BuildTargetIdentifier,
elapsedTimeMillis: Long
): CompileReport = {
val countBySeverity = problems.groupBy(_.severity()).mapValues(_.size)
val warnings = countBySeverity.getOrElse(Severity.Warn, 0)
val errors = countBySeverity.getOrElse(Severity.Error, 0)
CompileReport(targetId, None, errors, warnings, Some(elapsedTimeMillis.toInt))
}
}
case class BspCompileTask private (
targetId: BuildTargetIdentifier,
targetName: String,
id: TaskId,
startTimeMillis: Long
)

View File

@ -208,10 +208,7 @@ object BuildServerProtocol {
jars = scalaJars.toVector
)
val configuration = Keys.configuration.value
val displayName = configuration.name match {
case "compile" => thisProject.id
case configName => s"${thisProject.id}-$configName"
}
val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name)
val baseDirectory = Keys.baseDirectory.value.toURI
val projectDependencies = for {
(dep, configs) <- Keys.bspInternalDependencyConfigurations.value
@ -299,14 +296,7 @@ object BuildServerProtocol {
}
}
def scopeFilter(
targets: Seq[BuildTargetIdentifier],
workspace: Map[BuildTargetIdentifier, Scope]
): ScopeFilter = {
ScopeFilter.in(targets.map(workspace))
}
def toId(ref: ProjectReference, config: Configuration): BuildTargetIdentifier =
private def toId(ref: ProjectReference, config: Configuration): BuildTargetIdentifier =
ref match {
case ProjectRef(build, project) =>
BuildTargetIdentifier(new URI(s"$build#$project/${config.id}"))

View File

@ -0,0 +1,62 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/**
* @param target The build target that was compiled
* @param originId An optional request id to know the origin of this report
* @param errors The total number of reported errors compiling this target.
* @param warnings The total number of reported warnings compiling the target.
* @param time The total number of milliseconds it took to compile the target.
*/
final class CompileReport private (
val target: sbt.internal.bsp.BuildTargetIdentifier,
val originId: Option[String],
val errors: Int,
val warnings: Int,
val time: Option[Int]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: CompileReport => (this.target == x.target) && (this.originId == x.originId) && (this.errors == x.errors) && (this.warnings == x.warnings) && (this.time == x.time)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.CompileReport".##) + target.##) + originId.##) + errors.##) + warnings.##) + time.##)
}
override def toString: String = {
"CompileReport(" + target + ", " + originId + ", " + errors + ", " + warnings + ", " + time + ")"
}
private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target, originId: Option[String] = originId, errors: Int = errors, warnings: Int = warnings, time: Option[Int] = time): CompileReport = {
new CompileReport(target, originId, errors, warnings, time)
}
def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): CompileReport = {
copy(target = target)
}
def withOriginId(originId: Option[String]): CompileReport = {
copy(originId = originId)
}
def withOriginId(originId: String): CompileReport = {
copy(originId = Option(originId))
}
def withErrors(errors: Int): CompileReport = {
copy(errors = errors)
}
def withWarnings(warnings: Int): CompileReport = {
copy(warnings = warnings)
}
def withTime(time: Option[Int]): CompileReport = {
copy(time = time)
}
def withTime(time: Int): CompileReport = {
copy(time = Option(time))
}
}
object CompileReport {
def apply(target: sbt.internal.bsp.BuildTargetIdentifier, originId: Option[String], errors: Int, warnings: Int, time: Option[Int]): CompileReport = new CompileReport(target, originId, errors, warnings, time)
def apply(target: sbt.internal.bsp.BuildTargetIdentifier, originId: String, errors: Int, warnings: Int, time: Int): CompileReport = new CompileReport(target, Option(originId), errors, warnings, Option(time))
}

View File

@ -0,0 +1,33 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/** Compile Notifications */
final class CompileTask private (
val target: sbt.internal.bsp.BuildTargetIdentifier) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: CompileTask => (this.target == x.target)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.CompileTask".##) + target.##)
}
override def toString: String = {
"CompileTask(" + target + ")"
}
private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target): CompileTask = {
new CompileTask(target)
}
def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): CompileTask = {
copy(target = target)
}
}
object CompileTask {
def apply(target: sbt.internal.bsp.BuildTargetIdentifier): CompileTask = new CompileTask(target)
}

View File

@ -9,27 +9,31 @@ package sbt.internal.bsp
* @param eventTime Optional timestamp of when the event started in milliseconds since Epoch.
* @param message Optional message describing the task.
* @param status Task completion status: 1 -> success, 2 -> error, 3 -> cancelled
* @param dataKind Kind of data to expect in the `data` field.
* @param data Optional metadata about the task.
*/
final class TaskFinishParams private (
val taskId: sbt.internal.bsp.TaskId,
val eventTime: Option[Long],
val message: Option[String],
val status: Int) extends Serializable {
val status: Int,
val dataKind: Option[String],
val data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: TaskFinishParams => (this.taskId == x.taskId) && (this.eventTime == x.eventTime) && (this.message == x.message) && (this.status == x.status)
case x: TaskFinishParams => (this.taskId == x.taskId) && (this.eventTime == x.eventTime) && (this.message == x.message) && (this.status == x.status) && (this.dataKind == x.dataKind) && (this.data == x.data)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.TaskFinishParams".##) + taskId.##) + eventTime.##) + message.##) + status.##)
37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.TaskFinishParams".##) + taskId.##) + eventTime.##) + message.##) + status.##) + dataKind.##) + data.##)
}
override def toString: String = {
"TaskFinishParams(" + taskId + ", " + eventTime + ", " + message + ", " + status + ")"
"TaskFinishParams(" + taskId + ", " + eventTime + ", " + message + ", " + status + ", " + dataKind + ", " + data + ")"
}
private[this] def copy(taskId: sbt.internal.bsp.TaskId = taskId, eventTime: Option[Long] = eventTime, message: Option[String] = message, status: Int = status): TaskFinishParams = {
new TaskFinishParams(taskId, eventTime, message, status)
private[this] def copy(taskId: sbt.internal.bsp.TaskId = taskId, eventTime: Option[Long] = eventTime, message: Option[String] = message, status: Int = status, dataKind: Option[String] = dataKind, data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = data): TaskFinishParams = {
new TaskFinishParams(taskId, eventTime, message, status, dataKind, data)
}
def withTaskId(taskId: sbt.internal.bsp.TaskId): TaskFinishParams = {
copy(taskId = taskId)
@ -49,9 +53,21 @@ final class TaskFinishParams private (
def withStatus(status: Int): TaskFinishParams = {
copy(status = status)
}
def withDataKind(dataKind: Option[String]): TaskFinishParams = {
copy(dataKind = dataKind)
}
def withDataKind(dataKind: String): TaskFinishParams = {
copy(dataKind = Option(dataKind))
}
def withData(data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): TaskFinishParams = {
copy(data = data)
}
def withData(data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): TaskFinishParams = {
copy(data = Option(data))
}
}
object TaskFinishParams {
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Option[Long], message: Option[String], status: Int): TaskFinishParams = new TaskFinishParams(taskId, eventTime, message, status)
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Long, message: String, status: Int): TaskFinishParams = new TaskFinishParams(taskId, Option(eventTime), Option(message), status)
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Option[Long], message: Option[String], status: Int, dataKind: Option[String], data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): TaskFinishParams = new TaskFinishParams(taskId, eventTime, message, status, dataKind, data)
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Long, message: String, status: Int, dataKind: String, data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): TaskFinishParams = new TaskFinishParams(taskId, Option(eventTime), Option(message), status, Option(dataKind), Option(data))
}

View File

@ -9,26 +9,30 @@ package sbt.internal.bsp
* @param taskId Unique id of the task with optional reference to parent task id.
* @param eventTime Optional timestamp of when the event started in milliseconds since Epoch.
* @param message Optional message describing the task.
* @param dataKind Kind of data to expect in the `data` field.
* @param data Optional metadata about the task.
*/
final class TaskStartParams private (
val taskId: sbt.internal.bsp.TaskId,
val eventTime: Option[Long],
val message: Option[String]) extends Serializable {
val message: Option[String],
val dataKind: Option[String],
val data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: TaskStartParams => (this.taskId == x.taskId) && (this.eventTime == x.eventTime) && (this.message == x.message)
case x: TaskStartParams => (this.taskId == x.taskId) && (this.eventTime == x.eventTime) && (this.message == x.message) && (this.dataKind == x.dataKind) && (this.data == x.data)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.TaskStartParams".##) + taskId.##) + eventTime.##) + message.##)
37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.TaskStartParams".##) + taskId.##) + eventTime.##) + message.##) + dataKind.##) + data.##)
}
override def toString: String = {
"TaskStartParams(" + taskId + ", " + eventTime + ", " + message + ")"
"TaskStartParams(" + taskId + ", " + eventTime + ", " + message + ", " + dataKind + ", " + data + ")"
}
private[this] def copy(taskId: sbt.internal.bsp.TaskId = taskId, eventTime: Option[Long] = eventTime, message: Option[String] = message): TaskStartParams = {
new TaskStartParams(taskId, eventTime, message)
private[this] def copy(taskId: sbt.internal.bsp.TaskId = taskId, eventTime: Option[Long] = eventTime, message: Option[String] = message, dataKind: Option[String] = dataKind, data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = data): TaskStartParams = {
new TaskStartParams(taskId, eventTime, message, dataKind, data)
}
def withTaskId(taskId: sbt.internal.bsp.TaskId): TaskStartParams = {
copy(taskId = taskId)
@ -45,9 +49,21 @@ final class TaskStartParams private (
def withMessage(message: String): TaskStartParams = {
copy(message = Option(message))
}
def withDataKind(dataKind: Option[String]): TaskStartParams = {
copy(dataKind = dataKind)
}
def withDataKind(dataKind: String): TaskStartParams = {
copy(dataKind = Option(dataKind))
}
def withData(data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): TaskStartParams = {
copy(data = data)
}
def withData(data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): TaskStartParams = {
copy(data = Option(data))
}
}
object TaskStartParams {
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Option[Long], message: Option[String]): TaskStartParams = new TaskStartParams(taskId, eventTime, message)
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Long, message: String): TaskStartParams = new TaskStartParams(taskId, Option(eventTime), Option(message))
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Option[Long], message: Option[String], dataKind: Option[String], data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): TaskStartParams = new TaskStartParams(taskId, eventTime, message, dataKind, data)
def apply(taskId: sbt.internal.bsp.TaskId, eventTime: Long, message: String, dataKind: String, data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): TaskStartParams = new TaskStartParams(taskId, Option(eventTime), Option(message), Option(dataKind), Option(data))
}

View File

@ -0,0 +1,35 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait CompileReportFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val CompileReportFormat: JsonFormat[sbt.internal.bsp.CompileReport] = new JsonFormat[sbt.internal.bsp.CompileReport] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.CompileReport = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target")
val originId = unbuilder.readField[Option[String]]("originId")
val errors = unbuilder.readField[Int]("errors")
val warnings = unbuilder.readField[Int]("warnings")
val time = unbuilder.readField[Option[Int]]("time")
unbuilder.endObject()
sbt.internal.bsp.CompileReport(target, originId, errors, warnings, time)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.CompileReport, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("target", obj.target)
builder.addField("originId", obj.originId)
builder.addField("errors", obj.errors)
builder.addField("warnings", obj.warnings)
builder.addField("time", obj.time)
builder.endObject()
}
}
}

View File

@ -0,0 +1,27 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait CompileTaskFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val CompileTaskFormat: JsonFormat[sbt.internal.bsp.CompileTask] = new JsonFormat[sbt.internal.bsp.CompileTask] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.CompileTask = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target")
unbuilder.endObject()
sbt.internal.bsp.CompileTask(target)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.CompileTask, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("target", obj.target)
builder.endObject()
}
}
}

View File

@ -32,6 +32,8 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
with sbt.internal.bsp.codec.TaskFinishParamsFormats
with sbt.internal.bsp.codec.CompileParamsFormats
with sbt.internal.bsp.codec.BspCompileResultFormats
with sbt.internal.bsp.codec.CompileTaskFormats
with sbt.internal.bsp.codec.CompileReportFormats
with sbt.internal.bsp.codec.ScalaBuildTargetFormats
with sbt.internal.bsp.codec.SbtBuildTargetFormats
with sbt.internal.bsp.codec.ScalacOptionsParamsFormats

View File

@ -5,7 +5,7 @@
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait TaskFinishParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sjsonnew.BasicJsonProtocol =>
trait TaskFinishParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val TaskFinishParamsFormat: JsonFormat[sbt.internal.bsp.TaskFinishParams] = new JsonFormat[sbt.internal.bsp.TaskFinishParams] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.TaskFinishParams = {
__jsOpt match {
@ -15,8 +15,10 @@ implicit lazy val TaskFinishParamsFormat: JsonFormat[sbt.internal.bsp.TaskFinish
val eventTime = unbuilder.readField[Option[Long]]("eventTime")
val message = unbuilder.readField[Option[String]]("message")
val status = unbuilder.readField[Int]("status")
val dataKind = unbuilder.readField[Option[String]]("dataKind")
val data = unbuilder.readField[Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]]("data")
unbuilder.endObject()
sbt.internal.bsp.TaskFinishParams(taskId, eventTime, message, status)
sbt.internal.bsp.TaskFinishParams(taskId, eventTime, message, status, dataKind, data)
case None =>
deserializationError("Expected JsObject but found None")
}
@ -27,6 +29,8 @@ implicit lazy val TaskFinishParamsFormat: JsonFormat[sbt.internal.bsp.TaskFinish
builder.addField("eventTime", obj.eventTime)
builder.addField("message", obj.message)
builder.addField("status", obj.status)
builder.addField("dataKind", obj.dataKind)
builder.addField("data", obj.data)
builder.endObject()
}
}

View File

@ -5,7 +5,7 @@
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait TaskStartParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sjsonnew.BasicJsonProtocol =>
trait TaskStartParamsFormats { self: sbt.internal.bsp.codec.TaskIdFormats with sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val TaskStartParamsFormat: JsonFormat[sbt.internal.bsp.TaskStartParams] = new JsonFormat[sbt.internal.bsp.TaskStartParams] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.TaskStartParams = {
__jsOpt match {
@ -14,8 +14,10 @@ implicit lazy val TaskStartParamsFormat: JsonFormat[sbt.internal.bsp.TaskStartPa
val taskId = unbuilder.readField[sbt.internal.bsp.TaskId]("taskId")
val eventTime = unbuilder.readField[Option[Long]]("eventTime")
val message = unbuilder.readField[Option[String]]("message")
val dataKind = unbuilder.readField[Option[String]]("dataKind")
val data = unbuilder.readField[Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]]("data")
unbuilder.endObject()
sbt.internal.bsp.TaskStartParams(taskId, eventTime, message)
sbt.internal.bsp.TaskStartParams(taskId, eventTime, message, dataKind, data)
case None =>
deserializationError("Expected JsObject but found None")
}
@ -25,6 +27,8 @@ implicit lazy val TaskStartParamsFormat: JsonFormat[sbt.internal.bsp.TaskStartPa
builder.addField("taskId", obj.taskId)
builder.addField("eventTime", obj.eventTime)
builder.addField("message", obj.message)
builder.addField("dataKind", obj.dataKind)
builder.addField("data", obj.data)
builder.endObject()
}
}

View File

@ -284,11 +284,11 @@ type TaskStartParams {
## Optional message describing the task.
message: String
# Kind of data to expect in the `data` field.
# dataKind: String
## Kind of data to expect in the `data` field.
dataKind: String
# Optional metadata about the task.
# data: Any
## Optional metadata about the task.
data: sjsonnew.shaded.scalajson.ast.unsafe.JValue
}
type TaskFinishParams {
@ -304,11 +304,11 @@ type TaskFinishParams {
## Task completion status: 1 -> success, 2 -> error, 3 -> cancelled
status: Int!
# Kind of data to expect in the `data` field.
# dataKind: String
## Kind of data to expect in the `data` field.
dataKind: String
# Optional metadata about the task.
# data: Any
## Optional metadata about the task.
data: sjsonnew.shaded.scalajson.ast.unsafe.JValue
}
## Compile Request
@ -341,6 +341,29 @@ type BspCompileResult {
# data: any
}
## Compile Notifications
type CompileTask {
target: sbt.internal.bsp.BuildTargetIdentifier!
}
type CompileReport {
## The build target that was compiled
target: sbt.internal.bsp.BuildTargetIdentifier!
## An optional request id to know the origin of this report
originId: String
## The total number of reported errors compiling this target.
errors: Int!
## The total number of reported warnings compiling the target.
warnings: Int!
## The total number of milliseconds it took to compile the target.
time: Int
}
# Scala Extension
## Contains scala-specific metadata for compiling a target containing Scala sources.

View File

@ -0,0 +1,8 @@
package sbt.internal.bsp
import java.util.concurrent.atomic.AtomicInteger
object BuildServerTasks {
private val idGenerator = new AtomicInteger(0)
def uniqueId: String = idGenerator.getAndIncrement().toString
}

View File

@ -0,0 +1,10 @@
package sbt.internal.bsp
object BuildTargetName {
def fromScope(project: String, config: String): String = {
config match {
case "compile" => project
case _ => s"$project-$config"
}
}
}