From 2980c3921f1270f05add25239da93e05f64ad45f Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 31 May 2016 09:45:10 +0200 Subject: Keep line numbers when inlining from the same compilation unit So far, line numbers were kept only when inlining from the same class. We can also keep them when inlining from a different class defined in the same compilation unit. Longer-term we should support JSR-45, see SI-7518 and scala-dev#3. --- .../tools/nsc/backend/jvm/opt/InlinerTest.scala | 48 ++++++++++++++++++++++ .../scala/tools/testing/BytecodeTesting.scala | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'test/junit') 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 9b538573dc..9173a1d189 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala @@ -1526,4 +1526,52 @@ class InlinerTest extends BytecodeTesting { val c :: _ = compileClassesSeparately(codes, extraArgs = compilerArgs) assertInvoke(getMethod(c, "t"), "p1/Implicits$RichFunction1$", "toRx$extension") } + + @Test + def keepLineNumbersPerCompilationUnit(): Unit = { + val code1 = + """class A { + | def fx(): Unit = () + | @inline final def ma = { + | fx() + | 1 + | } + |} + """.stripMargin + val code2 = + """class B extends A { + | @inline final def mb = { + | fx() + | 1 + | } + |} + |class C extends B { + | @inline final def mc = { + | fx() + | 1 + | } + | def t1 = ma // no lines, not the same source file + | def t2 = mb // lines + | def t3 = mc // lines + |} + """.stripMargin + notPerRun.foreach(_.clear()) + val run = compiler.newRun + run.compileSources(List(makeSourceFile(code1, "A.scala"), makeSourceFile(code2, "B.scala"))) + val List(_, _, c) = readAsmClasses(getGeneratedClassfiles(global.settings.outputDirs.getSingleOutput.get)) + def is(name: String) = getMethod(c, name).instructions.filterNot(_.isInstanceOf[FrameEntry]) + + assertSameCode(is("t1"), List( + Label(0), LineNumber(12, Label(0)), + VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "A", "fx", "()V", false), + Op(ICONST_1), Op(IRETURN), Label(6))) + + assertSameCode(is("t2"), List( + Label(0), LineNumber(3, Label(0)), VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "B", "fx", "()V", false), + Label(4), LineNumber(4, Label(4)), Op(ICONST_1), Op(IRETURN), Label(8))) + + assertSameCode(is("t3"), List( + Label(0), LineNumber(9, Label(0)), VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C", "fx", "()V", false), + Label(4), LineNumber(10, Label(4)), Op(ICONST_1), Op(IRETURN), Label(8))) + } } diff --git a/test/junit/scala/tools/testing/BytecodeTesting.scala b/test/junit/scala/tools/testing/BytecodeTesting.scala index 1a0c1e210a..4ddb6580df 100644 --- a/test/junit/scala/tools/testing/BytecodeTesting.scala +++ b/test/junit/scala/tools/testing/BytecodeTesting.scala @@ -29,7 +29,7 @@ class Compiler(val global: Global) { global.settings.outputDirs.setSingleOutput(new VirtualDirectory("(memory)", None)) } - private def newRun: global.Run = { + def newRun: global.Run = { global.reporter.reset() resetOutput() new global.Run() -- cgit v1.2.3