summaryrefslogtreecommitdiff
path: root/src/repl
diff options
context:
space:
mode:
Diffstat (limited to 'src/repl')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JavapClass.scala34
1 files changed, 11 insertions, 23 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/JavapClass.scala b/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
index c80b94bf89..1ccade2172 100644
--- a/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JavapClass.scala
@@ -8,6 +8,7 @@ package tools.nsc
package interpreter
import java.lang.{ ClassLoader => JavaClassLoader, Iterable => JIterable }
+import scala.tools.asm.Opcodes
import scala.tools.nsc.util.ScalaClassLoader
import java.io.{ ByteArrayInputStream, CharArrayWriter, FileNotFoundException, PrintWriter, StringWriter, Writer }
import java.util.{ Locale }
@@ -758,32 +759,19 @@ object JavapClass {
import scala.tools.asm.ClassReader
import scala.tools.asm.Opcodes.INVOKESTATIC
import scala.tools.asm.tree.{ ClassNode, MethodInsnNode }
- // the accessor methods invoked statically by the apply of the given closure class
- def accesses(s: String): Seq[(String, String)] = {
- val accessor = """accessor\$\d+""".r
+ def callees(s: String): List[(String, String)] = {
loader classReader s withMethods { ms =>
- ms filter (_.name == "apply") flatMap (_.instructions.toArray.collect {
- case i: MethodInsnNode if i.getOpcode == INVOKESTATIC && when(i.name) { case accessor(_*) => true } => (i.owner, i.name)
- })
+ val nonBridgeApplyMethods = ms filter (_.name == "apply") filter (n => (n.access & Opcodes.ACC_BRIDGE) == 0)
+ val instructions = nonBridgeApplyMethods flatMap (_.instructions.toArray)
+ instructions.collect {
+ case i: MethodInsnNode => (i.owner, i.name)
+ }.toList
}
}
- // get the k.$anonfun for the accessor k.m
- def anonOf(k: String, m: String): String = {
- val res =
- loader classReader k withMethods { ms =>
- ms filter (_.name == m) flatMap (_.instructions.toArray.collect {
- case i: MethodInsnNode if i.getOpcode == INVOKESTATIC && i.name.startsWith("$anonfun") => i.name
- })
- }
- assert(res.size == 1)
- res.head
- }
- // the lambdas invoke accessors that call the anonfuns of interest. Filter k on the k#$anonfuns.
- val ack = accesses(lambda)
- assert(ack.size == 1) // There can be only one.
- ack.head match {
- case (k, _) if target.isModule && !(k endsWith "$") => None
- case (k, m) => Some(s"${k}#${anonOf(k, m)}")
+ callees(lambda) match {
+ case (k, _) :: Nil if target.isModule && !(k endsWith "$") => None
+ case (k, m) :: _ => Some(s"${k}#${m}")
+ case _ => None
}
}
/** Translate the supplied targets to patterns for anonfuns.