buildTarget/scalacOptions

This commit is contained in:
Eugene Yokota 2020-02-24 01:02:16 -05:00 committed by Adrien Piquerez
parent 10b2154d2e
commit d2d0a9ca80
12 changed files with 301 additions and 7 deletions

View File

@ -340,7 +340,9 @@ object Keys {
val allowZombieClassLoaders = settingKey[Boolean]("Allow a classloader that has previously been closed by `run` or `test` to continue loading classes.")
val buildTargetIdentifier = settingKey[BuildTargetIdentifier]("Id for BSP build target.").withRank(DSetting)
val bspBuildTargetSources = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetSourceItem = taskKey[SourcesItem]("").withRank(DTask)
val bspBuildTargetSourcesItem = taskKey[SourcesItem]("").withRank(DTask)
val bspBuildTargetScalacOptions = inputKey[Unit]("").withRank(DTask)
val bspBuildTargetScalacOptionsItem = taskKey[ScalacOptionsItem]("").withRank(DTask)
val useCoursier = settingKey[Boolean]("Use Coursier for dependency resolution.").withRank(BSetting)
val csrCacheDirectory = settingKey[File]("Coursier cache directory. Uses -Dsbt.coursier.home or Coursier's default.").withRank(CSetting)

View File

@ -35,14 +35,27 @@ object BuildServerProtocol {
val s = state.value
val args: Seq[String] = spaceDelimited("<arg>").parsed
val filter = toScopeFilter(args)
// run bspBuildTargetSourceItem concurrently
// run the worker task concurrently
Def.task {
import sbt.internal.bsp.codec.JsonProtocol._
val items = bspBuildTargetSourceItem.all(filter).value
val items = bspBuildTargetSourcesItem.all(filter).value
val result = SourcesResult(items.toVector)
s.respondEvent(result)
}
}).evaluated
}).evaluated,
bspBuildTargetScalacOptions := (Def.inputTaskDyn {
import DefaultParsers._
val s = state.value
val args: Seq[String] = spaceDelimited("<arg>").parsed
val filter = toScopeFilter(args)
// run the worker task concurrently
Def.task {
import sbt.internal.bsp.codec.JsonProtocol._
val items = bspBuildTargetScalacOptionsItem.all(filter).value
val result = ScalacOptionsResult(items.toVector)
s.respondEvent(result)
}
}).evaluated,
)
// This will be coped to Compile, Test, etc
@ -52,7 +65,7 @@ object BuildServerProtocol {
val c = configuration.value
toId(ref, c)
},
bspBuildTargetSourceItem := {
bspBuildTargetSourcesItem := {
val id = buildTargetIdentifier.value
val dirs = unmanagedSourceDirectories.value
val managed = managedSources.value
@ -63,7 +76,14 @@ object BuildServerProtocol {
SourceItem(x.toURI, SourceItemKind.File, true)
})
SourcesItem(id, items)
}
},
bspBuildTargetScalacOptionsItem :=
ScalacOptionsItem(
target = buildTargetIdentifier.value,
options = scalacOptions.value.toVector,
classpath = fullClasspath.value.toVector.map(_.data.toURI),
classDirectory = classDirectory.value.toURI
),
)
def toScopeFilter(args: Seq[String]): ScopeFilter = {

View File

@ -117,6 +117,19 @@ private[sbt] object LanguageServerProtocol {
)
)
()
case r: JsonRpcRequestMessage if r.method == "buildTarget/scalacOptions" =>
import sbt.internal.bsp.codec.JsonProtocol._
val param = Converter.fromJson[ScalacOptionsParams](json(r)).get
appendExec(
Exec(
s"""${Keys.bspBuildTargetScalacOptions.key} ${param.targets
.map(_.uri)
.mkString(" ")}""",
Option(r.id),
Some(CommandSource(name))
)
)
()
}
}, {
case n: JsonRpcNotificationMessage if n.method == "textDocument/didSave" =>

View File

@ -0,0 +1,57 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/**
* @param options Additional arguments to the compiler.
For example, -deprecation.
* @param classpath The dependency classpath for this target, must be
identical to what is passed as arguments to
the -classpath flag in the command line interface
of scalac.
* @param classDirectory The output directory for classfiles produced by this target
*/
final class ScalacOptionsItem private (
val target: sbt.internal.bsp.BuildTargetIdentifier,
val options: Vector[String],
val classpath: Vector[java.net.URI],
val classDirectory: Option[java.net.URI]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: ScalacOptionsItem => (this.target == x.target) && (this.options == x.options) && (this.classpath == x.classpath) && (this.classDirectory == x.classDirectory)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalacOptionsItem".##) + target.##) + options.##) + classpath.##) + classDirectory.##)
}
override def toString: String = {
"ScalacOptionsItem(" + target + ", " + options + ", " + classpath + ", " + classDirectory + ")"
}
private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target, options: Vector[String] = options, classpath: Vector[java.net.URI] = classpath, classDirectory: Option[java.net.URI] = classDirectory): ScalacOptionsItem = {
new ScalacOptionsItem(target, options, classpath, classDirectory)
}
def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): ScalacOptionsItem = {
copy(target = target)
}
def withOptions(options: Vector[String]): ScalacOptionsItem = {
copy(options = options)
}
def withClasspath(classpath: Vector[java.net.URI]): ScalacOptionsItem = {
copy(classpath = classpath)
}
def withClassDirectory(classDirectory: Option[java.net.URI]): ScalacOptionsItem = {
copy(classDirectory = classDirectory)
}
def withClassDirectory(classDirectory: java.net.URI): ScalacOptionsItem = {
copy(classDirectory = Option(classDirectory))
}
}
object ScalacOptionsItem {
def apply(target: sbt.internal.bsp.BuildTargetIdentifier, options: Vector[String], classpath: Vector[java.net.URI], classDirectory: Option[java.net.URI]): ScalacOptionsItem = new ScalacOptionsItem(target, options, classpath, classDirectory)
def apply(target: sbt.internal.bsp.BuildTargetIdentifier, options: Vector[String], classpath: Vector[java.net.URI], classDirectory: java.net.URI): ScalacOptionsItem = new ScalacOptionsItem(target, options, classpath, Option(classDirectory))
}

