-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix #19951: Align TASTy with the Java annotation model.
Scala annotations are classes, with a real constructor, which has a real signature where order is relevant but names are irrelevant. On the contrary, Java annotations are interfaces, without any real constructors. The names of "fields" are relevant, whereas their order is irrelevant. As illustrated by #19951, trying to shoehorn Java annotations into the Scala annotation model is not sustainable, and breaks in real ways. Therefore, in this commit we align how Java annotations are stored in TASTy with the Java annotation model. During pickling: * Selection of the constructor is pickled without a signature. * Default arguments are dropped. * (Due to the parent commit, all arguments are `NamedArg`s at this point.) During unpickling: * Selection of the constructor resolves to the unique constructor (instead of complaining because a signature-less `SELECT` should not resolve to a member with a signature). * Arguments to the constructor are reordered and extended with defaults to match the target constructor; we can do this because all the arguments are `NamedArg`s. For backward compatibility, during unpickling: * If we read a `SELECTin` for a Java annotation constructor, we disregard its signature and pretend it was a `SELECT`. * We adapt arguments in best-effort way if not all of them are `NamedArg`s.
- Loading branch information
Showing
20 changed files
with
314 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
sbt-test/scala3-compat/java-annotations-3.4/app/Main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
object Test: | ||
def main(args: Array[String]): Unit = | ||
val actual = listAnnots("ScalaUser") | ||
val expected = List( | ||
"new JavaAnnot(a = 5, b = _, c = _)", | ||
"new JavaAnnot(a = 5, b = _, c = _)", | ||
"new JavaAnnot(a = 5, b = \"foo\", c = _)", | ||
"new JavaAnnot(a = 5, b = \"foo\", c = 3)", | ||
"new JavaAnnot(a = 5, b = _, c = 3)", | ||
"new JavaAnnot(a = 5, b = \"foo\", c = 3)", | ||
"new JavaAnnot(a = 5, b = \"foo\", c = 3)", | ||
"new JavaAnnot(a = 5, b = \"foo\", c = _)", | ||
) | ||
if actual != expected then | ||
println("Expected:") | ||
expected.foreach(println(_)) | ||
println("Actual:") | ||
actual.foreach(println(_)) | ||
throw new AssertionError("test failed") | ||
end main | ||
end Test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
lazy val lib = project.in(file("lib")) | ||
.settings( | ||
scalaVersion := "3.4.2" | ||
) | ||
|
||
lazy val app = project.in(file("app")) | ||
.dependsOn(lib) |
7 changes: 7 additions & 0 deletions
7
sbt-test/scala3-compat/java-annotations-3.4/lib/AnnotMacro.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import scala.quoted.* | ||
|
||
inline def listAnnots(inline c: String): List[String] = ${ listAnnotsImpl('c) } | ||
|
||
def listAnnotsImpl(c: Expr[String])(using Quotes): Expr[List[String]] = | ||
import quotes.reflect.* | ||
Expr(Symbol.requiredClass(c.valueOrError).declaredMethods.flatMap(_.annotations.map(_.show))) |
10 changes: 10 additions & 0 deletions
10
sbt-test/scala3-compat/java-annotations-3.4/lib/JavaAnnot.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
@interface JavaAnnot { | ||
int a(); | ||
String b() default "empty"; | ||
int c() default 5; | ||
} |
25 changes: 25 additions & 0 deletions
25
sbt-test/scala3-compat/java-annotations-3.4/lib/ScalaUser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class ScalaUser { | ||
@JavaAnnot(5) | ||
def f1(): Int = 1 | ||
|
||
@JavaAnnot(a = 5) | ||
def f2(): Int = 1 | ||
|
||
@JavaAnnot(5, "foo") | ||
def f3(): Int = 1 | ||
|
||
@JavaAnnot(5, "foo", 3) | ||
def f4(): Int = 1 | ||
|
||
@JavaAnnot(5, c = 3) | ||
def f5(): Int = 1 | ||
|
||
@JavaAnnot(5, c = 3, b = "foo") | ||
def f6(): Int = 1 | ||
|
||
@JavaAnnot(b = "foo", c = 3, a = 5) | ||
def f7(): Int = 1 | ||
|
||
@JavaAnnot(b = "foo", a = 5) | ||
def f8(): Int = 1 | ||
} |
11 changes: 11 additions & 0 deletions
11
sbt-test/scala3-compat/java-annotations-3.4/project/DottyInjectedPlugin.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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") | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
> app/run |
11 changes: 11 additions & 0 deletions
11
tests/run-macros/i19951-java-annotations-tasty-compat-2/AnnotMacro_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import scala.quoted.* | ||
|
||
inline def showAnnots(inline c: String): Unit = ${ showAnnotsImpl('c) } | ||
|
||
def showAnnotsImpl(c: Expr[String])(using Quotes): Expr[Unit] = | ||
import quotes.reflect.* | ||
val al = Expr(Symbol.requiredClass(c.valueOrError).declaredMethods.flatMap(_.annotations.map(_.show))) | ||
'{ | ||
println($c + ":") | ||
$al.foreach(println) | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/run-macros/i19951-java-annotations-tasty-compat-2/JavaAnnot_1.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
@interface JavaAnnot { | ||
int a(); | ||
String b() default "empty"; | ||
int c() default 5; | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/run-macros/i19951-java-annotations-tasty-compat-2/JavaAnnot_2.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
@interface JavaAnnot { | ||
int c() default 5; | ||
int a(); | ||
int d() default 42; | ||
String b() default "empty"; | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/run-macros/i19951-java-annotations-tasty-compat-2/ScalaUser_1.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class ScalaUser { | ||
@JavaAnnot(5) | ||
def f1(): Int = 1 | ||
|
||
@JavaAnnot(a = 5) | ||
def f2(): Int = 1 | ||
|
||
@JavaAnnot(5, "foo") | ||
def f3(): Int = 1 | ||
|
||
@JavaAnnot(5, "foo", 3) | ||
def f4(): Int = 1 | ||
|
||
@JavaAnnot(5, c = 3) | ||
def f5(): Int = 1 | ||
|
||
@JavaAnnot(5, c = 3, b = "foo") | ||
def f6(): Int = 1 | ||
|
||
@JavaAnnot(b = "foo", c = 3, a = 5) | ||
def f7(): Int = 1 | ||
|
||
@JavaAnnot(b = "foo", a = 5) | ||
def f8(): Int = 1 | ||
} |
4 changes: 4 additions & 0 deletions
4
tests/run-macros/i19951-java-annotations-tasty-compat-2/Test_2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
object Test { | ||
def main(args: Array[String]): Unit = | ||
showAnnots("ScalaUser") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
ScalaUser: | ||
new JavaAnnot(c = _, a = 5, d = _, b = _) | ||
new JavaAnnot(c = _, a = 5, d = _, b = _) | ||
new JavaAnnot(c = _, a = 5, d = _, b = "foo") | ||
new JavaAnnot(c = 3, a = 5, d = _, b = "foo") | ||
new JavaAnnot(c = 3, a = 5, d = _, b = _) | ||
new JavaAnnot(c = 3, a = 5, d = _, b = "foo") | ||
new JavaAnnot(c = 3, a = 5, d = _, b = "foo") | ||
new JavaAnnot(c = _, a = 5, d = _, b = "foo") |
11 changes: 11 additions & 0 deletions
11
tests/run-macros/i19951-java-annotations-tasty-compat/AnnotMacro_2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import scala.quoted.* | ||
|
||
inline def showAnnots(inline c: String): Unit = ${ showAnnotsImpl('c) } | ||
|
||
def showAnnotsImpl(c: Expr[String])(using Quotes): Expr[Unit] = | ||
import quotes.reflect.* | ||
val al = Expr(Symbol.requiredClass(c.valueOrError).declaredMethods.flatMap(_.annotations.map(_.show))) | ||
'{ | ||
println($c + ":") | ||
$al.foreach(println) | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/run-macros/i19951-java-annotations-tasty-compat/JavaAnnot_1.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
@interface JavaAnnot { | ||
int a(); | ||
String b() default "empty"; | ||
int c() default 5; | ||
} |
11 changes: 11 additions & 0 deletions
11
tests/run-macros/i19951-java-annotations-tasty-compat/JavaAnnot_3.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
import java.lang.annotation.*; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
@interface JavaAnnot { | ||
int c() default 5; | ||
int a(); | ||
int d() default 42; | ||
String b() default "empty"; | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/run-macros/i19951-java-annotations-tasty-compat/ScalaUser_2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
class ScalaUser { | ||
@JavaAnnot(5) | ||
def f1(): Int = 1 | ||
|
||
@JavaAnnot(a = 5) | ||
def f2(): Int = 1 | ||
|
||
@JavaAnnot(5, "foo") | ||
def f3(): Int = 1 | ||
|
||
@JavaAnnot(5, "foo", 3) | ||
def f4(): Int = 1 | ||
|
||
@JavaAnnot(5, c = 3) | ||
def f5(): Int = 1 | ||
|
||
@JavaAnnot(5, c = 3, b = "foo") | ||
def f6(): Int = 1 | ||
|
||
@JavaAnnot(b = "foo", c = 3, a = 5) | ||
def f7(): Int = 1 | ||
|
||
@JavaAnnot(b = "foo", a = 5) | ||
def f8(): Int = 1 | ||
} |
4 changes: 4 additions & 0 deletions
4
tests/run-macros/i19951-java-annotations-tasty-compat/Test_4.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
object Test { | ||
def main(args: Array[String]): Unit = | ||
showAnnots("ScalaUser") | ||
} |