Return jvmBuildTarget for workspace/buildTargets

This commit is contained in:
Friendseeker 2024-11-25 17:38:12 -08:00 committed by Jiahui (Jerry) Tan
parent 3529e20279
commit ad0ab07e99
8 changed files with 147 additions and 12 deletions

View File

@ -34,6 +34,7 @@ import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter, Parser =>
import xsbti.CompileFailed
import java.io.File
import java.nio.file.Paths
import java.util.concurrent.atomic.AtomicBoolean
import scala.collection.mutable
@ -614,12 +615,19 @@ object BuildServerProtocol {
val thisProjectRef = Keys.thisProjectRef.value
val thisConfig = Keys.configuration.value
val scalaJars = Keys.scalaInstance.value.allJars.map(_.toURI.toString)
val (javaHomeForTarget, isForkedJava) = javaHome.value match {
case Some(forkedJava) => (Some(forkedJava.toURI), true)
case None => (sys.props.get("java.home").map(Paths.get(_)).map(_.toUri), false)
}
val javaVersionForTarget = extractJavaVersion(javacOptions.value, isForkedJava)
val jvmBuildTarget = JvmBuildTarget(javaHomeForTarget, javaVersionForTarget)
val compileData = ScalaBuildTarget(
scalaOrganization = scalaOrganization.value,
scalaVersion = scalaVersion.value,
scalaBinaryVersion = scalaBinaryVersion.value,
platform = ScalaPlatform.JVM,
jars = scalaJars.toVector
jars = scalaJars.toVector,
jvmBuildTarget = jvmBuildTarget,
)
val configuration = Keys.configuration.value
val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name)
@ -659,7 +667,11 @@ object BuildServerProtocol {
scalaVersion = scalaProvider.version(),
scalaBinaryVersion = binaryScalaVersion(scalaProvider.version()),
platform = ScalaPlatform.JVM,
jars = scalaJars.toVector.map(_.toURI.toString)
jars = scalaJars.toVector.map(_.toURI.toString),
jvmBuildTarget = JvmBuildTarget(
sys.props.get("java.home").map(Paths.get(_)).map(_.toUri),
sys.props.get("java.version")
),
)
val sbtVersionValue = sbtVersion.value
val sbtData = SbtBuildTarget(
@ -985,6 +997,26 @@ object BuildServerProtocol {
)
}
private def extractJavaVersion(
javacOptions: Seq[String],
isForkedJava: Boolean
): Option[String] = {
def getVersionAfterFlag(flag: String): Option[String] = {
val index = javacOptions.indexOf(flag)
if (index >= 0) javacOptions.lift(index + 1)
else None
}
val versionFromJavacOption = getVersionAfterFlag("--release")
.orElse(getVersionAfterFlag("--target"))
.orElse(getVersionAfterFlag("-target"))
versionFromJavacOption.orElse {
// TODO: extract java version from forked javac
if (isForkedJava) None else sys.props.get("java.version")
}
}
// naming convention still seems like the only reliable way to get IntelliJ to import this correctly
// https://github.com/JetBrains/intellij-scala/blob/a54c2a7c157236f35957049cbfd8c10587c9e60c/scala/scala-impl/src/org/jetbrains/sbt/language/SbtFileImpl.scala#L82-L84
private def toSbtTargetIdName(ref: LoadedBuildUnit): String = {

View File

@ -0,0 +1,48 @@
/**
* This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]].
*/
// DO NOT EDIT MANUALLY
package sbt.internal.bsp
/**
* Contains jvm-specific metadata, specifically JDK reference
* @param javaHome Uri representing absolute path to jdk
* @param javaVersion The java version this target is supposed to use (can be set using javac `-target` flag)
*/
final class JvmBuildTarget private (
val javaHome: Option[java.net.URI],
val javaVersion: Option[String]) extends Serializable {
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: JvmBuildTarget => (this.javaHome == x.javaHome) && (this.javaVersion == x.javaVersion)
case _ => false
})
override def hashCode: Int = {
37 * (37 * (37 * (17 + "sbt.internal.bsp.JvmBuildTarget".##) + javaHome.##) + javaVersion.##)
}
override def toString: String = {
"JvmBuildTarget(" + javaHome + ", " + javaVersion + ")"
}
private[this] def copy(javaHome: Option[java.net.URI] = javaHome, javaVersion: Option[String] = javaVersion): JvmBuildTarget = {
new JvmBuildTarget(javaHome, javaVersion)
}
def withJavaHome(javaHome: Option[java.net.URI]): JvmBuildTarget = {
copy(javaHome = javaHome)
}
def withJavaHome(javaHome: java.net.URI): JvmBuildTarget = {
copy(javaHome = Option(javaHome))
}
def withJavaVersion(javaVersion: Option[String]): JvmBuildTarget = {
copy(javaVersion = javaVersion)
}
def withJavaVersion(javaVersion: String): JvmBuildTarget = {
copy(javaVersion = Option(javaVersion))
}
}
object JvmBuildTarget {
def apply(javaHome: Option[java.net.URI], javaVersion: Option[String]): JvmBuildTarget = new JvmBuildTarget(javaHome, javaVersion)
def apply(javaHome: java.net.URI, javaVersion: String): JvmBuildTarget = new JvmBuildTarget(Option(javaHome), Option(javaVersion))
}

View File

@ -14,28 +14,30 @@ package sbt.internal.bsp
For example, 2.12 if scalaVersion is 2.12.4.
* @param platform The target platform for this target
* @param jars A sequence of Scala jars such as scala-library, scala-compiler and scala-reflect.
* @param jvmBuildTarget The jvm build target describing jdk to be used
*/
final class ScalaBuildTarget private (
val scalaOrganization: String,
val scalaVersion: String,
val scalaBinaryVersion: String,
val platform: Int,
val jars: Vector[String]) extends Serializable {
val jars: Vector[String],
val jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget]) extends Serializable {
override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match {
case x: ScalaBuildTarget => (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.platform == x.platform) && (this.jars == x.jars)
case x: ScalaBuildTarget => (this.scalaOrganization == x.scalaOrganization) && (this.scalaVersion == x.scalaVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.platform == x.platform) && (this.jars == x.jars) && (this.jvmBuildTarget == x.jvmBuildTarget)
case _ => false
})
override def hashCode: Int = {
37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalaBuildTarget".##) + scalaOrganization.##) + scalaVersion.##) + scalaBinaryVersion.##) + platform.##) + jars.##)
37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalaBuildTarget".##) + scalaOrganization.##) + scalaVersion.##) + scalaBinaryVersion.##) + platform.##) + jars.##) + jvmBuildTarget.##)
}
override def toString: String = {
"ScalaBuildTarget(" + scalaOrganization + ", " + scalaVersion + ", " + scalaBinaryVersion + ", " + platform + ", " + jars + ")"
"ScalaBuildTarget(" + scalaOrganization + ", " + scalaVersion + ", " + scalaBinaryVersion + ", " + platform + ", " + jars + ", " + jvmBuildTarget + ")"
}
private[this] def copy(scalaOrganization: String = scalaOrganization, scalaVersion: String = scalaVersion, scalaBinaryVersion: String = scalaBinaryVersion, platform: Int = platform, jars: Vector[String] = jars): ScalaBuildTarget = {
new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars)
private[this] def copy(scalaOrganization: String = scalaOrganization, scalaVersion: String = scalaVersion, scalaBinaryVersion: String = scalaBinaryVersion, platform: Int = platform, jars: Vector[String] = jars, jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget] = jvmBuildTarget): ScalaBuildTarget = {
new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget)
}
def withScalaOrganization(scalaOrganization: String): ScalaBuildTarget = {
copy(scalaOrganization = scalaOrganization)
@ -52,8 +54,15 @@ final class ScalaBuildTarget private (
def withJars(jars: Vector[String]): ScalaBuildTarget = {
copy(jars = jars)
}
def withJvmBuildTarget(jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget]): ScalaBuildTarget = {
copy(jvmBuildTarget = jvmBuildTarget)
}
def withJvmBuildTarget(jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget): ScalaBuildTarget = {
copy(jvmBuildTarget = Option(jvmBuildTarget))
}
}
object ScalaBuildTarget {
def apply(scalaOrganization: String, scalaVersion: String, scalaBinaryVersion: String, platform: Int, jars: Vector[String]): ScalaBuildTarget = new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars)
def apply(scalaOrganization: String, scalaVersion: String, scalaBinaryVersion: String, platform: Int, jars: Vector[String], jvmBuildTarget: Option[sbt.internal.bsp.JvmBuildTarget]): ScalaBuildTarget = new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget)
def apply(scalaOrganization: String, scalaVersion: String, scalaBinaryVersion: String, platform: Int, jars: Vector[String], jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget): ScalaBuildTarget = new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, Option(jvmBuildTarget))
}

