diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-10-20 14:03:43 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-10-20 14:09:12 +0200 |
commit | fa40ff3cd5edbf54eb2c77170f8d59861b372a5a (patch) | |
tree | 92554fd939ff73e785787c180cd38371e20d36d6 /test/junit | |
parent | 2b5df373638d08204b71258928289f6b39e25d5f (diff) | |
download | scala-fa40ff3cd5edbf54eb2c77170f8d59861b372a5a.tar.gz scala-fa40ff3cd5edbf54eb2c77170f8d59861b372a5a.tar.bz2 scala-fa40ff3cd5edbf54eb2c77170f8d59861b372a5a.zip |
SI-8926 default visbility RUNTIME for java annotations
When parsed from source, java annotation class symbol are lacking the
`@Retention` annotation. In mixed compilation, java annotations are
therefore emitted with visibility CLASS.
This patch conservatively uses the RUNTIME visibility in case there is
no @Retention annotation.
The real solution is to fix the Java parser, logged in SI-8928.
Diffstat (limited to 'test/junit')
-rw-r--r-- | test/junit/scala/issues/BytecodeTests.scala | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/test/junit/scala/issues/BytecodeTests.scala b/test/junit/scala/issues/BytecodeTests.scala index 7a05472277..d4ed063a03 100644 --- a/test/junit/scala/issues/BytecodeTests.scala +++ b/test/junit/scala/issues/BytecodeTests.scala @@ -4,6 +4,7 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.junit.Test import scala.tools.asm.Opcodes +import scala.tools.nsc.backend.jvm.AsmUtils import scala.tools.nsc.backend.jvm.CodeGenTools._ import org.junit.Assert._ import scala.collection.JavaConverters._ @@ -36,4 +37,44 @@ class BytecodeTests { assertTrue(getSingleMethod(c, "f").instructions.count(_.isInstanceOf[TableSwitch]) == 1) assertTrue(getSingleMethod(c, "g").instructions.count(_.isInstanceOf[LookupSwitch]) == 1) } + + @Test + def t8926(): Unit = { + import scala.reflect.internal.util.BatchSourceFile + + // this test cannot be implemented using partest because of its mixed-mode compilation strategy: + // partest first compiles all files with scalac, then the java files, and then again the scala + // using the output classpath. this shadows the bug SI-8926. + + val annotA = + """import java.lang.annotation.Retention; + |import java.lang.annotation.RetentionPolicy; + |@Retention(RetentionPolicy.RUNTIME) + |public @interface AnnotA { } + """.stripMargin + val annotB = "public @interface AnnotB { }" + + val scalaSrc = + """@AnnotA class A + |@AnnotB class B + """.stripMargin + + val compiler = newCompiler() + val run = new compiler.Run() + run.compileSources(List(new BatchSourceFile("AnnotA.java", annotA), new BatchSourceFile("AnnotB.java", annotB), new BatchSourceFile("Test.scala", scalaSrc))) + val outDir = compiler.settings.outputDirs.getSingleOutput.get + val outfiles = (for (f <- outDir.iterator if !f.isDirectory) yield (f.name, f.toByteArray)).toList + + def check(classfile: String, annotName: String) = { + val f = (outfiles collect { case (`classfile`, bytes) => AsmUtils.readClass(bytes) }).head + val descs = f.visibleAnnotations.asScala.map(_.desc).toList + assertTrue(descs.toString, descs exists (_ contains annotName)) + } + + check("A.class", "AnnotA") + + // known issue SI-8928: the visibility of AnnotB should be CLASS, but annotation classes without + // a @Retention annotation are currently emitted as RUNTIME. + check("B.class", "AnnotB") + } } |