summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-05-20 15:19:50 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2016-05-20 16:44:34 +0200
commit2537027195fd1702bbd12ba8e9d6cb3262b03482 (patch)
treee3e9c6ae78cc676da66f1e8fc12a30c618cb5179
parent46d523b47ad835e4124a7d3e1f03f103917fe89d (diff)
downloadscala-2537027195fd1702bbd12ba8e9d6cb3262b03482.tar.gz
scala-2537027195fd1702bbd12ba8e9d6cb3262b03482.tar.bz2
scala-2537027195fd1702bbd12ba8e9d6cb3262b03482.zip
Split RunTest and BytecodeTest into parts, put in matching packages.
-rw-r--r--test/junit/scala/BoxUnboxTest.scala119
-rw-r--r--test/junit/scala/PartialFunctionSerializationTest.scala16
-rw-r--r--test/junit/scala/issues/RunTest.scala247
-rw-r--r--test/junit/scala/lang/annotations/BytecodeTest.scala80
-rw-r--r--test/junit/scala/lang/annotations/RunTest.scala32
-rw-r--r--test/junit/scala/lang/primitives/BoxUnboxTest.scala222
-rw-r--r--test/junit/scala/lang/primitives/PredefAutoboxingTest.scala (renamed from test/junit/scala/PredefAutoboxingTest.scala)6
-rw-r--r--test/junit/scala/lang/stringinterpol/StringContextTest.scala (renamed from test/junit/scala/StringContextTest.scala)9
-rw-r--r--test/junit/scala/lang/traits/BytecodeTest.scala (renamed from test/junit/scala/issues/BytecodeTest.scala)242
-rw-r--r--test/junit/scala/lang/traits/RunTest.scala20
-rw-r--r--test/junit/scala/reflect/ClassOfTest.scala124
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala140
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala (renamed from test/junit/scala/issues/OptimizedBytecodeTest.scala)13
13 files changed, 660 insertions, 610 deletions
diff --git a/test/junit/scala/BoxUnboxTest.scala b/test/junit/scala/BoxUnboxTest.scala
deleted file mode 100644
index 88b3037e69..0000000000
--- a/test/junit/scala/BoxUnboxTest.scala
+++ /dev/null
@@ -1,119 +0,0 @@
-package scala
-
-import org.junit.Test
-import org.junit.Assert._
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-import scala.tools.testing.AssertUtil._
-
-@RunWith(classOf[JUnit4])
-class BoxUnboxTest {
- def genericNull[T] = null.asInstanceOf[T] // allowed, see SI-4437, point 2
-
- @Test
- def boxUnboxInt(): Unit = {
- val b = new Integer(1)
- val u = 1
-
- assertEquals(1.toInt, u)
-
- assertEquals(Predef.int2Integer(1), b)
- assertEquals(1: Integer, b)
- assertEquals(Int.box(1), b)
- assertEquals(1.asInstanceOf[Object], b)
-
- assertThrows[ClassCastException]("".asInstanceOf[Integer])
-
- assertEquals(Predef.Integer2int(b), u)
- assertEquals(b: Int, u)
- assertEquals(Int.unbox(b), u)
- assertEquals(b.asInstanceOf[Int], u)
- assertEquals(b.intValue, u)
- assertEquals(b.toInt, u)
- intWrapper(b).toInt
-
- assertThrows[ClassCastException](Int.unbox(""))
- assertThrows[ClassCastException]("".asInstanceOf[Int])
-
- // null unboxing in various positions
-
- val n1 = Int.unbox(null)
- assertEquals(n1, 0)
- val n2 = Predef.Integer2int(null)
- assertEquals(n2, 0)
- val n3 = (null: Integer): Int
- assertEquals(n3, 0)
- val n4 = null.asInstanceOf[Int]
- assertEquals(n4, 0)
- val n5 = null.asInstanceOf[Int] == 0
- assertTrue(n5)
- val n6 = null.asInstanceOf[Int] == null
- assertFalse(n6)
- val n7 = null.asInstanceOf[Int] != 0
- assertFalse(n7)
- val n8 = null.asInstanceOf[Int] != null
- assertTrue(n8)
-
- val mp = new java.util.HashMap[Int, Int]
- val n9 = mp.get(0)
- assertEquals(n9, 0)
- val n10 = mp.get(0) == null // SI-602
- assertThrows[AssertionError](assertFalse(n10)) // should not throw
-
- def f(a: Any) = "" + a
- val n11 = f(null.asInstanceOf[Int])
- assertEquals(n11, "0")
-
- def n12 = genericNull[Int]
- assertEquals(n12, 0)
- }
-
- @Test
- def numericConversions(): Unit = {
- val i1 = 1L.asInstanceOf[Int]
- assertEquals(i1, 1)
- assertThrows[ClassCastException] {
- val i2 = (1L: Any).asInstanceOf[Int] // SI-1448, should not throw. see also SI-4437 point 1.
- assertEquals(i2, 1)
- }
- }
-
- @Test
- def boxUnboxBoolean(): Unit = {
- val n1 = Option(null.asInstanceOf[Boolean])
- assertEquals(n1, Some(false))
- }
-
- @Test
- def boxUnboxUnit(): Unit = {
- // should not use assertEquals in this test: it takes two Object parameters. normally, Unit does
- // not conform to Object, but for Java-defined methods scalac makes an exception and treats them
- // as Any. passing a Unit as Any makes the compiler go through another layer of boxing, so it
- // can hide some bugs (where we actually have a null, but the compiler makes it a ()).
-
- var v = 0
- def eff() = { v = 1 }
- def chk() = { assert(v == 1); v = 0 }
-
- val b = runtime.BoxedUnit.UNIT
-
- assert(eff() == b); chk()
- assert(Unit.box(eff()) == b); chk()
- assert(().asInstanceOf[Object] == b)
-
- Unit.unbox({eff(); b}); chk()
- Unit.unbox({eff(); null}); chk()
- assertThrows[ClassCastException](Unit.unbox({eff(); ""})); chk()
-
- val n1 = null.asInstanceOf[Unit]
- assert(n1 == b)
-
- val n2 = null.asInstanceOf[Unit] == b
- assert(n2)
-
- def f(a: Any) = "" + a
- val n3 = f(null.asInstanceOf[Unit])
- assertEquals(n3, "()")
- }
-}
diff --git a/test/junit/scala/PartialFunctionSerializationTest.scala b/test/junit/scala/PartialFunctionSerializationTest.scala
index d525b045cd..2019e3a425 100644
--- a/test/junit/scala/PartialFunctionSerializationTest.scala
+++ b/test/junit/scala/PartialFunctionSerializationTest.scala
@@ -7,24 +7,18 @@ import org.junit.runners.JUnit4
@RunWith(classOf[JUnit4])
class PartialFunctionSerializationTest {
- val pf1: PartialFunction[Int, Int] = {
- case n if n > 0 => 1
- }
-
- val pf2: PartialFunction[Int, Int] = {
- case n if n <= 0 => 2
- }
+ val pf1: PartialFunction[Int, Int] = { case n if n > 0 => 1 }
+ val pf2: PartialFunction[Int, Int] = { case n if n <= 0 => 2 }
- private def assertSerializable[A,B](fn: A => B) = {
+ private def assertSerializable[A,B](fn: A => B): Unit = {
import java.io._
-
new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(fn)
}
- @Test def canSerializeLiteral= assertSerializable(pf1)
+ @Test def canSerializeLiteral = assertSerializable(pf1)
- @Test def canSerializeLifted= assertSerializable(pf1.lift)
+ @Test def canSerializeLifted = assertSerializable(pf1.lift)
@Test def canSerializeOrElse = assertSerializable(pf1 orElse pf2)
diff --git a/test/junit/scala/issues/RunTest.scala b/test/junit/scala/issues/RunTest.scala
deleted file mode 100644
index 0686d73d9b..0000000000
--- a/test/junit/scala/issues/RunTest.scala
+++ /dev/null
@@ -1,247 +0,0 @@
-package scala.issues
-
-import org.junit.Assert._
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-import scala.tools.testing.RunTesting
-
-object RunTest {
- class VC(val x: Any) extends AnyVal
- class VCI(val x: Int) extends AnyVal { override def toString = "" + x }
-}
-
-@RunWith(classOf[JUnit4])
-class RunTest extends RunTesting {
- import runner._
-
- @Test
- def classOfValueClassAlias(): Unit = {
- val code =
- """import scala.issues.RunTest.VC
- |type aVC = VC
- |type aInt = Int
- |type aInteger = Integer
- |classOf[VC] == classOf[aVC] &&
- | classOf[aInt] == classOf[Int] &&
- | classOf[aInteger] == classOf[Integer] &&
- | classOf[aInt] != classOf[aInteger]
- """.stripMargin
- assertTrue(run[Boolean](code))
- }
-
- @Test
- def classOfFinalVal(): Unit = {
- val code =
- """class C {
- | final val a1 = classOf[Int]
- | final val b1 = classOf[List[_]]
- | final val c1 = classOf[List[String]]
- | final val d1 = classOf[Array[Int]]
- | final val e1 = classOf[Array[List[_]]]
- | final val f1 = classOf[Array[_]]
- |
- | val a2 = classOf[Int]
- | val b2 = classOf[List[_]]
- | val c2 = classOf[List[String]]
- | val d2 = classOf[Array[Int]]
- | val e2 = classOf[Array[List[_]]]
- | val f2 = classOf[Array[_]]
- |
- | val listC = Class.forName("scala.collection.immutable.List")
- |
- | val compare = List(
- | (a1, a2, Integer.TYPE),
- | (b1, b2, listC),
- | (c1, c2, listC),
- | (d1, d2, Array(1).getClass),
- | (e1, e2, Array(List()).getClass),
- | (f1, f2, new Object().getClass))
- |}
- |(new C).compare
- """.stripMargin
- type K = Class[_]
- val cs = run[List[(K, K, K)]](code)
- for ((x, y, z) <- cs) {
- assertEquals(x, y)
- assertEquals(x, z)
- }
- }
-
- @Test
- def t9702(): Unit = {
- val code =
- """import javax.annotation.Resource
- |import scala.issues.RunTest.VC
- |class C {
- | type aList[K] = List[K]
- | type aVC = VC
- | type aInt = Int
- | type aInteger = Integer
- | @Resource(`type` = classOf[List[Int]]) def a = 0
- | @Resource(`type` = classOf[List[_]]) def b = 0
- | @Resource(`type` = classOf[aList[_]]) def c = 0
- | @Resource(`type` = classOf[Int]) def d = 0
- | @Resource(`type` = classOf[aInt]) def e = 0
- | @Resource(`type` = classOf[Integer]) def f = 0
- | @Resource(`type` = classOf[aInteger]) def g = 0
- | @Resource(`type` = classOf[VC]) def h = 0
- | @Resource(`type` = classOf[aVC]) def i = 0
- | @Resource(`type` = classOf[Array[Int]]) def j = 0
- | @Resource(`type` = classOf[Array[List[_]]]) def k = 0
- |}
- |val c = classOf[C]
- |def typeArg(meth: String) = c.getDeclaredMethod(meth).getDeclaredAnnotation(classOf[Resource]).`type`
- |('a' to 'k').toList.map(_.toString).map(typeArg)
- """.stripMargin
-
- val l = Class.forName("scala.collection.immutable.List")
- val i = Integer.TYPE
- val ig = new Integer(1).getClass
- val v = new RunTest.VC(1).getClass
- val ai = Array(1).getClass
- val al = Array(List()).getClass
-
- // sanity checks
- assertEquals(i, classOf[Int])
- assertNotEquals(i, ig)
-
- assertEquals(run[List[Class[_]]](code),
- List(l, l, l, i, i, ig, ig, v, v, ai, al))
- }
-
- @Test
- def annotationInfoNotErased(): Unit = {
- val code =
- """import javax.annotation.Resource
- |import scala.annotation.meta.getter
- |class C {
- | type Rg = Resource @getter
- | @(Resource @getter)(`type` = classOf[Int]) def a = 0
- | @Rg(`type` = classOf[Int]) def b = 0
- |}
- |val c = classOf[C]
- |def typeArg(meth: String) = c.getDeclaredMethod(meth).getDeclaredAnnotation(classOf[Resource]).`type`
- |List("a", "b") map typeArg
- |""".stripMargin
-
- val i = Integer.TYPE
- assertEquals(run[List[Class[_]]](code), List(i, i))
- }
-
- @Test
- def invocationReceivers(): Unit = {
- import invocationReceiversTestCode._
- assertEquals(run[String](definitions("Object") + runCode), "hi" * 9)
- assertEquals(run[String](definitions("String") + runCode), "hi" * 9) // bridge method for clone generated
- }
-
- @Test
- def classOfUnitConstant(): Unit = {
- val code =
- """abstract class A { def f: Class[_] }
- |class C extends A { final val f = classOf[Unit] }
- |val c = new C
- |(c.f, (c: A).f)
- """.stripMargin
- val u = Void.TYPE
- assertEquals(run[(Class[_], Class[_])](code), (u, u))
- }
-
- @Test
- def t9671(): Unit = {
- val code =
- """import scala.issues.RunTest.VCI
- |
- |def f1(a: Any) = "" + a
- |def f2(a: AnyVal) = "" + a
- |def f3[T](a: T) = "" + a
- |def f4(a: Int) = "" + a
- |def f5(a: VCI) = "" + a
- |def f6(u: Unit) = "" + u
- |
- |def n1: AnyRef = null
- |def n2: Null = null
- |def n3: Any = null
- |def n4[T]: T = null.asInstanceOf[T]
- |
- |def npe(s: => String) = try { s; throw new Error() } catch { case _: NullPointerException => "npe" }
- |
- | f1(null.asInstanceOf[Int]) +
- | f1( n1.asInstanceOf[Int]) +
- | f1( n2.asInstanceOf[Int]) +
- | f1( n3.asInstanceOf[Int]) +
- | f1( n4[Int]) + // "null"
- |"-" +
- | f1(null.asInstanceOf[VCI]) +
- |npe(f1( n1.asInstanceOf[VCI])) + // SI-8097
- | f1( n2.asInstanceOf[VCI]) +
- |npe(f1( n3.asInstanceOf[VCI])) + // SI-8097
- | f1( n4[VCI]) + // "null"
- |"-" +
- | f1(null.asInstanceOf[Unit]) +
- | f1( n1.asInstanceOf[Unit]) +
- | f1( n2.asInstanceOf[Unit]) +
- | f1( n3.asInstanceOf[Unit]) +
- | f1( n4[Unit]) + // "null"
- |"-" +
- | f2(null.asInstanceOf[Int]) +
- | f2( n1.asInstanceOf[Int]) +
- | f2( n2.asInstanceOf[Int]) +
- | f2( n3.asInstanceOf[Int]) +
- | f2( n4[Int]) + // "null"
- |"-" +
- | f2(null.asInstanceOf[VCI]) +
- |npe(f2( n1.asInstanceOf[VCI])) + // SI-8097
- | f2( n2.asInstanceOf[VCI]) +
- |npe(f2( n3.asInstanceOf[VCI])) + // SI-8097
- | f2( n4[VCI]) + // "null"
- |"-" +
- | f2(null.asInstanceOf[Unit]) +
- | f2( n1.asInstanceOf[Unit]) +
- | f2( n2.asInstanceOf[Unit]) +
- | f2( n3.asInstanceOf[Unit]) +
- | f2( n4[Unit]) + // "null"
- |"-" +
- | f3(null.asInstanceOf[Int]) +
- | f3( n1.asInstanceOf[Int]) +
- | f3( n2.asInstanceOf[Int]) +
- | f3( n3.asInstanceOf[Int]) +
- | f3( n4[Int]) + // "null"
- |"-" +
- | f3(null.asInstanceOf[VCI]) +
- |npe(f3( n1.asInstanceOf[VCI])) + // SI-8097
- | f3( n2.asInstanceOf[VCI]) +
- |npe(f3( n3.asInstanceOf[VCI])) + // SI-8097
- | f3( n4[VCI]) + // "null"
- |"-" +
- | f3(null.asInstanceOf[Unit]) +
- | f3( n1.asInstanceOf[Unit]) +
- | f3( n2.asInstanceOf[Unit]) +
- | f3( n3.asInstanceOf[Unit]) +
- | f3( n4[Unit]) + // "null"
- |"-" +
- | f4(null.asInstanceOf[Int]) +
- | f4( n1.asInstanceOf[Int]) +
- | f4( n2.asInstanceOf[Int]) +
- | f4( n3.asInstanceOf[Int]) +
- | f4( n4[Int]) +
- |"-" +
- | f5(null.asInstanceOf[VCI]) +
- |npe(f5( n1.asInstanceOf[VCI])) + // SI-8097
- | f5( n2.asInstanceOf[VCI]) +
- |npe(f5( n3.asInstanceOf[VCI])) + // SI-8097
- |npe(f5( n4[VCI])) + // SI-8097
- |"-" +
- | f6(null.asInstanceOf[Unit]) +
- | f6( n1.asInstanceOf[Unit]) +
- | f6( n2.asInstanceOf[Unit]) +
- | f6( n3.asInstanceOf[Unit]) +
- | f6( n4[Unit]) // "null"
- """.stripMargin
-
- assertEquals(run[String](code),
- "0000null-0npe0npenull-()()()()null-0000null-0npe0npenull-()()()()null-0000null-0npe0npenull-()()()()null-00000-0npe0npenpe-()()()()null")
- }
-}
diff --git a/test/junit/scala/lang/annotations/BytecodeTest.scala b/test/junit/scala/lang/annotations/BytecodeTest.scala
new file mode 100644
index 0000000000..09fc1d3572
--- /dev/null
+++ b/test/junit/scala/lang/annotations/BytecodeTest.scala
@@ -0,0 +1,80 @@
+package scala.lang.annotations
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.collection.JavaConverters._
+import scala.tools.nsc.backend.jvm.AsmUtils
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
+
+@RunWith(classOf[JUnit4])
+class BytecodeTest extends BytecodeTesting {
+ import compiler._
+
+ @Test
+ def t8731(): Unit = {
+ val code =
+ """class C {
+ | def f(x: Int) = (x: @annotation.switch) match {
+ | case 1 => 0
+ | case 2 => 1
+ | case 3 => 2
+ | }
+ | final val K = 10
+ | def g(x: Int) = (x: @annotation.switch) match {
+ | case K => 0
+ | case 1 => 10
+ | case 2 => 20
+ | }
+ |}
+ """.stripMargin
+
+ val c = compileClass(code)
+
+ assertTrue(getInstructions(c, "f").count(_.isInstanceOf[TableSwitch]) == 1)
+ assertTrue(getInstructions(c, "g").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 run = new global.Run()
+ run.compileSources(List(new BatchSourceFile("AnnotA.java", annotA), new BatchSourceFile("AnnotB.java", annotB), new BatchSourceFile("Test.scala", scalaSrc)))
+ val outDir = global.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")
+ }
+} \ No newline at end of file
diff --git a/test/junit/scala/lang/annotations/RunTest.scala b/test/junit/scala/lang/annotations/RunTest.scala
new file mode 100644
index 0000000000..0d9c0c4713
--- /dev/null
+++ b/test/junit/scala/lang/annotations/RunTest.scala
@@ -0,0 +1,32 @@
+package scala.lang.annotations
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.testing.RunTesting
+
+@RunWith(classOf[JUnit4])
+class RunTest extends RunTesting {
+ import runner._
+
+ @Test
+ def annotationInfoNotErased(): Unit = {
+ val code =
+ """import javax.annotation.Resource
+ |import scala.annotation.meta.getter
+ |class C {
+ | type Rg = Resource @getter
+ | @(Resource @getter)(`type` = classOf[Int]) def a = 0
+ | @Rg(`type` = classOf[Int]) def b = 0
+ |}
+ |val c = classOf[C]
+ |def typeArg(meth: String) = c.getDeclaredMethod(meth).getDeclaredAnnotation(classOf[Resource]).`type`
+ |List("a", "b") map typeArg
+ |""".stripMargin
+
+ val i = Integer.TYPE
+ assertEquals(run[List[Class[_]]](code), List(i, i))
+ }
+}
diff --git a/test/junit/scala/lang/primitives/BoxUnboxTest.scala b/test/junit/scala/lang/primitives/BoxUnboxTest.scala
new file mode 100644
index 0000000000..23c9326989
--- /dev/null
+++ b/test/junit/scala/lang/primitives/BoxUnboxTest.scala
@@ -0,0 +1,222 @@
+package scala.lang.primitives
+
+import org.junit.Test
+import org.junit.Assert._
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.testing.AssertUtil._
+import scala.tools.testing.RunTesting
+
+object BoxUnboxTest {
+ class VCI(val x: Int) extends AnyVal { override def toString = "" + x }
+}
+
+@RunWith(classOf[JUnit4])
+class BoxUnboxTest extends RunTesting {
+ import runner._
+
+ def genericNull[T] = null.asInstanceOf[T] // allowed, see SI-4437, point 2
+
+ @Test
+ def boxUnboxInt(): Unit = {
+ val b = new Integer(1)
+ val u = 1
+
+ assertEquals(1.toInt, u)
+
+ assertEquals(Predef.int2Integer(1), b)
+ assertEquals(1: Integer, b)
+ assertEquals(Int.box(1), b)
+ assertEquals(1.asInstanceOf[Object], b)
+
+ assertThrows[ClassCastException]("".asInstanceOf[Integer])
+
+ assertEquals(Predef.Integer2int(b), u)
+ assertEquals(b: Int, u)
+ assertEquals(Int.unbox(b), u)
+ assertEquals(b.asInstanceOf[Int], u)
+ assertEquals(b.intValue, u)
+ assertEquals(b.toInt, u)
+ intWrapper(b).toInt
+
+ assertThrows[ClassCastException](Int.unbox(""))
+ assertThrows[ClassCastException]("".asInstanceOf[Int])
+
+ // null unboxing in various positions
+
+ val n1 = Int.unbox(null)
+ assertEquals(n1, 0)
+ val n2 = Predef.Integer2int(null)
+ assertEquals(n2, 0)
+ val n3 = (null: Integer): Int
+ assertEquals(n3, 0)
+ val n4 = null.asInstanceOf[Int]
+ assertEquals(n4, 0)
+ val n5 = null.asInstanceOf[Int] == 0
+ assertTrue(n5)
+ val n6 = null.asInstanceOf[Int] == null
+ assertFalse(n6)
+ val n7 = null.asInstanceOf[Int] != 0
+ assertFalse(n7)
+ val n8 = null.asInstanceOf[Int] != null
+ assertTrue(n8)
+
+ val mp = new java.util.HashMap[Int, Int]
+ val n9 = mp.get(0)
+ assertEquals(n9, 0)
+ val n10 = mp.get(0) == null // SI-602
+ assertThrows[AssertionError](assertFalse(n10)) // should not throw
+
+ def f(a: Any) = "" + a
+ val n11 = f(null.asInstanceOf[Int])
+ assertEquals(n11, "0")
+
+ def n12 = genericNull[Int]
+ assertEquals(n12, 0)
+ }
+
+ @Test
+ def numericConversions(): Unit = {
+ val i1 = 1L.asInstanceOf[Int]
+ assertEquals(i1, 1)
+ assertThrows[ClassCastException] {
+ val i2 = (1L: Any).asInstanceOf[Int] // SI-1448, should not throw. see also SI-4437 point 1.
+ assertEquals(i2, 1)
+ }
+ }
+
+ @Test
+ def boxUnboxBoolean(): Unit = {
+ val n1 = Option(null.asInstanceOf[Boolean])
+ assertEquals(n1, Some(false))
+ }
+
+ @Test
+ def boxUnboxUnit(): Unit = {
+ // should not use assertEquals in this test: it takes two Object parameters. normally, Unit does
+ // not conform to Object, but for Java-defined methods scalac makes an exception and treats them
+ // as Any. passing a Unit as Any makes the compiler go through another layer of boxing, so it
+ // can hide some bugs (where we actually have a null, but the compiler makes it a ()).
+
+ var v = 0
+ def eff() = { v = 1 }
+ def chk() = { assert(v == 1); v = 0 }
+
+ val b = runtime.BoxedUnit.UNIT
+
+ assert(eff() == b); chk()
+ assert(Unit.box(eff()) == b); chk()
+ assert(().asInstanceOf[Object] == b)
+
+ Unit.unbox({eff(); b}); chk()
+ Unit.unbox({eff(); null}); chk()
+ assertThrows[ClassCastException](Unit.unbox({eff(); ""})); chk()
+
+ val n1 = null.asInstanceOf[Unit]
+ assert(n1 == b)
+
+ val n2 = null.asInstanceOf[Unit] == b
+ assert(n2)
+
+ def f(a: Any) = "" + a
+ val n3 = f(null.asInstanceOf[Unit])
+ assertEquals(n3, "()")
+ }
+
+ @Test
+ def t9671(): Unit = {
+ val code =
+ """import scala.lang.primitives.BoxUnboxTest.VCI
+ |
+ |def f1(a: Any) = "" + a
+ |def f2(a: AnyVal) = "" + a
+ |def f3[T](a: T) = "" + a
+ |def f4(a: Int) = "" + a
+ |def f5(a: VCI) = "" + a
+ |def f6(u: Unit) = "" + u
+ |
+ |def n1: AnyRef = null
+ |def n2: Null = null
+ |def n3: Any = null
+ |def n4[T]: T = null.asInstanceOf[T]
+ |
+ |def npe(s: => String) = try { s; throw new Error() } catch { case _: NullPointerException => "npe" }
+ |
+ | f1(null.asInstanceOf[Int]) +
+ | f1( n1.asInstanceOf[Int]) +
+ | f1( n2.asInstanceOf[Int]) +
+ | f1( n3.asInstanceOf[Int]) +
+ | f1( n4[Int]) + // "null"
+ |"-" +
+ | f1(null.asInstanceOf[VCI]) +
+ |npe(f1( n1.asInstanceOf[VCI])) + // SI-8097
+ | f1( n2.asInstanceOf[VCI]) +
+ |npe(f1( n3.asInstanceOf[VCI])) + // SI-8097
+ | f1( n4[VCI]) + // "null"
+ |"-" +
+ | f1(null.asInstanceOf[Unit]) +
+ | f1( n1.asInstanceOf[Unit]) +
+ | f1( n2.asInstanceOf[Unit]) +
+ | f1( n3.asInstanceOf[Unit]) +
+ | f1( n4[Unit]) + // "null"
+ |"-" +
+ | f2(null.asInstanceOf[Int]) +
+ | f2( n1.asInstanceOf[Int]) +
+ | f2( n2.asInstanceOf[Int]) +
+ | f2( n3.asInstanceOf[Int]) +
+ | f2( n4[Int]) + // "null"
+ |"-" +
+ | f2(null.asInstanceOf[VCI]) +
+ |npe(f2( n1.asInstanceOf[VCI])) + // SI-8097
+ | f2( n2.asInstanceOf[VCI]) +
+ |npe(f2( n3.asInstanceOf[VCI])) + // SI-8097
+ | f2( n4[VCI]) + // "null"
+ |"-" +
+ | f2(null.asInstanceOf[Unit]) +
+ | f2( n1.asInstanceOf[Unit]) +
+ | f2( n2.asInstanceOf[Unit]) +
+ | f2( n3.asInstanceOf[Unit]) +
+ | f2( n4[Unit]) + // "null"
+ |"-" +
+ | f3(null.asInstanceOf[Int]) +
+ | f3( n1.asInstanceOf[Int]) +
+ | f3( n2.asInstanceOf[Int]) +
+ | f3( n3.asInstanceOf[Int]) +
+ | f3( n4[Int]) + // "null"
+ |"-" +
+ | f3(null.asInstanceOf[VCI]) +
+ |npe(f3( n1.asInstanceOf[VCI])) + // SI-8097
+ | f3( n2.asInstanceOf[VCI]) +
+ |npe(f3( n3.asInstanceOf[VCI])) + // SI-8097
+ | f3( n4[VCI]) + // "null"
+ |"-" +
+ | f3(null.asInstanceOf[Unit]) +
+ | f3( n1.asInstanceOf[Unit]) +
+ | f3( n2.asInstanceOf[Unit]) +
+ | f3( n3.asInstanceOf[Unit]) +
+ | f3( n4[Unit]) + // "null"
+ |"-" +
+ | f4(null.asInstanceOf[Int]) +
+ | f4( n1.asInstanceOf[Int]) +
+ | f4( n2.asInstanceOf[Int]) +
+ | f4( n3.asInstanceOf[Int]) +
+ | f4( n4[Int]) +
+ |"-" +
+ | f5(null.asInstanceOf[VCI]) +
+ |npe(f5( n1.asInstanceOf[VCI])) + // SI-8097
+ | f5( n2.asInstanceOf[VCI]) +
+ |npe(f5( n3.asInstanceOf[VCI])) + // SI-8097
+ |npe(f5( n4[VCI])) + // SI-8097
+ |"-" +
+ | f6(null.asInstanceOf[Unit]) +
+ | f6( n1.asInstanceOf[Unit]) +
+ | f6( n2.asInstanceOf[Unit]) +
+ | f6( n3.asInstanceOf[Unit]) +
+ | f6( n4[Unit]) // "null"
+ """.stripMargin
+
+ assertEquals(run[String](code),
+ "0000null-0npe0npenull-()()()()null-0000null-0npe0npenull-()()()()null-0000null-0npe0npenull-()()()()null-00000-0npe0npenpe-()()()()null")
+ }
+}
diff --git a/test/junit/scala/PredefAutoboxingTest.scala b/test/junit/scala/lang/primitives/PredefAutoboxingTest.scala
index e5d8ded5d4..ab31a9e8f1 100644
--- a/test/junit/scala/PredefAutoboxingTest.scala
+++ b/test/junit/scala/lang/primitives/PredefAutoboxingTest.scala
@@ -1,12 +1,10 @@
-package scala
+package scala.lang.primitives
-import org.junit.Test
import org.junit.Assert._
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import scala.tools.testing.AssertUtil._
-
@RunWith(classOf[JUnit4])
class PredefAutoboxingTest {
@Test def unboxNullByte() =
diff --git a/test/junit/scala/StringContextTest.scala b/test/junit/scala/lang/stringinterpol/StringContextTest.scala
index b5af6de7eb..d2cb8149d7 100644
--- a/test/junit/scala/StringContextTest.scala
+++ b/test/junit/scala/lang/stringinterpol/StringContextTest.scala
@@ -1,15 +1,14 @@
-package scala
+package scala.lang.stringinterpol
import java.text.DecimalFormat
-import language.implicitConversions
-
-import org.junit.Test
import org.junit.Assert._
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import scala.language.implicitConversions
import scala.tools.testing.AssertUtil._
object StringContextTestUtils {
@@ -128,7 +127,7 @@ class StringContextTest {
val fff = new java.util.Formattable {
def formatTo(f: java.util.Formatter, g: Int, w: Int, p: Int) = f.format("4")
}
- import java.util.{ Calendar, Locale }
+ import java.util.{Calendar, Locale}
val c = Calendar.getInstance(Locale.US)
c.set(2012, Calendar.MAY, 26)
implicit def strToDate(x: String): Calendar = c
diff --git a/test/junit/scala/issues/BytecodeTest.scala b/test/junit/scala/lang/traits/BytecodeTest.scala
index 125024f746..f47fc9c127 100644
--- a/test/junit/scala/issues/BytecodeTest.scala
+++ b/test/junit/scala/lang/traits/BytecodeTest.scala
@@ -1,4 +1,4 @@
-package scala.issues
+package scala.lang.traits
import org.junit.Assert._
import org.junit.Test
@@ -9,7 +9,6 @@ import scala.collection.JavaConverters._
import scala.tools.asm.Opcodes
import scala.tools.asm.Opcodes._
import scala.tools.asm.tree.ClassNode
-import scala.tools.nsc.backend.jvm.AsmUtils
import scala.tools.partest.ASMConverters._
import scala.tools.testing.BytecodeTesting
import scala.tools.testing.BytecodeTesting._
@@ -18,194 +17,6 @@ import scala.tools.testing.BytecodeTesting._
class BytecodeTest extends BytecodeTesting {
import compiler._
- @Test
- def t8731(): Unit = {
- val code =
- """class C {
- | def f(x: Int) = (x: @annotation.switch) match {
- | case 1 => 0
- | case 2 => 1
- | case 3 => 2
- | }
- | final val K = 10
- | def g(x: Int) = (x: @annotation.switch) match {
- | case K => 0
- | case 1 => 10
- | case 2 => 20
- | }
- |}
- """.stripMargin
-
- val c = compileClass(code)
-
- assertTrue(getInstructions(c, "f").count(_.isInstanceOf[TableSwitch]) == 1)
- assertTrue(getInstructions(c, "g").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 run = new global.Run()
- run.compileSources(List(new BatchSourceFile("AnnotA.java", annotA), new BatchSourceFile("AnnotB.java", annotB), new BatchSourceFile("Test.scala", scalaSrc)))
- val outDir = global.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")
- }
-
- @Test
- def t6288bJumpPosition(): Unit = {
- val code =
- """object Case3 { // 01
- | def unapply(z: Any): Option[Int] = Some(-1) // 02
- | def main(args: Array[String]) { // 03
- | ("": Any) match { // 04
- | case x : String => // 05
- | println("case 0") // 06 println and jump at 6
- | case _ => // 07
- | println("default") // 08 println and jump at 8
- | } // 09
- | println("done") // 10
- | }
- |}
- """.stripMargin
- val List(mirror, module) = compileClasses(code)
-
- val unapplyLineNumbers = getInstructions(module, "unapply").filter(_.isInstanceOf[LineNumber])
- assert(unapplyLineNumbers == List(LineNumber(2, Label(0))), unapplyLineNumbers)
-
- val expected = List(
- LineNumber(4, Label(0)),
- LineNumber(5, Label(5)),
- Jump(IFEQ, Label(20)),
-
- LineNumber(6, Label(11)),
- Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false),
- Jump(GOTO, Label(33)),
-
- LineNumber(5, Label(20)),
- Jump(GOTO, Label(24)),
-
- LineNumber(8, Label(24)),
- Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false),
- Jump(GOTO, Label(33)),
-
- LineNumber(10, Label(33)),
- Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false)
- )
-
- val mainIns = getInstructions(module, "main") filter {
- case _: LineNumber | _: Invoke | _: Jump => true
- case _ => false
- }
- assertSameCode(mainIns, expected)
- }
-
- @Test
- def bytecodeForBranches(): Unit = {
- val code =
- """class C {
- | def t1(b: Boolean) = if (b) 1 else 2
- | def t2(x: Int) = if (x == 393) 1 else 2
- | def t3(a: Array[String], b: AnyRef) = a != b && b == a
- | def t4(a: AnyRef) = a == null || null != a
- | def t5(a: AnyRef) = (a eq null) || (null ne a)
- | def t6(a: Int, b: Boolean) = if ((a == 10) && b || a != 1) 1 else 2
- | def t7(a: AnyRef, b: AnyRef) = a == b
- | def t8(a: AnyRef) = Nil == a || "" != a
- |}
- """.stripMargin
-
- val c = compileClass(code)
-
- // t1: no unnecessary GOTOs
- assertSameCode(getMethod(c, "t1"), List(
- VarOp(ILOAD, 1), Jump(IFEQ, Label(6)),
- Op(ICONST_1), Jump(GOTO, Label(9)),
- Label(6), Op(ICONST_2),
- Label(9), Op(IRETURN)))
-
- // t2: no unnecessary GOTOs
- assertSameCode(getMethod(c, "t2"), List(
- VarOp(ILOAD, 1), IntOp(SIPUSH, 393), Jump(IF_ICMPNE, Label(7)),
- Op(ICONST_1), Jump(GOTO, Label(10)),
- Label(7), Op(ICONST_2),
- Label(10), Op(IRETURN)))
-
- // t3: Array == is translated to reference equality, AnyRef == to null checks and equals
- assertSameCode(getMethod(c, "t3"), List(
- // Array ==
- VarOp(ALOAD, 1), VarOp(ALOAD, 2), Jump(IF_ACMPEQ, Label(23)),
- // AnyRef ==
- VarOp(ALOAD, 2), VarOp(ALOAD, 1), VarOp(ASTORE, 3), Op(DUP), Jump(IFNONNULL, Label(14)),
- Op(POP), VarOp(ALOAD, 3), Jump(IFNULL, Label(19)), Jump(GOTO, Label(23)),
- Label(14), VarOp(ALOAD, 3), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFEQ, Label(23)),
- Label(19), Op(ICONST_1), Jump(GOTO, Label(26)),
- Label(23), Op(ICONST_0),
- Label(26), Op(IRETURN)))
-
- val t4t5 = List(
- VarOp(ALOAD, 1), Jump(IFNULL, Label(6)),
- VarOp(ALOAD, 1), Jump(IFNULL, Label(10)),
- Label(6), Op(ICONST_1), Jump(GOTO, Label(13)),
- Label(10), Op(ICONST_0),
- Label(13), Op(IRETURN))
-
- // t4: one side is known null, so just a null check on the other
- assertSameCode(getMethod(c, "t4"), t4t5)
-
- // t5: one side known null, so just a null check on the other
- assertSameCode(getMethod(c, "t5"), t4t5)
-
- // t6: no unnecessary GOTOs
- assertSameCode(getMethod(c, "t6"), List(
- VarOp(ILOAD, 1), IntOp(BIPUSH, 10), Jump(IF_ICMPNE, Label(7)),
- VarOp(ILOAD, 2), Jump(IFNE, Label(12)),
- Label(7), VarOp(ILOAD, 1), Op(ICONST_1), Jump(IF_ICMPEQ, Label(16)),
- Label(12), Op(ICONST_1), Jump(GOTO, Label(19)),
- Label(16), Op(ICONST_2),
- Label(19), Op(IRETURN)))
-
- // t7: universal equality
- assertInvoke(getMethod(c, "t7"), "scala/runtime/BoxesRunTime", "equals")
-
- // t8: no null checks invoking equals on modules and constants
- assertSameCode(getMethod(c, "t8"), List(
- Field(GETSTATIC, "scala/collection/immutable/Nil$", "MODULE$", "Lscala/collection/immutable/Nil$;"), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFNE, Label(10)),
- Ldc(LDC, ""), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFNE, Label(14)),
- Label(10), Op(ICONST_1), Jump(GOTO, Label(17)),
- Label(14), Op(ICONST_0),
- Label(17), Op(IRETURN)))
- }
-
def checkForwarder(classes: Map[String, ClassNode], clsName: Symbol, target: String) = {
val List(f) = getMethods(classes(clsName.name), "f")
assertSameCode(f, List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, target, "f", "()I", false), Op(IRETURN)))
@@ -417,36 +228,37 @@ class BytecodeTest extends BytecodeTesting {
// pass `null` to super constructor, no box-unbox, no Integer created
List(ALOAD, ILOAD, PUTFIELD, ALOAD, ACONST_NULL, "<init>", RETURN))
}
+
}
object invocationReceiversTestCode {
// if cloneType is more specific than Object (e.g., String), a bridge method is generated.
def definitions(cloneType: String) =
- s"""trait T { override def clone(): $cloneType = "hi" }
- |trait U extends T
- |class C1 extends U with Cloneable {
- | // The comments below are true when $cloneType is Object.
- | // C1 gets a forwarder for clone that invokes T.clone. this is needed because JVM method
- | // resolution always prefers class members, so it would resolve to Object.clone, even if
- | // C1 is a subtype of the interface T which has an overriding default method for clone.
- |
- | // invokeinterface T.clone
- | def f1 = (this: T).clone()
- |
- | // cannot invokeinterface U.clone (NoSuchMethodError). Object.clone would work here, but
- | // not in the example in C2 (illegal access to protected). T.clone works in all cases and
- | // resolves correctly.
- | def f2 = (this: U).clone()
- |
- | // invokevirtual C1.clone()
- | def f3 = (this: C1).clone()
- |}
- |
- |class C2 {
- | def f1(t: T) = t.clone() // invokeinterface T.clone
- | def f2(t: U) = t.clone() // invokeinterface T.clone -- Object.clone would be illegal (protected, explained in C1)
- | def f3(t: C1) = t.clone() // invokevirtual C1.clone -- Object.clone would be illegal
- |}
+ s"""trait T { override def clone(): $cloneType = "hi" }
+ |trait U extends T
+ |class C1 extends U with Cloneable {
+ | // The comments below are true when $cloneType is Object.
+ | // C1 gets a forwarder for clone that invokes T.clone. this is needed because JVM method
+ | // resolution always prefers class members, so it would resolve to Object.clone, even if
+ | // C1 is a subtype of the interface T which has an overriding default method for clone.
+ |
+ | // invokeinterface T.clone
+ | def f1 = (this: T).clone()
+ |
+ | // cannot invokeinterface U.clone (NoSuchMethodError). Object.clone would work here, but
+ | // not in the example in C2 (illegal access to protected). T.clone works in all cases and
+ | // resolves correctly.
+ | def f2 = (this: U).clone()
+ |
+ | // invokevirtual C1.clone()
+ | def f3 = (this: C1).clone()
+ |}
+ |
+ |class C2 {
+ | def f1(t: T) = t.clone() // invokeinterface T.clone
+ | def f2(t: U) = t.clone() // invokeinterface T.clone -- Object.clone would be illegal (protected, explained in C1)
+ | def f3(t: C1) = t.clone() // invokevirtual C1.clone -- Object.clone would be illegal
+ |}
""".stripMargin
val runCode =
diff --git a/test/junit/scala/lang/traits/RunTest.scala b/test/junit/scala/lang/traits/RunTest.scala
new file mode 100644
index 0000000000..d27dc15e20
--- /dev/null
+++ b/test/junit/scala/lang/traits/RunTest.scala
@@ -0,0 +1,20 @@
+package scala.lang.traits
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.testing.RunTesting
+
+@RunWith(classOf[JUnit4])
+class RunTest extends RunTesting {
+ import runner._
+
+ @Test
+ def invocationReceivers(): Unit = {
+ import invocationReceiversTestCode._
+ assertEquals(run[String](definitions("Object") + runCode), "hi" * 9)
+ assertEquals(run[String](definitions("String") + runCode), "hi" * 9) // bridge method for clone generated
+ }
+}
diff --git a/test/junit/scala/reflect/ClassOfTest.scala b/test/junit/scala/reflect/ClassOfTest.scala
new file mode 100644
index 0000000000..520b14ccd4
--- /dev/null
+++ b/test/junit/scala/reflect/ClassOfTest.scala
@@ -0,0 +1,124 @@
+package scala.reflect
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.testing.RunTesting
+
+object ClassOfTest {
+ class VC(val x: Any) extends AnyVal
+}
+
+@RunWith(classOf[JUnit4])
+class ClassOfTest extends RunTesting {
+ import runner._
+
+ @Test
+ def classOfValueClassAlias(): Unit = {
+ val code =
+ """import scala.reflect.ClassOfTest.VC
+ |type aVC = VC
+ |type aInt = Int
+ |type aInteger = Integer
+ |classOf[VC] == classOf[aVC] &&
+ | classOf[aInt] == classOf[Int] &&
+ | classOf[aInteger] == classOf[Integer] &&
+ | classOf[aInt] != classOf[aInteger]
+ """.stripMargin
+ assertTrue(run[Boolean](code))
+ }
+
+ @Test
+ def classOfFinalVal(): Unit = {
+ val code =
+ """class C {
+ | final val a1 = classOf[Int]
+ | final val b1 = classOf[List[_]]
+ | final val c1 = classOf[List[String]]
+ | final val d1 = classOf[Array[Int]]
+ | final val e1 = classOf[Array[List[_]]]
+ | final val f1 = classOf[Array[_]]
+ |
+ | val a2 = classOf[Int]
+ | val b2 = classOf[List[_]]
+ | val c2 = classOf[List[String]]
+ | val d2 = classOf[Array[Int]]
+ | val e2 = classOf[Array[List[_]]]
+ | val f2 = classOf[Array[_]]
+ |
+ | val listC = Class.forName("scala.collection.immutable.List")
+ |
+ | val compare = List(
+ | (a1, a2, Integer.TYPE),
+ | (b1, b2, listC),
+ | (c1, c2, listC),
+ | (d1, d2, Array(1).getClass),
+ | (e1, e2, Array(List()).getClass),
+ | (f1, f2, new Object().getClass))
+ |}
+ |(new C).compare
+ """.stripMargin
+ type K = Class[_]
+ val cs = run[List[(K, K, K)]](code)
+ for ((x, y, z) <- cs) {
+ assertEquals(x, y)
+ assertEquals(x, z)
+ }
+ }
+
+ @Test
+ def t9702(): Unit = {
+ val code =
+ """import javax.annotation.Resource
+ |import scala.reflect.ClassOfTest.VC
+ |class C {
+ | type aList[K] = List[K]
+ | type aVC = VC
+ | type aInt = Int
+ | type aInteger = Integer
+ | @Resource(`type` = classOf[List[Int]]) def a = 0
+ | @Resource(`type` = classOf[List[_]]) def b = 0
+ | @Resource(`type` = classOf[aList[_]]) def c = 0
+ | @Resource(`type` = classOf[Int]) def d = 0
+ | @Resource(`type` = classOf[aInt]) def e = 0
+ | @Resource(`type` = classOf[Integer]) def f = 0
+ | @Resource(`type` = classOf[aInteger]) def g = 0
+ | @Resource(`type` = classOf[VC]) def h = 0
+ | @Resource(`type` = classOf[aVC]) def i = 0
+ | @Resource(`type` = classOf[Array[Int]]) def j = 0
+ | @Resource(`type` = classOf[Array[List[_]]]) def k = 0
+ |}
+ |val c = classOf[C]
+ |def typeArg(meth: String) = c.getDeclaredMethod(meth).getDeclaredAnnotation(classOf[Resource]).`type`
+ |('a' to 'k').toList.map(_.toString).map(typeArg)
+ """.stripMargin
+
+ val l = Class.forName("scala.collection.immutable.List")
+ val i = Integer.TYPE
+ val ig = new Integer(1).getClass
+ val v = new ClassOfTest.VC(1).getClass
+ val ai = Array(1).getClass
+ val al = Array(List()).getClass
+
+ // sanity checks
+ assertEquals(i, classOf[Int])
+ assertNotEquals(i, ig)
+
+ assertEquals(run[List[Class[_]]](code),
+ List(l, l, l, i, i, ig, ig, v, v, ai, al))
+ }
+
+ @Test
+ def classOfUnitConstant(): Unit = {
+ val code =
+ """abstract class A { def f: Class[_] }
+ |class C extends A { final val f = classOf[Unit] }
+ |val c = new C
+ |(c.f, (c: A).f)
+ """.stripMargin
+ val u = Void.TYPE
+ assertEquals(run[(Class[_], Class[_])](code), (u, u))
+ }
+}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
new file mode 100644
index 0000000000..7954fe2360
--- /dev/null
+++ b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
@@ -0,0 +1,140 @@
+package scala.tools.nsc.backend.jvm
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.asm.Opcodes._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
+
+@RunWith(classOf[JUnit4])
+class BytecodeTest extends BytecodeTesting {
+ import compiler._
+
+ @Test
+ def t6288bJumpPosition(): Unit = {
+ val code =
+ """object Case3 { // 01
+ | def unapply(z: Any): Option[Int] = Some(-1) // 02
+ | def main(args: Array[String]) { // 03
+ | ("": Any) match { // 04
+ | case x : String => // 05
+ | println("case 0") // 06 println and jump at 6
+ | case _ => // 07
+ | println("default") // 08 println and jump at 8
+ | } // 09
+ | println("done") // 10
+ | }
+ |}
+ """.stripMargin
+ val List(mirror, module) = compileClasses(code)
+
+ val unapplyLineNumbers = getInstructions(module, "unapply").filter(_.isInstanceOf[LineNumber])
+ assert(unapplyLineNumbers == List(LineNumber(2, Label(0))), unapplyLineNumbers)
+
+ val expected = List(
+ LineNumber(4, Label(0)),
+ LineNumber(5, Label(5)),
+ Jump(IFEQ, Label(20)),
+
+ LineNumber(6, Label(11)),
+ Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false),
+ Jump(GOTO, Label(33)),
+
+ LineNumber(5, Label(20)),
+ Jump(GOTO, Label(24)),
+
+ LineNumber(8, Label(24)),
+ Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false),
+ Jump(GOTO, Label(33)),
+
+ LineNumber(10, Label(33)),
+ Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false)
+ )
+
+ val mainIns = getInstructions(module, "main") filter {
+ case _: LineNumber | _: Invoke | _: Jump => true
+ case _ => false
+ }
+ assertSameCode(mainIns, expected)
+ }
+
+ @Test
+ def bytecodeForBranches(): Unit = {
+ val code =
+ """class C {
+ | def t1(b: Boolean) = if (b) 1 else 2
+ | def t2(x: Int) = if (x == 393) 1 else 2
+ | def t3(a: Array[String], b: AnyRef) = a != b && b == a
+ | def t4(a: AnyRef) = a == null || null != a
+ | def t5(a: AnyRef) = (a eq null) || (null ne a)
+ | def t6(a: Int, b: Boolean) = if ((a == 10) && b || a != 1) 1 else 2
+ | def t7(a: AnyRef, b: AnyRef) = a == b
+ | def t8(a: AnyRef) = Nil == a || "" != a
+ |}
+ """.stripMargin
+
+ val c = compileClass(code)
+
+ // t1: no unnecessary GOTOs
+ assertSameCode(getMethod(c, "t1"), List(
+ VarOp(ILOAD, 1), Jump(IFEQ, Label(6)),
+ Op(ICONST_1), Jump(GOTO, Label(9)),
+ Label(6), Op(ICONST_2),
+ Label(9), Op(IRETURN)))
+
+ // t2: no unnecessary GOTOs
+ assertSameCode(getMethod(c, "t2"), List(
+ VarOp(ILOAD, 1), IntOp(SIPUSH, 393), Jump(IF_ICMPNE, Label(7)),
+ Op(ICONST_1), Jump(GOTO, Label(10)),
+ Label(7), Op(ICONST_2),
+ Label(10), Op(IRETURN)))
+
+ // t3: Array == is translated to reference equality, AnyRef == to null checks and equals
+ assertSameCode(getMethod(c, "t3"), List(
+ // Array ==
+ VarOp(ALOAD, 1), VarOp(ALOAD, 2), Jump(IF_ACMPEQ, Label(23)),
+ // AnyRef ==
+ VarOp(ALOAD, 2), VarOp(ALOAD, 1), VarOp(ASTORE, 3), Op(DUP), Jump(IFNONNULL, Label(14)),
+ Op(POP), VarOp(ALOAD, 3), Jump(IFNULL, Label(19)), Jump(GOTO, Label(23)),
+ Label(14), VarOp(ALOAD, 3), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFEQ, Label(23)),
+ Label(19), Op(ICONST_1), Jump(GOTO, Label(26)),
+ Label(23), Op(ICONST_0),
+ Label(26), Op(IRETURN)))
+
+ val t4t5 = List(
+ VarOp(ALOAD, 1), Jump(IFNULL, Label(6)),
+ VarOp(ALOAD, 1), Jump(IFNULL, Label(10)),
+ Label(6), Op(ICONST_1), Jump(GOTO, Label(13)),
+ Label(10), Op(ICONST_0),
+ Label(13), Op(IRETURN))
+
+ // t4: one side is known null, so just a null check on the other
+ assertSameCode(getMethod(c, "t4"), t4t5)
+
+ // t5: one side known null, so just a null check on the other
+ assertSameCode(getMethod(c, "t5"), t4t5)
+
+ // t6: no unnecessary GOTOs
+ assertSameCode(getMethod(c, "t6"), List(
+ VarOp(ILOAD, 1), IntOp(BIPUSH, 10), Jump(IF_ICMPNE, Label(7)),
+ VarOp(ILOAD, 2), Jump(IFNE, Label(12)),
+ Label(7), VarOp(ILOAD, 1), Op(ICONST_1), Jump(IF_ICMPEQ, Label(16)),
+ Label(12), Op(ICONST_1), Jump(GOTO, Label(19)),
+ Label(16), Op(ICONST_2),
+ Label(19), Op(IRETURN)))
+
+ // t7: universal equality
+ assertInvoke(getMethod(c, "t7"), "scala/runtime/BoxesRunTime", "equals")
+
+ // t8: no null checks invoking equals on modules and constants
+ assertSameCode(getMethod(c, "t8"), List(
+ Field(GETSTATIC, "scala/collection/immutable/Nil$", "MODULE$", "Lscala/collection/immutable/Nil$;"), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFNE, Label(10)),
+ Ldc(LDC, ""), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false), Jump(IFNE, Label(14)),
+ Label(10), Op(ICONST_1), Jump(GOTO, Label(17)),
+ Label(14), Op(ICONST_0),
+ Label(17), Op(IRETURN)))
+ }
+}
diff --git a/test/junit/scala/issues/OptimizedBytecodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala
index af1c50acac..003162c1ad 100644
--- a/test/junit/scala/issues/OptimizedBytecodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala
@@ -1,18 +1,13 @@
-package scala.issues
+package scala.tools.nsc.backend.jvm
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
import scala.tools.asm.Opcodes._
-import org.junit.Assert._
-
-import scala.tools.nsc.backend.jvm.AsmUtils
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
import scala.tools.testing.BytecodeTesting._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-import scala.tools.testing.{BytecodeTesting, ClearAfterClass}
@RunWith(classOf[JUnit4])
class OptimizedBytecodeTest extends BytecodeTesting {