summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-05-23 10:17:15 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-05-23 10:17:15 +1000
commit2e40aa5871859b9ab6bdc03d56a81746fa90b1e5 (patch)
tree44db43073e3d974fc5ced61de278abd45b8e1227
parenta79b9b7220c87ba21b374eda25702c7bc446dc29 (diff)
parente26835c01254ecb4d9b4fa3a8bbe9c835f808a38 (diff)
downloadscala-2e40aa5871859b9ab6bdc03d56a81746fa90b1e5.tar.gz
scala-2e40aa5871859b9ab6bdc03d56a81746fa90b1e5.tar.bz2
scala-2e40aa5871859b9ab6bdc03d56a81746fa90b1e5.zip
Merge pull request #5180 from lrytz/junit-pass
Clean up JUnit tests, make sure they pass without bootstrap [ci: last-only]
-rw-r--r--test/junit/scala/BoxUnboxTest.scala119
-rw-r--r--test/junit/scala/PartialFunctionSerializationTest.scala16
-rw-r--r--test/junit/scala/collection/convert/NullSafetyTest.scala279
-rw-r--r--test/junit/scala/collection/convert/NullSafetyToJavaTest.scala138
-rw-r--r--test/junit/scala/collection/convert/NullSafetyToScalaTest.scala148
-rw-r--r--test/junit/scala/issues/BytecodeTest.scala482
-rw-r--r--test/junit/scala/issues/RunTest.scala253
-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.scala249
-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.scala282
-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/BTypesTest.scala33
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala140
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala17
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala34
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala24
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala34
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala (renamed from test/junit/scala/issues/OptimizedBytecodeTest.scala)96
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala22
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala49
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala83
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala33
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala32
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala46
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala51
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala22
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala27
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala12
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala31
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala56
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala29
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala31
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala304
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala178
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala25
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala10
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala52
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala34
-rw-r--r--test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala16
-rw-r--r--test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala69
-rw-r--r--test/junit/scala/tools/testing/BytecodeTesting.scala (renamed from test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala)243
-rw-r--r--test/junit/scala/tools/testing/RunTesting.scala17
46 files changed, 2051 insertions, 2036 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/collection/convert/NullSafetyTest.scala b/test/junit/scala/collection/convert/NullSafetyTest.scala
deleted file mode 100644
index 173568408c..0000000000
--- a/test/junit/scala/collection/convert/NullSafetyTest.scala
+++ /dev/null
@@ -1,279 +0,0 @@
-package scala.collection.convert
-
-import java.{util => ju, lang => jl}
-import ju.{concurrent => juc}
-
-import org.junit.Test
-import org.junit.experimental.runners.Enclosed
-import org.junit.runner.RunWith
-
-import collection.convert.ImplicitConversions._
-import scala.collection.JavaConverters._
-import scala.collection.{mutable, concurrent}
-
-@RunWith(classOf[Enclosed])
-object NullSafetyTest {
-
- /*
- * Pertinent: SI-9113
- * Tests to insure that wrappers return null instead of wrapping it as a collection
- */
-
- class ToScala {
-
- @Test def testIteratorWrapping(): Unit = {
- val nullJIterator: ju.Iterator[AnyRef] = null
- val iterator: Iterator[AnyRef] = nullJIterator
-
- assert(iterator == null)
- }
-
- @Test def testEnumerationWrapping(): Unit = {
- val nullJEnumeration: ju.Enumeration[AnyRef] = null
- val enumeration: Iterator[AnyRef] = nullJEnumeration
-
- assert(enumeration == null)
- }
-
- @Test def testIterableWrapping(): Unit = {
- val nullJIterable: jl.Iterable[AnyRef] = null
- val iterable: Iterable[AnyRef] = nullJIterable
-
- assert(iterable == null)
- }
-
- @Test def testCollectionWrapping(): Unit = {
- val nullJCollection: ju.Collection[AnyRef] = null
- val collection: Iterable[AnyRef] = nullJCollection
-
- assert(collection == null)
- }
-
- @Test def testBufferWrapping(): Unit = {
- val nullJList: ju.List[AnyRef] = null
- val buffer: mutable.Buffer[AnyRef] = nullJList
-
- assert(buffer == null)
- }
-
- @Test def testSetWrapping(): Unit = {
- val nullJSet: ju.Set[AnyRef] = null
- val set: mutable.Set[AnyRef] = nullJSet
-
- assert(set == null)
- }
-
- @Test def testMapWrapping(): Unit = {
- val nullJMap: ju.Map[AnyRef, AnyRef] = null
- val map: mutable.Map[AnyRef, AnyRef] = nullJMap
-
- assert(map == null)
- }
-
- @Test def testConcurrentMapWrapping(): Unit = {
- val nullJConMap: juc.ConcurrentMap[AnyRef, AnyRef] = null
- val conMap: concurrent.Map[AnyRef, AnyRef] = nullJConMap
-
- assert(conMap == null)
- }
-
- @Test def testDictionaryWrapping(): Unit = {
- val nullJDict: ju.Dictionary[AnyRef, AnyRef] = null
- val dict: mutable.Map[AnyRef, AnyRef] = nullJDict
-
- assert(dict == null)
- }
-
-
- @Test def testPropertyWrapping(): Unit = {
- val nullJProps: ju.Properties = null
- val props: mutable.Map[String, String] = nullJProps
-
- assert(props == null)
- }
-
- @Test def testIteratorDecoration(): Unit = {
- val nullJIterator: ju.Iterator[AnyRef] = null
-
- assert(nullJIterator.asScala == null)
- }
-
- @Test def testEnumerationDecoration(): Unit = {
- val nullJEnumeration: ju.Enumeration[AnyRef] = null
-
- assert(nullJEnumeration.asScala == null)
- }
-
- @Test def testIterableDecoration(): Unit = {
- val nullJIterable: jl.Iterable[AnyRef] = null
-
- assert(nullJIterable.asScala == null)
- }
-
- @Test def testCollectionDecoration(): Unit = {
- val nullJCollection: ju.Collection[AnyRef] = null
-
- assert(nullJCollection.asScala == null)
- }
-
- @Test def testBufferDecoration(): Unit = {
- val nullJBuffer: ju.List[AnyRef] = null
-
- assert(nullJBuffer.asScala == null)
- }
-
- @Test def testSetDecoration(): Unit = {
- val nullJSet: ju.Set[AnyRef] = null
-
- assert(nullJSet.asScala == null)
- }
-
- @Test def testMapDecoration(): Unit = {
- val nullJMap: ju.Map[AnyRef, AnyRef] = null
-
- assert(nullJMap.asScala == null)
- }
-
- @Test def testConcurrentMapDecoration(): Unit = {
- val nullJConMap: juc.ConcurrentMap[AnyRef, AnyRef] = null
-
- assert(nullJConMap.asScala == null)
- }
-
- @Test def testDictionaryDecoration(): Unit = {
- val nullJDict: ju.Dictionary[AnyRef, AnyRef] = null
-
- assert(nullJDict.asScala == null)
- }
-
- @Test def testPropertiesDecoration(): Unit = {
- val nullJProperties: ju.Properties = null
-
- assert(nullJProperties.asScala == null)
- }
- }
-
- class ToJava {
-
- @Test def testIteratorWrapping(): Unit = {
- val nullIterator: Iterator[AnyRef] = null
- val jIterator: ju.Iterator[AnyRef] = nullIterator
-
- assert(jIterator == null)
- }
-
- @Test def testEnumerationWrapping(): Unit = {
- val nullEnumeration: Iterator[AnyRef] = null
- val enumeration: ju.Iterator[AnyRef] = nullEnumeration
-
- assert(enumeration == null)
- }
-
- @Test def testIterableWrapping(): Unit = {
- val nullIterable: Iterable[AnyRef] = null
- val iterable: jl.Iterable[AnyRef] = asJavaIterable(nullIterable)
-
- assert(iterable == null)
- }
-
- @Test def testCollectionWrapping(): Unit = {
- val nullCollection: Iterable[AnyRef] = null
- val collection: ju.Collection[AnyRef] = nullCollection
-
- assert(collection == null)
- }
-
- @Test def testBufferWrapping(): Unit = {
- val nullList: mutable.Buffer[AnyRef] = null
- val buffer: ju.List[AnyRef] = nullList
-
- assert(buffer == null)
- }
-
- @Test def testSetWrapping(): Unit = {
- val nullSet: mutable.Set[AnyRef] = null
- val set: ju.Set[AnyRef] = nullSet
-
- assert(set == null)
- }
-
- @Test def testMapWrapping(): Unit = {
- val nullMap: mutable.Map[AnyRef, AnyRef] = null
- val map: ju.Map[AnyRef, AnyRef] = nullMap
-
- assert(map == null)
- }
-
- @Test def testConcurrentMapWrapping(): Unit = {
- val nullConMap: concurrent.Map[AnyRef, AnyRef] = null
- val conMap: juc.ConcurrentMap[AnyRef, AnyRef] = nullConMap
-
- assert(conMap == null)
- }
-
- @Test def testDictionaryWrapping(): Unit = {
- val nullDict: mutable.Map[AnyRef, AnyRef] = null
- val dict: ju.Dictionary[AnyRef, AnyRef] = nullDict
-
- assert(dict == null)
- }
-
- // Implicit conversion to ju.Properties is not available
-
- @Test def testIteratorDecoration(): Unit = {
- val nullIterator: Iterator[AnyRef] = null
-
- assert(nullIterator.asJava == null)
- }
-
- @Test def testEnumerationDecoration(): Unit = {
- val nullEnumeration: Iterator[AnyRef] = null
-
- assert(nullEnumeration.asJavaEnumeration == null)
- }
-
- @Test def testIterableDecoration(): Unit = {
- val nullIterable: Iterable[AnyRef] = null
-
- assert(nullIterable.asJava == null)
- }
-
- @Test def testCollectionDecoration(): Unit = {
- val nullCollection: Iterable[AnyRef] = null
-
- assert(nullCollection.asJavaCollection == null)
- }
-
- @Test def testBufferDecoration(): Unit = {
- val nullBuffer: mutable.Buffer[AnyRef] = null
-
- assert(nullBuffer.asJava == null)
- }
-
- @Test def testSetDecoration(): Unit = {
- val nullSet: Set[AnyRef] = null
-
- assert(nullSet.asJava == null)
- }
-
- @Test def testMapDecoration(): Unit = {
- val nullMap: mutable.Map[AnyRef, AnyRef] = null
-
- assert(nullMap.asJava == null)
- }
-
- @Test def testConcurrentMapDecoration(): Unit = {
- val nullConMap: concurrent.Map[AnyRef, AnyRef] = null
-
- assert(nullConMap.asJava == null)
- }
-
- @Test def testDictionaryDecoration(): Unit = {
- val nullDict: mutable.Map[AnyRef, AnyRef] = null
-
- assert(nullDict.asJavaDictionary == null)
- }
-
- // Decorator conversion to ju.Properties is not available
- }
-}
diff --git a/test/junit/scala/collection/convert/NullSafetyToJavaTest.scala b/test/junit/scala/collection/convert/NullSafetyToJavaTest.scala
new file mode 100644
index 0000000000..da0513ed8a
--- /dev/null
+++ b/test/junit/scala/collection/convert/NullSafetyToJavaTest.scala
@@ -0,0 +1,138 @@
+package scala.collection.convert
+
+import java.util.{concurrent => juc}
+import java.{lang => jl, util => ju}
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.collection.JavaConverters._
+import scala.collection.convert.ImplicitConversions._
+import scala.collection.{concurrent, mutable}
+
+// SI-9113: tests to insure that wrappers return null instead of wrapping it as a collection
+
+@RunWith(classOf[JUnit4])
+class NullSafetyToJavaTest {
+ @Test def testIteratorWrapping(): Unit = {
+ val nullIterator: Iterator[AnyRef] = null
+ val jIterator: ju.Iterator[AnyRef] = nullIterator
+
+ assert(jIterator == null)
+ }
+
+ @Test def testEnumerationWrapping(): Unit = {
+ val nullEnumeration: Iterator[AnyRef] = null
+ val enumeration: ju.Iterator[AnyRef] = nullEnumeration
+
+ assert(enumeration == null)
+ }
+
+ @Test def testIterableWrapping(): Unit = {
+ val nullIterable: Iterable[AnyRef] = null
+ val iterable: jl.Iterable[AnyRef] = asJavaIterable(nullIterable)
+
+ assert(iterable == null)
+ }
+
+ @Test def testCollectionWrapping(): Unit = {
+ val nullCollection: Iterable[AnyRef] = null
+ val collection: ju.Collection[AnyRef] = nullCollection
+
+ assert(collection == null)
+ }
+
+ @Test def testBufferWrapping(): Unit = {
+ val nullList: mutable.Buffer[AnyRef] = null
+ val buffer: ju.List[AnyRef] = nullList
+
+ assert(buffer == null)
+ }
+
+ @Test def testSetWrapping(): Unit = {
+ val nullSet: mutable.Set[AnyRef] = null
+ val set: ju.Set[AnyRef] = nullSet
+
+ assert(set == null)
+ }
+
+ @Test def testMapWrapping(): Unit = {
+ val nullMap: mutable.Map[AnyRef, AnyRef] = null
+ val map: ju.Map[AnyRef, AnyRef] = nullMap
+
+ assert(map == null)
+ }
+
+ @Test def testConcurrentMapWrapping(): Unit = {
+ val nullConMap: concurrent.Map[AnyRef, AnyRef] = null
+ val conMap: juc.ConcurrentMap[AnyRef, AnyRef] = nullConMap
+
+ assert(conMap == null)
+ }
+
+ @Test def testDictionaryWrapping(): Unit = {
+ val nullDict: mutable.Map[AnyRef, AnyRef] = null
+ val dict: ju.Dictionary[AnyRef, AnyRef] = nullDict
+
+ assert(dict == null)
+ }
+
+ // Implicit conversion to ju.Properties is not available
+
+ @Test def testIteratorDecoration(): Unit = {
+ val nullIterator: Iterator[AnyRef] = null
+
+ assert(nullIterator.asJava == null)
+ }
+
+ @Test def testEnumerationDecoration(): Unit = {
+ val nullEnumeration: Iterator[AnyRef] = null
+
+ assert(nullEnumeration.asJavaEnumeration == null)
+ }
+
+ @Test def testIterableDecoration(): Unit = {
+ val nullIterable: Iterable[AnyRef] = null
+
+ assert(nullIterable.asJava == null)
+ }
+
+ @Test def testCollectionDecoration(): Unit = {
+ val nullCollection: Iterable[AnyRef] = null
+
+ assert(nullCollection.asJavaCollection == null)
+ }
+
+ @Test def testBufferDecoration(): Unit = {
+ val nullBuffer: mutable.Buffer[AnyRef] = null
+
+ assert(nullBuffer.asJava == null)
+ }
+
+ @Test def testSetDecoration(): Unit = {
+ val nullSet: Set[AnyRef] = null
+
+ assert(nullSet.asJava == null)
+ }
+
+ @Test def testMapDecoration(): Unit = {
+ val nullMap: mutable.Map[AnyRef, AnyRef] = null
+
+ assert(nullMap.asJava == null)
+ }
+
+ @Test def testConcurrentMapDecoration(): Unit = {
+ val nullConMap: concurrent.Map[AnyRef, AnyRef] = null
+
+ assert(nullConMap.asJava == null)
+ }
+
+ @Test def testDictionaryDecoration(): Unit = {
+ val nullDict: mutable.Map[AnyRef, AnyRef] = null
+
+ assert(nullDict.asJavaDictionary == null)
+ }
+
+ // Decorator conversion to ju.Properties is not available
+}
diff --git a/test/junit/scala/collection/convert/NullSafetyToScalaTest.scala b/test/junit/scala/collection/convert/NullSafetyToScalaTest.scala
new file mode 100644
index 0000000000..9b6d366faf
--- /dev/null
+++ b/test/junit/scala/collection/convert/NullSafetyToScalaTest.scala
@@ -0,0 +1,148 @@
+package scala.collection.convert
+
+import java.util.{concurrent => juc}
+import java.{lang => jl, util => ju}
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.collection.JavaConverters._
+import scala.collection.convert.ImplicitConversions._
+import scala.collection.{concurrent, mutable}
+
+// SI-9113: tests to insure that wrappers return null instead of wrapping it as a collection
+
+@RunWith(classOf[JUnit4])
+class NullSafetyToScalaTest {
+ @Test def testIteratorWrapping(): Unit = {
+ val nullJIterator: ju.Iterator[AnyRef] = null
+ val iterator: Iterator[AnyRef] = nullJIterator
+
+ assert(iterator == null)
+ }
+
+ @Test def testEnumerationWrapping(): Unit = {
+ val nullJEnumeration: ju.Enumeration[AnyRef] = null
+ val enumeration: Iterator[AnyRef] = nullJEnumeration
+
+ assert(enumeration == null)
+ }
+
+ @Test def testIterableWrapping(): Unit = {
+ val nullJIterable: jl.Iterable[AnyRef] = null
+ val iterable: Iterable[AnyRef] = nullJIterable
+
+ assert(iterable == null)
+ }
+
+ @Test def testCollectionWrapping(): Unit = {
+ val nullJCollection: ju.Collection[AnyRef] = null
+ val collection: Iterable[AnyRef] = nullJCollection
+
+ assert(collection == null)
+ }
+
+ @Test def testBufferWrapping(): Unit = {
+ val nullJList: ju.List[AnyRef] = null
+ val buffer: mutable.Buffer[AnyRef] = nullJList
+
+ assert(buffer == null)
+ }
+
+ @Test def testSetWrapping(): Unit = {
+ val nullJSet: ju.Set[AnyRef] = null
+ val set: mutable.Set[AnyRef] = nullJSet
+
+ assert(set == null)
+ }
+
+ @Test def testMapWrapping(): Unit = {
+ val nullJMap: ju.Map[AnyRef, AnyRef] = null
+ val map: mutable.Map[AnyRef, AnyRef] = nullJMap
+
+ assert(map == null)
+ }
+
+ @Test def testConcurrentMapWrapping(): Unit = {
+ val nullJConMap: juc.ConcurrentMap[AnyRef, AnyRef] = null
+ val conMap: concurrent.Map[AnyRef, AnyRef] = nullJConMap
+
+ assert(conMap == null)
+ }
+
+ @Test def testDictionaryWrapping(): Unit = {
+ val nullJDict: ju.Dictionary[AnyRef, AnyRef] = null
+ val dict: mutable.Map[AnyRef, AnyRef] = nullJDict
+
+ assert(dict == null)
+ }
+
+
+ @Test def testPropertyWrapping(): Unit = {
+ val nullJProps: ju.Properties = null
+ val props: mutable.Map[String, String] = nullJProps
+
+ assert(props == null)
+ }
+
+ @Test def testIteratorDecoration(): Unit = {
+ val nullJIterator: ju.Iterator[AnyRef] = null
+
+ assert(nullJIterator.asScala == null)
+ }
+
+ @Test def testEnumerationDecoration(): Unit = {
+ val nullJEnumeration: ju.Enumeration[AnyRef] = null
+
+ assert(nullJEnumeration.asScala == null)
+ }
+
+ @Test def testIterableDecoration(): Unit = {
+ val nullJIterable: jl.Iterable[AnyRef] = null
+
+ assert(nullJIterable.asScala == null)
+ }
+
+ @Test def testCollectionDecoration(): Unit = {
+ val nullJCollection: ju.Collection[AnyRef] = null
+
+ assert(nullJCollection.asScala == null)
+ }
+
+ @Test def testBufferDecoration(): Unit = {
+ val nullJBuffer: ju.List[AnyRef] = null
+
+ assert(nullJBuffer.asScala == null)
+ }
+
+ @Test def testSetDecoration(): Unit = {
+ val nullJSet: ju.Set[AnyRef] = null
+
+ assert(nullJSet.asScala == null)
+ }
+
+ @Test def testMapDecoration(): Unit = {
+ val nullJMap: ju.Map[AnyRef, AnyRef] = null
+
+ assert(nullJMap.asScala == null)
+ }
+
+ @Test def testConcurrentMapDecoration(): Unit = {
+ val nullJConMap: juc.ConcurrentMap[AnyRef, AnyRef] = null
+
+ assert(nullJConMap.asScala == null)
+ }
+
+ @Test def testDictionaryDecoration(): Unit = {
+ val nullJDict: ju.Dictionary[AnyRef, AnyRef] = null
+
+ assert(nullJDict.asScala == null)
+ }
+
+ @Test def testPropertiesDecoration(): Unit = {
+ val nullJProperties: ju.Properties = null
+
+ assert(nullJProperties.asScala == null)
+ }
+}
diff --git a/test/junit/scala/issues/BytecodeTest.scala b/test/junit/scala/issues/BytecodeTest.scala
deleted file mode 100644
index 7b9474b52e..0000000000
--- a/test/junit/scala/issues/BytecodeTest.scala
+++ /dev/null
@@ -1,482 +0,0 @@
-package scala.issues
-
-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._
-import scala.tools.asm.Opcodes
-import scala.tools.asm.tree.ClassNode
-import scala.tools.partest.ASMConverters._
-import scala.tools.testing.ClearAfterClass
-
-@RunWith(classOf[JUnit4])
-class BytecodeTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler())
-
- @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 List(c) = compileClasses(compiler)(code)
-
- 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 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")
- }
-
- @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(compiler)(code)
-
- val unapplyLineNumbers = getSingleMethod(module, "unapply").instructions.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 = getSingleMethod(module, "main").instructions 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 List(c) = compileClasses(compiler)(code)
-
- // t1: no unnecessary GOTOs
- assertSameCode(getSingleMethod(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(getSingleMethod(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(getSingleMethod(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(getSingleMethod(c, "t4"), t4t5)
-
- // t5: one side known null, so just a null check on the other
- assertSameCode(getSingleMethod(c, "t5"), t4t5)
-
- // t6: no unnecessary GOTOs
- assertSameCode(getSingleMethod(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(getSingleMethod(c, "t7"), "scala/runtime/BoxesRunTime", "equals")
-
- // t8: no null checks invoking equals on modules and constants
- assertSameCode(getSingleMethod(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)))
- }
-
- object forwarderTestUtils {
- def findMethods(cls: ClassNode, name: String): List[Method] = cls.methods.iterator.asScala.find(_.name == name).map(convertMethod).toList
-
- import language.implicitConversions
- implicit def s2c(s: Symbol)(implicit classes: Map[String, ClassNode]): ClassNode = classes(s.name)
-
- def checkForwarder(c: ClassNode, target: String) = {
- val List(f) = findMethods(c, "f")
- assertSameCode(f, List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, target, "f", "()I", false), Op(IRETURN)))
- }
- }
-
- @Test
- def traitMethodForwarders(): Unit = {
- import forwarderTestUtils._
- val code =
- """trait T1 { def f = 1 }
- |trait T2 extends T1 { override def f = 2 }
- |trait T3 { self: T1 => override def f = 3 }
- |
- |abstract class A1 { def f: Int }
- |class A2 { def f: Int = 4 }
- |
- |trait T4 extends A1 { def f = 5 }
- |trait T5 extends A2 { override def f = 6 }
- |
- |trait T6 { def f: Int }
- |trait T7 extends T6 { abstract override def f = super.f + 1 }
- |
- |trait T8 { override def clone() = super.clone() }
- |
- |class A3 extends T1 { override def f = 7 }
- |
- |class C1 extends T1
- |class C2 extends T2
- |class C3 extends T1 with T2
- |class C4 extends T2 with T1
- |class C5 extends T1 with T3
- |
- |// traits extending a class that defines f
- |class C6 extends T4
- |class C7 extends T5
- |class C8 extends A1 with T4
- |class C9 extends A2 with T5
- |
- |// T6: abstract f in trait
- |class C10 extends T6 with T1
- |class C11 extends T6 with T2
- |abstract class C12 extends A1 with T6
- |class C13 extends A2 with T6
- |class C14 extends T4 with T6
- |class C15 extends T5 with T6
- |
- |// superclass overrides a trait method
- |class C16 extends A3
- |class C17 extends A3 with T1
- |
- |// abstract override
- |class C18 extends T6 { def f = 22 }
- |class C19 extends C18 with T7
- |
- |class C20 extends T8
- """.stripMargin
-
- implicit val classes = compileClasses(compiler)(code).map(c => (c.name, c)).toMap
-
- val noForwarder = List('C1, 'C2, 'C3, 'C4, 'C10, 'C11, 'C12, 'C13, 'C16, 'C17)
- for (c <- noForwarder) assertEquals(findMethods(c, "f"), Nil)
-
- checkForwarder('C5, "T3")
- checkForwarder('C6, "T4")
- checkForwarder('C7, "T5")
- checkForwarder('C8, "T4")
- checkForwarder('C9, "T5")
- checkForwarder('C14, "T4")
- checkForwarder('C15, "T5")
- assertSameSummary(getSingleMethod('C18, "f"), List(BIPUSH, IRETURN))
- checkForwarder('C19, "T7")
- assertSameCode(getSingleMethod('C19, "T7$$super$f"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "C18", "f", "()I", false), Op(IRETURN)))
- assertInvoke(getSingleMethod('C20, "clone"), "T8", "clone") // mixin forwarder
- }
-
- @Test
- def noTraitMethodForwardersForOverloads(): Unit = {
- import forwarderTestUtils._
- val code =
- """trait T1 { def f(x: Int) = 0 }
- |trait T2 { def f(x: String) = 1 }
- |class C extends T1 with T2
- """.stripMargin
- val List(c, t1, t2) = compileClasses(compiler)(code)
- assertEquals(findMethods(c, "f"), Nil)
- }
-
- @Test
- def traitMethodForwardersForJavaDefaultMethods(): Unit = {
- import forwarderTestUtils._
- val j1 = ("interface J1 { int f(); }", "J1.java")
- val j2 = ("interface J2 { default int f() { return 1; } }", "J2.java")
- val j3 = ("interface J3 extends J1 { default int f() { return 2; } }", "J3.java")
- val j4 = ("interface J4 extends J2 { default int f() { return 3; } }", "J4.java")
- val code =
- """trait T1 extends J2 { override def f = 4 }
- |trait T2 { self: J2 => override def f = 5 }
- |
- |class K1 extends J2
- |class K2 extends J1 with J2
- |class K3 extends J2 with J1
- |
- |class K4 extends J3
- |class K5 extends J3 with J1
- |class K6 extends J1 with J3
- |
- |class K7 extends J4
- |class K8 extends J4 with J2
- |class K9 extends J2 with J4
- |
- |class K10 extends T1 with J2
- |class K11 extends J2 with T1
- |
- |class K12 extends J2 with T2
- """.stripMargin
- implicit val classes = compileClasses(compiler)(code, List(j1, j2, j3, j4)).map(c => (c.name, c)).toMap
-
- val noForwarder = List('K1, 'K2, 'K3, 'K4, 'K5, 'K6, 'K7, 'K8, 'K9, 'K10, 'K11)
- for (c <- noForwarder) assertEquals(findMethods(c, "f"), Nil)
-
- checkForwarder('K12, "T2")
- }
-
- @Test
- def invocationReceivers(): Unit = {
- val List(c1, c2, t, u) = compileClasses(compiler)(invocationReceiversTestCode.definitions("Object"))
- // mixin forwarder in C1
- assertSameCode(getSingleMethod(c1, "clone"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "T", "clone", "()Ljava/lang/Object;", false), Op(ARETURN)))
- assertInvoke(getSingleMethod(c1, "f1"), "T", "clone")
- assertInvoke(getSingleMethod(c1, "f2"), "T", "clone")
- assertInvoke(getSingleMethod(c1, "f3"), "C1", "clone")
- assertInvoke(getSingleMethod(c2, "f1"), "T", "clone")
- assertInvoke(getSingleMethod(c2, "f2"), "T", "clone")
- assertInvoke(getSingleMethod(c2, "f3"), "C1", "clone")
-
- val List(c1b, c2b, tb, ub) = compileClasses(compiler)(invocationReceiversTestCode.definitions("String"))
- def ms(c: ClassNode, n: String) = c.methods.asScala.toList.filter(_.name == n)
- assert(ms(tb, "clone").length == 1)
- assert(ms(ub, "clone").isEmpty)
- val List(c1Clone) = ms(c1b, "clone")
- assertEquals(c1Clone.desc, "()Ljava/lang/Object;")
- assert((c1Clone.access | Opcodes.ACC_BRIDGE) != 0)
- assertSameCode(convertMethod(c1Clone), List(VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C1", "clone", "()Ljava/lang/String;", false), Op(ARETURN)))
-
- def iv(m: Method) = getSingleMethod(c1b, "f1").instructions.collect({case i: Invoke => i})
- assertSameCode(iv(getSingleMethod(c1b, "f1")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true)))
- assertSameCode(iv(getSingleMethod(c1b, "f2")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true)))
- // invokeinterface T.clone in C1 is OK here because it is not an override of Object.clone (different siganture)
- assertSameCode(iv(getSingleMethod(c1b, "f3")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true)))
- }
-
- @Test
- def invocationReceiversProtected(): Unit = {
- // http://lrytz.github.io/scala-aladdin-bugtracker/displayItem.do%3Fid=455.html / 9954eaf
- // also https://issues.scala-lang.org/browse/SI-1430 / 0bea2ab (same but with interfaces)
- val aC =
- """package a;
- |/*package private*/ abstract class A {
- | public int f() { return 1; }
- | public int t;
- |}
- """.stripMargin
- val bC =
- """package a;
- |public class B extends A { }
- """.stripMargin
- val iC =
- """package a;
- |/*package private*/ interface I { int f(); }
- """.stripMargin
- val jC =
- """package a;
- |public interface J extends I { }
- """.stripMargin
- val cC =
- """package b
- |class C {
- | def f1(b: a.B) = b.f
- | def f2(b: a.B) = { b.t = b.t + 1 }
- | def f3(j: a.J) = j.f
- |}
- """.stripMargin
- val List(c) = compileClasses(compiler)(cC, javaCode = List((aC, "A.java"), (bC, "B.java"), (iC, "I.java"), (jC, "J.java")))
- assertInvoke(getSingleMethod(c, "f1"), "a/B", "f") // receiver needs to be B (A is not accessible in class C, package b)
- println(getSingleMethod(c, "f2").instructions.stringLines)
- assertInvoke(getSingleMethod(c, "f3"), "a/J", "f") // receiver needs to be J
- }
-
- @Test
- def specialInvocationReceivers(): Unit = {
- val code =
- """class C {
- | def f1(a: Array[String]) = a.clone()
- | def f2(a: Array[Int]) = a.hashCode()
- | def f3(n: Nothing) = n.hashCode()
- | def f4(n: Null) = n.toString()
- |
- |}
- """.stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertInvoke(getSingleMethod(c, "f1"), "[Ljava/lang/String;", "clone") // array descriptor as receiver
- assertInvoke(getSingleMethod(c, "f2"), "java/lang/Object", "hashCode") // object receiver
- assertInvoke(getSingleMethod(c, "f3"), "java/lang/Object", "hashCode")
- assertInvoke(getSingleMethod(c, "f4"), "java/lang/Object", "toString")
- }
-
- @Test
- def superConstructorArgumentInSpecializedClass(): Unit = {
- // see comment in SpecializeTypes.forwardCtorCall
- val code = "case class C[@specialized(Int) T](_1: T)"
- val List(c, cMod, cSpec) = compileClasses(compiler)(code)
- assertSameSummary(getSingleMethod(cSpec, "<init>"),
- // 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
- |}
- """.stripMargin
-
- val runCode =
- """
- |val r = new StringBuffer()
- |val c1 = new C1
- |r.append(c1.f1)
- |r.append(c1.f2)
- |r.append(c1.f3)
- |val t = new T { }
- |val u = new U { }
- |val c2 = new C2
- |r.append(c2.f1(t))
- |r.append(c2.f1(u))
- |r.append(c2.f1(c1))
- |r.append(c2.f2(u))
- |r.append(c2.f2(c1))
- |r.append(c2.f3(c1))
- |r.toString
- """.stripMargin
-}
diff --git a/test/junit/scala/issues/RunTest.scala b/test/junit/scala/issues/RunTest.scala
deleted file mode 100644
index 3ebdc8a72f..0000000000
--- a/test/junit/scala/issues/RunTest.scala
+++ /dev/null
@@ -1,253 +0,0 @@
-package scala.issues
-
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.junit.{AfterClass, BeforeClass, Test}
-import org.junit.Assert._
-
-import scala.reflect.runtime._
-import scala.tools.reflect.ToolBox
-import scala.tools.testing.ClearAfterClass
-
-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 ClearAfterClass {
- val toolBox = cached("toolbox", () => universe.runtimeMirror(getClass.getClassLoader).mkToolBox())
-
- def run[T](code: String): T = {
- toolBox.eval(toolBox.parse(code)).asInstanceOf[T]
- }
-
- @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..e4911f1af5
--- /dev/null
+++ b/test/junit/scala/lang/primitives/BoxUnboxTest.scala
@@ -0,0 +1,249 @@
+package scala.lang.primitives
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+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._
+
+ @Test
+ def boxUnboxInt(): Unit = {
+ // Once we use 2.12.0-M5 as starr, this code can be run directly in the JUnit test.
+ // Some fixes not yet available in M4 make the test fail when compiled with M4.
+ val code =
+ """import scala.tools.testing.AssertUtil._
+ |import org.junit.Assert._
+ |
+ |def genericNull[T] = null.asInstanceOf[T] // allowed, see SI-4437, point 2
+ |
+ |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)
+ """.stripMargin
+
+ run[Unit](code)
+ }
+
+ @Test
+ def numericConversions(): Unit = {
+ // Once we use 2.12.0-M5 as starr, this code can be run directly in the JUnit test.
+ val code =
+ """import scala.tools.testing.AssertUtil._
+ |import org.junit.Assert._
+ |
+ |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)
+ |}
+ """.stripMargin
+ run[Unit](code)
+ }
+
+ @Test
+ def boxUnboxBoolean(): Unit = {
+ // Once we use 2.12.0-M5 as starr, this code can be run directly in the JUnit test.
+ val code =
+ """val n1 = Option(null.asInstanceOf[Boolean])
+ |n1
+ """.stripMargin
+ assertEquals(run[Option[Boolean]](code), 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 ()).
+
+ // Once we use 2.12.0-M5 as starr, this code can be run directly in the JUnit test.
+ val code =
+ """import scala.tools.testing.AssertUtil._
+ |import org.junit.Assert._
+ |
+ |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, "()")
+ """.stripMargin
+ run[Unit](code)
+ }
+
+ @Test
+ def t9671(): Unit = {
+ // Once we use 2.12.0-M5 as starr, this code can be run directly in the JUnit test.
+ 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/lang/traits/BytecodeTest.scala b/test/junit/scala/lang/traits/BytecodeTest.scala
new file mode 100644
index 0000000000..f47fc9c127
--- /dev/null
+++ b/test/junit/scala/lang/traits/BytecodeTest.scala
@@ -0,0 +1,282 @@
+package scala.lang.traits
+
+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.asm.Opcodes
+import scala.tools.asm.Opcodes._
+import scala.tools.asm.tree.ClassNode
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
+
+@RunWith(classOf[JUnit4])
+class BytecodeTest extends BytecodeTesting {
+ import compiler._
+
+ 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)))
+ }
+
+ @Test
+ def traitMethodForwarders(): Unit = {
+ val code =
+ """trait T1 { def f = 1 }
+ |trait T2 extends T1 { override def f = 2 }
+ |trait T3 { self: T1 => override def f = 3 }
+ |
+ |abstract class A1 { def f: Int }
+ |class A2 { def f: Int = 4 }
+ |
+ |trait T4 extends A1 { def f = 5 }
+ |trait T5 extends A2 { override def f = 6 }
+ |
+ |trait T6 { def f: Int }
+ |trait T7 extends T6 { abstract override def f = super.f + 1 }
+ |
+ |trait T8 { override def clone() = super.clone() }
+ |
+ |class A3 extends T1 { override def f = 7 }
+ |
+ |class C1 extends T1
+ |class C2 extends T2
+ |class C3 extends T1 with T2
+ |class C4 extends T2 with T1
+ |class C5 extends T1 with T3
+ |
+ |// traits extending a class that defines f
+ |class C6 extends T4
+ |class C7 extends T5
+ |class C8 extends A1 with T4
+ |class C9 extends A2 with T5
+ |
+ |// T6: abstract f in trait
+ |class C10 extends T6 with T1
+ |class C11 extends T6 with T2
+ |abstract class C12 extends A1 with T6
+ |class C13 extends A2 with T6
+ |class C14 extends T4 with T6
+ |class C15 extends T5 with T6
+ |
+ |// superclass overrides a trait method
+ |class C16 extends A3
+ |class C17 extends A3 with T1
+ |
+ |// abstract override
+ |class C18 extends T6 { def f = 22 }
+ |class C19 extends C18 with T7
+ |
+ |class C20 extends T8
+ """.stripMargin
+
+ val c = compileClasses(code).map(c => (c.name, c)).toMap
+
+ val noForwarder = List('C1, 'C2, 'C3, 'C4, 'C10, 'C11, 'C12, 'C13, 'C16, 'C17)
+ for (cn <- noForwarder) assertEquals(getMethods(c(cn.name), "f"), Nil)
+
+ checkForwarder(c, 'C5, "T3")
+ checkForwarder(c, 'C6, "T4")
+ checkForwarder(c, 'C7, "T5")
+ checkForwarder(c, 'C8, "T4")
+ checkForwarder(c, 'C9, "T5")
+ checkForwarder(c, 'C14, "T4")
+ checkForwarder(c, 'C15, "T5")
+ assertSameSummary(getMethod(c("C18"), "f"), List(BIPUSH, IRETURN))
+ checkForwarder(c, 'C19, "T7")
+ assertSameCode(getMethod(c("C19"), "T7$$super$f"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "C18", "f", "()I", false), Op(IRETURN)))
+ assertInvoke(getMethod(c("C20"), "clone"), "T8", "clone") // mixin forwarder
+ }
+
+ @Test
+ def noTraitMethodForwardersForOverloads(): Unit = {
+ val code =
+ """trait T1 { def f(x: Int) = 0 }
+ |trait T2 { def f(x: String) = 1 }
+ |class C extends T1 with T2
+ """.stripMargin
+ val List(c, t1, t2) = compileClasses(code)
+ assertEquals(getMethods(c, "f"), Nil)
+ }
+
+ @Test
+ def traitMethodForwardersForJavaDefaultMethods(): Unit = {
+ val j1 = ("interface J1 { int f(); }", "J1.java")
+ val j2 = ("interface J2 { default int f() { return 1; } }", "J2.java")
+ val j3 = ("interface J3 extends J1 { default int f() { return 2; } }", "J3.java")
+ val j4 = ("interface J4 extends J2 { default int f() { return 3; } }", "J4.java")
+ val code =
+ """trait T1 extends J2 { override def f = 4 }
+ |trait T2 { self: J2 => override def f = 5 }
+ |
+ |class K1 extends J2
+ |class K2 extends J1 with J2
+ |class K3 extends J2 with J1
+ |
+ |class K4 extends J3
+ |class K5 extends J3 with J1
+ |class K6 extends J1 with J3
+ |
+ |class K7 extends J4
+ |class K8 extends J4 with J2
+ |class K9 extends J2 with J4
+ |
+ |class K10 extends T1 with J2
+ |class K11 extends J2 with T1
+ |
+ |class K12 extends J2 with T2
+ """.stripMargin
+ val c = compileClasses(code, List(j1, j2, j3, j4)).map(c => (c.name, c)).toMap
+
+ val noForwarder = List('K1, 'K2, 'K3, 'K4, 'K5, 'K6, 'K7, 'K8, 'K9, 'K10, 'K11)
+ for (cn <- noForwarder) assertEquals(getMethods(c(cn.name), "f"), Nil)
+
+ checkForwarder(c, 'K12, "T2")
+ }
+
+ @Test
+ def invocationReceivers(): Unit = {
+ val List(c1, c2, t, u) = compileClasses(invocationReceiversTestCode.definitions("Object"))
+ // mixin forwarder in C1
+ assertSameCode(getMethod(c1, "clone"), List(VarOp(ALOAD, 0), Invoke(INVOKESPECIAL, "T", "clone", "()Ljava/lang/Object;", false), Op(ARETURN)))
+ assertInvoke(getMethod(c1, "f1"), "T", "clone")
+ assertInvoke(getMethod(c1, "f2"), "T", "clone")
+ assertInvoke(getMethod(c1, "f3"), "C1", "clone")
+ assertInvoke(getMethod(c2, "f1"), "T", "clone")
+ assertInvoke(getMethod(c2, "f2"), "T", "clone")
+ assertInvoke(getMethod(c2, "f3"), "C1", "clone")
+
+ val List(c1b, c2b, tb, ub) = compileClasses(invocationReceiversTestCode.definitions("String"))
+ def ms(c: ClassNode, n: String) = c.methods.asScala.toList.filter(_.name == n)
+ assert(ms(tb, "clone").length == 1)
+ assert(ms(ub, "clone").isEmpty)
+ val List(c1Clone) = ms(c1b, "clone")
+ assertEquals(c1Clone.desc, "()Ljava/lang/Object;")
+ assert((c1Clone.access | Opcodes.ACC_BRIDGE) != 0)
+ assertSameCode(convertMethod(c1Clone), List(VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C1", "clone", "()Ljava/lang/String;", false), Op(ARETURN)))
+
+ def iv(m: Method) = getInstructions(c1b, "f1").collect({case i: Invoke => i})
+ assertSameCode(iv(getMethod(c1b, "f1")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true)))
+ assertSameCode(iv(getMethod(c1b, "f2")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true)))
+ // invokeinterface T.clone in C1 is OK here because it is not an override of Object.clone (different siganture)
+ assertSameCode(iv(getMethod(c1b, "f3")), List(Invoke(INVOKEINTERFACE, "T", "clone", "()Ljava/lang/String;", true)))
+ }
+
+ @Test
+ def invocationReceiversProtected(): Unit = {
+ // http://lrytz.github.io/scala-aladdin-bugtracker/displayItem.do%3Fid=455.html / 9954eaf
+ // also https://issues.scala-lang.org/browse/SI-1430 / 0bea2ab (same but with interfaces)
+ val aC =
+ """package a;
+ |/*package private*/ abstract class A {
+ | public int f() { return 1; }
+ | public int t;
+ |}
+ """.stripMargin
+ val bC =
+ """package a;
+ |public class B extends A { }
+ """.stripMargin
+ val iC =
+ """package a;
+ |/*package private*/ interface I { int f(); }
+ """.stripMargin
+ val jC =
+ """package a;
+ |public interface J extends I { }
+ """.stripMargin
+ val cC =
+ """package b
+ |class C {
+ | def f1(b: a.B) = b.f
+ | def f2(b: a.B) = { b.t = b.t + 1 }
+ | def f3(j: a.J) = j.f
+ |}
+ """.stripMargin
+ val c = compileClass(cC, javaCode = List((aC, "A.java"), (bC, "B.java"), (iC, "I.java"), (jC, "J.java")))
+ assertInvoke(getMethod(c, "f1"), "a/B", "f") // receiver needs to be B (A is not accessible in class C, package b)
+ assertInvoke(getMethod(c, "f3"), "a/J", "f") // receiver needs to be J
+ }
+
+ @Test
+ def specialInvocationReceivers(): Unit = {
+ val code =
+ """class C {
+ | def f1(a: Array[String]) = a.clone()
+ | def f2(a: Array[Int]) = a.hashCode()
+ | def f3(n: Nothing) = n.hashCode()
+ | def f4(n: Null) = n.toString()
+ |
+ |}
+ """.stripMargin
+ val c = compileClass(code)
+ assertInvoke(getMethod(c, "f1"), "[Ljava/lang/String;", "clone") // array descriptor as receiver
+ assertInvoke(getMethod(c, "f2"), "java/lang/Object", "hashCode") // object receiver
+ assertInvoke(getMethod(c, "f3"), "java/lang/Object", "hashCode")
+ assertInvoke(getMethod(c, "f4"), "java/lang/Object", "toString")
+ }
+
+ @Test
+ def superConstructorArgumentInSpecializedClass(): Unit = {
+ // see comment in SpecializeTypes.forwardCtorCall
+ val code = "case class C[@specialized(Int) T](_1: T)"
+ val List(c, cMod, cSpec) = compileClasses(code)
+ assertSameSummary(getMethod(cSpec, "<init>"),
+ // 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
+ |}
+ """.stripMargin
+
+ val runCode =
+ """
+ |val r = new StringBuffer()
+ |val c1 = new C1
+ |r.append(c1.f1)
+ |r.append(c1.f2)
+ |r.append(c1.f3)
+ |val t = new T { }
+ |val u = new U { }
+ |val c2 = new C2
+ |r.append(c2.f1(t))
+ |r.append(c2.f1(u))
+ |r.append(c2.f1(c1))
+ |r.append(c2.f2(u))
+ |r.append(c2.f2(c1))
+ |r.append(c2.f3(c1))
+ |r.toString
+ """.stripMargin
+}
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/BTypesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala
index e7bbbb9a4f..0144fa7366 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala
@@ -1,30 +1,29 @@
package scala.tools.nsc
package backend.jvm
+import org.junit.Assert._
+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.CodeGenTools._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.asm.Opcodes
+import scala.tools.testing.BytecodeTesting
@RunWith(classOf[JUnit4])
-class BTypesTest extends ClearAfterClass {
- val compiler = cached("compiler", () => {
- val comp = newCompiler(extraArgs = "-Yopt:l:none")
- new comp.Run() // initializes some of the compiler
- comp.exitingDelambdafy(comp.scalaPrimitives.init()) // needed: it's only done when running the backend, and we don't actually run the compiler
- comp.exitingDelambdafy(comp.genBCode.bTypes.initializeCoreBTypes())
- comp
- })
- import compiler.genBCode.bTypes._
+class BTypesTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:none"
+ import compiler.global
+ locally {
+ new global.Run() // initializes some of the compiler
+ global.exitingDelambdafy(global.scalaPrimitives.init()) // needed: it's only done when running the backend, and we don't actually run the compiler
+ global.exitingDelambdafy(global.genBCode.bTypes.initializeCoreBTypes())
+ }
+ import global.genBCode.bTypes._
- def classBTFS(sym: compiler.Symbol) = compiler.exitingDelambdafy(classBTypeFromSymbol(sym))
+ def classBTFS(sym: global.Symbol) = global.exitingDelambdafy(classBTypeFromSymbol(sym))
- def jlo = compiler.definitions.ObjectClass
- def jls = compiler.definitions.StringClass
+ def jlo = global.definitions.ObjectClass
+ def jls = global.definitions.StringClass
def o = classBTFS(jlo)
def s = classBTFS(jls)
def oArr = ArrayBType(o)
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/tools/nsc/backend/jvm/DefaultMethodTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala
index 7d4ae866fc..c9a958ee4f 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala
@@ -4,30 +4,29 @@ import org.junit.Assert._
import org.junit.Test
import scala.collection.JavaConverters
+import scala.collection.JavaConverters._
import scala.tools.asm.Opcodes
import scala.tools.asm.tree.ClassNode
-import scala.tools.nsc.backend.jvm.CodeGenTools._
-import JavaConverters._
-import scala.tools.testing.ClearAfterClass
-
-class DefaultMethodTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler())
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
+class DefaultMethodTest extends BytecodeTesting {
+ import compiler._
@Test
def defaultMethodsViaGenBCode(): Unit = {
- import compiler._
+ import global._
val code = "package pack { trait T { def foo: Int }}"
object makeFooDefaultMethod extends Transformer {
val Foo = TermName("foo")
/** Transforms a single tree. */
- override def transform(tree: compiler.Tree): compiler.Tree = tree match {
+ override def transform(tree: global.Tree): global.Tree = tree match {
case dd @ DefDef(_, Foo, _, _, _, _) =>
dd.symbol.setFlag(reflect.internal.Flags.JAVA_DEFAULTMETHOD)
copyDefDef(dd)(rhs = Literal(Constant(1)).setType(definitions.IntTpe))
case _ => super.transform(tree)
}
}
- val asmClasses: List[ClassNode] = readAsmClasses(compileTransformed(compiler)(code, Nil, makeFooDefaultMethod.transform(_)))
+ val asmClasses: List[ClassNode] = compiler.compileClassesTransformed(code, Nil, makeFooDefaultMethod.transform(_))
val foo = asmClasses.head.methods.iterator.asScala.toList.last
assertTrue("default method should not be abstract", (foo.access & Opcodes.ACC_ABSTRACT) == 0)
assertTrue("default method body emitted", foo.instructions.size() > 0)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala
index e984b75518..7fdfb31577 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala
@@ -1,21 +1,23 @@
package scala.tools.nsc.backend.jvm
+import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Assert._
-import CodeGenTools._
+
import scala.tools.asm.Opcodes._
import scala.tools.partest.ASMConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class DirectCompileTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:method"))
+class DirectCompileTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:method"
+ import compiler._
@Test
def testCompile(): Unit = {
- val List(("C.class", bytes)) = compile(compiler)(
+ val List(("C.class", bytes)) = compileToBytes(
"""class C {
| def f = 1
|}
@@ -26,12 +28,12 @@ class DirectCompileTest extends ClearAfterClass {
@Test
def testCompileClasses(): Unit = {
- val List(cClass, cModuleClass) = compileClasses(compiler)("class C; object C")
+ val List(cClass, cModuleClass) = compileClasses("class C; object C")
assertTrue(cClass.name == "C")
assertTrue(cModuleClass.name == "C$")
- val List(dMirror, dModuleClass) = compileClasses(compiler)("object D")
+ val List(dMirror, dModuleClass) = compileClasses("object D")
assertTrue(dMirror.name == "D")
assertTrue(dModuleClass.name == "D$")
@@ -39,25 +41,23 @@ class DirectCompileTest extends ClearAfterClass {
@Test
def testCompileMethods(): Unit = {
- val List(f, g) = compileMethods(compiler)(
+ val List(f, g) = compileMethods(
"""def f = 10
|def g = f
""".stripMargin)
- assertTrue(f.name == "f")
- assertTrue(g.name == "g")
- assertSameCode(instructionsFromMethod(f).dropNonOp,
+ assertSameCode(f.instructions.dropNonOp,
List(IntOp(BIPUSH, 10), Op(IRETURN)))
- assertSameCode(instructionsFromMethod(g).dropNonOp,
+ assertSameCode(g.instructions.dropNonOp,
List(VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C", "f", "()I", itf = false), Op(IRETURN)))
}
@Test
def testDropNonOpAliveLabels(): Unit = {
// makes sure that dropNoOp doesn't drop labels that are being used
- val List(f) = compileMethods(compiler)("""def f(x: Int) = if (x == 0) "a" else "b"""")
- assertSameCode(instructionsFromMethod(f).dropLinesFrames, List(
+ val is = compileInstructions("""def f(x: Int) = if (x == 0) "a" else "b"""")
+ assertSameCode(is.dropLinesFrames, List(
Label(0),
VarOp(ILOAD, 1),
Op(ICONST_0),
@@ -77,7 +77,7 @@ class DirectCompileTest extends ClearAfterClass {
val codeA = "class A { def f = 1 }"
val codeB = "class B extends A { def g = f }"
val List(a, b) = compileClassesSeparately(List(codeA, codeB))
- val ins = getSingleMethod(b, "g").instructions
+ val ins = getInstructions(b, "g")
assert(ins exists {
case Invoke(_, "B", "f", _, _) => true
case _ => false
@@ -86,6 +86,6 @@ class DirectCompileTest extends ClearAfterClass {
@Test
def compileErroneous(): Unit = {
- compileClasses(compiler)("class C { def f: String = 1 }", allowMessage = _.msg contains "type mismatch")
+ compileToBytes("class C { def f: String = 1 }", allowMessage = _.msg contains "type mismatch")
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala
index b906942ffa..ac2aab01dc 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/IndyLambdaTest.scala
@@ -1,21 +1,19 @@
package scala.tools.nsc.backend.jvm
import org.junit.Assert._
-import org.junit.{Assert, Test}
+import org.junit.Test
-import scala.tools.asm.{Handle, Opcodes}
-import scala.tools.asm.tree.InvokeDynamicInsnNode
-import scala.tools.nsc.backend.jvm.AsmUtils._
-import scala.tools.nsc.backend.jvm.CodeGenTools._
-import scala.tools.testing.ClearAfterClass
import scala.collection.JavaConverters._
+import scala.tools.asm.Handle
+import scala.tools.asm.tree.InvokeDynamicInsnNode
+import scala.tools.testing.BytecodeTesting
-class IndyLambdaTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler())
+class IndyLambdaTest extends BytecodeTesting {
+ import compiler._
@Test def boxingBridgeMethodUsedSelectively(): Unit = {
def implMethodDescriptorFor(code: String): String = {
- val method = compileMethods(compiler)(s"""def f = $code """).find(_.name == "f").get
+ val method = compileAsmMethods(s"""def f = $code """).find(_.name == "f").get
val x = method.instructions.iterator.asScala.toList
x.flatMap {
case insn : InvokeDynamicInsnNode => insn.bsmArgs.collect { case h : Handle => h.getDesc }
@@ -48,17 +46,17 @@ class IndyLambdaTest extends ClearAfterClass {
assertEquals("(I)I", implMethodDescriptorFor("(x: Int) => x"))
// non-builtin sams are like specialized functions
- compileClasses(compiler)("class VC(private val i: Int) extends AnyVal; trait FunVC { def apply(a: VC): VC }")
+ compileToBytes("class VC(private val i: Int) extends AnyVal; trait FunVC { def apply(a: VC): VC }")
assertEquals("(I)I", implMethodDescriptorFor("((x: VC) => x): FunVC"))
- compileClasses(compiler)("trait Fun1[T, U] { def apply(a: T): U }")
+ compileToBytes("trait Fun1[T, U] { def apply(a: T): U }")
assertEquals(s"($obj)$str", implMethodDescriptorFor("(x => x.toString): Fun1[Int, String]"))
assertEquals(s"($obj)$obj", implMethodDescriptorFor("(x => println(x)): Fun1[Int, Unit]"))
assertEquals(s"($obj)$str", implMethodDescriptorFor("((x: VC) => \"\") : Fun1[VC, String]"))
assertEquals(s"($str)$obj", implMethodDescriptorFor("((x: String) => new VC(0)) : Fun1[String, VC]"))
- compileClasses(compiler)("trait Coll[A, Repr] extends Any")
- compileClasses(compiler)("final class ofInt(val repr: Array[Int]) extends AnyVal with Coll[Int, Array[Int]]")
+ compileToBytes("trait Coll[A, Repr] extends Any")
+ compileToBytes("final class ofInt(val repr: Array[Int]) extends AnyVal with Coll[Int, Array[Int]]")
assertEquals(s"([I)$obj", implMethodDescriptorFor("((xs: Array[Int]) => new ofInt(xs)): Array[Int] => Coll[Int, Array[Int]]"))
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
index 5c2ab6a2c7..2bcbcc870c 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/IndySammyTest.scala
@@ -2,26 +2,20 @@ package scala.tools.nsc
package backend.jvm
import org.junit.Assert.assertEquals
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
import scala.tools.asm.Opcodes._
-import scala.tools.asm.tree._
import scala.tools.nsc.reporters.StoreReporter
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-
-import scala.tools.testing.ClearAfterClass
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class IndySammyTest extends ClearAfterClass {
-
- val compiler = cached("compiler", () => newCompiler())
- def compile(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] =
- compileClasses(compiler)(scalaCode, javaCode, allowMessage)
+class IndySammyTest extends BytecodeTesting {
+ import compiler._
def funClassName(from: String, to: String) = s"Fun$from$to"
def classPrologue(from: String, to: String) =
@@ -45,13 +39,13 @@ class IndySammyTest extends ClearAfterClass {
def test(from: String, to: String, arg: String, body: String => String = x => x)
(expectedSig: String, lamBody: List[Instruction], appArgs: List[Instruction], ret: Instruction)
(allowMessage: StoreReporter#Info => Boolean = _ => false) = {
- val cls = compile(s"${classPrologue(from, to)}")
- val methodNodes = compileMethods(compiler)(lamDef(from, to, body) +";"+ appDef(arg), allowMessage)
+ val List(funClass, vcClass, vcCompanion) = compileClasses(s"${classPrologue(from, to)}")
+ val c = compileClass(s"class C { ${lamDef(from, to, body)}; ${appDef(arg)} }", allowMessage = allowMessage)
- val applySig = cls.head.methods.get(0).desc
- val anonfun = methodNodes.find(_.name contains "$anonfun$").map(convertMethod).get
- val lamInsn = methodNodes.find(_.name == "lam").map(instructionsFromMethod).get.dropNonOp
- val applyInvoke = methodNodes.find(_.name == "app").map(convertMethod).get
+ val applySig = getAsmMethod(funClass, "apply").desc
+ val anonfun = getMethod(c, "C$$$anonfun$1")
+ val lamInsn = getInstructions(c, "lam").dropNonOp
+ val applyInvoke = getMethod(c, "app")
assertEquals(expectedSig, applySig)
assert(lamInsn.length == 2 && lamInsn.head.isInstanceOf[InvokeDynamic], lamInsn)
@@ -64,7 +58,7 @@ class IndySammyTest extends ClearAfterClass {
}
// def testSpecial(lam: String, lamTp: String, arg: String)(allowMessage: StoreReporter#Info => Boolean = _ => false) = {
-// val cls = compile("trait Special[@specialized A] { def apply(a: A): A}" )
+// val cls = compileClasses("trait Special[@specialized A] { def apply(a: A): A}" )
// val methodNodes = compileMethods(compiler)(s"def lam : $lamTp = $lam" +";"+ appDef(arg), allowMessage)
//
// val anonfun = methodNodes.filter(_.name contains "$anonfun$").map(convertMethod)
@@ -146,7 +140,7 @@ class IndySammyTest extends ClearAfterClass {
// Tests ThisReferringMethodsTraverser
@Test
def testStaticIfNoThisReference: Unit = {
- val methodNodes = compileMethods(compiler)("def foo = () => () => () => 42")
+ val methodNodes = compileAsmMethods("def foo = () => () => () => 42")
methodNodes.forall(m => !m.name.contains("anonfun") || (m.access & ACC_STATIC) == ACC_STATIC)
}
}
diff --git a/test/junit/scala/issues/OptimizedBytecodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala
index c69229ae22..003162c1ad 100644
--- a/test/junit/scala/issues/OptimizedBytecodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/OptimizedBytecodeTest.scala
@@ -1,24 +1,18 @@
-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, CodeGenTools}
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-
-import scala.tools.testing.ClearAfterClass
+import scala.tools.asm.Opcodes._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class OptimizedBytecodeTest extends ClearAfterClass {
- val args = "-Yopt:l:classpath -Yopt-warnings"
- val compiler = cached("compiler", () => newCompiler(extraArgs = args))
+class OptimizedBytecodeTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:classpath -Yopt-warnings"
+ import compiler._
@Test
def t2171(): Unit = {
@@ -28,8 +22,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| def t(): Unit = while (true) m("...")
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertSameCode(getSingleMethod(c, "t"), List(Label(0), Jump(GOTO, Label(0))))
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"), List(Label(0), Jump(GOTO, Label(0))))
}
@Test
@@ -46,12 +40,12 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
+ val c = compileClass(code)
- assertSameSummary(getSingleMethod(c, "t"), List(
+ assertSameSummary(getMethod(c, "t"), List(
LDC, ASTORE, ALOAD /*0*/, ALOAD /*1*/, "C$$$anonfun$1", IRETURN))
- assertSameSummary(getSingleMethod(c, "C$$$anonfun$1"), List(LDC, "C$$$anonfun$2", IRETURN))
- assertSameSummary(getSingleMethod(c, "C$$$anonfun$2"), List(-1 /*A*/, GOTO /*A*/))
+ assertSameSummary(getMethod(c, "C$$$anonfun$1"), List(LDC, "C$$$anonfun$2", IRETURN))
+ assertSameSummary(getMethod(c, "C$$$anonfun$2"), List(-1 /*A*/, GOTO /*A*/))
}
@Test
@@ -72,8 +66,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| def h(block: => Unit): Nothing = ???
|}
""".stripMargin
- val List(c, t, tMod) = compileClasses(compiler)(code, allowMessage = _.msg.contains("not be exhaustive"))
- assertSameSummary(getSingleMethod(c, "t"), List(GETSTATIC, "$qmark$qmark$qmark", ATHROW))
+ val List(c, t, tMod) = compileClasses(code, allowMessage = _.msg.contains("not be exhaustive"))
+ assertSameSummary(getMethod(c, "t"), List(GETSTATIC, "$qmark$qmark$qmark", ATHROW))
}
@Test
@@ -97,7 +91,7 @@ class OptimizedBytecodeTest extends ClearAfterClass {
|arguments expected by the callee ErrorHandler$::defaultIfIOException(Lscala/Function0;Lscala/Function0;)Ljava/lang/Object;. These values would be discarded
|when entering an exception handler declared in the inlined method.""".stripMargin
- compileClasses(compiler)(code, allowMessage = _.msg == msg)
+ compileClasses(code, allowMessage = _.msg == msg)
}
@Test
@@ -110,7 +104,7 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- compileClasses(compiler)(code)
+ compileToBytes(code)
}
@Test
@@ -120,8 +114,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
|object Warmup { def filter[A](p: Any => Boolean): Any = filter[Any](p) }
""".stripMargin
val c2 = "class C { def t = warmup.Warmup.filter[Any](x => false) }"
- val List(c, _, _) = compileClassesSeparately(List(c1, c2), extraArgs = args)
- assertInvoke(getSingleMethod(c, "t"), "warmup/Warmup$", "filter")
+ val List(c, _, _) = compileClassesSeparately(List(c1, c2), extraArgs = compilerArgs)
+ assertInvoke(getMethod(c, "t"), "warmup/Warmup$", "filter")
}
@Test
@@ -135,7 +129,7 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- compileClasses(compiler)(code)
+ compileToBytes(code)
}
@Test
@@ -163,7 +157,7 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- compileClasses(compiler)(code)
+ compileToBytes(code)
}
@Test
@@ -179,7 +173,7 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- compileClasses(compiler)(code)
+ compileToBytes(code)
}
@Test
@@ -201,7 +195,7 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| val NoContext = self.analyzer.NoContext
|}
""".stripMargin
- compileClasses(compiler)(code)
+ compileClasses(code)
}
@Test
@@ -218,8 +212,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertSameSummary(getSingleMethod(c, "t"), List(
+ val c = compileClass(code)
+ assertSameSummary(getMethod(c, "t"), List(
ALOAD /*1*/, INSTANCEOF /*Some*/, IFNE /*A*/,
ALOAD /*0*/, "getInt", POP,
-1 /*A*/, BIPUSH, IRETURN))
@@ -237,8 +231,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertSameSummary(getSingleMethod(c, "t"), List(
+ val c = compileClass(code)
+ assertSameSummary(getMethod(c, "t"), List(
-1 /*A*/, ILOAD /*1*/, TABLESWITCH,
-1, ALOAD, "pr", RETURN,
-1, ALOAD, "pr", RETURN,
@@ -261,9 +255,9 @@ class OptimizedBytecodeTest extends ClearAfterClass {
|}
""".stripMargin
- val cls = compileClassesSeparately(List(c1, c2), extraArgs = args)
- val c = cls.find(_.name == "C").get
- assertSameSummary(getSingleMethod(c, "t"), List(
+ val cls = compileClassesSeparately(List(c1, c2), extraArgs = compilerArgs)
+ val c = findClass(cls, "C")
+ assertSameSummary(getMethod(c, "t"), List(
GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW, // module load and null checks not yet eliminated
-1, ICONST_1, GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW,
-1, ICONST_2, IADD, IRETURN))
@@ -300,11 +294,11 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| def f2b() = identity(wrapper2(5)) // not inlined
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code, allowMessage = _.msg.contains("exception handler declared in the inlined method"))
- assertInvoke(getSingleMethod(c, "f1a"), "C", "C$$$anonfun$1")
- assertInvoke(getSingleMethod(c, "f1b"), "C", "wrapper1")
- assertInvoke(getSingleMethod(c, "f2a"), "C", "C$$$anonfun$3")
- assertInvoke(getSingleMethod(c, "f2b"), "C", "wrapper2")
+ val c = compileClass(code, allowMessage = _.msg.contains("exception handler declared in the inlined method"))
+ assertInvoke(getMethod(c, "f1a"), "C", "C$$$anonfun$1")
+ assertInvoke(getMethod(c, "f1b"), "C", "wrapper1")
+ assertInvoke(getMethod(c, "f2a"), "C", "C$$$anonfun$3")
+ assertInvoke(getMethod(c, "f2b"), "C", "wrapper2")
}
@Test
@@ -318,8 +312,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| def t = mbarray_apply_minibox(null, 0)
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertNoInvoke(getSingleMethod(c, "t"))
+ val c = compileClass(code)
+ assertNoInvoke(getMethod(c, "t"))
}
@Test
@@ -336,8 +330,8 @@ class OptimizedBytecodeTest extends ClearAfterClass {
|object Nill extends Listt
|class Listt
""".stripMargin
- val List(c, nil, nilMod, listt) = compileClasses(compiler)(code)
- assertInvoke(getSingleMethod(c, "t"), "C", "C$$$anonfun$1")
+ val List(c, nil, nilMod, listt) = compileClasses(code)
+ assertInvoke(getMethod(c, "t"), "C", "C$$$anonfun$1")
}
@Test
@@ -355,14 +349,14 @@ class OptimizedBytecodeTest extends ClearAfterClass {
| final def apply(a: Any): Any = throw new RuntimeException(key)
|}
""".stripMargin
- val List(c, f) = compileClasses(compiler)(code)
- assertInvoke(getSingleMethod(c, "crash"), "C", "map")
+ val List(c, f) = compileClasses(code)
+ assertInvoke(getMethod(c, "crash"), "C", "map")
}
@Test
def optimiseEnablesNewOpt(): Unit = {
val code = """class C { def t = (1 to 10) foreach println }"""
- val List(c) = readAsmClasses(compile(newCompiler(extraArgs = "-optimise -deprecation"))(code, allowMessage = _.msg.contains("is deprecated")))
- assertInvoke(getSingleMethod(c, "t"), "C", "C$$$anonfun$1") // range-foreach inlined from classpath
+ val List(c) = readAsmClasses(newCompiler(extraArgs = "-optimise -deprecation").compileToBytes(code, allowMessage = _.msg.contains("is deprecated")))
+ assertInvoke(getMethod(c, "t"), "C", "C$$$anonfun$1") // range-foreach inlined from classpath
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala b/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala
index fc0c96e71a..af2c8f9ce0 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala
@@ -1,22 +1,18 @@
package scala.tools.nsc
package backend.jvm
+import org.junit.Assert._
+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.testing.AssertUtil._
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class StringConcatTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler())
+class StringConcatTest extends BytecodeTesting {
+ import compiler._
@Test
def appendOverloadNoBoxing(): Unit = {
@@ -54,9 +50,9 @@ class StringConcatTest extends ClearAfterClass {
| chrs: Array[Char]) = this + str + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
+ val c = compileClass(code)
- def invokeNameDesc(m: String): List[String] = getSingleMethod(c, m).instructions collect {
+ def invokeNameDesc(m: String): List[String] = getInstructions(c, m) collect {
case Invoke(_, _, name, desc, _) => name + desc
}
assertEquals(invokeNameDesc("t1"), List(
diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala
index 075f42d18f..b0a86dfd28 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala
@@ -2,32 +2,29 @@ package scala.tools.nsc
package backend.jvm
package analysis
+import org.junit.Assert._
+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 CodeGenTools._
-import scala.tools.asm.tree.{AbstractInsnNode, MethodNode}
+import scala.collection.JavaConverters._
+import scala.tools.asm.tree.MethodNode
+import scala.tools.nsc.backend.jvm.AsmUtils._
import scala.tools.nsc.backend.jvm.BTypes._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import scala.tools.testing.ClearAfterClass
import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._
-import AsmUtils._
-
-import scala.collection.JavaConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class NullnessAnalyzerTest extends ClearAfterClass {
- val noOptCompiler = cached("noOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
- import noOptCompiler.genBCode.bTypes.backendUtils._
+class NullnessAnalyzerTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:none"
+ import compiler._
+ import global.genBCode.bTypes.backendUtils._
- def newNullnessAnalyzer(methodNode: MethodNode, classInternalName: InternalName = "C") = new AsmAnalyzer(methodNode, classInternalName, new NullnessAnalyzer(noOptCompiler.genBCode.bTypes))
+ def newNullnessAnalyzer(methodNode: MethodNode, classInternalName: InternalName = "C") = new AsmAnalyzer(methodNode, classInternalName, new NullnessAnalyzer(global.genBCode.bTypes))
def testNullness(analyzer: AsmAnalyzer[NullnessValue], method: MethodNode, query: String, index: Int, nullness: NullnessValue): Unit = {
- for (i <- findInstr(method, query)) {
+ for (i <- findInstrs(method, query)) {
val r = analyzer.frameAt(i).getValue(index)
assertTrue(s"Expected: $nullness, found: $r. At instr ${textify(i)}", nullness == r)
}
@@ -53,7 +50,7 @@ class NullnessAnalyzerTest extends ClearAfterClass {
@Test
def showNullnessFramesTest(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = this.toString")
+ val m = compileAsmMethod("def f = this.toString")
// NOTE: the frame for an instruction represents the state *before* executing that instr.
// So in the frame for `ALOAD 0`, the stack is still empty.
@@ -71,14 +68,14 @@ class NullnessAnalyzerTest extends ClearAfterClass {
@Test
def thisNonNull(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = this.toString")
+ val m = compileAsmMethod("def f = this.toString")
val a = newNullnessAnalyzer(m)
testNullness(a, m, "ALOAD 0", 0, NotNullValue)
}
@Test
def instanceMethodCall(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f(a: String) = a.trim")
+ val m = compileAsmMethod("def f(a: String) = a.trim")
val a = newNullnessAnalyzer(m)
testNullness(a, m, "INVOKEVIRTUAL java/lang/String.trim", 1, UnknownValue1)
testNullness(a, m, "ARETURN", 1, NotNullValue)
@@ -86,7 +83,7 @@ class NullnessAnalyzerTest extends ClearAfterClass {
@Test
def constructorCall(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = { val a = new Object; a.toString }")
+ val m = compileAsmMethod("def f = { val a = new Object; a.toString }")
val a = newNullnessAnalyzer(m)
// for reference, the output of showAllNullnessFrames(a, m) - note that the frame represents the state *before* executing the instr.
@@ -111,7 +108,7 @@ class NullnessAnalyzerTest extends ClearAfterClass {
@Test
def explicitNull(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = { var a: Object = null; a }")
+ val m = compileAsmMethod("def f = { var a: Object = null; a }")
val a = newNullnessAnalyzer(m)
for ((insn, index, nullness) <- List(
("+ACONST_NULL", 2, NullValue),
@@ -122,14 +119,14 @@ class NullnessAnalyzerTest extends ClearAfterClass {
@Test
def stringLiteralsNotNull(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("""def f = { val a = "hi"; a.trim }""")
+ val m = compileAsmMethod("""def f = { val a = "hi"; a.trim }""")
val a = newNullnessAnalyzer(m)
testNullness(a, m, "+ASTORE 1", 1, NotNullValue)
}
@Test
def newArraynotNull() {
- val List(m) = compileMethods(noOptCompiler)("def f = { val a = new Array[Int](2); a(0) }")
+ val m = compileAsmMethod("def f = { val a = new Array[Int](2); a(0) }")
val a = newNullnessAnalyzer(m)
testNullness(a, m, "+NEWARRAY T_INT", 2, NotNullValue) // new array on stack
testNullness(a, m, "+ASTORE 1", 1, NotNullValue) // local var (a)
@@ -147,7 +144,7 @@ class NullnessAnalyzerTest extends ClearAfterClass {
| a.toString
|}
""".stripMargin
- val List(m) = compileMethods(noOptCompiler)(code)
+ val m = compileAsmMethod(code)
val a = newNullnessAnalyzer(m)
val toSt = "+INVOKEVIRTUAL java/lang/Object.toString"
testNullness(a, m, toSt, 3, UnknownValue1)
@@ -173,7 +170,7 @@ class NullnessAnalyzerTest extends ClearAfterClass {
| // d is null here, assinged in both branches.
|}
""".stripMargin
- val List(m) = compileMethods(noOptCompiler)(code)
+ val m = compileAsmMethod(code)
val a = newNullnessAnalyzer(m)
val trim = "INVOKEVIRTUAL java/lang/String.trim"
@@ -209,7 +206,7 @@ class NullnessAnalyzerTest extends ClearAfterClass {
| a.asInstanceOf[String].trim // the stack value (LOAD of local a) is still not-null after the CHECKCAST
|}
""".stripMargin
- val List(m) = compileMethods(noOptCompiler)(code)
+ val m = compileAsmMethod(code)
val a = newNullnessAnalyzer(m)
val instof = "+INSTANCEOF"
diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala
index 8d4bc19ec3..fc26785237 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala
@@ -2,22 +2,23 @@ package scala.tools.nsc
package backend.jvm
package analysis
+import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Assert._
import scala.tools.asm.Opcodes
import scala.tools.asm.tree.AbstractInsnNode
+import scala.tools.nsc.backend.jvm.AsmUtils._
import scala.tools.partest.ASMConverters._
-import scala.tools.testing.ClearAfterClass
-import CodeGenTools._
-import AsmUtils._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class ProdConsAnalyzerTest extends ClearAfterClass {
- val noOptCompiler =cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
- import noOptCompiler.genBCode.bTypes.backendUtils._
+class ProdConsAnalyzerTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:none"
+ import compiler._
+ import global.genBCode.bTypes.backendUtils._
def prodToString(producer: AbstractInsnNode) = producer match {
case p: InitialProducer => p.toString
@@ -48,9 +49,9 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
@Test
def parameters(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = this.toString")
+ val m = compileAsmMethod("def f = this.toString")
val a = new ProdConsAnalyzer(m, "C")
- val call = findInstr(m, "INVOKEVIRTUAL").head
+ val call = findInstr(m, "INVOKEVIRTUAL")
testSingleInsn(a.producersForValueAt(call, 1), "ALOAD 0") // producer of stack value
testSingleInsn(a.producersForInputsOf(call), "ALOAD 0")
@@ -83,55 +84,55 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
m.maxStack = 1
val a = new ProdConsAnalyzer(m, "C")
- val ifne = findInstr(m, "IFNE").head
+ val ifne = findInstr(m, "IFNE")
testSingleInsn(a.producersForValueAt(ifne, 1), "ParameterProducer")
- val ret = findInstr(m, "IRETURN").head
+ val ret = findInstr(m, "IRETURN")
testMultiInsns(a.producersForValueAt(ret, 1), List("ParameterProducer", "ISTORE 1"))
}
@Test
def branching(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f(x: Int) = { var a = x; if (a == 0) a = 12; a }")
+ val m = compileAsmMethod("def f(x: Int) = { var a = x; if (a == 0) a = 12; a }")
val a = new ProdConsAnalyzer(m, "C")
- val List(ret) = findInstr(m, "IRETURN")
+ val ret = findInstr(m, "IRETURN")
testMultiInsns(a.producersForValueAt(ret, 2), List("ISTORE 2", "ISTORE 2"))
testMultiInsns(a.initialProducersForValueAt(ret, 2), List("BIPUSH 12", "ParameterProducer"))
- val List(bipush) = findInstr(m, "BIPUSH 12")
+ val bipush = findInstr(m, "BIPUSH 12")
testSingleInsn(a.consumersOfOutputsFrom(bipush), "ISTORE 2")
testSingleInsn(a.ultimateConsumersOfValueAt(bipush.getNext, 3), "IRETURN")
}
@Test
def checkCast(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f(o: Object) = o.asInstanceOf[String]")
+ val m = compileAsmMethod("def f(o: Object) = o.asInstanceOf[String]")
val a = new ProdConsAnalyzer(m, "C")
- assert(findInstr(m, "CHECKCAST java/lang/String").length == 1)
+ assert(findInstrs(m, "CHECKCAST java/lang/String").length == 1)
- val List(ret) = findInstr(m, "ARETURN")
+ val ret = findInstr(m, "ARETURN")
testSingleInsn(a.initialProducersForInputsOf(ret), "ParameterProducer(1)")
}
@Test
def instanceOf(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f(o: Object) = o.isInstanceOf[String]")
+ val m = compileAsmMethod("def f(o: Object) = o.isInstanceOf[String]")
val a = new ProdConsAnalyzer(m, "C")
- assert(findInstr(m, "INSTANCEOF java/lang/String").length == 1)
+ assert(findInstrs(m, "INSTANCEOF java/lang/String").length == 1)
- val List(ret) = findInstr(m, "IRETURN")
+ val ret = findInstr(m, "IRETURN")
testSingleInsn(a.initialProducersForInputsOf(ret), "INSTANCEOF")
}
@Test
def unInitLocal(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }")
+ val m = compileAsmMethod("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }")
val a = new ProdConsAnalyzer(m, "C")
- val List(store) = findInstr(m, "ISTORE")
- val List(call) = findInstr(m, "INVOKEVIRTUAL")
- val List(ret) = findInstr(m, "IRETURN")
+ val store = findInstr(m, "ISTORE")
+ val call = findInstr(m, "INVOKEVIRTUAL")
+ val ret = findInstr(m, "IRETURN")
testSingleInsn(a.producersForValueAt(store, 2), "UninitializedLocalProducer(2)")
testSingleInsn(a.producersForValueAt(call, 2), "ISTORE")
@@ -140,11 +141,11 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
@Test
def dupCopying(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = new Object")
+ val m = compileAsmMethod("def f = new Object")
val a = new ProdConsAnalyzer(m, "C")
- val List(newO) = findInstr(m, "NEW")
- val List(constr) = findInstr(m, "INVOKESPECIAL")
+ val newO = findInstr(m, "NEW")
+ val constr = findInstr(m, "INVOKESPECIAL")
testSingleInsn(a.producersForInputsOf(constr), "DUP")
testSingleInsn(a.initialProducersForInputsOf(constr), "NEW")
@@ -169,11 +170,11 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
m.maxStack = 4
val a = new ProdConsAnalyzer(m, "C")
- val List(dup2) = findInstr(m, "DUP2")
- val List(add) = findInstr(m, "IADD")
- val List(swap) = findInstr(m, "SWAP")
- val List(store) = findInstr(m, "ISTORE")
- val List(ret) = findInstr(m, "IRETURN")
+ val dup2 = findInstr(m, "DUP2")
+ val add = findInstr(m, "IADD")
+ val swap = findInstr(m, "SWAP")
+ val store = findInstr(m, "ISTORE")
+ val ret = findInstr(m, "IRETURN")
testMultiInsns(a.producersForInputsOf(dup2), List("ILOAD", "ILOAD"))
testSingleInsn(a.consumersOfValueAt(dup2.getNext, 4), "IADD")
@@ -204,9 +205,9 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
m.maxStack = 1
val a = new ProdConsAnalyzer(m, "C")
- val List(inc) = findInstr(m, "IINC")
- val List(load) = findInstr(m, "ILOAD")
- val List(ret) = findInstr(m, "IRETURN")
+ val inc = findInstr(m, "IINC")
+ val load = findInstr(m, "ILOAD")
+ val ret = findInstr(m, "IRETURN")
testSingleInsn(a.producersForInputsOf(inc), "ParameterProducer(1)")
testSingleInsn(a.consumersOfOutputsFrom(inc), "ILOAD")
@@ -222,12 +223,12 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
@Test
def copyingInsns(): Unit = {
- val List(m) = compileMethods(noOptCompiler)("def f = 0l.asInstanceOf[Int]")
+ val m = compileAsmMethod("def f = 0l.asInstanceOf[Int]")
val a = new ProdConsAnalyzer(m, "C")
- val List(cnst) = findInstr(m, "LCONST_0")
- val List(l2i) = findInstr(m, "L2I") // l2i is not a copying instruction
- val List(ret) = findInstr(m, "IRETURN")
+ val cnst = findInstr(m, "LCONST_0")
+ val l2i = findInstr(m, "L2I") // l2i is not a copying instruction
+ val ret = findInstr(m, "IRETURN")
testSingleInsn(a.consumersOfOutputsFrom(cnst), "L2I")
testSingleInsn(a.ultimateConsumersOfOutputsFrom(cnst), "L2I")
@@ -263,10 +264,10 @@ class ProdConsAnalyzerTest extends ClearAfterClass {
m.maxStack = 2
val a = new ProdConsAnalyzer(m, "C")
- val List(iadd) = findInstr(m, "IADD")
+ val iadd = findInstr(m, "IADD")
val firstLoad = iadd.getPrevious.getPrevious
assert(firstLoad.getOpcode == ILOAD)
- val secondLoad = findInstr(m, "ISTORE").head.getPrevious
+ val secondLoad = findInstr(m, "ISTORE").getPrevious
assert(secondLoad.getOpcode == ILOAD)
testSingleInsn(a.producersForValueAt(iadd, 2), "ILOAD")
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala
index 09675870f0..025248ac28 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/AnalyzerTest.scala
@@ -2,28 +2,21 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
-import org.junit.Assert._
-import scala.tools.asm.tree._
import scala.tools.asm.tree.analysis._
-import scala.tools.nsc.backend.jvm.analysis.{AliasingFrame, AliasingAnalyzer}
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-import BackendReporting._
-import BytecodeUtils._
-
-import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.nsc.backend.jvm.analysis.{AliasingAnalyzer, AliasingFrame}
+import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class AnalyzerTest extends ClearAfterClass {
- val noOptCompiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
+class AnalyzerTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:none"
+ import compiler._
@Test
def aliasingOfPrimitives(): Unit = {
@@ -39,17 +32,17 @@ class AnalyzerTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(noOptCompiler)(code)
+ val c = compileClass(code)
val a = new AliasingAnalyzer(new BasicInterpreter)
- val f = findAsmMethod(c, "f")
+ val f = getAsmMethod(c, "f")
a.analyze("C", f)
- val List(_, i2l) = findInstr(f, "I2L")
+ val List(_, i2l) = findInstrs(f, "I2L")
val aliasesAtI2l = a.frameAt(i2l, f).asInstanceOf[AliasingFrame[_]].aliases
assertEquals(aliasesAtI2l(1).iterator.toList, List(1, 8, 9)) // a, e and stack top
assertEquals(aliasesAtI2l(4).iterator.toList, List(4, 6))
- val List(add) = findInstr(f, "LADD")
+ val add = findInstr(f, "LADD")
val aliasesAtAdd = a.frameAt(add, f).asInstanceOf[AliasingFrame[_]].aliases
assertEquals(aliasesAtAdd(1).iterator.toList, List(1, 8)) // after i2l the value on the stack is no longer an alias
assertEquals(aliasesAtAdd(4).iterator.toList, List(4, 6, 10)) // c, d and stack top
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala
index aba0aab038..e7aea71e72 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala
@@ -2,37 +2,29 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.{Ignore, 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.asm.Opcodes._
import scala.tools.nsc.backend.jvm.BTypes.InternalName
-import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-
-import BackendReporting._
-
-import scala.collection.JavaConverters._
+import scala.tools.nsc.backend.jvm.BackendReporting._
+import scala.tools.testing.BytecodeTesting
@RunWith(classOf[JUnit4])
-class BTypesFromClassfileTest {
+class BTypesFromClassfileTest extends BytecodeTesting {
// inliner enabled -> inlineInfos are collected (and compared) in ClassBTypes
- val compiler = newCompiler(extraArgs = "-Yopt:inline-global")
+ override def compilerArgs = "-Yopt:inline-global"
- import compiler._
+ import compiler.global._
import definitions._
import genBCode.bTypes
import bTypes._
- def duringBackend[T](f: => T) = compiler.exitingDelambdafy(f)
+ def duringBackend[T](f: => T) = global.exitingDelambdafy(f)
- val run = new compiler.Run() // initializes some of the compiler
- duringBackend(compiler.scalaPrimitives.init()) // needed: it's only done when running the backend, and we don't actually run the compiler
+ val run = new global.Run() // initializes some of the compiler
+ duringBackend(global.scalaPrimitives.init()) // needed: it's only done when running the backend, and we don't actually run the compiler
duringBackend(bTypes.initializeCoreBTypes())
def clearCache() = bTypes.classBTypeFromInternalName.clear()
@@ -91,7 +83,9 @@ class BTypesFromClassfileTest {
sameBType(fromSymbol, fromClassfile)
}
- @Test
+ // Can be enabled when using 2.12.0-M5 as starr. This test works under a full boostrap, but not
+ // when compiled with M4.
+ @Test @Ignore
def compareClassBTypes(): Unit = {
// Note that not only these classes are tested, but also all their parents and all nested
// classes in their InnerClass attributes.
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
index 9a27c42cac..630416a925 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
@@ -2,46 +2,38 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
+
+import scala.collection.JavaConverters._
import scala.collection.generic.Clearable
import scala.collection.immutable.IntMap
-import scala.tools.asm.Opcodes._
-import org.junit.Assert._
-
import scala.tools.asm.tree._
-import scala.tools.asm.tree.analysis._
+import scala.tools.nsc.backend.jvm.BackendReporting._
import scala.tools.nsc.reporters.StoreReporter
-import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-import BackendReporting._
-
-import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class CallGraphTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:inline-global -Yopt-warnings")
- )
- import compiler.genBCode.bTypes
+class CallGraphTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:inline-global -Yopt-warnings"
+ import compiler._
+ import global.genBCode.bTypes
val notPerRun: List[Clearable] = List(
bTypes.classBTypeFromInternalName,
bTypes.byteCodeRepository.compilingClasses,
bTypes.byteCodeRepository.parsedClasses,
bTypes.callGraph.callsites)
- notPerRun foreach compiler.perRunCaches.unrecordCache
+ notPerRun foreach global.perRunCaches.unrecordCache
- import compiler.genBCode.bTypes._
+ import global.genBCode.bTypes._
import callGraph._
def compile(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = {
notPerRun.foreach(_.clear())
- compileClasses(compiler)(code, allowMessage = allowMessage).map(c => byteCodeRepository.classNode(c.name).get)
+ compileClasses(code, allowMessage = allowMessage).map(c => byteCodeRepository.classNode(c.name).get)
}
def callsInMethod(methodNode: MethodNode): List[MethodInsnNode] = methodNode.instructions.iterator.asScala.collect({
@@ -112,10 +104,10 @@ class CallGraphTest extends ClearAfterClass {
val List(cCls, cMod, dCls, testCls) = compile(code, checkMsg)
assert(msgCount == 6, msgCount)
- val List(cf1, cf2, cf3, cf4, cf5, cf6, cf7) = findAsmMethods(cCls, _.startsWith("f"))
- val List(df1, df3) = findAsmMethods(dCls, _.startsWith("f"))
- val g1 = findAsmMethod(cMod, "g1")
- val List(t1, t2) = findAsmMethods(testCls, _.startsWith("t"))
+ val List(cf1, cf2, cf3, cf4, cf5, cf6, cf7) = getAsmMethods(cCls, _.startsWith("f"))
+ val List(df1, df3) = getAsmMethods(dCls, _.startsWith("f"))
+ val g1 = getAsmMethod(cMod, "g1")
+ val List(t1, t2) = getAsmMethods(testCls, _.startsWith("t"))
val List(cf1Call, cf2Call, cf3Call, cf4Call, cf5Call, cf6Call, cf7Call, cg1Call) = callsInMethod(t1)
val List(df1Call, df2Call, df3Call, df4Call, df5Call, df6Call, df7Call, dg1Call) = callsInMethod(t2)
@@ -151,7 +143,7 @@ class CallGraphTest extends ClearAfterClass {
|}
""".stripMargin
val List(c) = compile(code)
- val m = findAsmMethod(c, "m")
+ val m = getAsmMethod(c, "m")
val List(fn) = callsInMethod(m)
val forNameMeth = byteCodeRepository.methodNode("java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;").get._1
val classTp = classBTypeFromInternalName("java/lang/Class")
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala
index e8530af4e0..218b02f822 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala
@@ -2,34 +2,19 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
-import scala.collection.generic.Clearable
-import scala.collection.mutable.ListBuffer
-import scala.reflect.internal.util.BatchSourceFile
-import scala.tools.asm.Opcodes._
-import org.junit.Assert._
-
-import scala.tools.asm.tree._
-import scala.tools.asm.tree.analysis._
-import scala.tools.nsc.io._
-import scala.tools.nsc.reporters.StoreReporter
-import scala.tools.testing.AssertUtil._
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-
-import BackendReporting._
-
-import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.asm.Opcodes._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class ClosureOptimizerTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:classpath -Yopt-warnings:_"))
+class ClosureOptimizerTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:classpath -Yopt-warnings:_"
+ import compiler._
@Test
def nothingTypedClosureBody(): Unit = {
@@ -41,9 +26,9 @@ class ClosureOptimizerTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- val t = findAsmMethod(c, "t")
- val List(bodyCall) = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Nothing$")
+ val c = compileClass(code)
+ val t = getAsmMethod(c, "t")
+ val bodyCall = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Nothing$")
assert(bodyCall.getNext.getOpcode == ATHROW)
}
@@ -57,9 +42,9 @@ class ClosureOptimizerTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- val t = findAsmMethod(c, "t")
- val List(bodyCall) = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Null$")
+ val c = compileClass(code)
+ val t = getAsmMethod(c, "t")
+ val bodyCall = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Null$")
assert(bodyCall.getNext.getOpcode == POP)
assert(bodyCall.getNext.getNext.getOpcode == ACONST_NULL)
}
@@ -74,8 +59,8 @@ class ClosureOptimizerTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertSameCode(getSingleMethod(c, "t"),
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"),
List(VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "scala/collection/immutable/List", "head", "()Ljava/lang/Object;", false),
TypeOp(CHECKCAST, "java/lang/String"), Invoke(INVOKESTATIC, "C", "C$$$anonfun$1", "(Ljava/lang/String;)Ljava/lang/String;", false),
Op(ARETURN)))
@@ -95,7 +80,7 @@ class ClosureOptimizerTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assertSameSummary(getSingleMethod(c, "t"), List(NEW, DUP, LDC, "<init>", ATHROW))
+ val c = compileClass(code)
+ assertSameSummary(getMethod(c, "t"), List(NEW, DUP, LDC, "<init>", ATHROW))
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala
index ac1b759fe2..c3748a05bd 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CompactLocalVariablesTest.scala
@@ -2,23 +2,21 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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 CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting._
+import scala.tools.testing.ClearAfterClass
@RunWith(classOf[JUnit4])
-class CompactLocalVariablesTest {
-
+class CompactLocalVariablesTest extends ClearAfterClass {
// recurse-unreachable-jumps is required for eliminating catch blocks, in the first dce round they
// are still live.only after eliminating the empty handler the catch blocks become unreachable.
- val methodOptCompiler = newCompiler(extraArgs = "-Yopt:unreachable-code,compact-locals")
- val noCompactVarsCompiler = newCompiler(extraArgs = "-Yopt:unreachable-code")
+ val methodOptCompiler = cached("methodOptCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code,compact-locals"))
+ val noCompactVarsCompiler = cached("noCompactVarsCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
@Test
def compactUnused(): Unit = {
@@ -58,8 +56,8 @@ class CompactLocalVariablesTest {
|}
|""".stripMargin
- val List(noCompact) = compileMethods(noCompactVarsCompiler)(code)
- val List(withCompact) = compileMethods(methodOptCompiler)(code)
+ val noCompact = noCompactVarsCompiler.compileAsmMethod(code)
+ val withCompact = methodOptCompiler.compileAsmMethod(code)
// code is the same, except for local var indices
assertTrue(noCompact.instructions.size == withCompact.instructions.size)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
index 6d566c722f..3324058cb7 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
@@ -2,22 +2,23 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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 CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.asm.Opcodes._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class EmptyExceptionHandlersTest extends ClearAfterClass {
+class EmptyExceptionHandlersTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:unreachable-code"
+ def dceCompiler = compiler
+
val noOptCompiler = cached("noOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
- val dceCompiler = cached("dceCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
val exceptionDescriptor = "java/lang/Exception"
@@ -59,8 +60,8 @@ class EmptyExceptionHandlersTest extends ClearAfterClass {
def eliminateUnreachableHandler(): Unit = {
val code = "def f: Unit = try { } catch { case _: Exception => println(0) }; println(1)"
- assertTrue(singleMethod(noOptCompiler)(code).handlers.length == 1)
- val optMethod = singleMethod(dceCompiler)(code)
+ assertTrue(noOptCompiler.compileMethod(code).handlers.length == 1)
+ val optMethod = dceCompiler.compileMethod(code)
assertTrue(optMethod.handlers.isEmpty)
val code2 =
@@ -72,7 +73,7 @@ class EmptyExceptionHandlersTest extends ClearAfterClass {
| println(2)
|}""".stripMargin
- assertTrue(singleMethod(dceCompiler)(code2).handlers.isEmpty)
+ assertTrue(dceCompiler.compileMethod(code2).handlers.isEmpty)
}
@Test
@@ -84,6 +85,6 @@ class EmptyExceptionHandlersTest extends ClearAfterClass {
| catch { case _: Exception => 2 }
|}""".stripMargin
- assertTrue(singleMethod(dceCompiler)(code).handlers.length == 1)
+ assertTrue(dceCompiler.compileMethod(code).handlers.length == 1)
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
index 7283e20745..d57d44f2a3 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyLabelsAndLineNumbersTest.scala
@@ -2,16 +2,16 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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.testing.AssertUtil._
-import CodeGenTools._
+import scala.tools.asm.Opcodes._
import scala.tools.partest.ASMConverters
-import ASMConverters._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.AssertUtil._
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
class EmptyLabelsAndLineNumbersTest {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala
index 5cb1aab4a9..e45d7139a3 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala
@@ -2,36 +2,31 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
-import scala.collection.generic.Clearable
-import org.junit.Assert._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-import scala.tools.testing.ClearAfterClass
-
-import BackendReporting._
import scala.collection.JavaConverters._
+import scala.collection.generic.Clearable
+import scala.tools.nsc.backend.jvm.BackendReporting._
+import scala.tools.testing.BytecodeTesting
@RunWith(classOf[JUnit4])
-class InlineInfoTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:classpath"))
+class InlineInfoTest extends BytecodeTesting {
+ import compiler.global
+ import global.genBCode.bTypes
+
+ override def compilerArgs = "-Yopt:l:classpath"
- import compiler.genBCode.bTypes
def notPerRun: List[Clearable] = List(
bTypes.classBTypeFromInternalName,
bTypes.byteCodeRepository.compilingClasses,
bTypes.byteCodeRepository.parsedClasses)
- notPerRun foreach compiler.perRunCaches.unrecordCache
+ notPerRun foreach global.perRunCaches.unrecordCache
def compile(code: String) = {
notPerRun.foreach(_.clear())
- compileClasses(compiler)(code)
+ compiler.compileClasses(code)
}
@Test
@@ -55,11 +50,11 @@ class InlineInfoTest extends ClearAfterClass {
""".stripMargin
val classes = compile(code)
- val fromSyms = classes.map(c => compiler.genBCode.bTypes.classBTypeFromInternalName(c.name).info.get.inlineInfo)
+ val fromSyms = classes.map(c => global.genBCode.bTypes.classBTypeFromInternalName(c.name).info.get.inlineInfo)
val fromAttrs = classes.map(c => {
assert(c.attrs.asScala.exists(_.isInstanceOf[InlineInfoAttribute]), c.attrs)
- compiler.genBCode.bTypes.inlineInfoFromClassfile(c)
+ global.genBCode.bTypes.inlineInfoFromClassfile(c)
})
assert(fromSyms == fromAttrs)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
index 6dd0a33289..f0913f3631 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
@@ -2,41 +2,21 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
-import scala.collection.generic.Clearable
-import scala.collection.mutable.ListBuffer
-import scala.reflect.internal.util.BatchSourceFile
-import scala.tools.asm.Opcodes._
-import org.junit.Assert._
-
-import scala.tools.asm.tree._
-import scala.tools.asm.tree.analysis._
-import scala.tools.nsc.io._
-import scala.tools.nsc.reporters.StoreReporter
-import scala.tools.testing.AssertUtil._
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
-import BackendReporting._
+@RunWith(classOf[JUnit4])
+class InlineWarningTest extends BytecodeTesting {
+ def optCp = "-Yopt:l:classpath"
+ override def compilerArgs = s"$optCp -Yopt-warnings"
-import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+ import compiler._
-@RunWith(classOf[JUnit4])
-class InlineWarningTest extends ClearAfterClass {
- val argsNoWarn = "-Yopt:l:classpath"
- val args = argsNoWarn + " -Yopt-warnings"
- val compiler = cached("compiler", () => newCompiler(extraArgs = args))
- val compilerWarnAll = cached("compilerWarnAll", () => newCompiler(extraArgs = argsNoWarn + " -Yopt-warnings:_"))
-
- def compile(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false, compiler: Global = compiler): List[ClassNode] = {
- compileClasses(compiler)(scalaCode, javaCode, allowMessage)
- }
+ val compilerWarnAll = cached("compilerWarnAll", () => newCompiler(extraArgs = s"$optCp -Yopt-warnings:_"))
@Test
def nonFinal(): Unit = {
@@ -58,7 +38,7 @@ class InlineWarningTest extends ClearAfterClass {
"C::m1()I is annotated @inline but cannot be inlined: the method is not final and may be overridden",
"T::m2()I is annotated @inline but cannot be inlined: the method is not final and may be overridden",
"D::m2()I is annotated @inline but cannot be inlined: the method is not final and may be overridden")
- compile(code, allowMessage = i => {count += 1; warns.exists(i.msg contains _)})
+ compileToBytes(code, allowMessage = i => {count += 1; warns.exists(i.msg contains _)})
assert(count == 4, count)
}
@@ -73,7 +53,7 @@ class InlineWarningTest extends ClearAfterClass {
""".stripMargin
var c = 0
- compile(code, allowMessage = i => {c += 1; i.msg contains "operand stack at the callsite in C::t1()V contains more values"})
+ compileToBytes(code, allowMessage = i => {c += 1; i.msg contains "operand stack at the callsite in C::t1()V contains more values"})
assert(c == 1, c)
}
@@ -103,14 +83,14 @@ class InlineWarningTest extends ClearAfterClass {
|Note that the parent class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin)
var c = 0
- val List(b) = compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.tail.exists(i.msg contains _)})
+ val List(b) = compileToBytes(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.tail.exists(i.msg contains _)})
assert(c == 1, c)
// no warnings here
- compileClasses(newCompiler(extraArgs = argsNoWarn + " -Yopt-warnings:none"))(scalaCode, List((javaCode, "A.java")))
+ newCompiler(extraArgs = s"$optCp -Yopt-warnings:none").compileToBytes(scalaCode, List((javaCode, "A.java")))
c = 0
- compileClasses(newCompiler(extraArgs = argsNoWarn + " -Yopt-warnings:no-inline-mixed"))(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.exists(i.msg contains _)})
+ newCompiler(extraArgs = s"$optCp -Yopt-warnings:no-inline-mixed").compileToBytes(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.exists(i.msg contains _)})
assert(c == 2, c)
}
@@ -137,7 +117,7 @@ class InlineWarningTest extends ClearAfterClass {
|that would cause an IllegalAccessError when inlined into class N""".stripMargin
var c = 0
- compile(code, allowMessage = i => { c += 1; i.msg contains warn })
+ compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn })
assert(c == 1, c)
}
@@ -156,7 +136,7 @@ class InlineWarningTest extends ClearAfterClass {
| def t(a: M) = a.f(x => x + 1)
|}
""".stripMargin
- compile(code, allowMessage = _ => false) // no warnings allowed
+ compileToBytes(code, allowMessage = _ => false) // no warnings allowed
val warn =
"""M::f(Lscala/Function1;)I could not be inlined:
@@ -164,7 +144,7 @@ class InlineWarningTest extends ClearAfterClass {
|that would cause an IllegalAccessError when inlined into class N""".stripMargin
var c = 0
- compile(code, compiler = compilerWarnAll, allowMessage = i => { c += 1; i.msg contains warn })
+ compilerWarnAll.compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn })
assert(c == 1, c)
}
@@ -185,7 +165,7 @@ class InlineWarningTest extends ClearAfterClass {
|does not have the same strictfp mode as the callee C::f()I.""".stripMargin
var c = 0
- compile(code, allowMessage = i => { c += 1; i.msg contains warn })
+ compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn })
assert(c == 1, c)
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala
index ab1aef47cd..c2ada8afec 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala
@@ -2,27 +2,22 @@ package scala.tools.nsc
package backend.jvm
package opt
+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.asm.tree._
-import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.asm.Opcodes._
+import scala.tools.asm.tree._
+import scala.tools.nsc.backend.jvm.AsmUtils._
+import scala.tools.testing.BytecodeTesting
@RunWith(classOf[JUnit4])
-class InlinerIllegalAccessTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
- import compiler.genBCode.bTypes._
+class InlinerIllegalAccessTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:none"
+
+ import compiler._
+ import global.genBCode.bTypes._
def addToRepo(cls: List[ClassNode]): Unit = for (c <- cls) byteCodeRepository.add(c, ByteCodeRepository.Classfile)
def assertEmpty(ins: Option[AbstractInsnNode]) = for (i <- ins)
@@ -44,7 +39,7 @@ class InlinerIllegalAccessTest extends ClearAfterClass {
|}
""".stripMargin
- val allClasses = compileClasses(compiler)(code)
+ val allClasses = compileClasses(code)
val List(cClass, dClass, eClass) = allClasses
assert(cClass.name == "a/C" && dClass.name == "a/D" && eClass.name == "b/E", s"${cClass.name}, ${dClass.name}, ${eClass.name}")
addToRepo(allClasses) // they are not on the compiler's classpath, so we add them manually to the code repo
@@ -120,7 +115,7 @@ class InlinerIllegalAccessTest extends ClearAfterClass {
|}
""".stripMargin
- val allClasses = compileClasses(compiler)(code)
+ val allClasses = compileClasses(code)
val List(cCl, dCl, eCl, fCl, gCl, hCl, iCl) = allClasses
addToRepo(allClasses)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala
index 075513a2b7..b196f1a9ba 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala
@@ -2,26 +2,15 @@ package scala.tools.nsc
package backend.jvm
package opt
+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 CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-
-import scala.collection.JavaConverters._
-
-object InlinerSeparateCompilationTest {
- val args = "-Yopt:l:classpath"
-}
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
class InlinerSeparateCompilationTest {
- import InlinerSeparateCompilationTest._
+ val args = "-Yopt:l:classpath"
@Test
def inlnieMixedinMember(): Unit = {
@@ -44,9 +33,9 @@ class InlinerSeparateCompilationTest {
val warn = "T::f()I is annotated @inline but cannot be inlined: the method is not final and may be overridden"
val List(c, o, oMod, t) = compileClassesSeparately(List(codeA, codeB), args + " -Yopt-warnings", _.msg contains warn)
- assertInvoke(getSingleMethod(c, "t1"), "T", "f")
- assertNoInvoke(getSingleMethod(c, "t2"))
- assertNoInvoke(getSingleMethod(c, "t3"))
+ assertInvoke(getMethod(c, "t1"), "T", "f")
+ assertNoInvoke(getMethod(c, "t2"))
+ assertNoInvoke(getMethod(c, "t3"))
}
@Test
@@ -64,7 +53,7 @@ class InlinerSeparateCompilationTest {
""".stripMargin
val List(c, t) = compileClassesSeparately(List(codeA, codeB), args)
- assertNoInvoke(getSingleMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t1"))
}
@Test
@@ -87,7 +76,7 @@ class InlinerSeparateCompilationTest {
""".stripMargin
val List(c, t, u) = compileClassesSeparately(List(codeA, codeB), args)
- for (m <- List("t1", "t2", "t3")) assertNoInvoke(getSingleMethod(c, m))
+ for (m <- List("t1", "t2", "t3")) assertNoInvoke(getMethod(c, m))
}
@Test
@@ -108,7 +97,7 @@ class InlinerSeparateCompilationTest {
""".stripMargin
val List(a, t) = compileClassesSeparately(List(codeA, assembly), args)
- assertNoInvoke(getSingleMethod(t, "f"))
- assertNoInvoke(getSingleMethod(a, "n"))
+ assertNoInvoke(getMethod(t, "f"))
+ assertNoInvoke(getMethod(a, "n"))
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index b7641b5ec7..4e014d4529 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -2,48 +2,44 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+import org.junit.{Ignore, Test}
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.junit.Test
+
+import scala.collection.JavaConverters._
import scala.collection.generic.Clearable
import scala.tools.asm.Opcodes._
-import org.junit.Assert._
-
import scala.tools.asm.tree._
+import scala.tools.nsc.backend.jvm.BackendReporting._
import scala.tools.nsc.reporters.StoreReporter
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import AsmUtils._
-
-import BackendReporting._
-
-import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class InlinerTest extends ClearAfterClass {
- val args = "-Yopt:l:classpath -Yopt-warnings"
- val compiler = cached("compiler", () => newCompiler(extraArgs = args))
+class InlinerTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:classpath -Yopt-warnings"
+
val inlineOnlyCompiler = cached("inlineOnlyCompiler", () => newCompiler(extraArgs = "-Yopt:inline-project"))
- import compiler.genBCode.bTypes
+
+ import compiler._
+ import global.genBCode.bTypes
// allows inspecting the caches after a compilation run
def notPerRun: List[Clearable] = List(
bTypes.classBTypeFromInternalName,
bTypes.byteCodeRepository.compilingClasses,
bTypes.byteCodeRepository.parsedClasses,
bTypes.callGraph.callsites)
- notPerRun foreach compiler.perRunCaches.unrecordCache
+ notPerRun foreach global.perRunCaches.unrecordCache
- import compiler.genBCode.bTypes._
- import compiler.genBCode.bTypes.backendUtils._
+ import global.genBCode.bTypes.{byteCodeRepository, callGraph, inliner, inlinerHeuristics}
import inlinerHeuristics._
def compile(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = {
notPerRun.foreach(_.clear())
- compileClasses(compiler)(scalaCode, javaCode, allowMessage)
+ compileToBytes(scalaCode, javaCode, allowMessage)
// Use the class nodes stored in the byteCodeRepository. The ones returned by compileClasses are not the same,
// these are created new from the classfile byte array. They are completely separate instances which cannot
// be used to look up methods / callsites in the callGraph hash maps for example.
@@ -64,7 +60,7 @@ class InlinerTest extends ClearAfterClass {
def gMethAndFCallsite(code: String, mod: ClassNode => Unit = _ => ()) = {
val List(c) = compile(code)
mod(c)
- val gMethod = findAsmMethod(c, "g")
+ val gMethod = getAsmMethod(c, "g")
val fCall = getCallsite(gMethod, "f")
(gMethod, fCall)
}
@@ -138,7 +134,7 @@ class InlinerTest extends ClearAfterClass {
assertSameCode(convertMethod(g), gBeforeLocalOpt)
- compiler.genBCode.bTypes.localOpt.methodOptimizations(g, "C")
+ global.genBCode.bTypes.localOpt.methodOptimizations(g, "C")
assertSameCode(convertMethod(g), invokeQQQ :+ Op(ATHROW))
}
@@ -152,7 +148,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val can = canInlineTest(code, cls => {
- val f = cls.methods.asScala.find(_.name == "f").get
+ val f = getAsmMethod(cls, "f")
f.access |= ACC_SYNCHRONIZED
})
assert(can.nonEmpty && can.get.isInstanceOf[SynchronizedMethod], can)
@@ -201,7 +197,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c, d) = compile(code)
- val hMeth = findAsmMethod(d, "h")
+ val hMeth = getAsmMethod(d, "h")
val gCall = getCallsite(hMeth, "g")
val r = inliner.canInlineBody(gCall)
assert(r.nonEmpty && r.get.isInstanceOf[IllegalAccessInstruction], r)
@@ -218,7 +214,7 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(cCls) = compile(code)
- val instructions = getSingleMethod(cCls, "test").instructions
+ val instructions = getInstructions(cCls, "test")
assert(instructions.contains(Op(ICONST_0)), instructions.stringLines)
assert(!instructions.contains(Op(ICONST_1)), instructions)
}
@@ -284,7 +280,7 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c, _, _) = compile(code)
- val ins = getSingleMethod(c, "f").instructions
+ val ins = getInstructions(c, "f")
val invokeSysArraycopy = Invoke(INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", false)
assert(ins contains invokeSysArraycopy, ins.stringLines)
}
@@ -316,7 +312,7 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c, t) = compile(code)
- assertNoInvoke(getSingleMethod(c, "g"))
+ assertNoInvoke(getMethod(c, "g"))
}
@Test
@@ -329,7 +325,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
// no more invoke, f is inlined
- assertNoInvoke(getSingleMethod(c, "g"))
+ assertNoInvoke(getMethod(c, "g"))
}
@Test
@@ -341,7 +337,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- val fMeth = findAsmMethod(c, "f")
+ val fMeth = getAsmMethod(c, "f")
val call = getCallsite(fMeth, "lowestOneBit")
val warning = inliner.canInlineBody(call)
@@ -380,7 +376,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
// use a compiler without local optimizations (cleanups)
- val List(c) = compileClasses(inlineOnlyCompiler)(code)
+ val c = inlineOnlyCompiler.compileClass(code)
val ms @ List(f1, f2, g1, g2) = c.methods.asScala.filter(_.name.length == 2).toList
// stack height at callsite of f1 is 1, so max of g1 after inlining is max of f1 + 1
@@ -425,7 +421,7 @@ class InlinerTest extends ClearAfterClass {
var c = 0
val List(b) = compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; i.msg contains warn})
assert(c == 1, c)
- val ins = getSingleMethod(b, "g").instructions
+ val ins = getInstructions(b, "g")
val invokeFlop = Invoke(INVOKEVIRTUAL, "B", "flop", "()I", false)
assert(ins contains invokeFlop, ins.stringLines)
}
@@ -445,8 +441,8 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c, t) = compile(code)
// both are just `return 1`, no more calls
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertNoInvoke(getSingleMethod(c, "t2"))
+ assertNoInvoke(getMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t2"))
}
@Test
@@ -464,8 +460,8 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c, t, u) = compile(code)
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertNoInvoke(getSingleMethod(c, "t2"))
+ assertNoInvoke(getMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t2"))
}
@Test
@@ -485,8 +481,8 @@ class InlinerTest extends ClearAfterClass {
var count = 0
val List(c, t) = compile(code, allowMessage = i => {count += 1; warns.exists(i.msg contains _)})
assert(count == 2, count)
- assertInvoke(getSingleMethod(c, "t1"), "T", "f")
- assertInvoke(getSingleMethod(c, "t2"), "C", "f")
+ assertInvoke(getMethod(c, "t1"), "T", "f")
+ assertInvoke(getMethod(c, "t2"), "C", "f")
}
@Test
@@ -500,7 +496,7 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c, t) = compile(code)
- assertNoInvoke(getSingleMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t1"))
}
@Test
@@ -524,11 +520,11 @@ class InlinerTest extends ClearAfterClass {
val List(c, oMirror, oModule, t) = compile(code, allowMessage = i => {count += 1; i.msg contains warn})
assert(count == 1, count)
- assertNoInvoke(getSingleMethod(t, "f"))
+ assertNoInvoke(getMethod(t, "f"))
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertNoInvoke(getSingleMethod(c, "t2"))
- assertInvoke(getSingleMethod(c, "t3"), "T", "f")
+ assertNoInvoke(getMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t2"))
+ assertInvoke(getMethod(c, "t3"), "T", "f")
}
@Test
@@ -550,12 +546,12 @@ class InlinerTest extends ClearAfterClass {
val List(assembly, c, t) = compile(code)
- assertNoInvoke(getSingleMethod(t, "f"))
+ assertNoInvoke(getMethod(t, "f"))
- assertNoInvoke(getSingleMethod(assembly, "n"))
+ assertNoInvoke(getMethod(assembly, "n"))
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertNoInvoke(getSingleMethod(c, "t2"))
+ assertNoInvoke(getMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t2"))
}
@Test
@@ -628,20 +624,20 @@ class InlinerTest extends ClearAfterClass {
val List(ca, cb, t1, t2a, t2b) = compile(code, allowMessage = i => {count += 1; i.msg contains warning})
assert(count == 4, count) // see comments, f is not inlined 4 times
- assertNoInvoke(getSingleMethod(t2a, "g2a"))
- assertInvoke(getSingleMethod(t2b, "g2b"), "T1", "f")
+ assertNoInvoke(getMethod(t2a, "g2a"))
+ assertInvoke(getMethod(t2b, "g2b"), "T1", "f")
- assertInvoke(getSingleMethod(ca, "m1a"), "T1", "f")
- assertNoInvoke(getSingleMethod(ca, "m2a")) // no invoke, see comment on def g2a
- assertNoInvoke(getSingleMethod(ca, "m3a"))
- assertInvoke(getSingleMethod(ca, "m4a"), "T1", "f")
- assertNoInvoke(getSingleMethod(ca, "m5a"))
+ assertInvoke(getMethod(ca, "m1a"), "T1", "f")
+ assertNoInvoke(getMethod(ca, "m2a")) // no invoke, see comment on def g2a
+ assertNoInvoke(getMethod(ca, "m3a"))
+ assertInvoke(getMethod(ca, "m4a"), "T1", "f")
+ assertNoInvoke(getMethod(ca, "m5a"))
- assertInvoke(getSingleMethod(cb, "m1b"), "T1", "f")
- assertInvoke(getSingleMethod(cb, "m2b"), "T1", "f") // invoke, see comment on def g2b
- assertNoInvoke(getSingleMethod(cb, "m3b"))
- assertInvoke(getSingleMethod(cb, "m4b"), "T1", "f")
- assertNoInvoke(getSingleMethod(cb, "m5b"))
+ assertInvoke(getMethod(cb, "m1b"), "T1", "f")
+ assertInvoke(getMethod(cb, "m2b"), "T1", "f") // invoke, see comment on def g2b
+ assertNoInvoke(getMethod(cb, "m3b"))
+ assertInvoke(getMethod(cb, "m4b"), "T1", "f")
+ assertNoInvoke(getMethod(cb, "m5b"))
}
@Test
@@ -658,7 +654,7 @@ class InlinerTest extends ClearAfterClass {
|} // so d.f can be resolved statically. same for E.f
""".stripMargin
val List(c, d, e, eModule, t) = compile(code)
- assertNoInvoke(getSingleMethod(t, "t1"))
+ assertNoInvoke(getMethod(t, "t1"))
}
@Test
@@ -673,8 +669,8 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c, d, t) = compile(code)
- assertNoInvoke(getSingleMethod(d, "m"))
- assertNoInvoke(getSingleMethod(c, "m"))
+ assertNoInvoke(getMethod(d, "m"))
+ assertNoInvoke(getMethod(c, "m"))
}
@Test
@@ -688,8 +684,8 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c, t) = compile(code)
- val t1 = getSingleMethod(t, "t1")
- val t2 = getSingleMethod(t, "t2")
+ val t1 = getMethod(t, "t1")
+ val t2 = getMethod(t, "t2")
val cast = TypeOp(CHECKCAST, "C")
Set(t1, t2).foreach(m => assert(m.instructions.contains(cast), m.instructions))
}
@@ -769,27 +765,27 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c, t, u) = compile(code, allowMessage = _.msg contains "i()I is annotated @inline but cannot be inlined")
- val m1 = getSingleMethod(c, "m1")
+ val m1 = getMethod(c, "m1")
assertInvoke(m1, "T", "a")
assertInvoke(m1, "T", "b")
assertInvoke(m1, "T", "c")
- assertNoInvoke(getSingleMethod(c, "m2"))
+ assertNoInvoke(getMethod(c, "m2"))
- val m3 = getSingleMethod(c, "m3")
+ val m3 = getMethod(c, "m3")
assertInvoke(m3, "T", "f")
assertInvoke(m3, "T", "g")
assertInvoke(m3, "T", "h")
assertInvoke(m3, "T", "i")
- val m4 = getSingleMethod(c, "m4")
+ val m4 = getMethod(c, "m4")
assertInvoke(m4, "U", "a")
assertInvoke(m4, "U", "b")
assertInvoke(m4, "U", "c")
- assertNoInvoke(getSingleMethod(c, "m5"))
+ assertNoInvoke(getMethod(c, "m5"))
- val m6 = getSingleMethod(c, "m6")
+ val m6 = getMethod(c, "m6")
assertInvoke(m6, "U", "f")
assertInvoke(m6, "U", "g")
assertInvoke(m6, "U", "h")
@@ -829,7 +825,7 @@ class InlinerTest extends ClearAfterClass {
var c = 0
- compileClasses(newCompiler(extraArgs = args + " -Yopt-warnings:_"))(
+ newCompiler(extraArgs = compilerArgs + " -Yopt-warnings:_").compileClasses(
scalaCode,
List((javaCode, "A.java")),
allowMessage = i => {c += 1; i.msg contains warn})
@@ -873,15 +869,15 @@ class InlinerTest extends ClearAfterClass {
val List(a, b, t) = compile(code, allowMessage = i => {c += 1; i.msg contains warn})
assert(c == 1, c)
- assertInvoke(getSingleMethod(b, "t1"), "Aa", "f1")
- assertInvoke(getSingleMethod(b, "t2"), "B", "B$$f2m")
- assertInvoke(getSingleMethod(b, "t3"), "B", "<init>")
- assertInvoke(getSingleMethod(b, "t4"), "B", "<init>")
+ assertInvoke(getMethod(b, "t1"), "Aa", "f1")
+ assertInvoke(getMethod(b, "t2"), "B", "B$$f2m")
+ assertInvoke(getMethod(b, "t3"), "B", "<init>")
+ assertInvoke(getMethod(b, "t4"), "B", "<init>")
- assertInvoke(getSingleMethod(t, "t1"), "B", "f1")
- assertInvoke(getSingleMethod(t, "t2"), "B", "B$$f2m")
- assertInvoke(getSingleMethod(t, "t3"), "B", "<init>")
- assertInvoke(getSingleMethod(t, "t4"), "B", "<init>")
+ assertInvoke(getMethod(t, "t1"), "B", "f1")
+ assertInvoke(getMethod(t, "t2"), "B", "B$$f2m")
+ assertInvoke(getMethod(t, "t3"), "B", "<init>")
+ assertInvoke(getMethod(t, "t4"), "B", "<init>")
}
@Test
@@ -891,8 +887,8 @@ class InlinerTest extends ClearAfterClass {
| def t = System.arraycopy(null, 0, null, 0, 0)
|}
""".stripMargin
- val List(c) = compileClasses(newCompiler(extraArgs = args + " -Yopt-inline-heuristics:everything"))(code)
- assertInvoke(getSingleMethod(c, "t"), "java/lang/System", "arraycopy")
+ val c = newCompiler(extraArgs = compilerArgs + " -Yopt-inline-heuristics:everything").compileClass(code)
+ assertInvoke(getMethod(c, "t"), "java/lang/System", "arraycopy")
}
@Test
@@ -906,7 +902,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- assertInvoke(getSingleMethod(c, "t"), "java/lang/Error", "<init>")
+ assertInvoke(getMethod(c, "t"), "java/lang/Error", "<init>")
}
@Test
@@ -919,7 +915,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- val t = getSingleMethod(c, "t").instructions
+ val t = getInstructions(c, "t")
assertNoInvoke(t)
assert(1 == t.collect({case Ldc(_, "hai!") => }).size) // push-pop eliminates the first LDC("hai!")
assert(1 == t.collect({case Jump(IFNONNULL, _) => }).size) // one single null check
@@ -946,12 +942,12 @@ class InlinerTest extends ClearAfterClass {
val List(c, _, _) = compile(code)
- val t1 = getSingleMethod(c, "t1")
+ val t1 = getMethod(c, "t1")
assertNoIndy(t1)
// the indy call is inlined into t, and the closure elimination rewrites the closure invocation to the body method
assertInvoke(t1, "C", "C$$$anonfun$2")
- val t2 = getSingleMethod(c, "t2")
+ val t2 = getMethod(c, "t2")
assertNoIndy(t2)
assertInvoke(t2, "M$", "M$$$anonfun$1")
}
@@ -968,9 +964,9 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- val hMeth = findAsmMethod(c, "h")
- val gMeth = findAsmMethod(c, "g")
- val iMeth = findAsmMethod(c, "i")
+ val hMeth = getAsmMethod(c, "h")
+ val gMeth = getAsmMethod(c, "g")
+ val iMeth = getAsmMethod(c, "i")
val fCall = getCallsite(gMeth, "f")
val gCall = getCallsite(hMeth, "g")
val hCall = getCallsite(iMeth, "h")
@@ -997,7 +993,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(cl) = compile(code)
- val List(b, c, d) = List("b", "c", "d").map(findAsmMethod(cl, _))
+ val List(b, c, d) = List("b", "c", "d").map(getAsmMethod(cl, _))
val aCall = getCallsite(b, "a")
val bCall = getCallsite(c, "b")
val cCall = getCallsite(d, "c")
@@ -1037,15 +1033,15 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- assertInvoke(getSingleMethod(c, "t1"), "C", "C$$$anonfun$1")
- assertInvoke(getSingleMethod(c, "t2"), "C", "a")
- assertInvoke(getSingleMethod(c, "t3"), "C", "b")
- assertNoInvoke(getSingleMethod(c, "t4"))
- assertNoInvoke(getSingleMethod(c, "t5"))
- assertNoInvoke(getSingleMethod(c, "t6"))
- assertInvoke(getSingleMethod(c, "t7"), "C", "c")
- assertInvoke(getSingleMethod(c, "t8"), "scala/Predef$", "println")
- assertNoInvoke(getSingleMethod(c, "t9"))
+ assertInvoke(getMethod(c, "t1"), "C", "C$$$anonfun$1")
+ assertInvoke(getMethod(c, "t2"), "C", "a")
+ assertInvoke(getMethod(c, "t3"), "C", "b")
+ assertNoInvoke(getMethod(c, "t4"))
+ assertNoInvoke(getMethod(c, "t5"))
+ assertNoInvoke(getMethod(c, "t6"))
+ assertInvoke(getMethod(c, "t7"), "C", "c")
+ assertInvoke(getMethod(c, "t8"), "scala/Predef$", "println")
+ assertNoInvoke(getMethod(c, "t9"))
}
@Test
@@ -1070,15 +1066,15 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertInvoke(getSingleMethod(c, "t2"), "C", "f2")
- assertInvoke(getSingleMethod(c, "t3"), "C", "f1")
- assertInvoke(getSingleMethod(c, "t4"), "C", "f2")
- assertNoInvoke(getSingleMethod(c, "t5"))
- assertInvoke(getSingleMethod(c, "t6"), "C", "f3")
- assertNoInvoke(getSingleMethod(c, "t7"))
- assertInvoke(getSingleMethod(c, "t8"), "C", "f1")
- assertNoInvoke(getSingleMethod(c, "t9"))
+ assertNoInvoke(getMethod(c, "t1"))
+ assertInvoke(getMethod(c, "t2"), "C", "f2")
+ assertInvoke(getMethod(c, "t3"), "C", "f1")
+ assertInvoke(getMethod(c, "t4"), "C", "f2")
+ assertNoInvoke(getMethod(c, "t5"))
+ assertInvoke(getMethod(c, "t6"), "C", "f3")
+ assertNoInvoke(getMethod(c, "t7"))
+ assertInvoke(getMethod(c, "t8"), "C", "f1")
+ assertNoInvoke(getMethod(c, "t9"))
}
@Test
@@ -1101,11 +1097,11 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c) = compile(code)
- assertInvoke(getSingleMethod(c, "t1"), "C", "C$$$anonfun$1")
- assertInvoke(getSingleMethod(c, "t2"), "C", "C$$$anonfun$2")
- assertInvoke(getSingleMethod(c, "t3"), "scala/Function1", "apply$mcII$sp")
- assertInvoke(getSingleMethod(c, "t4"), "scala/Function1", "apply$mcII$sp")
- assertInvoke(getSingleMethod(c, "t5"), "C", "h")
+ assertInvoke(getMethod(c, "t1"), "C", "C$$$anonfun$1")
+ assertInvoke(getMethod(c, "t2"), "C", "C$$$anonfun$2")
+ assertInvoke(getMethod(c, "t3"), "scala/Function1", "apply$mcII$sp")
+ assertInvoke(getMethod(c, "t4"), "scala/Function1", "apply$mcII$sp")
+ assertInvoke(getMethod(c, "t5"), "C", "h")
}
@Test
@@ -1125,7 +1121,7 @@ class InlinerTest extends ClearAfterClass {
|when entering an exception handler declared in the inlined method.""".stripMargin
val List(c) = compile(code, allowMessage = _.msg contains warn)
- assertInvoke(getSingleMethod(c, "t"), "C", "g")
+ assertInvoke(getMethod(c, "t"), "C", "g")
}
@Test
@@ -1149,8 +1145,8 @@ class InlinerTest extends ClearAfterClass {
|that would cause an IllegalAccessError when inlined into class D.""".stripMargin
val List(c, d) = compile(code, allowMessage = _.msg contains warn)
- assertInvoke(getSingleMethod(c, "h"), "C", "f$1")
- assertInvoke(getSingleMethod(d, "t"), "C", "h")
+ assertInvoke(getMethod(c, "h"), "C", "f$1")
+ assertInvoke(getMethod(d, "t"), "C", "h")
}
@Test
@@ -1168,8 +1164,8 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c, d) = compile(code)
- assertNoInvoke(getSingleMethod(c, "g"))
- assertNoInvoke(getSingleMethod(d, "t"))
+ assertNoInvoke(getMethod(c, "g"))
+ assertNoInvoke(getMethod(d, "t"))
}
@Test
@@ -1277,40 +1273,40 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c, _, _) = compile(code)
- assertSameSummary(getSingleMethod(c, "t1"), List(BIPUSH, "C$$$anonfun$1", IRETURN))
- assertSameSummary(getSingleMethod(c, "t1a"), List(LCONST_1, "C$$$anonfun$2", IRETURN))
- assertSameSummary(getSingleMethod(c, "t2"), List(ICONST_1, ICONST_2, "C$$$anonfun$3",IRETURN))
+ assertSameSummary(getMethod(c, "t1"), List(BIPUSH, "C$$$anonfun$1", IRETURN))
+ assertSameSummary(getMethod(c, "t1a"), List(LCONST_1, "C$$$anonfun$2", IRETURN))
+ assertSameSummary(getMethod(c, "t2"), List(ICONST_1, ICONST_2, "C$$$anonfun$3",IRETURN))
// val a = new ValKl(n); new ValKl(anonfun(a.x)).x
// value class instantiation-extraction should be optimized by boxing elim
- assertSameSummary(getSingleMethod(c, "t3"), List(
+ assertSameSummary(getMethod(c, "t3"), List(
NEW, DUP, ICONST_1, "<init>", ASTORE,
NEW, DUP, ALOAD, "x",
"C$$$anonfun$4",
"<init>",
"x", IRETURN))
- assertSameSummary(getSingleMethod(c, "t4"), List(BIPUSH, "C$$$anonfun$5", "boxToInteger", ARETURN))
- assertSameSummary(getSingleMethod(c, "t4a"), List(ICONST_1, LDC, "C$$$anonfun$6", LRETURN))
- assertSameSummary(getSingleMethod(c, "t5"), List(BIPUSH, ICONST_3, "C$$$anonfun$7", "boxToInteger", ARETURN))
- assertSameSummary(getSingleMethod(c, "t5a"), List(BIPUSH, BIPUSH, I2B, "C$$$anonfun$8", IRETURN))
- assertSameSummary(getSingleMethod(c, "t6"), List(BIPUSH, "C$$$anonfun$9", RETURN))
- assertSameSummary(getSingleMethod(c, "t7"), List(ICONST_1, "C$$$anonfun$10", RETURN))
- assertSameSummary(getSingleMethod(c, "t8"), List(ICONST_1, LDC, "C$$$anonfun$11", LRETURN))
- assertSameSummary(getSingleMethod(c, "t9"), List(ICONST_1, "boxToInteger", "C$$$anonfun$12", RETURN))
+ assertSameSummary(getMethod(c, "t4"), List(BIPUSH, "C$$$anonfun$5", "boxToInteger", ARETURN))
+ assertSameSummary(getMethod(c, "t4a"), List(ICONST_1, LDC, "C$$$anonfun$6", LRETURN))
+ assertSameSummary(getMethod(c, "t5"), List(BIPUSH, ICONST_3, "C$$$anonfun$7", "boxToInteger", ARETURN))
+ assertSameSummary(getMethod(c, "t5a"), List(BIPUSH, BIPUSH, I2B, "C$$$anonfun$8", IRETURN))
+ assertSameSummary(getMethod(c, "t6"), List(BIPUSH, "C$$$anonfun$9", RETURN))
+ assertSameSummary(getMethod(c, "t7"), List(ICONST_1, "C$$$anonfun$10", RETURN))
+ assertSameSummary(getMethod(c, "t8"), List(ICONST_1, LDC, "C$$$anonfun$11", LRETURN))
+ assertSameSummary(getMethod(c, "t9"), List(ICONST_1, "boxToInteger", "C$$$anonfun$12", RETURN))
// t9a inlines Range.foreach, which is quite a bit of code, so just testing the core
- assertInvoke(getSingleMethod(c, "t9a"), "C", "C$$$anonfun$13")
- assertInvoke(getSingleMethod(c, "t9a"), "scala/runtime/BoxesRunTime", "boxToInteger")
+ assertInvoke(getMethod(c, "t9a"), "C", "C$$$anonfun$13")
+ assertInvoke(getMethod(c, "t9a"), "scala/runtime/BoxesRunTime", "boxToInteger")
- assertSameSummary(getSingleMethod(c, "t10"), List(
+ assertSameSummary(getMethod(c, "t10"), List(
ICONST_1, ISTORE,
ALOAD, ILOAD,
"C$$$anonfun$14", RETURN))
// t10a inlines Range.foreach
- assertInvoke(getSingleMethod(c, "t10a"), "C", "C$$$anonfun$15")
- assertDoesNotInvoke(getSingleMethod(c, "t10a"), "boxToInteger")
+ assertInvoke(getMethod(c, "t10a"), "C", "C$$$anonfun$15")
+ assertDoesNotInvoke(getMethod(c, "t10a"), "boxToInteger")
}
@Test
@@ -1333,8 +1329,8 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c) = compile(code)
- assertSameCode(getSingleMethod(c, "t1"), List(Op(ICONST_0), Op(ICONST_1), Op(IADD), Op(IRETURN)))
- assertEquals(getSingleMethod(c, "t2").instructions collect { case i: Invoke => i.owner +"."+ i.name }, List(
+ assertSameCode(getMethod(c, "t1"), List(Op(ICONST_0), Op(ICONST_1), Op(IADD), Op(IRETURN)))
+ assertEquals(getInstructions(c, "t2") collect { case i: Invoke => i.owner +"."+ i.name }, List(
"scala/runtime/IntRef.create", "C.C$$$anonfun$1"))
}
@@ -1374,11 +1370,11 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c) = compile(code)
- assertSameCode(getSingleMethod(c, "t1"), List(Op(ICONST_3), Op(ICONST_4), Op(IADD), Op(IRETURN)))
- assertSameCode(getSingleMethod(c, "t2"), List(Op(ICONST_1), Op(ICONST_2), Op(IADD), Op(IRETURN)))
- assertSameCode(getSingleMethod(c, "t3"), List(Op(ICONST_1), Op(ICONST_3), Op(ISUB), Op(IRETURN)))
- assertNoInvoke(getSingleMethod(c, "t4"))
- assertNoInvoke(getSingleMethod(c, "t5"))
+ assertSameCode(getMethod(c, "t1"), List(Op(ICONST_3), Op(ICONST_4), Op(IADD), Op(IRETURN)))
+ assertSameCode(getMethod(c, "t2"), List(Op(ICONST_1), Op(ICONST_2), Op(IADD), Op(IRETURN)))
+ assertSameCode(getMethod(c, "t3"), List(Op(ICONST_1), Op(ICONST_3), Op(ISUB), Op(IRETURN)))
+ assertNoInvoke(getMethod(c, "t4"))
+ assertNoInvoke(getMethod(c, "t5"))
}
@Test
@@ -1404,10 +1400,10 @@ class InlinerTest extends ClearAfterClass {
|class D extends C
""".stripMargin
val List(c, _) = compile(code)
- def casts(m: String) = getSingleMethod(c, m).instructions collect { case TypeOp(CHECKCAST, tp) => tp }
- assertSameCode(getSingleMethod(c, "t1"), List(VarOp(ALOAD, 1), Op(ARETURN)))
- assertSameCode(getSingleMethod(c, "t2"), List(VarOp(ALOAD, 1), Op(ARETURN)))
- assertSameCode(getSingleMethod(c, "t3"), List(VarOp(ALOAD, 1), TypeOp(CHECKCAST, "C"), Op(ARETURN)))
+ def casts(m: String) = getInstructions(c, m) collect { case TypeOp(CHECKCAST, tp) => tp }
+ assertSameCode(getMethod(c, "t1"), List(VarOp(ALOAD, 1), Op(ARETURN)))
+ assertSameCode(getMethod(c, "t2"), List(VarOp(ALOAD, 1), Op(ARETURN)))
+ assertSameCode(getMethod(c, "t3"), List(VarOp(ALOAD, 1), TypeOp(CHECKCAST, "C"), Op(ARETURN)))
assertEquals(casts("t4"), List("C"))
assertEquals(casts("t5"), Nil)
assertEquals(casts("t6"), Nil)
@@ -1432,8 +1428,8 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val cls = compile(code)
- val test = cls.find(_.name == "Test$").get
- assertSameSummary(getSingleMethod(test, "f"), List(
+ val test = findClass(cls, "Test$")
+ assertSameSummary(getMethod(test, "f"), List(
GETSTATIC, "mkFoo",
BIPUSH, ISTORE,
IFNONNULL, ACONST_NULL, ATHROW, -1 /*label*/,
@@ -1452,7 +1448,7 @@ class InlinerTest extends ClearAfterClass {
val List(c) = compile(code)
// box-unbox will clean it up
- assertSameSummary(getSingleMethod(c, "t"), List(
+ assertSameSummary(getMethod(c, "t"), List(
ALOAD, "C$$$anonfun$1", IFEQ /*A*/,
"C$$$anonfun$2", IRETURN,
-1 /*A*/, "C$$$anonfun$3", IRETURN))
@@ -1464,7 +1460,7 @@ class InlinerTest extends ClearAfterClass {
val codeB = "class B { def t(a: A) = a.f }"
// tests that no warning is emitted
val List(a, b) = compileClassesSeparately(List(codeA, codeB), extraArgs = "-Yopt:l:project -Yopt-warnings")
- assertInvoke(getSingleMethod(b, "t"), "A", "f")
+ assertInvoke(getMethod(b, "t"), "A", "f")
}
@Test
@@ -1476,7 +1472,7 @@ class InlinerTest extends ClearAfterClass {
""".stripMargin
val List(c, t1, t2) = compile(code, allowMessage = _ => true)
// the forwarder C.f is inlined, so there's no invocation
- assertSameSummary(getSingleMethod(c, "f"), List(ICONST_1, IRETURN))
+ assertSameSummary(getMethod(c, "f"), List(ICONST_1, IRETURN))
}
@Test
@@ -1489,10 +1485,12 @@ class InlinerTest extends ClearAfterClass {
|class C { def t = (new K).f }
""".stripMargin
val c :: _ = compile(code)
- assertSameSummary(getSingleMethod(c, "t"), List(NEW, "<init>", ICONST_1, IRETURN)) // ICONST_1, U.f is inlined (not T.f)
+ assertSameSummary(getMethod(c, "t"), List(NEW, "<init>", ICONST_1, IRETURN)) // ICONST_1, U.f is inlined (not T.f)
}
- @Test
+ // Can be enabled when using 2.12.0-M5 as starr. This test works under a full boostrap, but not
+ // when compiled with M4.
+ @Test @Ignore
def inlineArrayForeach(): Unit = {
val code =
"""class C {
@@ -1501,7 +1499,7 @@ class InlinerTest extends ClearAfterClass {
|}
""".stripMargin
val List(c) = compile(code)
- val t = getSingleMethod(c, "t")
+ val t = getMethod(c, "t")
assertNoIndy(t)
assertInvoke(t, "C", "C$$$anonfun$1")
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala
index 003b2d4880..fa76c0d930 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala
@@ -2,42 +2,40 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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.collection.JavaConverters._
+import scala.tools.asm.Opcodes._
import scala.tools.asm.tree.ClassNode
import scala.tools.nsc.backend.jvm.AsmUtils._
-import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import scala.tools.testing.ClearAfterClass
-import scala.collection.JavaConverters._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class MethodLevelOptsTest extends ClearAfterClass {
- val methodOptCompiler = cached("methodOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:method"))
+class MethodLevelOptsTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:method"
+ import compiler._
def wrapInDefault(code: Instruction*) = List(Label(0), LineNumber(1, Label(0))) ::: code.toList ::: List(Label(1))
- def locals(c: ClassNode, m: String) = findAsmMethod(c, m).localVariables.asScala.toList.map(l => (l.name, l.index)).sortBy(_._2)
+ def locals(c: ClassNode, m: String) = getAsmMethod(c, m).localVariables.asScala.toList.map(l => (l.name, l.index)).sortBy(_._2)
@Test
def eliminateEmptyTry(): Unit = {
val code = "def f = { try {} catch { case _: Throwable => 0; () }; 1 }"
val warn = "a pure expression does nothing in statement position"
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code, allowMessage = _.msg contains warn), wrapInDefault(Op(ICONST_1), Op(IRETURN)))
+ assertSameCode(compileInstructions(code, allowMessage = _.msg contains warn), wrapInDefault(Op(ICONST_1), Op(IRETURN)))
}
@Test
def eliminateLoadBoxedUnit(): Unit = {
// the compiler inserts a boxed into the try block. it's therefore non-empty (and live) and not eliminated.
val code = "def f = { try {} catch { case _: Throwable => 0 }; 1 }"
- val m = singleMethod(methodOptCompiler)(code)
+ val m = compileMethod(code)
assertTrue(m.handlers.length == 0)
assertSameCode(m, List(Op(ICONST_1), Op(IRETURN)))
}
@@ -46,7 +44,7 @@ class MethodLevelOptsTest extends ClearAfterClass {
def inlineThrowInCatchNotTry(): Unit = {
// the try block does not contain the `ATHROW` instruction, but in the catch block, `ATHROW` is inlined
val code = "def f(e: Exception) = throw { try e catch { case _: Throwable => e } }"
- val m = singleMethod(methodOptCompiler)(code)
+ val m = compileMethod(code)
assertHandlerLabelPostions(m.handlers.head, m.instructions, 0, 3, 5)
assertSameCode(m.instructions,
wrapInDefault(VarOp(ALOAD, 1), Label(3), Op(ATHROW), Label(5), FrameEntry(4, List(), List("java/lang/Throwable")), Op(POP), VarOp(ALOAD, 1), Op(ATHROW))
@@ -57,7 +55,7 @@ class MethodLevelOptsTest extends ClearAfterClass {
def inlineReturnInCatchNotTry(): Unit = {
val code = "def f: Int = return { try 1 catch { case _: Throwable => 2 } }"
// cannot inline the IRETURN into the try block (because RETURN may throw IllegalMonitorState)
- val m = singleMethod(methodOptCompiler)(code)
+ val m = compileMethod(code)
assertHandlerLabelPostions(m.handlers.head, m.instructions, 0, 3, 5)
assertSameCode(m.instructions,
wrapInDefault(Op(ICONST_1), Label(3), Op(IRETURN), Label(5), FrameEntry(4, List(), List("java/lang/Throwable")), Op(POP), Op(ICONST_2), Op(IRETURN)))
@@ -79,7 +77,7 @@ class MethodLevelOptsTest extends ClearAfterClass {
| println(x)
| }
""".stripMargin
- val m = singleMethod(methodOptCompiler)(code)
+ val m = compileMethod(code)
assertTrue(m.handlers.isEmpty)
assertSameCode(m, List(Op(ICONST_3), Op(IRETURN)))
}
@@ -99,8 +97,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameCode(getSingleMethod(c, "t"), List(
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"), List(
Op(ACONST_NULL), Invoke(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false), Op(ARETURN)))
}
@@ -116,9 +114,9 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
+ val c = compileClass(code)
assertSameCode(
- getSingleMethod(c, "t"), List(Ldc(LDC, "c"), Op(ARETURN)))
+ getMethod(c, "t"), List(Ldc(LDC, "c"), Op(ARETURN)))
}
@Test
@@ -136,9 +134,9 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
+ val c = compileClass(code)
- assertSameCode(getSingleMethod(c, "t"), List(
+ assertSameCode(getMethod(c, "t"), List(
Ldc(LDC, "el"), VarOp(ASTORE, 1),
Field(GETSTATIC, "scala/Predef$", "MODULE$", "Lscala/Predef$;"), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "scala/Predef$", "println", "(Ljava/lang/Object;)V", false),
Op(ACONST_NULL), VarOp(ASTORE, 1),
@@ -160,8 +158,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameCode(getSingleMethod(c, "t"), List(
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"), List(
IntOp(BIPUSH, 23), IntOp(NEWARRAY, 5), Op(POP), VarOp(ILOAD, 1), VarOp(ILOAD, 2), Op(IADD), Op(IRETURN)))
}
@@ -175,8 +173,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameCode(getSingleMethod(c, "t"), List(
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"), List(
TypeOp(NEW, "java/lang/Integer"), Ldc(LDC, "nono"), Invoke(INVOKESPECIAL, "java/lang/Integer", "<init>", "(Ljava/lang/String;)V", false),
VarOp(ILOAD, 1), VarOp(ILOAD, 2), Op(IADD), Op(IRETURN)))
}
@@ -201,8 +199,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameCode(getSingleMethod(c, "t"), List(Op(ICONST_0), Op(IRETURN)))
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"), List(Op(ICONST_0), Op(IRETURN)))
}
@Test
@@ -217,8 +215,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameCode(getSingleMethod(c, "t"), List(
+ val c = compileClass(code)
+ assertSameCode(getMethod(c, "t"), List(
IntOp(BIPUSH, 30), VarOp(ISTORE, 3), // no constant propagation, so we keep the store (and load below) of a const
VarOp(ILOAD, 1),
VarOp(ILOAD, 2),
@@ -238,8 +236,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- val t = getSingleMethod(c, "t")
+ val c = compileClass(code)
+ val t = getMethod(c, "t")
assert(!t.instructions.exists(_.opcode == INVOKEDYNAMIC), t)
}
@@ -319,23 +317,23 @@ class MethodLevelOptsTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
-
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertNoInvoke(getSingleMethod(c, "t2"))
- assertInvoke(getSingleMethod(c, "t3"), "scala/runtime/BoxesRunTime", "unboxToInt")
- assertInvoke(getSingleMethod(c, "t4"), "scala/runtime/BoxesRunTime", "boxToLong")
- assertNoInvoke(getSingleMethod(c, "t5"))
- assertNoInvoke(getSingleMethod(c, "t6"))
- assertNoInvoke(getSingleMethod(c, "t7"))
- assertSameSummary(getSingleMethod(c, "t8"), List(ICONST_0, IRETURN))
- assertNoInvoke(getSingleMethod(c, "t9"))
+ val c = compileClass(code)
+
+ assertNoInvoke(getMethod(c, "t1"))
+ assertNoInvoke(getMethod(c, "t2"))
+ assertInvoke(getMethod(c, "t3"), "scala/runtime/BoxesRunTime", "unboxToInt")
+ assertInvoke(getMethod(c, "t4"), "scala/runtime/BoxesRunTime", "boxToLong")
+ assertNoInvoke(getMethod(c, "t5"))
+ assertNoInvoke(getMethod(c, "t6"))
+ assertNoInvoke(getMethod(c, "t7"))
+ assertSameSummary(getMethod(c, "t8"), List(ICONST_0, IRETURN))
+ assertNoInvoke(getMethod(c, "t9"))
// t10: no invocation of unbox
- assertEquals(getSingleMethod(c, "t10").instructions collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List(
+ assertEquals(getInstructions(c, "t10") collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List(
("java/lang/Integer", "valueOf"),
("C", "escape")))
- assertSameSummary(getSingleMethod(c, "t11"), List(
+ assertSameSummary(getMethod(c, "t11"), List(
BIPUSH, "valueOf", ASTORE /*2*/,
BIPUSH, "valueOf", ASTORE /*3*/,
ALOAD /*0*/, ALOAD /*2*/, "escape",
@@ -343,7 +341,7 @@ class MethodLevelOptsTest extends ClearAfterClass {
ASTORE /*4*/, GETSTATIC /*Predef*/, ALOAD /*4*/, "Integer2int", IRETURN))
// no unbox invocations
- assertEquals(getSingleMethod(c, "t12").instructions collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List(
+ assertEquals(getInstructions(c, "t12") collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List(
("java/lang/Integer", "valueOf"),
("java/lang/Integer", "valueOf"),
("C", "escape")))
@@ -395,14 +393,14 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameSummary(getSingleMethod(c, "t1"), List(ICONST_0, IRETURN))
- assertNoInvoke(getSingleMethod(c, "t2"))
- assertSameSummary(getSingleMethod(c, "t3"), List(LDC, LDC, LADD, LRETURN))
- assertNoInvoke(getSingleMethod(c, "t4"))
- assertEquals(getSingleMethod(c, "t5").instructions collect { case Field(_, owner, name, _) => s"$owner.$name" },
+ val c = compileClass(code)
+ assertSameSummary(getMethod(c, "t1"), List(ICONST_0, IRETURN))
+ assertNoInvoke(getMethod(c, "t2"))
+ assertSameSummary(getMethod(c, "t3"), List(LDC, LDC, LADD, LRETURN))
+ assertNoInvoke(getMethod(c, "t4"))
+ assertEquals(getInstructions(c, "t5") collect { case Field(_, owner, name, _) => s"$owner.$name" },
List("scala/runtime/IntRef.elem"))
- assertEquals(getSingleMethod(c, "t6").instructions collect { case Field(op, owner, name, _) => s"$op $owner.$name" },
+ assertEquals(getInstructions(c, "t6") collect { case Field(op, owner, name, _) => s"$op $owner.$name" },
List(s"$PUTFIELD scala/runtime/IntRef.elem", s"$GETFIELD scala/runtime/IntRef.elem"))
}
@@ -459,23 +457,23 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertNoInvoke(getSingleMethod(c, "t1"))
- assertSameSummary(getSingleMethod(c, "t2"), List(ICONST_1, ICONST_3, IADD, IRETURN))
- assertSameSummary(getSingleMethod(c, "t3"), List(ICONST_3, ICONST_4, IADD, IRETURN))
- assertSameSummary(getSingleMethod(c, "t4"), List(ICONST_3, "boxToInteger", ARETURN))
- assertEquals(getSingleMethod(c, "t5").instructions collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List(
+ val c = compileClass(code)
+ assertNoInvoke(getMethod(c, "t1"))
+ assertSameSummary(getMethod(c, "t2"), List(ICONST_1, ICONST_3, IADD, IRETURN))
+ assertSameSummary(getMethod(c, "t3"), List(ICONST_3, ICONST_4, IADD, IRETURN))
+ assertSameSummary(getMethod(c, "t4"), List(ICONST_3, "boxToInteger", ARETURN))
+ assertEquals(getInstructions(c, "t5") collect { case Invoke(_, owner, name, _, _) => (owner, name) }, List(
("scala/runtime/BoxesRunTime", "boxToInteger"),
("scala/runtime/BoxesRunTime", "boxToInteger"),
("C", "tpl"),
("scala/Tuple2", "_1$mcI$sp")))
- assertSameSummary(getSingleMethod(c, "t6"), List(ICONST_1, ICONST_2, ISUB, IRETURN))
- assertSameSummary(getSingleMethod(c, "t7"), List(
+ assertSameSummary(getMethod(c, "t6"), List(ICONST_1, ICONST_2, ISUB, IRETURN))
+ assertSameSummary(getMethod(c, "t7"), List(
ICONST_1, ICONST_2, ISTORE, ISTORE,
ICONST_3, ISTORE,
ILOAD, ILOAD, IADD, ILOAD, IADD, IRETURN))
- assertNoInvoke(getSingleMethod(c, "t8"))
- assertNoInvoke(getSingleMethod(c, "t9"))
+ assertNoInvoke(getMethod(c, "t8"))
+ assertNoInvoke(getMethod(c, "t9"))
}
@Test
@@ -524,14 +522,14 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertSameSummary(getSingleMethod(c, "t1"), List(NEW, DUP, "<init>", ARETURN))
- assertSameCode(getSingleMethod(c, "t2"), List(Op(LCONST_0), Op(LRETURN)))
- assertSameCode(getSingleMethod(c, "t3"), List(Op(ICONST_1), Op(IRETURN)))
- assertSameCode(getSingleMethod(c, "t4"), List(Op(ICONST_1), Op(IRETURN)))
- assertSameCode(getSingleMethod(c, "t5"), List(Op(DCONST_0), Op(DRETURN)))
- assertSameCode(getSingleMethod(c, "t6"), List(Op(ACONST_NULL), Op(ARETURN)))
- assertSameCode(getSingleMethod(c, "t7"), List(Op(ICONST_0), Op(IRETURN)))
+ val c = compileClass(code)
+ assertSameSummary(getMethod(c, "t1"), List(NEW, DUP, "<init>", ARETURN))
+ assertSameCode(getMethod(c, "t2"), List(Op(LCONST_0), Op(LRETURN)))
+ assertSameCode(getMethod(c, "t3"), List(Op(ICONST_1), Op(IRETURN)))
+ assertSameCode(getMethod(c, "t4"), List(Op(ICONST_1), Op(IRETURN)))
+ assertSameCode(getMethod(c, "t5"), List(Op(DCONST_0), Op(DRETURN)))
+ assertSameCode(getMethod(c, "t6"), List(Op(ACONST_NULL), Op(ARETURN)))
+ assertSameCode(getMethod(c, "t7"), List(Op(ICONST_0), Op(IRETURN)))
}
@Test
@@ -544,9 +542,9 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
+ val c = compileClass(code)
assertSameCode(
- getSingleMethod(c, "t"), List(
+ getMethod(c, "t"), List(
VarOp(ALOAD, 1), Jump(IFNULL, Label(6)), Op(ICONST_1), Op(IRETURN), Label(6), Op(ICONST_0), Op(IRETURN)))
}
@@ -615,28 +613,28 @@ class MethodLevelOptsTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- def stores(m: String) = getSingleMethod(c, m).instructions.filter(_.opcode == ASTORE)
+ val c = compileClass(code)
+ def stores(m: String) = getInstructions(c, m).filter(_.opcode == ASTORE)
assertEquals(locals(c, "t1"), List(("this",0), ("kept1",1), ("result",2)))
assert(stores("t1") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 2), VarOp(ASTORE, 1), VarOp(ASTORE, 1)),
- textify(findAsmMethod(c, "t1")))
+ textify(getAsmMethod(c, "t1")))
assertEquals(locals(c, "t2"), List(("this",0), ("kept2",1), ("kept3",2)))
assert(stores("t2") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 2), VarOp(ASTORE, 1)),
- textify(findAsmMethod(c, "t2")))
+ textify(getAsmMethod(c, "t2")))
assertEquals(locals(c, "t3"), List(("this",0), ("kept4",1)))
assert(stores("t3") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 1)),
- textify(findAsmMethod(c, "t3")))
+ textify(getAsmMethod(c, "t3")))
assertEquals(locals(c, "t4"), List(("this",0), ("kept5",1)))
assert(stores("t4") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 1)),
- textify(findAsmMethod(c, "t4")))
+ textify(getAsmMethod(c, "t4")))
assertEquals(locals(c, "t5"), List(("this",0), ("kept6",1)))
assert(stores("t5") == List(VarOp(ASTORE, 1), VarOp(ASTORE, 1)),
- textify(findAsmMethod(c, "t5")))
+ textify(getAsmMethod(c, "t5")))
}
@Test
@@ -683,13 +681,13 @@ class MethodLevelOptsTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
+ val c = compileClass(code)
assertEquals(locals(c, "t1"), List(("this", 0), ("x", 1)))
assertEquals(locals(c, "t2"), List(("this", 0), ("x", 1)))
// we don't have constant propagation (yet).
// the local var can't be optimized as a store;laod sequence, there's a GETSTATIC between the two
- assertSameSummary(getSingleMethod(c, "t2"), List(
+ assertSameSummary(getMethod(c, "t2"), List(
ICONST_2, ISTORE, GETSTATIC, ILOAD, "boxToInteger", "println", RETURN))
assertEquals(locals(c, "t3"), List(("this", 0)))
@@ -711,8 +709,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- val t = getSingleMethod(c, "t")
+ val c = compileClass(code)
+ val t = getMethod(c, "t")
assertEquals(t.handlers, Nil)
assertEquals(locals(c, "t"), List(("this", 0)))
assertSameSummary(t, List(GETSTATIC, LDC, "print", -1, GOTO))
@@ -729,8 +727,8 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
- assertNoInvoke(getSingleMethod(c, "compare"))
+ val c = compileClass(code)
+ assertNoInvoke(getMethod(c, "compare"))
}
@Test
@@ -743,9 +741,9 @@ class MethodLevelOptsTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val List(c) = compileClasses(methodOptCompiler)(code)
+ val c = compileClass(code)
- assertSameSummary(getSingleMethod(c, "t"), List(
+ assertSameSummary(getMethod(c, "t"), List(
BIPUSH, ILOAD, IF_ICMPNE,
BIPUSH, ILOAD, IF_ICMPNE,
LDC, ASTORE, GOTO,
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
index 6cb3fd3bba..5bd285f97f 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
@@ -2,23 +2,20 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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 CodeGenTools._
-import scala.tools.asm.tree.ClassNode
-import scala.tools.nsc.backend.jvm.BTypes.{MethodInlineInfo, InlineInfo}
-import scala.tools.partest.ASMConverters
-import ASMConverters._
import scala.collection.JavaConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.asm.tree.ClassNode
+import scala.tools.nsc.backend.jvm.BTypes.{InlineInfo, MethodInlineInfo}
+import scala.tools.testing.BytecodeTesting
@RunWith(classOf[JUnit4])
-class ScalaInlineInfoTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
+class ScalaInlineInfoTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:l:none"
+ import compiler._
def inlineInfo(c: ClassNode): InlineInfo = c.attrs.asScala.collect({ case a: InlineInfoAttribute => a.inlineInfo }).head
@@ -72,7 +69,7 @@ class ScalaInlineInfoTest extends ClearAfterClass {
|}
""".stripMargin
- val cs @ List(c, t, tl, to) = compileClasses(compiler)(code)
+ val cs @ List(c, t, tl, to) = compileClasses(code)
val infoT = inlineInfo(t)
val expectT = InlineInfo (
false, // final class
@@ -149,7 +146,7 @@ class ScalaInlineInfoTest extends ClearAfterClass {
| def nullary: Int
|}
""".stripMargin
- val cs = compileClasses(compiler)(code)
+ val cs = compileClasses(code)
val sams = cs.map(c => (c.name, inlineInfo(c).sam))
assertEquals(sams,
List(
@@ -165,7 +162,7 @@ class ScalaInlineInfoTest extends ClearAfterClass {
@Test
def lzyComputeInlineInfo(): Unit = {
val code = "class C { object O }"
- val List(c, om) = compileClasses(compiler)(code)
+ val List(c, om) = compileClasses(code)
val infoC = inlineInfo(c)
val expected = Map(
"<init>()V" -> MethodInlineInfo(false,false,false),
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
index 99acb318de..992a0e541b 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
@@ -2,15 +2,15 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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 CodeGenTools._
+import scala.tools.asm.Opcodes._
import scala.tools.partest.ASMConverters
-import ASMConverters._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
class SimplifyJumpsTest {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
index 46f06d1d39..63bbcc396b 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
@@ -2,17 +2,15 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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.asm.Opcodes._
+import scala.tools.partest.ASMConverters._
import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
+import scala.tools.testing.BytecodeTesting._
import scala.tools.testing.ClearAfterClass
@RunWith(classOf[JUnit4])
@@ -20,12 +18,12 @@ class UnreachableCodeTest extends ClearAfterClass {
// jvm-1.6 enables emitting stack map frames, which impacts the code generation wrt dead basic blocks,
// see comment in BCodeBodyBuilder
val methodOptCompiler = cached("methodOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:method"))
- val dceCompiler = cached("dceCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
- val noOptCompiler = cached("noOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
+ val dceCompiler = cached("dceCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
+ val noOptCompiler = cached("noOptCompiler", () => newCompiler(extraArgs = "-Yopt:l:none"))
def assertEliminateDead(code: (Instruction, Boolean)*): Unit = {
val method = genMethod()(code.map(_._1): _*)
- dceCompiler.genBCode.bTypes.localOpt.removeUnreachableCodeImpl(method, "C")
+ dceCompiler.global.genBCode.bTypes.localOpt.removeUnreachableCodeImpl(method, "C")
val nonEliminated = instructionsFromMethod(method)
val expectedLive = code.filter(_._2).map(_._1).toList
assertSameCode(nonEliminated, expectedLive)
@@ -112,10 +110,10 @@ class UnreachableCodeTest extends ClearAfterClass {
@Test
def basicEliminationCompiler(): Unit = {
val code = "def f: Int = { return 1; 2 }"
- val withDce = singleMethodInstructions(dceCompiler)(code)
+ val withDce = dceCompiler.compileInstructions(code)
assertSameCode(withDce.dropNonOp, List(Op(ICONST_1), Op(IRETURN)))
- val noDce = singleMethodInstructions(noOptCompiler)(code)
+ val noDce = noOptCompiler.compileInstructions(code)
// The emitted code is ICONST_1, IRETURN, ICONST_2, IRETURN. The latter two are dead.
//
@@ -141,23 +139,23 @@ class UnreachableCodeTest extends ClearAfterClass {
def wrapInDefault(code: Instruction*) = List(Label(0), LineNumber(1, Label(0))) ::: code.toList ::: List(Label(1))
val code = "def f: Int = { return 0; try { 1 } catch { case _: Exception => 2 } }"
- val m = singleMethod(dceCompiler)(code)
+ val m = dceCompiler.compileMethod(code)
assertTrue(m.handlers.isEmpty) // redundant (if code is gone, handler is gone), but done once here for extra safety
assertSameCode(m.instructions,
wrapInDefault(Op(ICONST_0), Op(IRETURN)))
val code2 = "def f: Unit = { try { } catch { case _: Exception => () }; () }"
// requires fixpoint optimization of methodOptCompiler (dce alone is not enough): first the handler is eliminated, then it's dead catch block.
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code2), wrapInDefault(Op(RETURN)))
+ assertSameCode(methodOptCompiler.compileInstructions(code2), wrapInDefault(Op(RETURN)))
val code3 = "def f: Unit = { try { } catch { case _: Exception => try { } catch { case _: Exception => () } }; () }"
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code3), wrapInDefault(Op(RETURN)))
+ assertSameCode(methodOptCompiler.compileInstructions(code3), wrapInDefault(Op(RETURN)))
// this example requires two iterations to get rid of the outer handler.
// the first iteration of DCE cannot remove the inner handler. then the inner (empty) handler is removed.
// then the second iteration of DCE removes the inner catch block, and then the outer handler is removed.
val code4 = "def f: Unit = { try { try { } catch { case _: Exception => () } } catch { case _: Exception => () }; () }"
- assertSameCode(singleMethodInstructions(methodOptCompiler)(code4), wrapInDefault(Op(RETURN)))
+ assertSameCode(methodOptCompiler.compileInstructions(code4), wrapInDefault(Op(RETURN)))
}
@Test // test the dce-testing tools
@@ -174,7 +172,7 @@ class UnreachableCodeTest extends ClearAfterClass {
}
@Test
- def bytecodeEquivalence: Unit = {
+ def bytecodeEquivalence(): Unit = {
assertTrue(List(VarOp(ILOAD, 1)) ===
List(VarOp(ILOAD, 2)))
assertTrue(List(VarOp(ILOAD, 1), VarOp(ISTORE, 1)) ===
@@ -216,35 +214,35 @@ class UnreachableCodeTest extends ClearAfterClass {
| def t4 = cons(nt)
|}
""".stripMargin
- val List(c) = compileClasses(noOptCompiler)(code)
+ val c = noOptCompiler.compileClass(code)
- assertSameSummary(getSingleMethod(c, "nl"), List(ACONST_NULL, ARETURN))
+ assertSameSummary(getMethod(c, "nl"), List(ACONST_NULL, ARETURN))
- assertSameSummary(getSingleMethod(c, "nt"), List(
+ assertSameSummary(getMethod(c, "nt"), List(
NEW, DUP, LDC, "<init>", ATHROW))
- assertSameSummary(getSingleMethod(c, "t1"), List(
+ assertSameSummary(getMethod(c, "t1"), List(
ALOAD, ACONST_NULL, "cons", RETURN))
// GenBCode introduces POP; ACONST_NULL after loading an expression of type scala.runtime.Null$,
// see comment in BCodeBodyBuilder.adapt
- assertSameSummary(getSingleMethod(c, "t2"), List(
+ assertSameSummary(getMethod(c, "t2"), List(
ALOAD, ALOAD, "nl", POP, ACONST_NULL, "cons", RETURN))
// the bytecode generated by GenBCode is ... ATHROW; INVOKEVIRTUAL C.cons; RETURN
// the ASM classfile writer creates a new basic block (creates a label) right after the ATHROW
// and replaces all instructions by NOP*; ATHROW, see comment in BCodeBodyBuilder.adapt
// NOTE: DCE is enabled by default and gets rid of the redundant code (tested below)
- assertSameSummary(getSingleMethod(c, "t3"), List(
+ assertSameSummary(getMethod(c, "t3"), List(
ALOAD, NEW, DUP, LDC, "<init>", ATHROW, NOP, NOP, NOP, ATHROW))
// GenBCode introduces an ATHROW after the invocation of C.nt, see BCodeBodyBuilder.adapt
// NOTE: DCE is enabled by default and gets rid of the redundant code (tested below)
- assertSameSummary(getSingleMethod(c, "t4"), List(
+ assertSameSummary(getMethod(c, "t4"), List(
ALOAD, ALOAD, "nt", ATHROW, NOP, NOP, NOP, ATHROW))
- val List(cDCE) = compileClasses(dceCompiler)(code)
- assertSameSummary(getSingleMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "<init>", ATHROW))
- assertSameSummary(getSingleMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW))
+ val cDCE = dceCompiler.compileClass(code)
+ assertSameSummary(getMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "<init>", ATHROW))
+ assertSameSummary(getMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW))
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala
index 77e73e64b9..c9c98b403b 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala
@@ -2,21 +2,20 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
+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.collection.JavaConverters._
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.collection.JavaConverters._
+import scala.tools.partest.ASMConverters._
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class UnusedLocalVariablesTest extends ClearAfterClass {
- val dceCompiler = cached("dceCompiler", () => newCompiler(extraArgs = "-Yopt:unreachable-code"))
+class UnusedLocalVariablesTest extends BytecodeTesting {
+ override def compilerArgs = "-Yopt:unreachable-code"
+ import compiler._
@Test
def removeUnusedVar(): Unit = {
@@ -49,7 +48,7 @@ class UnusedLocalVariablesTest extends ClearAfterClass {
| }
|}
|""".stripMargin
- val cls = compileClasses(dceCompiler)(code).head
+ val cls = compileClass(code)
val m = convertMethod(cls.methods.asScala.toList.find(_.desc == "(I)V").get)
assertTrue(m.localVars.length == 2) // this, a, but not y
@@ -70,19 +69,14 @@ class UnusedLocalVariablesTest extends ClearAfterClass {
|}
""".stripMargin
- val clss2 = compileClasses(dceCompiler)(code2)
- val cls2 = clss2.find(_.name == "C").get
- val companion2 = clss2.find(_.name == "C$").get
-
- val clsConstr = convertMethod(cls2.methods.asScala.toList.find(_.name == "<init>").get)
- val companionConstr = convertMethod(companion2.methods.asScala.toList.find(_.name == "<init>").get)
+ val List(cls2, companion2) = compileClasses(code2)
- assertTrue(clsConstr.localVars.length == 1) // this
- assertTrue(companionConstr.localVars.length == 1) // this
+ assertTrue(getMethod(cls2, "<init>").localVars.length == 1) // this
+ assertTrue(getMethod(companion2, "<init>").localVars.length == 1) // this
}
def assertLocalVarCount(code: String, numVars: Int): Unit = {
- assertTrue(singleMethod(dceCompiler)(code).localVars.length == numVars)
+ assertTrue(compileMethod(code).localVars.length == numVars)
}
}
diff --git a/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala b/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala
index e4bf038f32..609f481721 100644
--- a/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala
+++ b/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala
@@ -1,17 +1,15 @@
package scala.tools.nsc.transform.delambdafy
-import scala.reflect.io.Path.jfile2path
-import scala.tools.nsc.backend.jvm.CodeGenTools.getGeneratedClassfiles
-import scala.tools.nsc.backend.jvm.CodeGenTools.makeSourceFile
-import scala.tools.nsc.backend.jvm.CodeGenTools.newCompilerWithoutVirtualOutdir
-import scala.tools.nsc.io.AbstractFile
-import scala.tools.testing.TempDir
-
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import scala.reflect.io.Path.jfile2path
+import scala.tools.nsc.io.AbstractFile
+import scala.tools.testing.BytecodeTesting._
+import scala.tools.testing.TempDir
+
@RunWith(classOf[JUnit4])
class DelambdafyTest {
def compileToMultipleOutputWithDelamdbafyMethod(): List[(String, Array[Byte])] = {
@@ -55,9 +53,9 @@ object Delambdafy {
val extraArgs = "-Ydelambdafy:method"
val argsWithOutDir = extraArgs + s" -d $outDirPath -cp $outDirPath"
val compiler = newCompilerWithoutVirtualOutdir(extraArgs = argsWithOutDir)
- compiler.settings.outputDirs.add(srcFile.file, outDir)
+ compiler.global.settings.outputDirs.add(srcFile.file, outDir)
- new compiler.Run().compileSources(List(srcFile))
+ new compiler.global.Run().compileSources(List(srcFile))
val classfiles = getGeneratedClassfiles(outDir)
outDir.delete()
diff --git a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala
index aa83520efb..b6e8d4fbf2 100644
--- a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala
+++ b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala
@@ -1,26 +1,21 @@
package scala.tools.nsc
package transform.patmat
+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.asm.Opcodes._
import scala.tools.nsc.backend.jvm.AsmUtils._
-import scala.tools.nsc.backend.jvm.CodeGenTools
-import scala.tools.testing.AssertUtil._
-
-import CodeGenTools._
-import scala.tools.partest.ASMConverters
-import ASMConverters._
-import scala.tools.testing.ClearAfterClass
+import scala.tools.testing.BytecodeTesting
+import scala.tools.testing.BytecodeTesting._
@RunWith(classOf[JUnit4])
-class PatmatBytecodeTest extends ClearAfterClass {
- val compiler = cached("compiler", () => newCompiler())
+class PatmatBytecodeTest extends BytecodeTesting {
val optCompiler = cached("optCompiler", () => newCompiler(extraArgs = "-Yopt:l:project"))
+ import compiler._
+
@Test
def t6956(): Unit = {
val code =
@@ -43,9 +38,9 @@ class PatmatBytecodeTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assert(getSingleMethod(c, "s1").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c))
- assert(getSingleMethod(c, "s2").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c))
+ val c = compileClass(code)
+ assert(getInstructions(c, "s1").count(_.opcode == TABLESWITCH) == 1, textify(c))
+ assert(getInstructions(c, "s2").count(_.opcode == TABLESWITCH) == 1, textify(c))
}
@Test
@@ -71,9 +66,9 @@ class PatmatBytecodeTest extends ClearAfterClass {
|}
""".stripMargin
- val List(c) = compileClasses(compiler)(code)
- assert(getSingleMethod(c, "s1").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c))
- assert(getSingleMethod(c, "s2").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c))
+ val c = compileClass(code)
+ assert(getInstructions(c, "s1").count(_.opcode == TABLESWITCH) == 1, textify(c))
+ assert(getInstructions(c, "s2").count(_.opcode == TABLESWITCH) == 1, textify(c))
}
@Test
@@ -86,9 +81,9 @@ class PatmatBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val c = compileClasses(optCompiler)(code).head
+ val c :: _ = optCompiler.compileClasses(code)
- assertSameSummary(getSingleMethod(c, "a"), List(
+ assertSameSummary(getMethod(c, "a"), List(
NEW, DUP, ICONST_1, LDC, "<init>",
"y", ARETURN))
}
@@ -103,8 +98,8 @@ class PatmatBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val c = compileClasses(optCompiler)(code).head
- assert(!getSingleMethod(c, "a").instructions.exists(i => i.opcode == IFNULL || i.opcode == IFNONNULL), textify(findAsmMethod(c, "a")))
+ val c :: _ = optCompiler.compileClasses(code)
+ assert(!getInstructions(c, "a").exists(i => i.opcode == IFNULL || i.opcode == IFNONNULL), textify(getAsmMethod(c, "a")))
}
@Test
@@ -117,8 +112,8 @@ class PatmatBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val c = compileClasses(optCompiler)(code).head
- assertSameSummary(getSingleMethod(c, "a"), List(
+ val c :: _ = optCompiler.compileClasses(code)
+ assertSameSummary(getMethod(c, "a"), List(
NEW, DUP, ICONST_1, "boxToInteger", LDC, "<init>", ASTORE /*1*/,
ALOAD /*1*/, "y", ASTORE /*2*/,
ALOAD /*1*/, "x", INSTANCEOF, IFNE /*R*/,
@@ -138,7 +133,7 @@ class PatmatBytecodeTest extends ClearAfterClass {
| }
|}
""".stripMargin
- val c = compileClasses(optCompiler)(code, allowMessage = _.msg.contains("may not be exhaustive")).head
+ val c = optCompiler.compileClass(code, allowMessage = _.msg.contains("may not be exhaustive"))
val expected = List(
ALOAD /*1*/ , INSTANCEOF /*::*/ , IFEQ /*A*/ ,
@@ -147,8 +142,8 @@ class PatmatBytecodeTest extends ClearAfterClass {
-1 /*A*/ , NEW /*MatchError*/ , DUP, ALOAD /*1*/ , "<init>", ATHROW,
-1 /*B*/ , ILOAD, IRETURN)
- assertSameSummary(getSingleMethod(c, "a"), expected)
- assertSameSummary(getSingleMethod(c, "b"), expected)
+ assertSameSummary(getMethod(c, "a"), expected)
+ assertSameSummary(getMethod(c, "b"), expected)
}
@Test
@@ -170,18 +165,18 @@ class PatmatBytecodeTest extends ClearAfterClass {
| def t9 = { val C(a, _) = C("hi", 23); a.toString }
|}
""".stripMargin
- val List(c, cMod) = compileClasses(optCompiler)(code)
- assertSameSummary(getSingleMethod(c, "t1"), List(ICONST_1, ICONST_2, IADD, IRETURN))
- assertSameSummary(getSingleMethod(c, "t2"), List(ICONST_1, IRETURN))
- assertInvokedMethods(getSingleMethod(c, "t3"), List("C.tplCall", "scala/Tuple2._1", "scala/Tuple2._2$mcI$sp", "scala/MatchError.<init>", "java/lang/String.length"))
- assertInvokedMethods(getSingleMethod(c, "t4"), List("C.tplCall", "scala/Tuple2._2$mcI$sp", "scala/MatchError.<init>"))
- assertNoInvoke(getSingleMethod(c, "t5"))
- assertSameSummary(getSingleMethod(c, "t6"), List(BIPUSH, IRETURN))
+ val List(c, cMod) = optCompiler.compileClasses(code)
+ assertSameSummary(getMethod(c, "t1"), List(ICONST_1, ICONST_2, IADD, IRETURN))
+ assertSameSummary(getMethod(c, "t2"), List(ICONST_1, IRETURN))
+ assertInvokedMethods(getMethod(c, "t3"), List("C.tplCall", "scala/Tuple2._1", "scala/Tuple2._2$mcI$sp", "scala/MatchError.<init>", "java/lang/String.length"))
+ assertInvokedMethods(getMethod(c, "t4"), List("C.tplCall", "scala/Tuple2._2$mcI$sp", "scala/MatchError.<init>"))
+ assertNoInvoke(getMethod(c, "t5"))
+ assertSameSummary(getMethod(c, "t6"), List(BIPUSH, IRETURN))
// MatchError reachable because of the type pattern `s: String`
- assertInvokedMethods(getSingleMethod(c, "t7"), List("C.a", "C.b", "scala/MatchError.<init>", "java/lang/String.length"))
- assertSameSummary(getSingleMethod(c, "t8"), List(ALOAD, "b", IRETURN))
+ assertInvokedMethods(getMethod(c, "t7"), List("C.a", "C.b", "scala/MatchError.<init>", "java/lang/String.length"))
+ assertSameSummary(getMethod(c, "t8"), List(ALOAD, "b", IRETURN))
// C allocation not eliminated - constructor may have side-effects.
- assertSameSummary(getSingleMethod(c, "t9"), List(NEW, DUP, LDC, BIPUSH, "<init>", "a", "toString", ARETURN))
+ assertSameSummary(getMethod(c, "t9"), List(NEW, DUP, LDC, BIPUSH, "<init>", "a", "toString", ARETURN))
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala b/test/junit/scala/tools/testing/BytecodeTesting.scala
index 389e5b2ead..b11ad27148 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
+++ b/test/junit/scala/tools/testing/BytecodeTesting.scala
@@ -1,32 +1,117 @@
-package scala.tools.nsc.backend.jvm
+package scala.tools.testing
import org.junit.Assert._
+import scala.collection.JavaConverters._
import scala.collection.mutable.ListBuffer
import scala.reflect.internal.util.BatchSourceFile
import scala.reflect.io.VirtualDirectory
import scala.tools.asm.Opcodes
import scala.tools.asm.tree.{AbstractInsnNode, ClassNode, MethodNode}
import scala.tools.cmd.CommandLineParser
+import scala.tools.nsc.backend.jvm.AsmUtils
+import scala.tools.nsc.backend.jvm.AsmUtils._
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.reporters.StoreReporter
-import scala.tools.nsc.settings.MutableSettings
-import scala.tools.nsc.{Settings, Global}
-import scala.tools.partest.ASMConverters
-import scala.collection.JavaConverters._
-import scala.tools.testing.TempDir
-import AsmUtils._
-
-object CodeGenTools {
- import ASMConverters._
-
- def genMethod( flags: Int = Opcodes.ACC_PUBLIC,
- name: String = "m",
- descriptor: String = "()V",
- genericSignature: String = null,
- throwsExceptions: Array[String] = null,
- handlers: List[ExceptionHandler] = Nil,
- localVars: List[LocalVariable] = Nil)(body: Instruction*): MethodNode = {
+import scala.tools.nsc.{Global, Settings}
+import scala.tools.partest.ASMConverters._
+
+trait BytecodeTesting extends ClearAfterClass {
+ def compilerArgs = "" // to be overridden
+ val compiler = cached("compiler", () => BytecodeTesting.newCompiler(extraArgs = compilerArgs))
+}
+
+class Compiler(val global: Global) {
+ import BytecodeTesting._
+
+ def resetOutput(): Unit = {
+ global.settings.outputDirs.setSingleOutput(new VirtualDirectory("(memory)", None))
+ }
+
+ private def newRun: global.Run = {
+ global.reporter.reset()
+ resetOutput()
+ new global.Run()
+ }
+
+ private def reporter = global.reporter.asInstanceOf[StoreReporter]
+
+ def checkReport(allowMessage: StoreReporter#Info => Boolean = _ => false): Unit = {
+ val disallowed = reporter.infos.toList.filter(!allowMessage(_)) // toList prevents an infer-non-wildcard-existential warning.
+ if (disallowed.nonEmpty) {
+ val msg = disallowed.mkString("\n")
+ assert(false, "The compiler issued non-allowed warnings or errors:\n" + msg)
+ }
+ }
+
+ def compileToBytes(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[(String, Array[Byte])] = {
+ val run = newRun
+ run.compileSources(makeSourceFile(scalaCode, "unitTestSource.scala") :: javaCode.map(p => makeSourceFile(p._1, p._2)))
+ checkReport(allowMessage)
+ getGeneratedClassfiles(global.settings.outputDirs.getSingleOutput.get)
+ }
+
+ def compileClasses(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = {
+ readAsmClasses(compileToBytes(code, javaCode, allowMessage))
+ }
+
+ def compileClass(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): ClassNode = {
+ val List(c) = compileClasses(code, javaCode, allowMessage)
+ c
+ }
+
+ def compileToBytesTransformed(scalaCode: String, javaCode: List[(String, String)] = Nil, beforeBackend: global.Tree => global.Tree): List[(String, Array[Byte])] = {
+ import global._
+ settings.stopBefore.value = "jvm" :: Nil
+ val run = newRun
+ val scalaUnit = newCompilationUnit(scalaCode, "unitTestSource.scala")
+ val javaUnits = javaCode.map(p => newCompilationUnit(p._1, p._2))
+ val units = scalaUnit :: javaUnits
+ run.compileUnits(units, run.parserPhase)
+ settings.stopBefore.value = Nil
+ scalaUnit.body = beforeBackend(scalaUnit.body)
+ checkReport(_ => false)
+ val run1 = newRun
+ run1.compileUnits(units, run1.phaseNamed("jvm"))
+ checkReport(_ => false)
+ getGeneratedClassfiles(settings.outputDirs.getSingleOutput.get)
+ }
+
+ def compileClassesTransformed(scalaCode: String, javaCode: List[(String, String)] = Nil, beforeBackend: global.Tree => global.Tree): List[ClassNode] =
+ readAsmClasses(compileToBytesTransformed(scalaCode, javaCode, beforeBackend))
+
+ def compileAsmMethods(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[MethodNode] = {
+ val c = compileClass(s"class C { $code }", allowMessage = allowMessage)
+ getAsmMethods(c, _ != "<init>")
+ }
+
+ def compileAsmMethod(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): MethodNode = {
+ val List(m) = compileAsmMethods(code, allowMessage)
+ m
+ }
+
+ def compileMethods(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Method] =
+ compileAsmMethods(code, allowMessage).map(convertMethod)
+
+ def compileMethod(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): Method = {
+ val List(m) = compileMethods(code, allowMessage = allowMessage)
+ m
+ }
+
+ def compileInstructions(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Instruction] = {
+ val List(m) = compileMethods(code, allowMessage = allowMessage)
+ m.instructions
+ }
+}
+
+object BytecodeTesting {
+ def genMethod(flags: Int = Opcodes.ACC_PUBLIC,
+ name: String = "m",
+ descriptor: String = "()V",
+ genericSignature: String = null,
+ throwsExceptions: Array[String] = null,
+ handlers: List[ExceptionHandler] = Nil,
+ localVars: List[LocalVariable] = Nil)(body: Instruction*): MethodNode = {
val node = new MethodNode(flags, name, descriptor, genericSignature, throwsExceptions)
applyToMethod(node, Method(body.toList, handlers, localVars))
node
@@ -39,33 +124,21 @@ object CodeGenTools {
cls
}
- private def resetOutput(compiler: Global): Unit = {
- compiler.settings.outputDirs.setSingleOutput(new VirtualDirectory("(memory)", None))
- }
-
- def newCompiler(defaultArgs: String = "-usejavacp", extraArgs: String = ""): Global = {
+ def newCompiler(defaultArgs: String = "-usejavacp", extraArgs: String = ""): Compiler = {
val compiler = newCompilerWithoutVirtualOutdir(defaultArgs, extraArgs)
- resetOutput(compiler)
+ compiler.resetOutput()
compiler
}
- def newCompilerWithoutVirtualOutdir(defaultArgs: String = "-usejavacp", extraArgs: String = ""): Global = {
+ def newCompilerWithoutVirtualOutdir(defaultArgs: String = "-usejavacp", extraArgs: String = ""): Compiler = {
def showError(s: String) = throw new Exception(s)
val settings = new Settings(showError)
val args = (CommandLineParser tokenize defaultArgs) ++ (CommandLineParser tokenize extraArgs)
val (_, nonSettingsArgs) = settings.processArguments(args, processAll = true)
if (nonSettingsArgs.nonEmpty) showError("invalid compiler flags: " + nonSettingsArgs.mkString(" "))
- new Global(settings, new StoreReporter)
- }
-
- def newRun(compiler: Global): compiler.Run = {
- compiler.reporter.reset()
- resetOutput(compiler)
- new compiler.Run()
+ new Compiler(new Global(settings, new StoreReporter))
}
- def reporter(compiler: Global) = compiler.reporter.asInstanceOf[StoreReporter]
-
def makeSourceFile(code: String, filename: String): BatchSourceFile = new BatchSourceFile(filename, code)
def getGeneratedClassfiles(outDir: AbstractFile): List[(String, Array[Byte])] = {
@@ -80,38 +153,6 @@ object CodeGenTools {
files(outDir)
}
- def checkReport(compiler: Global, allowMessage: StoreReporter#Info => Boolean = _ => false): Unit = {
- val disallowed = reporter(compiler).infos.toList.filter(!allowMessage(_)) // toList prevents an infer-non-wildcard-existential warning.
- if (disallowed.nonEmpty) {
- val msg = disallowed.mkString("\n")
- assert(false, "The compiler issued non-allowed warnings or errors:\n" + msg)
- }
- }
-
- def compile(compiler: Global)(scalaCode: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[(String, Array[Byte])] = {
- val run = newRun(compiler)
- run.compileSources(makeSourceFile(scalaCode, "unitTestSource.scala") :: javaCode.map(p => makeSourceFile(p._1, p._2)))
- checkReport(compiler, allowMessage)
- getGeneratedClassfiles(compiler.settings.outputDirs.getSingleOutput.get)
- }
-
- def compileTransformed(compiler: Global)(scalaCode: String, javaCode: List[(String, String)] = Nil, beforeBackend: compiler.Tree => compiler.Tree): List[(String, Array[Byte])] = {
- compiler.settings.stopBefore.value = "jvm" :: Nil
- val run = newRun(compiler)
- import compiler._
- val scalaUnit = newCompilationUnit(scalaCode, "unitTestSource.scala")
- val javaUnits = javaCode.map(p => newCompilationUnit(p._1, p._2))
- val units = scalaUnit :: javaUnits
- run.compileUnits(units, run.parserPhase)
- compiler.settings.stopBefore.value = Nil
- scalaUnit.body = beforeBackend(scalaUnit.body)
- checkReport(compiler, _ => false)
- val run1 = newRun(compiler)
- run1.compileUnits(units, run1.phaseNamed("jvm"))
- checkReport(compiler, _ => false)
- getGeneratedClassfiles(compiler.settings.outputDirs.getSingleOutput.get)
- }
-
/**
* Compile multiple Scala files separately into a single output directory.
*
@@ -121,15 +162,15 @@ object CodeGenTools {
* The output directory is a physical directory, I have not figured out if / how it's possible to
* add a VirtualDirectory to the classpath of a compiler.
*/
- def compileSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()): List[(String, Array[Byte])] = {
+ def compileToBytesSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()): List[(String, Array[Byte])] = {
val outDir = AbstractFile.getDirectory(TempDir.createTempDir())
val outDirPath = outDir.canonicalPath
val argsWithOutDir = extraArgs + s" -d $outDirPath -cp $outDirPath"
for (code <- codes) {
val compiler = newCompilerWithoutVirtualOutdir(extraArgs = argsWithOutDir)
- new compiler.Run().compileSources(List(makeSourceFile(code, "unitTestSource.scala")))
- checkReport(compiler, allowMessage)
+ new compiler.global.Run().compileSources(List(makeSourceFile(code, "unitTestSource.scala")))
+ compiler.checkReport(allowMessage)
afterEach(outDir)
}
@@ -138,31 +179,11 @@ object CodeGenTools {
classfiles
}
- def compileClassesSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()) = {
- readAsmClasses(compileSeparately(codes, extraArgs, allowMessage, afterEach))
+ def compileClassesSeparately(codes: List[String], extraArgs: String = "", allowMessage: StoreReporter#Info => Boolean = _ => false, afterEach: AbstractFile => Unit = _ => ()): List[ClassNode] = {
+ readAsmClasses(compileToBytesSeparately(codes, extraArgs, allowMessage, afterEach))
}
- def readAsmClasses(classfiles: List[(String, Array[Byte])]) = {
- classfiles.map(p => AsmUtils.readClass(p._2)).sortBy(_.name)
- }
-
- def compileClasses(compiler: Global)(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = {
- readAsmClasses(compile(compiler)(code, javaCode, allowMessage))
- }
-
- def compileMethods(compiler: Global)(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[MethodNode] = {
- compileClasses(compiler)(s"class C { $code }", allowMessage = allowMessage).head.methods.asScala.toList.filterNot(_.name == "<init>")
- }
-
- def singleMethodInstructions(compiler: Global)(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Instruction] = {
- val List(m) = compileMethods(compiler)(code, allowMessage = allowMessage)
- instructionsFromMethod(m)
- }
-
- def singleMethod(compiler: Global)(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): Method = {
- val List(m) = compileMethods(compiler)(code, allowMessage = allowMessage)
- convertMethod(m)
- }
+ def readAsmClasses(classfiles: List[(String, Array[Byte])]) = classfiles.map(p => AsmUtils.readClass(p._2)).sortBy(_.name)
def assertSameCode(method: Method, expected: List[Instruction]): Unit = assertSameCode(method.instructions.dropNonOp, expected)
def assertSameCode(actual: List[Instruction], expected: List[Instruction]): Unit = {
@@ -212,23 +233,51 @@ object CodeGenTools {
assert(indy.isEmpty, indy)
}
- def getSingleMethod(classNode: ClassNode, name: String): Method =
- convertMethod(classNode.methods.asScala.toList.find(_.name == name).get)
+ def findClass(cs: List[ClassNode], name: String): ClassNode = {
+ val List(c) = cs.filter(_.name == name)
+ c
+ }
+
+ def getAsmMethods(c: ClassNode, p: String => Boolean): List[MethodNode] =
+ c.methods.iterator.asScala.filter(m => p(m.name)).toList.sortBy(_.name)
- def findAsmMethods(c: ClassNode, p: String => Boolean) = c.methods.iterator.asScala.filter(m => p(m.name)).toList.sortBy(_.name)
- def findAsmMethod(c: ClassNode, name: String) = findAsmMethods(c, _ == name).head
+ def getAsmMethods(c: ClassNode, name: String): List[MethodNode] =
+ getAsmMethods(c, _ == name)
+
+ def getAsmMethod(c: ClassNode, name: String): MethodNode = {
+ val List(m) = getAsmMethods(c, name)
+ m
+ }
+
+ def getMethods(c: ClassNode, name: String): List[Method] =
+ getAsmMethods(c, name).map(convertMethod)
+
+ def getMethod(c: ClassNode, name: String): Method =
+ convertMethod(getAsmMethod(c, name))
+
+ def getInstructions(c: ClassNode, name: String): List[Instruction] =
+ getMethod(c, name).instructions
/**
* Instructions that match `query` when textified.
* If `query` starts with a `+`, the next instruction is returned.
*/
- def findInstr(method: MethodNode, query: String): List[AbstractInsnNode] = {
+ def findInstrs(method: MethodNode, query: String): List[AbstractInsnNode] = {
val useNext = query(0) == '+'
val instrPart = if (useNext) query.drop(1) else query
val insns = method.instructions.iterator.asScala.filter(i => textify(i) contains instrPart).toList
if (useNext) insns.map(_.getNext) else insns
}
+ /**
+ * Instruction that matches `query` when textified.
+ * If `query` starts with a `+`, the next instruction is returned.
+ */
+ def findInstr(method: MethodNode, query: String): AbstractInsnNode = {
+ val List(i) = findInstrs(method, query)
+ i
+ }
+
def assertHandlerLabelPostions(h: ExceptionHandler, instructions: List[Instruction], startIndex: Int, endIndex: Int, handlerIndex: Int): Unit = {
val insVec = instructions.toVector
assertTrue(h.start == insVec(startIndex) && h.end == insVec(endIndex) && h.handler == insVec(handlerIndex))
diff --git a/test/junit/scala/tools/testing/RunTesting.scala b/test/junit/scala/tools/testing/RunTesting.scala
new file mode 100644
index 0000000000..1320db4230
--- /dev/null
+++ b/test/junit/scala/tools/testing/RunTesting.scala
@@ -0,0 +1,17 @@
+package scala.tools.testing
+
+import scala.reflect.runtime._
+import scala.tools.reflect.ToolBox
+
+trait RunTesting extends ClearAfterClass {
+ def compilerArgs = "" // to be overridden
+ val runner = cached("toolbox", () => Runner.make(compilerArgs))
+}
+
+class Runner(val toolBox: ToolBox[universe.type]) {
+ def run[T](code: String): T = toolBox.eval(toolBox.parse(code)).asInstanceOf[T]
+}
+
+object Runner {
+ def make(compilerArgs: String) = new Runner(universe.runtimeMirror(getClass.getClassLoader).mkToolBox(options = compilerArgs))
+}