summaryrefslogtreecommitdiff
path: root/test/junit
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-08-26 17:15:18 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2015-09-17 20:16:14 +0200
commit89c0a7f0a320e898f360c7c94b1ad0bbce681b3a (patch)
tree6b3e9196b6562be22d236214a6bebb5a4d99e174 /test/junit
parentda8f263208f8934650d3900793a4115ff1751310 (diff)
downloadscala-89c0a7f0a320e898f360c7c94b1ad0bbce681b3a.tar.gz
scala-89c0a7f0a320e898f360c7c94b1ad0bbce681b3a.tar.bz2
scala-89c0a7f0a320e898f360c7c94b1ad0bbce681b3a.zip
Store information about function literals in call graph
Remember in the call graph if a function literal is passed as an argument to a higher-order function.
Diffstat (limited to 'test/junit')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala66
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala2
2 files changed, 59 insertions, 9 deletions
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 715db3f8c2..b518cbdc50 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/CallGraphTest.scala
@@ -6,6 +6,7 @@ import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.junit.Test
import scala.collection.generic.Clearable
+import scala.collection.immutable.IntMap
import scala.tools.asm.Opcodes._
import org.junit.Assert._
@@ -21,18 +22,31 @@ import AsmUtils._
import BackendReporting._
import scala.collection.convert.decorateAsScala._
+import scala.tools.testing.ClearAfterClass
-@RunWith(classOf[JUnit4])
-class CallGraphTest {
- val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:inline-global -Yopt-warnings")
- import compiler.genBCode.bTypes._
+object CallGraphTest extends ClearAfterClass.Clearable {
+ var compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:inline-global -Yopt-warnings")
+ def clear(): Unit = { compiler = null }
// allows inspecting the caches after a compilation run
- val notPerRun: List[Clearable] = List(classBTypeFromInternalName, byteCodeRepository.compilingClasses, byteCodeRepository.parsedClasses, callGraph.callsites)
+ val notPerRun: List[Clearable] = List(
+ compiler.genBCode.bTypes.classBTypeFromInternalName,
+ compiler.genBCode.bTypes.byteCodeRepository.compilingClasses,
+ compiler.genBCode.bTypes.byteCodeRepository.parsedClasses,
+ compiler.genBCode.bTypes.callGraph.callsites)
notPerRun foreach compiler.perRunCaches.unrecordCache
+}
+
+@RunWith(classOf[JUnit4])
+class CallGraphTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = CallGraphTest
- def compile(code: String, allowMessage: StoreReporter#Info => Boolean): List[ClassNode] = {
- notPerRun.foreach(_.clear())
+ val compiler = CallGraphTest.compiler
+ import compiler.genBCode.bTypes._
+ import callGraph._
+
+ def compile(code: String, allowMessage: StoreReporter#Info => Boolean = _ => false): List[ClassNode] = {
+ CallGraphTest.notPerRun.foreach(_.clear())
compileClasses(compiler)(code, allowMessage = allowMessage)
}
@@ -107,7 +121,7 @@ class CallGraphTest {
assert(callee.annotatedInline == atInline)
assert(callee.annotatedNoInline == atNoInline)
- assert(callsite.argInfos == List()) // not defined yet
+ assert(callsite.argInfos == IntMap.empty) // no higher-order methods
} catch {
case e: Throwable => println(callsite); throw e
}
@@ -135,4 +149,40 @@ class CallGraphTest {
checkCallsite(df7Call, t2, cf7, cClassBType, false, true, true)
checkCallsite(dg1Call, t2, g1, cMClassBType, true, false, false)
}
+
+ /**
+ * NOTE: if this test fails for you when running within the IDE, it's probably because you're
+ * using 2.12.0-M2 for compilining within the IDE, which doesn't add SAM information to the
+ * InlineInfo attribute. So the InlineInfo in the classfile for Function1 doesn't say that
+ * it's a SAM type. The test passes when running with ant (which does a full bootstrap).
+ */
+ @Test
+ def checkArgInfos(): Unit = {
+ val code =
+ """abstract class C {
+ | def h(f: Int => Int): Int = f(1)
+ | def t1 = h(x => x + 1)
+ | def t2(i: Int, f: Int => Int, z: Int) = h(f) + i - z
+ | def t3(f: Int => Int) = h(x => f(x + 1))
+ |}
+ |abstract class D {
+ | def iAmASam(x: Int): Int
+ | def selfSamCall = iAmASam(10)
+ |}
+ |""".stripMargin
+ val List(c, d) = compile(code)
+
+ def callIn(m: String) = callGraph.callsites.find(_._1.name == m).get._2.values.head
+ val t1h = callIn("t1")
+ assertEquals(t1h.argInfos.toList, List((1, FunctionLiteral)))
+
+ val t2h = callIn("t2")
+ assertEquals(t2h.argInfos.toList, List((1, ForwardedParam(2))))
+
+ val t3h = callIn("t3")
+ assertEquals(t3h.argInfos.toList, List((1, FunctionLiteral)))
+
+ val selfSamCall = callIn("selfSamCall")
+ assertEquals(selfSamCall.argInfos.toList, List((0,ForwardedParam(0))))
+ }
}
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 135ebe9a78..6dfdf20587 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -97,7 +97,7 @@ class InlinerTest extends ClearAfterClass {
callsiteMethod = callsiteMethod,
callsiteClass = callsiteClass,
callee = Right(callGraph.Callee(callee = callee, calleeDeclarationClass = calleeDeclarationClass, safeToInline = true, safeToRewrite = false, annotatedInline = false, annotatedNoInline = false, higherOrderParams = IntMap.empty, calleeInfoWarning = None)),
- argInfos = Nil,
+ argInfos = IntMap.empty,
callsiteStackHeight = callsiteStackHeight,
receiverKnownNotNull = receiverKnownNotNull,
callsitePosition = NoPosition),