diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala index c7a05fe2f284..863909066161 100644 --- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala +++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala @@ -604,10 +604,12 @@ private class ExtractAPICollector(using Context) extends ThunkHolder { // In the Scala2 ExtractAPI phase we only extract annotations that extend // StaticAnnotation, but in Dotty we currently pickle all annotations so we - // extract everything (except inline body annotations which are handled - // above). - s.annotations.filter(_.symbol != defn.BodyAnnot) foreach { annot => - annots += apiAnnotation(annot) + // extract everything (except annotations missing from the classpath which + // we simply skip over, and inline body annotations which are handled above). + s.annotations.foreach { annot => + val sym = annot.symbol + if sym.exists && sym != defn.BodyAnnot then + annots += apiAnnotation(annot) } annots.toList diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/A.scala b/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/A.scala new file mode 100644 index 000000000000..77ab340e6e4a --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/A.scala @@ -0,0 +1,4 @@ +class A { + @JavaAnnot def foo: Int = 1 + @ScalaAnnot def bar: Int = 1 +} diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/JavaAnnot.java b/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/JavaAnnot.java new file mode 100644 index 000000000000..745105f178ea --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/JavaAnnot.java @@ -0,0 +1,3 @@ +import java.lang.annotation.*; + +public @interface JavaAnnot {} diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/ScalaAnnot.scala b/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/ScalaAnnot.scala new file mode 100644 index 000000000000..8b0ee32e9dbd --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/a/ScalaAnnot.scala @@ -0,0 +1 @@ +class ScalaAnnot extends scala.annotation.StaticAnnotation diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/b/B.scala b/sbt-dotty/sbt-test/source-dependencies/missing-annot/b/B.scala new file mode 100644 index 000000000000..a18aec3dbe9b --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/b/B.scala @@ -0,0 +1 @@ +class B extends A diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/build.sbt b/sbt-dotty/sbt-test/source-dependencies/missing-annot/build.sbt new file mode 100644 index 000000000000..350b46c7b27b --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/build.sbt @@ -0,0 +1,9 @@ +lazy val a = project.in(file("a")) + .settings( + Compile / classDirectory := (ThisBuild / baseDirectory).value / "a-output" + ) + +lazy val b = project.in(file("b")) + .settings( + Compile / unmanagedClasspath += (ThisBuild / baseDirectory).value / "b-input" + ) diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/project/DottyInjectedPlugin.scala b/sbt-dotty/sbt-test/source-dependencies/missing-annot/project/DottyInjectedPlugin.scala new file mode 100644 index 000000000000..fb946c4b8c61 --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/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-dotty/sbt-test/source-dependencies/missing-annot/project/plugins.sbt b/sbt-dotty/sbt-test/source-dependencies/missing-annot/project/plugins.sbt new file mode 100644 index 000000000000..c17caab2d98c --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version")) diff --git a/sbt-dotty/sbt-test/source-dependencies/missing-annot/test b/sbt-dotty/sbt-test/source-dependencies/missing-annot/test new file mode 100644 index 000000000000..1e8071204c47 --- /dev/null +++ b/sbt-dotty/sbt-test/source-dependencies/missing-annot/test @@ -0,0 +1,8 @@ +> a/compile +$ mkdir b-input +# Add A to the classpath of b but not the annotations referenced by the members of A +$ copy-file a-output/A.class b-input/A.class +$ copy-file a-output/A.tasty b-input/A.tasty +# B should still be able to compile even though ExtractAPI forces the +# annotations of all inherited members. +> b/compile