diff --git a/sbt-test/pipelining/pipelining-changes/build.sbt b/sbt-test/pipelining/pipelining-changes/build.sbt new file mode 100644 index 000000000000..630bd4be5b3e --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/build.sbt @@ -0,0 +1,27 @@ +import sbt.internal.inc.Analysis +import complete.DefaultParsers._ + +ThisBuild / usePipelining := true + +// Reset compiler iterations, necessary because tests run in batch mode +val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") +recordPreviousIterations := { + val log = streams.value.log + CompileState.previousIterations = { + val previousAnalysis = (previousCompile in Compile).value.analysis.asScala + previousAnalysis match { + case None => + log.info("No previous analysis detected") + 0 + case Some(a: Analysis) => a.compilations.allCompilations.size + } + } +} + +val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.") + +checkIterations := { + val expected: Int = (Space ~> NatBasic).parsed + val actual: Int = ((compile in Compile).value match { case a: Analysis => a.compilations.allCompilations.size }) - CompileState.previousIterations + assert(expected == actual, s"Expected $expected compilations, got $actual (previous: ${CompileState.previousIterations})") +} diff --git a/sbt-test/pipelining/pipelining-changes/changes/A1.scala b/sbt-test/pipelining/pipelining-changes/changes/A1.scala new file mode 100644 index 000000000000..db5605e419d1 --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/changes/A1.scala @@ -0,0 +1,5 @@ +package a + +enum A { + case A, B +} diff --git a/sbt-test/pipelining/pipelining-changes/project/CompileState.scala b/sbt-test/pipelining/pipelining-changes/project/CompileState.scala new file mode 100644 index 000000000000..078db9c7bf56 --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/project/CompileState.scala @@ -0,0 +1,4 @@ +// This is necessary because tests are run in batch mode +object CompileState { + @volatile var previousIterations: Int = -1 +} diff --git a/sbt-test/pipelining/pipelining-changes/project/DottyInjectedPlugin.scala b/sbt-test/pipelining/pipelining-changes/project/DottyInjectedPlugin.scala new file mode 100644 index 000000000000..1c6c00400f04 --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/project/DottyInjectedPlugin.scala @@ -0,0 +1,11 @@ +import sbt._ +import Keys._ + +object DottyInjectedPlugin extends AutoPlugin { + override def requires = plugins.JvmPlugin + override def trigger = allRequirements + + override val projectSettings = Seq( + scalaVersion := sys.props("plugin.scalaVersion"), + ) +} diff --git a/sbt-test/pipelining/pipelining-changes/src/main/scala/a/A.scala b/sbt-test/pipelining/pipelining-changes/src/main/scala/a/A.scala new file mode 100644 index 000000000000..4a0eec46ec7e --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/src/main/scala/a/A.scala @@ -0,0 +1,5 @@ +package a + +enum A { + case A +} diff --git a/sbt-test/pipelining/pipelining-changes/src/main/scala/a/App.scala b/sbt-test/pipelining/pipelining-changes/src/main/scala/a/App.scala new file mode 100644 index 000000000000..a9862cea9dc4 --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/src/main/scala/a/App.scala @@ -0,0 +1,11 @@ +package a + +import scala.deriving.Mirror + +object App { + val m = summon[Mirror.SumOf[a.A]] + def size = compiletime.constValue[Tuple.Size[m.MirroredElemTypes]] + + @main def test = + assert(size == 2, s"Expected size 2, got $size") +} diff --git a/sbt-test/pipelining/pipelining-changes/test b/sbt-test/pipelining/pipelining-changes/test new file mode 100644 index 000000000000..e6fb01d57f5a --- /dev/null +++ b/sbt-test/pipelining/pipelining-changes/test @@ -0,0 +1,7 @@ +# test the interaction of incremental compilation and pipelining +> compile +> recordPreviousIterations +$ copy-file changes/A1.scala src/main/scala/a/A.scala +# A recompilation should trigger recompilation of App.scala, otherwise test assert will fail +> run +> checkIterations 2