mirror of https://github.com/sbt/sbt.git
[2.x] wip: Save working state before refactoring to plugin approach
Working but architecturally wrong - logic in Defaults.scala instead of BestEffortPlugin. Saving state before refactoring to proper plugin pattern (option 1).
This commit is contained in:
parent
69e958bbc6
commit
a8b706925b
|
|
@ -204,6 +204,7 @@ object Defaults extends BuildCommon with DefExtra {
|
|||
testForkedParallelism :== None,
|
||||
javaOptions :== Nil,
|
||||
sbtPlugin :== false,
|
||||
bestEffortEnabled :== internal.SysProp.bestEffort,
|
||||
isMetaBuild :== false,
|
||||
reresolveSbtArtifacts :== false,
|
||||
crossPaths :== true,
|
||||
|
|
@ -694,7 +695,6 @@ object Defaults extends BuildCommon with DefExtra {
|
|||
case vf: VirtualFile => vf
|
||||
},
|
||||
semanticdbTargetRoot := target.value / (prefix(configuration.value.name) + "meta"),
|
||||
bestEffortTargetRoot := target.value / (prefix(configuration.value.name) + "betasty"),
|
||||
compileAnalysisTargetRoot := target.value / (prefix(configuration.value.name) + "zinc"),
|
||||
earlyCompileAnalysisTargetRoot := target.value / (prefix(
|
||||
configuration.value.name
|
||||
|
|
@ -1079,6 +1079,12 @@ object Defaults extends BuildCommon with DefExtra {
|
|||
then old ++ Seq("-Wconf:cat=unused-nowarn:s", "-Xsource:3")
|
||||
else old
|
||||
},
|
||||
scalacOptions := {
|
||||
val old = scalacOptions.value
|
||||
if bestEffortEnabled.value && plugins.BestEffortPlugin.isScala35Plus(scalaVersion.value)
|
||||
then old ++ Seq("-Ybest-effort", "-Ywith-best-effort-tasty")
|
||||
else old
|
||||
},
|
||||
persistJarClasspath :== true,
|
||||
classpathEntryDefinesClassVF := Def.uncached {
|
||||
val cache =
|
||||
|
|
|
|||
|
|
@ -258,8 +258,6 @@ object Keys {
|
|||
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 bestEffortTargetRoot = settingKey[File]("The output directory for Best Effort TASTy (.betasty) files").withRank(CSetting)
|
||||
val bestEffortOptions = settingKey[Seq[String]]("The Scalac options introduced for Best Effort compilation").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)
|
||||
|
|
|
|||
|
|
@ -9,99 +9,25 @@
|
|||
package sbt
|
||||
package plugins
|
||||
|
||||
import java.io.File
|
||||
|
||||
import Keys.*
|
||||
import sbt.internal.SysProp
|
||||
import sbt.librarymanagement.syntax.*
|
||||
import sbt.librarymanagement.Configuration
|
||||
import ProjectExtra.inConfig
|
||||
import sbt.internal.inc.ScalaInstance
|
||||
import sbt.ScopeFilter.Make.*
|
||||
import sbt.util.CacheImplicits.given
|
||||
|
||||
/**
|
||||
* An AutoPlugin that wires Scala 3's Best Effort compilation into sbt.
|
||||
*
|
||||
* When `bestEffortEnabled` is true and the project uses Scala 3.5+,
|
||||
* the plugin appends `-Ybest-effort` and `-Ybest-effort-dir` to scalacOptions
|
||||
* so that the compiler produces .betasty files even when compilation fails.
|
||||
* These files are consumed by IDEs such as Metals for improved code intelligence.
|
||||
* `-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 = JvmPlugin
|
||||
override def trigger = allRequirements
|
||||
|
||||
override lazy val globalSettings: Seq[Def.Setting[?]] = Seq(
|
||||
bestEffortEnabled := SysProp.bestEffort,
|
||||
bestEffortOptions := List(),
|
||||
)
|
||||
|
||||
override lazy val projectSettings: Seq[Def.Setting[?]] = Seq(
|
||||
bestEffortOptions ++= {
|
||||
val enabled = bestEffortEnabled.value
|
||||
val sv = scalaVersion.value
|
||||
if enabled && isScala35Plus(sv) then Seq("-Ybest-effort")
|
||||
else Nil
|
||||
},
|
||||
) ++
|
||||
inConfig(Compile)(configurationSettings) ++
|
||||
inConfig(Test)(configurationSettings)
|
||||
|
||||
lazy val configurationSettings: Seq[Def.Setting[?]] = List(
|
||||
compileIncremental := Def.taskIf {
|
||||
if !bestEffortEnabled.value then compileIncremental.value
|
||||
else compileIncAndCacheBestEffortTargetRootTask.value
|
||||
}.value,
|
||||
bestEffortOptions --= Def.settingDyn {
|
||||
val scalaV = scalaVersion.value
|
||||
val config = configuration.value
|
||||
Def.setting {
|
||||
bestEffortTargetRoot.?.all(ancestorConfigs(config)).value.flatten
|
||||
.flatMap(targetRootOptions(scalaV, _))
|
||||
}
|
||||
}.value,
|
||||
bestEffortOptions ++=
|
||||
targetRootOptions(scalaVersion.value, bestEffortTargetRoot.value),
|
||||
scalacOptions := (Def.taskDyn {
|
||||
val orig = scalacOptions.value
|
||||
val config = configuration.value
|
||||
if bestEffortEnabled.value then
|
||||
Def.task {
|
||||
(orig diff bestEffortOptions.?.all(ancestorConfigs(config)).value.flatten.flatten) ++
|
||||
bestEffortOptions.value
|
||||
}
|
||||
else
|
||||
Def.task {
|
||||
orig
|
||||
}
|
||||
}).value,
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
def targetRootOptions(scalaVersion: String, targetRoot: File): Seq[String] =
|
||||
if isScala35Plus(scalaVersion) then
|
||||
Seq("-Ybest-effort-dir", targetRoot.toString)
|
||||
else Nil
|
||||
|
||||
private val compileIncAndCacheBestEffortTargetRootTask = Def.cachedTask {
|
||||
val prev = compileIncremental.value
|
||||
val converter = fileConverter.value
|
||||
val targetRoot = bestEffortTargetRoot.value
|
||||
|
||||
val vfTargetRoot = converter.toVirtualFile(targetRoot.toPath)
|
||||
Def.declareOutputDirectory(vfTargetRoot)
|
||||
prev
|
||||
}
|
||||
|
||||
private def ancestorConfigs(config: Configuration) =
|
||||
def ancestors(configs: Vector[Configuration]): Vector[Configuration] =
|
||||
configs ++ configs.flatMap(conf => ancestors(conf.extendsConfigs))
|
||||
ScopeFilter(configurations = inConfigurations(ancestors(config.extendsConfigs)*))
|
||||
end BestEffortPlugin
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
# Step 1: Verify best effort flags appear in scalacOptions for Scala 3.5+
|
||||
> show Compile / scalacOptions
|
||||
# Step 1: Compile succeeds with best effort enabled (Scala 3.5+)
|
||||
> compile
|
||||
|
||||
# Step 2: Introduce a type error — compile should fail but produce .betasty
|
||||
# Step 2: Introduce a type error — compile should fail
|
||||
$ copy-file changes/ErrorFile.scala src/main/scala/A.scala
|
||||
-> compile
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue