summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-06-09 12:28:23 -0700
committerJason Zaugg <jzaugg@gmail.com>2013-06-09 12:28:23 -0700
commit076e37bb67001fe3ca1e120c9c3ac63c1de5ea01 (patch)
tree954e62ce0998d6d69fd3a528521e866b757a7480
parenta9972cc7e851882b5e0b4d6d97ad951b012167c0 (diff)
parentac4e3ca19246ae3d983f99607b865c5ed3acb2b9 (diff)
downloadscala-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.scala27
-rw-r--r--test/files/run/classfile-format-51.scala8
-rw-r--r--test/files/run/classfile-format-52.check2
-rw-r--r--test/files/run/classfile-format-52.scala77
-rw-r--r--test/files/run/t7398.scala11
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 = """