View File

@ -0,0 +1,37 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/**
* Scalac options
* The build target scalac options request is sent from the client to the server
* to query for the list of compiler options necessary to compile in a given list of targets.
*/
final class ScalacOptionsParams private (
val targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]) extends Serializable {
override def equals(o: Any): Boolean = o match {
case x: ScalacOptionsParams => (this.targets == x.targets)
case _ => false
}
override def hashCode: Int = {
37 * (37 * (17 + "sbt.internal.bsp.ScalacOptionsParams".##) + targets.##)
}
override def toString: String = {
"ScalacOptionsParams(" + targets + ")"
}
private[this] def copy(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier] = targets): ScalacOptionsParams = {
new ScalacOptionsParams(targets)
}
def withTargets(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): ScalacOptionsParams = {
copy(targets = targets)
}
}
object ScalacOptionsParams {
def apply(targets: Vector[sbt.internal.bsp.BuildTargetIdentifier]): ScalacOptionsParams = new ScalacOptionsParams(targets)
}

View File

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

View File

@ -18,4 +18,7 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
with sbt.internal.bsp.codec.SourcesResultFormats
with sbt.internal.bsp.codec.ScalaBuildTargetFormats
with sbt.internal.bsp.codec.SbtBuildTargetFormats
with sbt.internal.bsp.codec.ScalacOptionsParamsFormats
with sbt.internal.bsp.codec.ScalacOptionsItemFormats
with sbt.internal.bsp.codec.ScalacOptionsResultFormats
object JsonProtocol extends JsonProtocol

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.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait ScalacOptionsItemFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ScalacOptionsItemFormat: JsonFormat[sbt.internal.bsp.ScalacOptionsItem] = new JsonFormat[sbt.internal.bsp.ScalacOptionsItem] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalacOptionsItem = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target")
val options = unbuilder.readField[Vector[String]]("options")
val classpath = unbuilder.readField[Vector[java.net.URI]]("classpath")
val classDirectory = unbuilder.readField[Option[java.net.URI]]("classDirectory")
unbuilder.endObject()
sbt.internal.bsp.ScalacOptionsItem(target, options, classpath, classDirectory)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ScalacOptionsItem, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("target", obj.target)
builder.addField("options", obj.options)
builder.addField("classpath", obj.classpath)
builder.addField("classDirectory", obj.classDirectory)
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 ScalacOptionsParamsFormats { self: sbt.internal.bsp.codec.BuildTargetIdentifierFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ScalacOptionsParamsFormat: JsonFormat[sbt.internal.bsp.ScalacOptionsParams] = new JsonFormat[sbt.internal.bsp.ScalacOptionsParams] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalacOptionsParams = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val targets = unbuilder.readField[Vector[sbt.internal.bsp.BuildTargetIdentifier]]("targets")
unbuilder.endObject()
sbt.internal.bsp.ScalacOptionsParams(targets)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ScalacOptionsParams, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("targets", obj.targets)
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 ScalacOptionsResultFormats { self: sbt.internal.bsp.codec.ScalacOptionsItemFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ScalacOptionsResultFormat: JsonFormat[sbt.internal.bsp.ScalacOptionsResult] = new JsonFormat[sbt.internal.bsp.ScalacOptionsResult] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalacOptionsResult = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val items = unbuilder.readField[Vector[sbt.internal.bsp.ScalacOptionsItem]]("items")
unbuilder.endObject()
sbt.internal.bsp.ScalacOptionsResult(items)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.ScalacOptionsResult, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("items", obj.items)
builder.endObject()
}
}
}

