Skip to content

Commit

Permalink
Merge pull request #10617 from Friendseeker/sam
Browse files Browse the repository at this point in the history
Register inheritance relationship for SAM-type lambda [ci: last-only]
  • Loading branch information
lrytz committed Dec 7, 2023
2 parents 22fb9c4 + 04d6da1 commit 847554c
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 0 deletions.
2 changes: 2 additions & 0 deletions build.sbt
Expand Up @@ -948,6 +948,7 @@ def osgiTestProject(p: Project, framework: ModuleID) = p
// - `sbtTest/scripted source-dependencies/scalac-options` to run a single test
// - `set sbtTest/scriptedBufferLog := false` to see sbt log of test
// - add `> set logLevel := Level.Debug` to individual `test` script for debug output
// - uncomment `-agentlib:...` below to attach the debugger while running a test
lazy val sbtTest = project.in(file("test") / "sbt-test")
.enablePlugins(ScriptedPlugin)
.settings(disableDocs)
Expand All @@ -969,6 +970,7 @@ lazy val sbtTest = project.in(file("test") / "sbt-test")
"-Dplugin.scalaVersion=" + version.value,
"-Dsbt.boot.directory=" + (target.value / ".sbt-scripted").getAbsolutePath, // Workaround sbt/sbt#3469
"-Dscripted.common=" + (baseDirectory.value / "common.sbt.template").getAbsolutePath,
// "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005",
),

// Pass along ivy home and repositories settings to sbt instances run from the tests
Expand Down
11 changes: 11 additions & 0 deletions src/sbt-bridge/scala/tools/xsbt/Dependency.scala
Expand Up @@ -479,6 +479,17 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile with
val sym = if (tree.symbol.isModule) tree.symbol.moduleClass else tree.symbol
localToNonLocalClass.resolveNonLocal(sym)
super.traverse(tree)

case f: Function =>
f.attachments.get[SAMFunction].foreach { sam =>
addDependency(sam.samTp.typeSymbol)
// Not using addInheritanceDependency as it would incorrectly classify dependency as non-local
// ref: https://github.com/scala/scala/pull/10617/files#r1415226169
val from = resolveDependencySource
addClassDependency(_localInheritanceCache, processor.localInheritance, from, sam.samTp.typeSymbol)
}
super.traverse(tree)

case other => super.traverse(other)
}
}
Expand Down
@@ -0,0 +1,3 @@
trait A {
def foo(): Int
}
@@ -0,0 +1,3 @@
class B {
val f: A = () => 1
}
@@ -0,0 +1 @@
class C extends B
@@ -0,0 +1,3 @@
trait A {
def foo(): AnyVal
}
@@ -0,0 +1,24 @@
import sbt._
import Keys._

object ScriptedTestPlugin extends AutoPlugin {
override def requires = plugins.JvmPlugin
override def trigger = allRequirements

object autoImport {
val setup = taskKey[StateTransform]("setup scripted test")
val cacheId = AttributeKey[String]("cacheId")
}
import autoImport._

override val projectSettings = Seq(
scalaVersion := sys.props("plugin.scalaVersion"),
setup := {
IO.copyFile(Path(sys.props("scripted.common")).asFile, baseDirectory.value / "common.sbt")
val id = java.util.UUID.randomUUID().toString
StateTransform(_.put(cacheId, id))
},
// https://github.com/sbt/sbt/issues/7432
Compile / compileAnalysisFilename := (Compile / compileAnalysisFilename).value.dropRight(4) + "-" + state.value.get(cacheId).get + ".zip"
)
}
15 changes: 15 additions & 0 deletions test/sbt-test/source-dependencies/sam-local-inheritance/test
@@ -0,0 +1,15 @@
> setup; reload

> compile

> checkRecompilations 0 A B C

# change the SAM type
$ copy-file changes/A.scala A.scala

> compile

> checkIterations 3
> checkRecompilations 1 A
# SAM type change does not affect C, hence C should not be recompiled
> checkRecompilations 2 B
3 changes: 3 additions & 0 deletions test/sbt-test/source-dependencies/sam/A.scala
@@ -0,0 +1,3 @@
trait A {
def foo(): Int
}
3 changes: 3 additions & 0 deletions test/sbt-test/source-dependencies/sam/B.scala
@@ -0,0 +1,3 @@
class B {
val f: A = () => 1
}
3 changes: 3 additions & 0 deletions test/sbt-test/source-dependencies/sam/changes/A.scala
@@ -0,0 +1,3 @@
trait A {
def foo(): String
}
@@ -0,0 +1,24 @@
import sbt._
import Keys._

object ScriptedTestPlugin extends AutoPlugin {
override def requires = plugins.JvmPlugin
override def trigger = allRequirements

object autoImport {
val setup = taskKey[StateTransform]("setup scripted test")
val cacheId = AttributeKey[String]("cacheId")
}
import autoImport._

override val projectSettings = Seq(
scalaVersion := sys.props("plugin.scalaVersion"),
setup := {
IO.copyFile(Path(sys.props("scripted.common")).asFile, baseDirectory.value / "common.sbt")
val id = java.util.UUID.randomUUID().toString
StateTransform(_.put(cacheId, id))
},
// https://github.com/sbt/sbt/issues/7432
Compile / compileAnalysisFilename := (Compile / compileAnalysisFilename).value.dropRight(4) + "-" + state.value.get(cacheId).get + ".zip"
)
}
9 changes: 9 additions & 0 deletions test/sbt-test/source-dependencies/sam/test
@@ -0,0 +1,9 @@
> setup; reload

> compile

# change the SAM type
$ copy-file changes/A.scala A.scala

# Both A.scala and B.scala should be recompiled, producing a compile error
-> compile

0 comments on commit 847554c

Please sign in to comment.