diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-06-09 12:28:23 -0700 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-06-09 12:28:23 -0700 |
commit | 076e37bb67001fe3ca1e120c9c3ac63c1de5ea01 (patch) | |
tree | 954e62ce0998d6d69fd3a528521e866b757a7480 | |
parent | a9972cc7e851882b5e0b4d6d97ad951b012167c0 (diff) | |
parent | ac4e3ca19246ae3d983f99607b865c5ed3acb2b9 (diff) | |
download | scala-076e37bb67001fe3ca1e120c9c3ac63c1de5ea01.tar.gz scala-076e37bb67001fe3ca1e120c9c3ac63c1de5ea01.tar.bz2 scala-076e37bb67001fe3ca1e120c9c3ac63c1de5ea01.zip |
Merge pull request #2606 from JamesIry/2.10.x_classfile_52
Test for reading JDK 8 (classfile format 52) class files.
-rw-r--r-- | src/partest/scala/tools/partest/DirectTest.scala | 27 | ||||
-rw-r--r-- | test/files/run/classfile-format-51.scala | 8 | ||||
-rw-r--r-- | test/files/run/classfile-format-52.check | 2 | ||||
-rw-r--r-- | test/files/run/classfile-format-52.scala | 77 | ||||
-rw-r--r-- | test/files/run/t7398.scala | 11 |
5 files changed, 114 insertions, 11 deletions
diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala index e2dac2fd55..8fcaa6423c 100644 --- a/src/partest/scala/tools/partest/DirectTest.scala +++ b/src/partest/scala/tools/partest/DirectTest.scala @@ -6,6 +6,7 @@ package scala.tools.partest import scala.tools.nsc._ +import settings.ScalaVersion import io.Directory import util.{ SourceFile, BatchSourceFile, CommandLineParser } import reporters.{Reporter, ConsoleReporter} @@ -101,4 +102,30 @@ abstract class DirectTest extends App { final def log(msg: => Any) { if (isDebug) Console.err println msg } + + /** + * Run a test only if the current java version is at least the version specified. + */ + def testUnderJavaAtLeast[A](version: String)(yesRun: =>A) = new TestUnderJavaAtLeast(version, { yesRun }) + + class TestUnderJavaAtLeast[A](version: String, yesRun: => A) { + val javaVersion = System.getProperty("java.specification.version") + + // the "ScalaVersion" class parses Java specification versions just fine + val requiredJavaVersion = ScalaVersion(version) + val executingJavaVersion = ScalaVersion(javaVersion) + val shouldRun = executingJavaVersion >= requiredJavaVersion + val preamble = if (shouldRun) "Attempting" else "Doing fallback for" + + def logInfo() = log(s"$preamble java $version specific test under java version $javaVersion") + + /* + * If the current java version is at least 'version' then 'yesRun' is evaluated + * otherwise 'fallback' is + */ + def otherwise(fallback: =>A): A = { + logInfo() + if (shouldRun) yesRun else fallback + } + } } diff --git a/test/files/run/classfile-format-51.scala b/test/files/run/classfile-format-51.scala index 9b1e612f4f..378caa7936 100644 --- a/test/files/run/classfile-format-51.scala +++ b/test/files/run/classfile-format-51.scala @@ -112,12 +112,12 @@ object Driver { System.setErr(System.out) try { // this test is only valid under JDK 1.7+ - // cheat a little by using 'ScalaVersion' because it can parse java versions just as well - val requiredJavaVersion = ScalaVersion("1.7") - val executingJavaVersion = ScalaVersion(System.getProperty("java.specification.version")) - if (executingJavaVersion >= requiredJavaVersion) { + testUnderJavaAtLeast("1.7") { generateClass() compile() + () + } otherwise { + () } } finally diff --git a/test/files/run/classfile-format-52.check b/test/files/run/classfile-format-52.check new file mode 100644 index 0000000000..5d24ef03cc --- /dev/null +++ b/test/files/run/classfile-format-52.check @@ -0,0 +1,2 @@ +hello from publicMethod +hello from staticMethod diff --git a/test/files/run/classfile-format-52.scala b/test/files/run/classfile-format-52.scala new file mode 100644 index 0000000000..7afa09ae0b --- /dev/null +++ b/test/files/run/classfile-format-52.scala @@ -0,0 +1,77 @@ +import java.io.{File, FileOutputStream} + +import scala.tools.nsc.settings.ScalaVersion +import scala.tools.partest._ +import scala.tools.asm +import asm.{AnnotationVisitor, ClassWriter, FieldVisitor, Handle, MethodVisitor, Opcodes} +import Opcodes._ + +// This test ensures that we can read JDK 8 (classfile format 52) files, including those +// with default methods. To do that it first uses ASM to generate an interface called +// HasDefaultMethod. Then it runs a normal compile on Scala source that extends that +// interface. Any failure will be dumped to std out. +// +// By it's nature the test can only work on JDK 8+ because under JDK 7- the +// interface won't verify. +object Test extends DirectTest { + override def extraSettings: String = "-optimise -usejavacp -d " + testOutput.path + " -cp " + testOutput.path + + def generateInterface() { + val interfaceName = "HasDefaultMethod" + val methodType = "()Ljava/lang/String;" + + val cw = new ClassWriter(0) + cw.visit(52, ACC_PUBLIC+ACC_ABSTRACT+ACC_INTERFACE, interfaceName, null, "java/lang/Object", null) + + def createMethod(flags:Int, name: String) { + val method = cw.visitMethod(flags, name, methodType, null, null) + method.visitCode() + method.visitLdcInsn(s"hello from $name") + method.visitInsn(ARETURN) + method.visitMaxs(1, 1) + method.visitEnd() + } + + createMethod(ACC_PUBLIC, "publicMethod") + createMethod(ACC_PUBLIC+ACC_STATIC, "staticMethod") + createMethod(ACC_PRIVATE, "privateMethod") + + cw.visitEnd() + val bytes = cw.toByteArray() + + val fos = new FileOutputStream(new File(s"${testOutput.path}/$interfaceName.class")) + try + fos write bytes + finally + fos.close() + + } + + def code = +""" +class Driver extends HasDefaultMethod { + println(publicMethod()) + println(HasDefaultMethod.staticMethod()) +} +""" + + override def show(): Unit = { + // redirect err to out, for logging + val prevErr = System.err + System.setErr(System.out) + try { + // this test is only valid under JDK 1.8+ + testUnderJavaAtLeast("1.8") { + generateInterface() + compile() + Class.forName("Driver").newInstance() + () + } otherwise { + println("hello from publicMethod") + println("hello from staticMethod") + } + } + finally + System.setErr(prevErr) + } +} diff --git a/test/files/run/t7398.scala b/test/files/run/t7398.scala index e4090f7db3..dd59697b71 100644 --- a/test/files/run/t7398.scala +++ b/test/files/run/t7398.scala @@ -3,14 +3,11 @@ import scala.tools.partest._ object Test extends CompilerTest { import global._ - def javaVersion = scala.util.Properties.javaVersion - def isJavaEight = javaVersion startsWith "1.8" // This way we auto-pass on non-java8 since there's nothing to check - override lazy val units = { - val res: List[CompilationUnit] = if (isJavaEight) javaCompilationUnits(global)(defaultMethodSource) else Nil - val word = if (isJavaEight) "Attempting" else "Skipping" - log(s"$word java8-specific test under java version $javaVersion") - res + override lazy val units: List[CompilationUnit] = testUnderJavaAtLeast("1.8") { + javaCompilationUnits(global)(defaultMethodSource) + } otherwise { + Nil } private def defaultMethodSource = """ |