View File

@ -183,3 +183,31 @@ type SbtBuildTarget {
## sbt build targets if this target represents an sbt meta-meta build.
children: [sbt.internal.bsp.BuildTargetIdentifier]!
}
## Scalac options
## The build target scalac options request is sent from the client to the server
## to query for the list of compiler options necessary to compile in a given list of targets.
type ScalacOptionsParams {
targets: [sbt.internal.bsp.BuildTargetIdentifier]
}
type ScalacOptionsResult {
items: [sbt.internal.bsp.ScalacOptionsItem]
}
type ScalacOptionsItem {
target: sbt.internal.bsp.BuildTargetIdentifier!
## Additional arguments to the compiler.
## For example, -deprecation.
options: [String]
## The dependency classpath for this target, must be
## identical to what is passed as arguments to
## the -classpath flag in the command line interface
## of scalac.
classpath: [java.net.URI]
## The output directory for classfiles produced by this target
classDirectory: java.net.URI
}

View File

@ -41,7 +41,22 @@ object BuildServerTest extends AbstractServerTest {
)
assert(svr.waitForString(10.seconds) { s =>
println(s)
(s contains """"id":"12"""")
(s contains """"id":"12"""") &&
(s contains "util/src/main/scala")
})
}
test("buildTarget/scalacOptions") { _ =>
val x = s"${svr.baseDirectory.getAbsoluteFile.toURI}#util/Compile"
svr.sendJsonRpc(
s"""{ "jsonrpc": "2.0", "id": "13", "method": "buildTarget/scalacOptions", "params": {
| "targets": [{ "uri": "$x" }]
|} }""".stripMargin
)
assert(svr.waitForString(10.seconds) { s =>
println(s)
(s contains """"id":"13"""") &&
(s contains "scala-library-2.13.1.jar")
})
}