Skip to content

Commit

Permalink
improvement: Automatically calculate last supported versions for sema…
Browse files Browse the repository at this point in the history
…nticdb

Previously, we would fail if our version of semanticdb was not supported for a sepcific scala version. Now, we calculate last supported version for each scala version when compiling.

Potentially this means we could get a new semanticdb version automatically, but that should not be an issue as semanticdb is well tested in scalameta itself
  • Loading branch information
tgodzik committed Sep 25, 2023
1 parent 27fed26 commit 6089338
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 46 deletions.
23 changes: 16 additions & 7 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,9 @@ val sharedSettings = sharedJavacOptions ++ sharedScalacOptions ++ List(
scalaVersion.value,
if2 = List(
compilerPlugin(
"org.scalameta" % "semanticdb-scalac" % V.scalameta cross CrossVersion.full
"org.scalameta" % "semanticdb-scalac" % V.semanticdb(
scalaVersion.value
) cross CrossVersion.full
)
),
),
Expand Down Expand Up @@ -323,7 +325,9 @@ val mtagsSettings = List(
if2 = List(
// for token edit-distance used by goto definition
"com.googlecode.java-diff-utils" % "diffutils" % "1.3.0",
"org.scalameta" % "semanticdb-scalac-core" % V.scalameta cross CrossVersion.full,
"org.scalameta" % "semanticdb-scalac-core" % V.semanticdb(
scalaVersion.value
) cross CrossVersion.full,
),
if3 = List(
"org.scala-lang" %% "scala3-compiler" % scalaVersion.value,
Expand Down Expand Up @@ -489,9 +493,11 @@ lazy val metals = project
"com.lihaoyi" %% "ujson" % "3.1.3",
// For remote language server
"com.lihaoyi" %% "requests" % "0.8.0",
// for producing SemanticDB from Scala source files
"org.scalameta" %% "scalameta" % V.scalameta,
"org.scalameta" % "semanticdb-scalac-core" % V.scalameta cross CrossVersion.full,
// for producing SemanticDB from Scala source files, to be sure we want the same version of scalameta
"org.scalameta" %% "scalameta" % V.semanticdb(scalaVersion.value),
"org.scalameta" % "semanticdb-scalac-core" % V.semanticdb(
scalaVersion.value
) cross CrossVersion.full,
// For starting Ammonite
"io.github.alexarchambault.ammonite" %% "ammonite-runner" % "0.4.0",
"org.scala-lang.modules" %% "scala-xml" % "2.2.0",
Expand All @@ -514,7 +520,7 @@ lazy val metals = project
"mavenBloopVersion" -> V.mavenBloop,
"gradleBloopVersion" -> V.gradleBloop,
"scalametaVersion" -> V.scalameta,
"semanticdbVersion" -> V.semanticdb,
"semanticdbVersion" -> V.semanticdb(scalaVersion.value),
"javaSemanticdbVersion" -> V.javaSemanticdb,
"scalafmtVersion" -> V.scalafmt,
"ammoniteVersion" -> V.ammonite,
Expand All @@ -536,6 +542,7 @@ lazy val metals = project
"ammonite3" -> V.ammonite3Version,
"scala213" -> V.scala213,
"scala3" -> V.scala3,
"lastSupportedSemanticdb" -> SemanticDbSupport.last,
),
)
.dependsOn(mtags, `mtags-java`)
Expand All @@ -545,9 +552,10 @@ lazy val `sbt-metals` = project
.settings(
buildInfoPackage := "scala.meta.internal.sbtmetals",
buildInfoKeys := Seq[BuildInfoKey](
"semanticdbVersion" -> V.semanticdb,
"semanticdbVersion" -> V.semanticdb(scalaVersion.value),
"supportedScala2Versions" -> V.scala2Versions,
"javaSemanticdbVersion" -> V.javaSemanticdb,
"lastSupportedSemanticdb" -> SemanticDbSupport.last,
),
scalaVersion := V.scala212,
scriptedLaunchOpts ++= Seq(s"-Dplugin.version=${version.value}"),
Expand Down Expand Up @@ -683,6 +691,7 @@ lazy val mtest = project
"scalaVersion" -> scalaVersion.value,
"kindProjector" -> V.kindProjector,
"betterMonadicFor" -> V.betterMonadicFor,
"lastSupportedSemanticdb" -> SemanticDbSupport.last,
),
crossScalaVersions := V.nonDeprecatedScalaVersions,
Compile / unmanagedSourceDirectories ++= multiScalaDirectories(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ object Embedded {
Dependency.of(
"org.scalameta",
s"semanticdb-scalac_$scalaVersion",
BuildInfo.scalametaVersion,
BuildInfo.lastSupportedSemanticdb
.getOrElse(scalaVersion, BuildInfo.scalametaVersion),
)

def downloadDependency(
Expand Down
32 changes: 32 additions & 0 deletions project/SemanticDbSupport.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import scala.jdk.CollectionConverters._

object SemanticDbSupport {

private val Scala211Versions = getVersions(2, 11, 12 to 12)
private val last212 = V.scala212.split('.').last.toInt
private val Scala212Versions = getVersions(2, 12, 9 to last212)
private val last213 = V.scala213.split('.').last.toInt
private val Scala213Versions = getVersions(2, 13, 1 to last213)

private val AllScalaVersions =
Scala213Versions ++ Scala212Versions ++ Scala211Versions

val last: Map[String, String] = AllScalaVersions.flatMap { scalaVersion =>
coursierapi.Complete
.create()
.withScalaVersion(scalaVersion)
.withScalaBinaryVersion(scalaVersion.split('.').take(2).mkString("."))
.withInput(s"org.scalameta:semanticdb-scalac_$scalaVersion:")
.complete()
.getCompletions()
.asScala
.lastOption
.map(scalaVersion -> _)
}.toMap

// returns versions from newest to oldest
private def getVersions(major: Int, minor: Int, range: Range) = {
val desc = if (range.step > 0) range.reverse else range
desc.map { x => s"$major.$minor.$x" }
}
}
6 changes: 4 additions & 2 deletions project/V.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ object V {
val scalaCli = "1.0.4"
val scalafix = "0.11.1"
val scalafmt = "3.7.14"
val scalameta = "4.8.3"
val scalameta = "4.8.10"
val scribe = "3.12.2"
val semanticdb = scalameta
val qdox = "2.0.3"

val guava = "com.google.guava" % "guava" % "32.1.2-jre"
val lsp4j = "org.eclipse.lsp4j" % "org.eclipse.lsp4j" % lsp4jV
val dap4j = "org.eclipse.lsp4j" % "org.eclipse.lsp4j.debug" % lsp4jV

def semanticdb(scalaVersion: String) =
SemanticDbSupport.last.getOrElse(scalaVersion, scalameta)

def isNightliesEnabled: Boolean =
sys.env.get("CI").isDefined || sys.env.get("NIGHTLIES").isDefined

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ object MetalsPlugin extends AutoPlugin {
override lazy val projectSettings: Seq[Def.Setting[_]] = Def.settings(
Keys.semanticdbVersion := {
if (requiresSemanticdb.value && !isScala3.value)
BuildInfo.semanticdbVersion
BuildInfo.lastSupportedSemanticdb.getOrElse(
scalaVersion.value,
BuildInfo.semanticdbVersion,
)
else Keys.semanticdbVersion.value
},
semanticdbEnabled := {
Expand Down
6 changes: 3 additions & 3 deletions sbt-metals/src/sbt-test/sbt-metals/semanticdb/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ val checkSemanticdb =
lazy val a = project
.in(file("a"))
.settings(
scalaVersion := "2.13.5",
scalaVersion := "2.13.12",
inConfig(Compile) {
checkSemanticdb := {
assertSemanticdbForScala2.value
Expand All @@ -21,7 +21,7 @@ lazy val a = project
lazy val b = project
.in(file("b"))
.settings(
scalaVersion := "3.0.1",
scalaVersion := "3.3.1",
inConfig(Compile) { checkSemanticdb := assertSemanticdbForScala3.value },
inConfig(Test) { checkSemanticdb := assertSemanticdbForScala3.value },
)
Expand All @@ -30,7 +30,7 @@ lazy val b = project
lazy val c = project
.in(file("c"))
.settings(
scalaVersion := "2.12.17",
scalaVersion := "2.12.18",
inConfig(Compile) {
checkSemanticdb := {
assertSemanticdbForScala2.value
Expand Down
13 changes: 10 additions & 3 deletions tests/unit/src/main/scala/tests/QuickBuild.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,16 @@ case class QuickBuild(
}
val classpath = classDirectory :: allJars.filterNot(isSourceJar)
val allPlugins =
if (ScalaVersions.isSupportedAtReleaseMomentScalaVersion(scalaVersion))
s"org.scalameta:::semanticdb-scalac:${V.semanticdbVersion}" :: compilerPlugins.toList
else compilerPlugins.toList
if (
ScalaVersions.isSupportedAtReleaseMomentScalaVersion(
scalaVersion
) && !ScalaVersions.isScala3Version(scalaVersion)
) {
val semanticdbVersion = BuildInfoVersions.lastSupportedSemanticdb(
scalaVersion
)
s"org.scalameta:::semanticdb-scalac:$semanticdbVersion" :: compilerPlugins.toList
} else compilerPlugins.toList
val pluginDependencies = allPlugins.map(plugin =>
QuickBuild
.toDependency(plugin, scalaVersion, binaryVersion)
Expand Down
58 changes: 29 additions & 29 deletions tests/unit/src/test/scala/tests/FormattingLspSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -378,18 +378,18 @@ class FormattingLspSuite extends BaseLspSuite("formatting") {
}
for {
_ <- initialize(
"""|/metals.json
|{
| "a": {
| "scalaVersion": "2.13.6",
| "scalacOptions": ["-Xsource:3"]
| }
|}
|/.scalafmt.conf
|version = "2.7.5"
|/a/src/main/scala/A.scala
|object A
|""".stripMargin
s"""|/metals.json
|{
| "a": {
| "scalaVersion": "${V.scala213}",
| "scalacOptions": ["-Xsource:3"]
| }
|}
|/.scalafmt.conf
|version = "2.7.5"
|/a/src/main/scala/A.scala
|object A
|""".stripMargin
)
_ = assertNoDiff(
server.textContents(".scalafmt.conf"),
Expand Down Expand Up @@ -447,23 +447,23 @@ class FormattingLspSuite extends BaseLspSuite("formatting") {
}
for {
_ <- initialize(
"""|/metals.json
|{
| "a": {
| "scalaVersion": "3.0.0"
| },
| "b" : {
| "scalaVersion": "2.13.5",
| "scalacOptions": ["-Xsource:3"]
| }
|}
|/.scalafmt.conf
|version = "2.7.5"
|/a/src/main/scala/A.scala
|object A
|/b/src/main/scala/B.scala
|object B
|""".stripMargin
s"""|/metals.json
|{
| "a": {
| "scalaVersion": "3.0.0"
| },
| "b" : {
| "scalaVersion": "${V.scala213}",
| "scalacOptions": ["-Xsource:3"]
| }
|}
|/.scalafmt.conf
|version = "2.7.5"
|/a/src/main/scala/A.scala
|object A
|/b/src/main/scala/B.scala
|object B
|""".stripMargin
)
_ = assertNoDiff(
server.textContents(".scalafmt.conf"),
Expand Down

0 comments on commit 6089338

Please sign in to comment.