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 xsbti.CompileFailed
import java.io.File import java.io.File
import java.nio.file.Paths
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import scala.collection.mutable import scala.collection.mutable
@ -614,12 +615,19 @@ object BuildServerProtocol {
val thisProjectRef = Keys.thisProjectRef.value val thisProjectRef = Keys.thisProjectRef.value
val thisConfig = Keys.configuration.value val thisConfig = Keys.configuration.value
val scalaJars = Keys.scalaInstance.value.allJars.map(_.toURI.toString) 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( val compileData = ScalaBuildTarget(
scalaOrganization = scalaOrganization.value, scalaOrganization = scalaOrganization.value,
scalaVersion = scalaVersion.value, scalaVersion = scalaVersion.value,
scalaBinaryVersion = scalaBinaryVersion.value, scalaBinaryVersion = scalaBinaryVersion.value,
platform = ScalaPlatform.JVM, platform = ScalaPlatform.JVM,
jars = scalaJars.toVector jars = scalaJars.toVector,
jvmBuildTarget = jvmBuildTarget,
) )
val configuration = Keys.configuration.value val configuration = Keys.configuration.value
val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name) val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name)
@ -659,7 +667,11 @@ object BuildServerProtocol {
scalaVersion = scalaProvider.version(), scalaVersion = scalaProvider.version(),
scalaBinaryVersion = binaryScalaVersion(scalaProvider.version()), scalaBinaryVersion = binaryScalaVersion(scalaProvider.version()),
platform = ScalaPlatform.JVM, 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 sbtVersionValue = sbtVersion.value
val sbtData = SbtBuildTarget( 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 // 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 // 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 = { 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. For example, 2.12 if scalaVersion is 2.12.4.
* @param platform The target platform for this target * @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 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 ( final class ScalaBuildTarget private (
val scalaOrganization: String, val scalaOrganization: String,
val scalaVersion: String, val scalaVersion: String,
val scalaBinaryVersion: String, val scalaBinaryVersion: String,
val platform: Int, 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 { 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 case _ => false
}) })
override def hashCode: Int = { 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 = { 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 = { 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) new ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget)
} }
def withScalaOrganization(scalaOrganization: String): ScalaBuildTarget = { def withScalaOrganization(scalaOrganization: String): ScalaBuildTarget = {
copy(scalaOrganization = scalaOrganization) copy(scalaOrganization = scalaOrganization)
@ -52,8 +54,15 @@ final class ScalaBuildTarget private (
def withJars(jars: Vector[String]): ScalaBuildTarget = { def withJars(jars: Vector[String]): ScalaBuildTarget = {
copy(jars = jars) 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 { 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.TestResultFormats
with sbt.internal.bsp.codec.RunParamsFormats with sbt.internal.bsp.codec.RunParamsFormats
with sbt.internal.bsp.codec.RunResultFormats with sbt.internal.bsp.codec.RunResultFormats
with sbt.internal.bsp.codec.JvmBuildTargetFormats
with sbt.internal.bsp.codec.ScalaBuildTargetFormats with sbt.internal.bsp.codec.ScalaBuildTargetFormats
with sbt.internal.bsp.codec.ScalacOptionsParamsFormats with sbt.internal.bsp.codec.ScalacOptionsParamsFormats
with sbt.internal.bsp.codec.ScalacOptionsItemFormats 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 // DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } 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] { 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 = { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.SbtBuildTarget = {
__jsOpt match { __jsOpt match {

View File

@ -5,7 +5,7 @@
// DO NOT EDIT MANUALLY // DO NOT EDIT MANUALLY
package sbt.internal.bsp.codec package sbt.internal.bsp.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } 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] { 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 = { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.bsp.ScalaBuildTarget = {
__jsOpt match { __jsOpt match {
@ -16,8 +16,9 @@ implicit lazy val ScalaBuildTargetFormat: JsonFormat[sbt.internal.bsp.ScalaBuild
val scalaBinaryVersion = unbuilder.readField[String]("scalaBinaryVersion") val scalaBinaryVersion = unbuilder.readField[String]("scalaBinaryVersion")
val platform = unbuilder.readField[Int]("platform") val platform = unbuilder.readField[Int]("platform")
val jars = unbuilder.readField[Vector[String]]("jars") val jars = unbuilder.readField[Vector[String]]("jars")
val jvmBuildTarget = unbuilder.readField[Option[sbt.internal.bsp.JvmBuildTarget]]("jvmBuildTarget")
unbuilder.endObject() unbuilder.endObject()
sbt.internal.bsp.ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars) sbt.internal.bsp.ScalaBuildTarget(scalaOrganization, scalaVersion, scalaBinaryVersion, platform, jars, jvmBuildTarget)
case None => case None =>
deserializationError("Expected JsObject but found 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("scalaBinaryVersion", obj.scalaBinaryVersion)
builder.addField("platform", obj.platform) builder.addField("platform", obj.platform)
builder.addField("jars", obj.jars) builder.addField("jars", obj.jars)
builder.addField("jvmBuildTarget", obj.jvmBuildTarget)
builder.endObject() 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 # Scala Extension
## Contains scala-specific metadata for compiling a target containing Scala sources. ## 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. ## A sequence of Scala jars such as scala-library, scala-compiler and scala-reflect.
jars: [String]! jars: [String]!
## The jvm build target describing jdk to be used
jvmBuildTarget: sbt.internal.bsp.JvmBuildTarget
} }
## Scalac options ## Scalac options