-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Meta-annotations written at use-site are ignored #12492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
can someone hint me as to where the parsing of the constructor params is done? I could perhaps try to understand where the problem lies in the code. |
@bchazalet I don't think this is a parsing issue, the annotation shows up with sbt:scala3> run -Xprint:typer /tmp/foo.java /tmp/bar.scala
[info] running (fork) dotty.tools.dotc.Main -classpath /home/olivier/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.5/scala-library-2.13.5.jar:/home/olivier/workspace/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.0.1-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.0.1-RC1-bin-SNAPSHOT.jar -Xprint:typer /tmp/foo.java /tmp/bar.scala
result of /tmp/bar.scala after typer:
package <empty> {
import annotation.meta.field
class MyTable(@MyColumn(_, name = "BRAND_NAME") brandName: String) extends
Object
() {
@MyColumn(_, name = "BRAND_NAME") val brandName: String
@MyColumn(_, name = "WEIGHT") val weightInGrams: Option[String] = None
}
final lazy module val bar$package: bar$package$ = new bar$package$()
final module class bar$package$() extends Object() { this: bar$package.type =>
type MyColumn = MyColumnBase @annotation.meta.field()
@main() def test: Unit =
{
val clasz: Class[MyTable] = classOf[MyTable]
refArrayOps[java.lang.reflect.Field](clasz.getDeclaredFields()).foreach[
Unit
](
{
def $anonfun(m: java.lang.reflect.Field): Unit =
{
m.setAccessible(true)
if
m.getName().==("weightInGrams").||(m.getName().==("brandName")
)
then
{
println(
_root_.scala.StringContext.apply(
["inspecting field ","" : String]*
).s([m.getName() : Any]*)
)
if
refArrayOps[java.lang.annotation.Annotation](
m.getAnnotations()
).size.==(1).unary_!
then
scala.runtime.Scala3RunTime.assertFailed(
_root_.scala.StringContext.apply(
["no annotation found for ","" : String]*
).s([m.getName() : Any]*)
)
else ()
}
else ()
}
closure($anonfun)
}
)
}
}
final class test() extends Object() {
<static> def main(args: Array[String]): Unit =
try test catch
{
case error @ _:scala.util.CommandLineParser.ParseError =>
scala.util.CommandLineParser.showError(error)
}
}
} |
thanks for the info @OlivierBlanvillain. Is there somewhere I can find the order of the different phases so that I can maybe try to identify in which one it gets 'lost'? |
I found the useful result of /tmp/bar.scala after posttyper:
package <empty> {
import annotation.meta.field
@scala.annotation.internal.SourceFile("/tmp/bar.scala") class MyTable(
@MyColumn(_, name = "BRAND_NAME") brandName: String
) extends Object() {
val brandName: String
@MyColumn(_, name = "WEIGHT") val weightInGrams: Option[String] = None
}
final lazy module val bar$package: bar$package$ = new bar$package$()
@scala.annotation.internal.SourceFile("/tmp/bar.scala") final module class
bar$package$
() extends Object() { this: bar$package.type =>
private def writeReplace(): AnyRef =
new scala.runtime.ModuleSerializationProxy(classOf[bar$package.type])
type MyColumn = MyColumnBase @annotation.meta.field()
@main() def main(): Unit =
{
val clasz: Class[MyTable] = classOf[MyTable]
refArrayOps[java.lang.reflect.Field](clasz.getDeclaredFields()).foreach[
Unit
](
{
def $anonfun(m: java.lang.reflect.Field): Unit =
{
m.setAccessible(true)
if
m.getName().==("weightInGrams").||(m.getName().==("brandName")
)
then
{
println(
_root_.scala.StringContext.apply(
["inspecting field ","" : String]*
).s([m.getName() : Any]*)
)
if
refArrayOps[java.lang.annotation.Annotation](
m.getAnnotations()
).size.==(1).unary_!
then
scala.runtime.Scala3RunTime.assertFailed(
_root_.scala.StringContext.apply(
["no annotation found for ","" : String]*
).s([m.getName() : Any]*)
)
else ()
}
else ()
}
closure($anonfun)
}
)
}
}
@scala.annotation.internal.SourceFile("/tmp/bar.scala") final class main()
extends
Object() {
<static> def main(args: Array[String]): Unit =
try main() catch
{
case error @ _:scala.util.CommandLineParser.ParseError =>
scala.util.CommandLineParser.showError(error)
}
}
} The annotation doesn't disappear, it's still there on the constructor param but it is not set on the |
The issue is that we look for meta-annotations on the symbol definition (https://github.com/lampepfl/dotty/blob/a956774180d124adc98527863b919c35d5f9db92/compiler/src/dotty/tools/dotc/transform/PostTyper.scala#L158, https://github.com/lampepfl/dotty/blob/a956774180d124adc98527863b919c35d5f9db92/compiler/src/dotty/tools/dotc/transform/Memoize.scala#L112), whereas here the meta-annotation |
@smarter does that explain why it works for |
In that case the meta-annotation isn't needed since we're directly annotating a field (from https://www.scala-lang.org/api/current/scala/annotation/meta/index.html):
|
I'm not sure if this test case is related but annotation in this example seems to be ignored by the Scala3 compiler (while it is handled by Scala2 compiler).
Scala 2.13.7: https://scastie.scala-lang.org/0JhMWXbvQPKbcNZjqALHAg (final println shows the 1 expected annotation) |
Same thing yes. |
Workaround issue with annotations covered by scala/scala3#12492, fixed with scala/scala3#16445 This commit can be reverted as soon as the fix is released (according to https://github.com/lampepfl/dotty/releases this is not yet the case)
Workaround issue with annotations covered by scala/scala3#12492, fixed with scala/scala3#16445 This commit can be reverted as soon as the fix is released (according to https://github.com/lampepfl/dotty/releases this is not yet the case)
Workaround issue with annotations covered by scala/scala3#12492, fixed with scala/scala3#16445 This commit can be reverted as soon as the fix is released (according to https://github.com/lampepfl/dotty/releases this is not yet the case)
Compiler version
3.0.0
Minimized code
This is an issue I've encountered while trying to port squeryl to scala 3.
In a
MyColumnBase.java
file:and in a scala file:
Output
Expectation
I would expect to see the annotation on the field
brandName
. In scala 2.13, I can at least.The text was updated successfully, but these errors were encountered: