diff options
Diffstat (limited to 'test/junit')
30 files changed, 453 insertions, 555 deletions
diff --git a/test/junit/scala/issues/BytecodeTest.scala b/test/junit/scala/issues/BytecodeTest.scala index 8aa76bbac2..3fd5e3a222 100644 --- a/test/junit/scala/issues/BytecodeTest.scala +++ b/test/junit/scala/issues/BytecodeTest.scala @@ -1,23 +1,22 @@ package scala.issues +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 scala.tools.nsc.backend.jvm.AsmUtils -import scala.tools.testing.BytecodeTesting._ -import org.junit.Assert._ import scala.collection.JavaConverters._ import scala.tools.asm.Opcodes +import scala.tools.asm.Opcodes._ import scala.tools.asm.tree.ClassNode +import scala.tools.nsc.backend.jvm.AsmUtils import scala.tools.partest.ASMConverters._ -import scala.tools.testing.ClearAfterClass +import scala.tools.testing.BytecodeTesting +import scala.tools.testing.BytecodeTesting._ @RunWith(classOf[JUnit4]) -class BytecodeTest extends ClearAfterClass { - val compiler = cached("compiler", () => newCompiler()) +class BytecodeTest extends BytecodeTesting { + import compiler._ @Test def t8731(): Unit = { @@ -37,7 +36,7 @@ class BytecodeTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertTrue(getSingleMethod(c, "f").instructions.count(_.isInstanceOf[TableSwitch]) == 1) assertTrue(getSingleMethod(c, "g").instructions.count(_.isInstanceOf[LookupSwitch]) == 1) @@ -64,9 +63,9 @@ class BytecodeTest extends ClearAfterClass { |@AnnotB class B """.stripMargin - val run = new compiler.Run() + 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 = compiler.settings.outputDirs.getSingleOutput.get + 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) = { @@ -98,7 +97,7 @@ class BytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val List(mirror, module) = compileClasses(compiler)(code) + val List(mirror, module) = compileClasses(code) val unapplyLineNumbers = getSingleMethod(module, "unapply").instructions.filter(_.isInstanceOf[LineNumber]) assert(unapplyLineNumbers == List(LineNumber(2, Label(0))), unapplyLineNumbers) @@ -145,7 +144,7 @@ class BytecodeTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) // t1: no unnecessary GOTOs assertSameCode(getSingleMethod(c, "t1"), List( @@ -271,7 +270,7 @@ class BytecodeTest extends ClearAfterClass { |class C20 extends T8 """.stripMargin - implicit val classes = compileClasses(compiler)(code).map(c => (c.name, c)).toMap + implicit val classes = compileClasses(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) @@ -297,7 +296,7 @@ class BytecodeTest extends ClearAfterClass { |trait T2 { def f(x: String) = 1 } |class C extends T1 with T2 """.stripMargin - val List(c, t1, t2) = compileClasses(compiler)(code) + val List(c, t1, t2) = compileClasses(code) assertEquals(findMethods(c, "f"), Nil) } @@ -329,7 +328,7 @@ class BytecodeTest extends ClearAfterClass { | |class K12 extends J2 with T2 """.stripMargin - implicit val classes = compileClasses(compiler)(code, List(j1, j2, j3, j4)).map(c => (c.name, c)).toMap + implicit val classes = 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 (c <- noForwarder) assertEquals(findMethods(c, "f"), Nil) @@ -339,7 +338,7 @@ class BytecodeTest extends ClearAfterClass { @Test def invocationReceivers(): Unit = { - val List(c1, c2, t, u) = compileClasses(compiler)(invocationReceiversTestCode.definitions("Object")) + val List(c1, c2, t, u) = compileClasses(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") @@ -349,7 +348,7 @@ class BytecodeTest extends ClearAfterClass { assertInvoke(getSingleMethod(c2, "f2"), "T", "clone") assertInvoke(getSingleMethod(c2, "f3"), "C1", "clone") - val List(c1b, c2b, tb, ub) = compileClasses(compiler)(invocationReceiversTestCode.definitions("String")) + 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) @@ -396,9 +395,8 @@ class BytecodeTest extends ClearAfterClass { | 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"))) + val List(c) = compileClasses(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 } @@ -413,7 +411,7 @@ class BytecodeTest extends ClearAfterClass { | |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(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") @@ -424,7 +422,7 @@ class BytecodeTest extends ClearAfterClass { 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) + val List(c, cMod, cSpec) = compileClasses(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)) diff --git a/test/junit/scala/issues/OptimizedBytecodeTest.scala b/test/junit/scala/issues/OptimizedBytecodeTest.scala index 9c0fbebde7..b074215534 100644 --- a/test/junit/scala/issues/OptimizedBytecodeTest.scala +++ b/test/junit/scala/issues/OptimizedBytecodeTest.scala @@ -3,22 +3,21 @@ package scala.issues import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.junit.Test + import scala.tools.asm.Opcodes._ import org.junit.Assert._ import scala.tools.nsc.backend.jvm.AsmUtils - import scala.tools.testing.BytecodeTesting._ import scala.tools.partest.ASMConverters import ASMConverters._ import AsmUtils._ - -import scala.tools.testing.ClearAfterClass +import scala.tools.testing.{BytecodeTesting, ClearAfterClass} @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,7 +27,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | def t(): Unit = while (true) m("...") |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(c, "t"), List(Label(0), Jump(GOTO, Label(0)))) } @@ -46,7 +45,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertSameSummary(getSingleMethod(c, "t"), List( LDC, ASTORE, ALOAD /*0*/, ALOAD /*1*/, "C$$$anonfun$1", IRETURN)) @@ -72,7 +71,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | def h(block: => Unit): Nothing = ??? |} """.stripMargin - val List(c, t, tMod) = compileClasses(compiler)(code, allowMessage = _.msg.contains("not be exhaustive")) + val List(c, t, tMod) = compileClasses(code, allowMessage = _.msg.contains("not be exhaustive")) assertSameSummary(getSingleMethod(c, "t"), List(GETSTATIC, "$qmark$qmark$qmark", ATHROW)) } @@ -97,7 +96,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 +109,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - compileClasses(compiler)(code) + compileClasses(code) } @Test @@ -120,7 +119,7 @@ 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) + val List(c, _, _) = compileClassesSeparately(List(c1, c2), extraArgs = compilerArgs) assertInvoke(getSingleMethod(c, "t"), "warmup/Warmup$", "filter") } @@ -135,7 +134,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - compileClasses(compiler)(code) + compileClasses(code) } @Test @@ -163,7 +162,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - compileClasses(compiler)(code) + compileClasses(code) } @Test @@ -179,7 +178,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - compileClasses(compiler)(code) + compileClasses(code) } @Test @@ -201,7 +200,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | val NoContext = self.analyzer.NoContext |} """.stripMargin - compileClasses(compiler)(code) + compileClasses(code) } @Test @@ -218,7 +217,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertSameSummary(getSingleMethod(c, "t"), List( ALOAD /*1*/, INSTANCEOF /*Some*/, IFNE /*A*/, ALOAD /*0*/, "getInt", POP, @@ -237,7 +236,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertSameSummary(getSingleMethod(c, "t"), List( -1 /*A*/, ILOAD /*1*/, TABLESWITCH, -1, ALOAD, "pr", RETURN, @@ -261,7 +260,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { |} """.stripMargin - val cls = compileClassesSeparately(List(c1, c2), extraArgs = args) + val cls = compileClassesSeparately(List(c1, c2), extraArgs = compilerArgs) val c = cls.find(_.name == "C").get assertSameSummary(getSingleMethod(c, "t"), List( GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW, // module load and null checks not yet eliminated @@ -300,7 +299,7 @@ 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")) + val List(c) = compileClasses(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") @@ -318,7 +317,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { | def t = mbarray_apply_minibox(null, 0) |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertNoInvoke(getSingleMethod(c, "t")) } @@ -336,7 +335,7 @@ class OptimizedBytecodeTest extends ClearAfterClass { |object Nill extends Listt |class Listt """.stripMargin - val List(c, nil, nilMod, listt) = compileClasses(compiler)(code) + val List(c, nil, nilMod, listt) = compileClasses(code) assertInvoke(getSingleMethod(c, "t"), "C", "C$$$anonfun$1") } @@ -355,14 +354,14 @@ class OptimizedBytecodeTest extends ClearAfterClass { | final def apply(a: Any): Any = throw new RuntimeException(key) |} """.stripMargin - val List(c, f) = compileClasses(compiler)(code) + val List(c, f) = compileClasses(code) assertInvoke(getSingleMethod(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"))) + val List(c) = readAsmClasses(newCompiler(extraArgs = "-optimise -deprecation").compile(code, allowMessage = _.msg.contains("is deprecated"))) assertInvoke(getSingleMethod(c, "t"), "C", "C$$$anonfun$1") // range-foreach inlined from classpath } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala index ebeb577149..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.testing.BytecodeTesting._ -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/DefaultMethodTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DefaultMethodTest.scala index 0991e5fbcf..b538ae0bc6 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.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import JavaConverters._ -import scala.tools.testing.ClearAfterClass - -class DefaultMethodTest extends ClearAfterClass { - val compiler = cached("compiler", () => newCompiler()) +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] = readAsmClasses(compiler.compileTransformed(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 ab57c5a1c5..65b4264ee9 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 scala.tools.testing.BytecodeTesting._ + 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)) = compile( """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,7 +41,7 @@ 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) @@ -56,7 +58,7 @@ class DirectCompileTest extends ClearAfterClass { @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"""") + val List(f) = compileMethods("""def f(x: Int) = if (x == 0) "a" else "b"""") assertSameCode(instructionsFromMethod(f).dropLinesFrames, List( Label(0), VarOp(ILOAD, 1), @@ -86,6 +88,6 @@ class DirectCompileTest extends ClearAfterClass { @Test def compileErroneous(): Unit = { - compileClasses(compiler)("class C { def f: String = 1 }", allowMessage = _.msg contains "type mismatch") + compileClasses("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 66054f246f..22ced47a02 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.testing.BytecodeTesting._ -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 = compileMethods(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 }") + compileClasses("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 }") + compileClasses("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]]") + compileClasses("trait Coll[A, Repr] extends Any") + compileClasses("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 598899c705..d7c1f191d0 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 scala.tools.partest.ASMConverters._ +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ - -import scala.tools.testing.ClearAfterClass @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,8 +39,8 @@ 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 cls = compileClasses(s"${classPrologue(from, to)}") + val methodNodes = compileMethods(lamDef(from, to, body) +";"+ appDef(arg), allowMessage) val applySig = cls.head.methods.get(0).desc val anonfun = methodNodes.find(_.name contains "$anonfun$").map(convertMethod).get @@ -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 = compileMethods("def foo = () => () => () => 42") methodNodes.forall(m => !m.name.contains("anonfun") || (m.access & ACC_STATIC) == ACC_STATIC) } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala b/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala index f300090268..f231df8af0 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 scala.tools.partest.ASMConverters._ +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import scala.tools.testing.ClearAfterClass @RunWith(classOf[JUnit4]) -class StringConcatTest extends ClearAfterClass { - val compiler = cached("compiler", () => newCompiler()) +class StringConcatTest extends BytecodeTesting { + import compiler._ @Test def appendOverloadNoBoxing(): Unit = { @@ -54,7 +50,7 @@ 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 List(c) = compileClasses(code) def invokeNameDesc(m: String): List[String] = getSingleMethod(c, m).instructions collect { case Invoke(_, _, name, desc, _) => name + desc 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 d37adb2265..358a461026 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala @@ -2,29 +2,26 @@ 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 scala.tools.testing.BytecodeTesting._ -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)) { @@ -53,7 +50,7 @@ class NullnessAnalyzerTest extends ClearAfterClass { @Test def showNullnessFramesTest(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f = this.toString") + val List(m) = compileMethods("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 List(m) = compileMethods("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 List(m) = compileMethods("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 List(m) = compileMethods("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 List(m) = compileMethods("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 List(m) = compileMethods("""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 List(m) = compileMethods("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 List(m) = compileMethods(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 List(m) = compileMethods(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 List(m) = compileMethods(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 7f6aaca67c..be10370312 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 scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import AsmUtils._ @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,7 +49,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def parameters(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f = this.toString") + val List(m) = compileMethods("def f = this.toString") val a = new ProdConsAnalyzer(m, "C") val call = findInstr(m, "INVOKEVIRTUAL").head @@ -92,7 +93,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def branching(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f(x: Int) = { var a = x; if (a == 0) a = 12; a }") + val List(m) = compileMethods("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") @@ -106,7 +107,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def checkCast(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f(o: Object) = o.asInstanceOf[String]") + val List(m) = compileMethods("def f(o: Object) = o.asInstanceOf[String]") val a = new ProdConsAnalyzer(m, "C") assert(findInstr(m, "CHECKCAST java/lang/String").length == 1) @@ -116,7 +117,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def instanceOf(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f(o: Object) = o.isInstanceOf[String]") + val List(m) = compileMethods("def f(o: Object) = o.isInstanceOf[String]") val a = new ProdConsAnalyzer(m, "C") assert(findInstr(m, "INSTANCEOF java/lang/String").length == 1) @@ -126,7 +127,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def unInitLocal(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }") + val List(m) = compileMethods("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }") val a = new ProdConsAnalyzer(m, "C") val List(store) = findInstr(m, "ISTORE") @@ -140,7 +141,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def dupCopying(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f = new Object") + val List(m) = compileMethods("def f = new Object") val a = new ProdConsAnalyzer(m, "C") val List(newO) = findInstr(m, "NEW") @@ -222,7 +223,7 @@ class ProdConsAnalyzerTest extends ClearAfterClass { @Test def copyingInsns(): Unit = { - val List(m) = compileMethods(noOptCompiler)("def f = 0l.asInstanceOf[Int]") + val List(m) = compileMethods("def f = 0l.asInstanceOf[Int]") val a = new ProdConsAnalyzer(m, "C") val List(cnst) = findInstr(m, "LCONST_0") 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 7f07ce51d3..a5fb1e7d17 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 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._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import AsmUtils._ -import BackendReporting._ -import BytecodeUtils._ - -import scala.collection.JavaConverters._ -import scala.tools.testing.ClearAfterClass @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,7 +32,7 @@ class AnalyzerTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(noOptCompiler)(code) + val List(c) = compileClasses(code) val a = new AliasingAnalyzer(new BasicInterpreter) val f = findAsmMethod(c, "f") a.analyze("C", f) 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 30d5db06dd..1169871ecd 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.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 scala.tools.testing.BytecodeTesting._ -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() 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 e29d41f061..900608837f 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 scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import AsmUtils._ -import BackendReporting._ - -import scala.collection.JavaConverters._ -import scala.tools.testing.ClearAfterClass @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({ 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 d143231882..ddd95ddc02 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 scala.tools.asm.Opcodes._ +import scala.tools.partest.ASMConverters._ +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import AsmUtils._ - -import BackendReporting._ - -import scala.collection.JavaConverters._ -import scala.tools.testing.ClearAfterClass @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,7 +26,7 @@ class ClosureOptimizerTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) val t = findAsmMethod(c, "t") val List(bodyCall) = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Nothing$") assert(bodyCall.getNext.getOpcode == ATHROW) @@ -57,7 +42,7 @@ class ClosureOptimizerTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) val t = findAsmMethod(c, "t") val List(bodyCall) = findInstr(t, "INVOKESTATIC C.C$$$anonfun$1 ()Lscala/runtime/Null$") assert(bodyCall.getNext.getOpcode == POP) @@ -74,7 +59,7 @@ class ClosureOptimizerTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(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), @@ -95,7 +80,7 @@ class ClosureOptimizerTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assertSameSummary(getSingleMethod(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 8ee2b2aa6b..50e3af6ee5 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 scala.tools.partest.ASMConverters._ import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ +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 List(noCompact) = noCompactVarsCompiler.compileMethods(code) + val List(withCompact) = methodOptCompiler.compileMethods(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 d9479fde1d..9fb4aa1658 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 scala.tools.asm.Opcodes._ +import scala.tools.partest.ASMConverters._ +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import scala.tools.testing.ClearAfterClass @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.singleMethod(code).handlers.length == 1) + val optMethod = dceCompiler.singleMethod(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.singleMethod(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.singleMethod(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 a833192fb1..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.partest.ASMConverters +import scala.tools.partest.ASMConverters._ import scala.tools.testing.AssertUtil._ - import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ @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 dc3eede556..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 scala.tools.testing.BytecodeTesting._ -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 428841e0e0..876c47a84e 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 scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import AsmUtils._ -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 = { @@ -107,10 +87,10 @@ class InlineWarningTest extends ClearAfterClass { 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").compile(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").compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.exists(i.msg contains _)}) assert(c == 2, c) } @@ -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.compile(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 e0b1d758f7..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 scala.tools.testing.BytecodeTesting._ -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 748eff88ea..8a44f12045 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerSeparateCompilationTest.scala @@ -2,18 +2,11 @@ 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.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import AsmUtils._ - -import scala.collection.JavaConverters._ object InlinerSeparateCompilationTest { val args = "-Yopt:l:classpath" 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 52ee118a94..4db7695fdd 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.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 scala.tools.partest.ASMConverters._ +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import AsmUtils._ - -import BackendReporting._ - -import scala.collection.JavaConverters._ -import scala.tools.testing.ClearAfterClass @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) + compileClasses(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. @@ -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)) } @@ -380,7 +376,7 @@ class InlinerTest extends ClearAfterClass { """.stripMargin // use a compiler without local optimizations (cleanups) - val List(c) = compileClasses(inlineOnlyCompiler)(code) + val List(c) = inlineOnlyCompiler.compileClasses(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 @@ -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}) @@ -891,7 +887,7 @@ 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) + val List(c) = newCompiler(extraArgs = compilerArgs + " -Yopt-inline-heuristics:everything").compileClasses(code) assertInvoke(getSingleMethod(c, "t"), "java/lang/System", "arraycopy") } 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 1ceaaf7f69..3867f10145 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala @@ -2,25 +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 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 scala.tools.partest.ASMConverters._ +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import scala.tools.testing.ClearAfterClass -import scala.collection.JavaConverters._ @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)) @@ -30,14 +28,14 @@ class MethodLevelOptsTest extends ClearAfterClass { 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(singleMethodInstructions(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 = singleMethod(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 = singleMethod(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 = singleMethod(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 = singleMethod(code) assertTrue(m.handlers.isEmpty) assertSameCode(m, List(Op(ICONST_3), Op(IRETURN))) } @@ -99,7 +97,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(c, "t"), List( Op(ACONST_NULL), Invoke(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false), Op(ARETURN))) } @@ -116,7 +114,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode( getSingleMethod(c, "t"), List(Ldc(LDC, "c"), Op(ARETURN))) } @@ -136,7 +134,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(c, "t"), List( Ldc(LDC, "el"), VarOp(ASTORE, 1), @@ -160,7 +158,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(c, "t"), List( IntOp(BIPUSH, 23), IntOp(NEWARRAY, 5), Op(POP), VarOp(ILOAD, 1), VarOp(ILOAD, 2), Op(IADD), Op(IRETURN))) } @@ -175,7 +173,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(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,7 +199,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(c, "t"), List(Op(ICONST_0), Op(IRETURN))) } @@ -217,7 +215,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode(getSingleMethod(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), @@ -238,7 +236,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) val t = getSingleMethod(c, "t") assert(!t.instructions.exists(_.opcode == INVOKEDYNAMIC), t) } @@ -319,7 +317,7 @@ class MethodLevelOptsTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertNoInvoke(getSingleMethod(c, "t1")) assertNoInvoke(getSingleMethod(c, "t2")) @@ -395,7 +393,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameSummary(getSingleMethod(c, "t1"), List(ICONST_0, IRETURN)) assertNoInvoke(getSingleMethod(c, "t2")) assertSameSummary(getSingleMethod(c, "t3"), List(LDC, LDC, LADD, LRETURN)) @@ -459,7 +457,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(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)) @@ -524,7 +522,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(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))) @@ -544,7 +542,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameCode( getSingleMethod(c, "t"), List( VarOp(ALOAD, 1), Jump(IFNULL, Label(6)), Op(ICONST_1), Op(IRETURN), Label(6), Op(ICONST_0), Op(IRETURN))) @@ -615,7 +613,7 @@ class MethodLevelOptsTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) def stores(m: String) = getSingleMethod(c, m).instructions.filter(_.opcode == ASTORE) assertEquals(locals(c, "t1"), List(("this",0), ("kept1",1), ("result",2))) @@ -683,7 +681,7 @@ class MethodLevelOptsTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertEquals(locals(c, "t1"), List(("this", 0), ("x", 1))) assertEquals(locals(c, "t2"), List(("this", 0), ("x", 1))) @@ -711,7 +709,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) val t = getSingleMethod(c, "t") assertEquals(t.handlers, Nil) assertEquals(locals(c, "t"), List(("this", 0))) @@ -729,7 +727,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertNoInvoke(getSingleMethod(c, "compare")) } @@ -743,7 +741,7 @@ class MethodLevelOptsTest extends ClearAfterClass { | } |} """.stripMargin - val List(c) = compileClasses(methodOptCompiler)(code) + val List(c) = compileClasses(code) assertSameSummary(getSingleMethod(c, "t"), List( BIPUSH, ILOAD, IF_ICMPNE, 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 ba6bdcf658..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 scala.tools.testing.BytecodeTesting._ -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 0133fc9dce..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 scala.tools.testing.BytecodeTesting._ +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 ca095b8a51..99a662b897 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 scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ 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.singleMethodInstructions(code) assertSameCode(withDce.dropNonOp, List(Op(ICONST_1), Op(IRETURN))) - val noDce = singleMethodInstructions(noOptCompiler)(code) + val noDce = noOptCompiler.singleMethodInstructions(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.singleMethod(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.singleMethodInstructions(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.singleMethodInstructions(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.singleMethodInstructions(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,7 +214,7 @@ class UnreachableCodeTest extends ClearAfterClass { | def t4 = cons(nt) |} """.stripMargin - val List(c) = compileClasses(noOptCompiler)(code) + val List(c) = noOptCompiler.compileClasses(code) assertSameSummary(getSingleMethod(c, "nl"), List(ACONST_NULL, ARETURN)) @@ -243,7 +241,7 @@ class UnreachableCodeTest extends ClearAfterClass { assertSameSummary(getSingleMethod(c, "t4"), List( ALOAD, ALOAD, "nt", ATHROW, NOP, NOP, NOP, ATHROW)) - val List(cDCE) = compileClasses(dceCompiler)(code) + val List(cDCE) = dceCompiler.compileClasses(code) assertSameSummary(getSingleMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "<init>", ATHROW)) assertSameSummary(getSingleMethod(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 7ae946f581..303600aa70 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 scala.tools.testing.BytecodeTesting._ +import scala.collection.JavaConverters._ import scala.tools.partest.ASMConverters -import ASMConverters._ -import scala.tools.testing.ClearAfterClass +import scala.tools.partest.ASMConverters._ +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 = compileClasses(code).head val m = convertMethod(cls.methods.asScala.toList.find(_.desc == "(I)V").get) assertTrue(m.localVars.length == 2) // this, a, but not y @@ -70,7 +69,7 @@ class UnusedLocalVariablesTest extends ClearAfterClass { |} """.stripMargin - val clss2 = compileClasses(dceCompiler)(code2) + val clss2 = compileClasses(code2) val cls2 = clss2.find(_.name == "C").get val companion2 = clss2.find(_.name == "C$").get @@ -82,7 +81,7 @@ class UnusedLocalVariablesTest extends ClearAfterClass { } def assertLocalVarCount(code: String, numVars: Int): Unit = { - assertTrue(singleMethod(dceCompiler)(code).localVars.length == numVars) + assertTrue(singleMethod(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 d30f458177..609f481721 100644 --- a/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala +++ b/test/junit/scala/tools/nsc/transform/delambdafy/DelambdafyTest.scala @@ -1,15 +1,15 @@ package scala.tools.nsc.transform.delambdafy -import scala.reflect.io.Path.jfile2path -import scala.tools.testing.BytecodeTesting._ -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])] = { @@ -53,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 99975abc50..cc6d1d7483 100644 --- a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala +++ b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala @@ -1,25 +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.testing.AssertUtil._ - +import scala.tools.testing.BytecodeTesting import scala.tools.testing.BytecodeTesting._ -import scala.tools.partest.ASMConverters -import ASMConverters._ -import scala.tools.testing.ClearAfterClass @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 = @@ -42,7 +38,7 @@ class PatmatBytecodeTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assert(getSingleMethod(c, "s1").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) assert(getSingleMethod(c, "s2").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) } @@ -70,7 +66,7 @@ class PatmatBytecodeTest extends ClearAfterClass { |} """.stripMargin - val List(c) = compileClasses(compiler)(code) + val List(c) = compileClasses(code) assert(getSingleMethod(c, "s1").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) assert(getSingleMethod(c, "s2").instructions.count(_.opcode == TABLESWITCH) == 1, textify(c)) } @@ -85,7 +81,7 @@ class PatmatBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val c = compileClasses(optCompiler)(code).head + val c = optCompiler.compileClasses(code).head assertSameSummary(getSingleMethod(c, "a"), List( NEW, DUP, ICONST_1, LDC, "<init>", @@ -102,7 +98,7 @@ class PatmatBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val c = compileClasses(optCompiler)(code).head + val c = optCompiler.compileClasses(code).head assert(!getSingleMethod(c, "a").instructions.exists(i => i.opcode == IFNULL || i.opcode == IFNONNULL), textify(findAsmMethod(c, "a"))) } @@ -116,7 +112,7 @@ class PatmatBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val c = compileClasses(optCompiler)(code).head + val c = optCompiler.compileClasses(code).head assertSameSummary(getSingleMethod(c, "a"), List( NEW, DUP, ICONST_1, "boxToInteger", LDC, "<init>", ASTORE /*1*/, ALOAD /*1*/, "y", ASTORE /*2*/, @@ -137,7 +133,7 @@ class PatmatBytecodeTest extends ClearAfterClass { | } |} """.stripMargin - val c = compileClasses(optCompiler)(code, allowMessage = _.msg.contains("may not be exhaustive")).head + val c = optCompiler.compileClasses(code, allowMessage = _.msg.contains("may not be exhaustive")).head val expected = List( ALOAD /*1*/ , INSTANCEOF /*::*/ , IFEQ /*A*/ , @@ -169,7 +165,7 @@ class PatmatBytecodeTest extends ClearAfterClass { | def t9 = { val C(a, _) = C("hi", 23); a.toString } |} """.stripMargin - val List(c, cMod) = compileClasses(optCompiler)(code) + val List(c, cMod) = optCompiler.compileClasses(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")) diff --git a/test/junit/scala/tools/testing/BytecodeTesting.scala b/test/junit/scala/tools/testing/BytecodeTesting.scala index 21b1ce2e77..d6f8dbc219 100644 --- a/test/junit/scala/tools/testing/BytecodeTesting.scala +++ b/test/junit/scala/tools/testing/BytecodeTesting.scala @@ -2,30 +2,99 @@ 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.{Global, Settings} -import scala.tools.partest.ASMConverters -import scala.collection.JavaConverters._ -import scala.tools.nsc.backend.jvm.AsmUtils +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 compile(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 compileTransformed(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 compileClasses(code: String, javaCode: List[(String, String)] = Nil, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = { + readAsmClasses(compile(code, javaCode, allowMessage)) + } + + def compileMethods(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[MethodNode] = { + compileClasses(s"class C { $code }", allowMessage = allowMessage).head.methods.asScala.toList.filterNot(_.name == "<init>") + } + + def singleMethodInstructions(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[Instruction] = { + val List(m) = compileMethods(code, allowMessage = allowMessage) + instructionsFromMethod(m) + } + + def singleMethod(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): Method = { + val List(m) = compileMethods(code, allowMessage = allowMessage) + convertMethod(m) + } +} object BytecodeTesting { - import AsmUtils._ - 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 = { + 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 @@ -38,33 +107,21 @@ object BytecodeTesting { 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])] = { @@ -79,38 +136,6 @@ object BytecodeTesting { 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. * @@ -127,8 +152,8 @@ object BytecodeTesting { 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) } @@ -145,24 +170,6 @@ object BytecodeTesting { 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 assertSameCode(method: Method, expected: List[Instruction]): Unit = assertSameCode(method.instructions.dropNonOp, expected) def assertSameCode(actual: List[Instruction], expected: List[Instruction]): Unit = { assert(actual === expected, s"\nExpected: $expected\nActual : $actual") |