View File

@ -55,6 +55,7 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
with sbt.internal.bsp.codec.TestResultFormats
with sbt.internal.bsp.codec.RunParamsFormats
with sbt.internal.bsp.codec.RunResultFormats
with sbt.internal.bsp.codec.JvmBuildTargetFormats
with sbt.internal.bsp.codec.ScalaBuildTargetFormats
with sbt.internal.bsp.codec.ScalacOptionsParamsFormats
with sbt.internal.bsp.codec.ScalacOptionsItemFormats

View File

@ -0,0 +1,29 @@
/**
* 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 JvmBuildTargetFormats { self: sjsonnew.BasicJsonProtocol =>
implicit lazy val JvmBuildTargetFormat: JsonFormat[sbt.internal.bsp.JvmBuildTarget] = new JsonFormat[sbt.internal.bsp.JvmBuildTarget] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.JvmBuildTarget = {
__jsOpt match {
case Some(__js) =>
unbuilder.beginObject(__js)
val javaHome = unbuilder.readField[Option[java.net.URI]]("javaHome")
val javaVersion = unbuilder.readField[Option[String]]("javaVersion")
unbuilder.endObject()
sbt.internal.bsp.JvmBuildTarget(javaHome, javaVersion)
case None =>
deserializationError("Expected JsObject but found None")
}
}
override def write[J](obj: sbt.internal.bsp.JvmBuildTarget, builder: Builder[J]): Unit = {
builder.beginObject()
builder.addField("javaHome", obj.javaHome)
builder.addField("javaVersion", obj.javaVersion)
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 SbtBuildTargetFormats { self: sbt.internal.bsp.codec.ScalaBuildTargetFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.BuildTargetIdentifierFormats =>
trait SbtBuildTargetFormats { self: sbt.internal.bsp.codec.ScalaBuildTargetFormats with sbt.internal.bsp.codec.JvmBuildTargetFormats with sjsonnew.BasicJsonProtocol with sbt.internal.bsp.codec.BuildTargetIdentifierFormats =>
implicit lazy val SbtBuildTargetFormat: JsonFormat[sbt.internal.bsp.SbtBuildTarget] = new JsonFormat[sbt.internal.bsp.SbtBuildTarget] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.SbtBuildTarget = {
__jsOpt match {

View File

@ -5,7 +5,7 @@
// DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
trait ScalaBuildTargetFormats { self: sjsonnew.BasicJsonProtocol =>
trait ScalaBuildTargetFormats { self: sbt.internal.bsp.codec.JvmBuildTargetFormats with sjsonnew.BasicJsonProtocol =>
implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuildTarget] = new JsonFormat[sbt.internal.bsp.ScalaBuildTarget] {
override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaBuildTarget = {
__jsOpt match {
@ -16,8 +16,9 @@ implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuild
val scalaBinaryVersion = unbuilder.readField[String]("scalaBinaryVersion")
val platform = unbuilder.readField[Int]("platform")
val jars = unbuilder.readField[Vector[String]]("jars")
val jvmBuildTarget = unbuilder.readField[Option[sbt.internal.bsp.JvmBuildTarget]]("jvmBuildTarget")
unbuilder.endObject()
sbt.internal.bsp.ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars)
sbt.internal.bsp.ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget)
case None =>
deserializationError("Expected JsObject but found None")
}
@ -29,6 +30,7 @@ implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuild
builder.addField("scalaBinaryVersion", obj.scalaBinaryVersion)
builder.addField("platform", obj.platform)
builder.addField("jars", obj.jars)
builder.addField("jvmBuildTarget", obj.jvmBuildTarget)
builder.endObject()
}
}

View File

@ -605,6 +605,17 @@ type RunResult {
}
# JVM extension
## Contains jvm-specific metadata, specifically JDK reference
type JvmBuildTarget {
## Uri representing absolute path to jdk
javaHome: java.net.URI
## The java version this target is supposed to use (can be set using javac `-target` flag)
javaVersion: String
}
# Scala Extension
## Contains scala-specific metadata for compiling a target containing Scala sources.
@ -626,6 +637,9 @@ type ScalaBuildTarget {
## A sequence of Scala jars such as scala-library, scala-compiler and scala-reflect.
jars: [String]!
## The jvm build target describing jdk to be used
jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget
}
## Scalac options