mirror of https://github.com/sbt/sbt.git
Merge fa20dd618b into 8bcc6ae420
This commit is contained in:
commit
036ccaef4f
|
|
@ -257,6 +257,7 @@ object Keys {
|
|||
val semanticdbIncludeInJar = settingKey[Boolean]("Include *.semanticdb files in published artifacts").withRank(CSetting)
|
||||
val semanticdbTargetRoot = settingKey[File]("The output directory to produce META-INF/semanticdb/**/*.semanticdb files").withRank(CSetting)
|
||||
val semanticdbOptions = settingKey[Seq[String]]("The Scalac options introduced for SemanticDB").withRank(CSetting)
|
||||
val bestEffortEnabled = settingKey[Boolean]("Enables Scala 3 Best Effort compilation to produce .betasty files").withRank(CSetting)
|
||||
|
||||
val clean = taskKey[Unit]("Deletes files produced by the build, such as generated sources, compiled classes, and task caches.").withRank(APlusTask)
|
||||
val console = taskKey[Unit]("Starts the Scala interpreter with the project classes on the classpath.").withRank(APlusTask)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ object PluginDiscovery:
|
|||
"sbt.ScriptedPlugin" -> sbt.ScriptedPlugin,
|
||||
"sbt.plugins.SbtPlugin" -> sbt.plugins.SbtPlugin,
|
||||
"sbt.plugins.SemanticdbPlugin" -> sbt.plugins.SemanticdbPlugin,
|
||||
"sbt.plugins.BestEffortPlugin" -> sbt.plugins.BestEffortPlugin,
|
||||
"sbt.plugins.JUnitXmlReportPlugin" -> sbt.plugins.JUnitXmlReportPlugin,
|
||||
"sbt.plugins.Giter8TemplatePlugin" -> sbt.plugins.Giter8TemplatePlugin,
|
||||
"sbt.plugins.DependencyTreePlugin" -> sbt.plugins.DependencyTreePlugin,
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ object SysProp:
|
|||
def allowRootDir: Boolean = getOrFalse("sbt.rootdir")
|
||||
def legacyTestReport: Boolean = getOrFalse("sbt.testing.legacyreport")
|
||||
def semanticdb: Boolean = getOrFalse("sbt.semanticdb")
|
||||
def bestEffort: Boolean = getOrFalse("sbt.bestEffort")
|
||||
def forceServerStart: Boolean = getOrFalse("sbt.server.forcestart")
|
||||
def serverAutoStart: Boolean = getOrTrue("sbt.server.autostart")
|
||||
def remoteCache: Option[URI] = sys.props
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2023, Scala center
|
||||
* Copyright 2011 - 2022, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt
|
||||
package plugins
|
||||
|
||||
import Keys.*
|
||||
import sbt.internal.SysProp
|
||||
import sbt.librarymanagement.syntax.*
|
||||
import ProjectExtra.inConfig
|
||||
import sbt.internal.inc.ScalaInstance
|
||||
|
||||
/**
|
||||
* An AutoPlugin that wires Scala 3's Best Effort compilation into sbt.
|
||||
*
|
||||
* When `bestEffortEnabled` is true and the project uses Scala 3.5+,
|
||||
* `-Ybest-effort` and `-Ywith-best-effort-tasty` are appended to scalacOptions
|
||||
* so that the compiler produces .betasty files (to META-INF/best-effort/ inside classes)
|
||||
* even when compilation fails. These files are consumed by IDEs such as Metals
|
||||
* for improved code intelligence.
|
||||
*/
|
||||
object BestEffortPlugin extends AutoPlugin:
|
||||
override def requires = SemanticdbPlugin
|
||||
override def trigger = allRequirements
|
||||
|
||||
private val bestEffortFlags = Seq("-Ybest-effort", "-Ywith-best-effort-tasty")
|
||||
|
||||
override lazy val globalSettings: Seq[Def.Setting[?]] = Seq(
|
||||
bestEffortEnabled := SysProp.bestEffort,
|
||||
)
|
||||
|
||||
override lazy val projectSettings: Seq[Def.Setting[?]] =
|
||||
inConfig(Compile)(configurationSettings) ++
|
||||
inConfig(Test)(configurationSettings)
|
||||
|
||||
lazy val configurationSettings: Seq[Def.Setting[?]] = List(
|
||||
scalacOptions := {
|
||||
val orig = scalacOptions.value
|
||||
val enabled = bestEffortEnabled.value
|
||||
val sv = scalaVersion.value
|
||||
if enabled && isScala35Plus(sv) then
|
||||
(orig.filterNot(bestEffortFlags.contains) ++ bestEffortFlags).distinct
|
||||
else orig.filterNot(bestEffortFlags.contains)
|
||||
},
|
||||
)
|
||||
|
||||
private[sbt] def isScala35Plus(scalaVersion: String): Boolean =
|
||||
ScalaInstance.isDotty(scalaVersion) && {
|
||||
val versionPart = scalaVersion.stripPrefix("3.")
|
||||
val minor = versionPart.takeWhile(_.isDigit)
|
||||
minor.nonEmpty && minor.toInt >= 5
|
||||
}
|
||||
end BestEffortPlugin
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
scalaVersion := "3.6.4"
|
||||
bestEffortEnabled := true
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
object A {
|
||||
val x: Int = 1
|
||||
}
|
||||
//object B
|
||||
val error: Int = "not an int"
|
||||
object C {
|
||||
val z: Boolean = true
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
//object A
|
||||
object B {
|
||||
val y: String = "hello"
|
||||
}
|
||||
//error
|
||||
object C {
|
||||
val z: Boolean = true
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
object A {
|
||||
val x: Int = 1
|
||||
}
|
||||
object B {
|
||||
val y: String = "hello"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Step 1: Compile succeeds with best effort enabled (Scala 3.5+)
|
||||
> compile
|
||||
|
||||
# Step 2: Introduce a type error — compile should fail
|
||||
$ copy-file changes/ErrorFile.scala src/main/scala/A.scala
|
||||
-> compile
|
||||
|
||||
# Step 3: Fix the error — compile should succeed again
|
||||
$ copy-file changes/FixedFile.scala src/main/scala/A.scala
|
||||
> compile
|
||||
|
||||
# Step 4: Verify best effort flags are absent for Scala 2
|
||||
> set scalaVersion := "2.13.16"
|
||||
> show Compile / scalacOptions
|
||||
|
||||
# Step 5: Switch back to Scala 3 and verify flags are restored
|
||||
> set scalaVersion := "3.6.4"
|
||||
> show Compile / scalacOptions
|
||||
Loading…
Reference in New Issue