Open
Description
Welcome to Scala 2.13.5 (OpenJDK 64-Bit Server VM, Java 16).
Type in expressions for evaluation. Or try :help.
scala> :javap scala.Some
java.lang.IllegalAccessException: class scala.tools.nsc.interpreter.shell.JavapTask cannot access class com.sun.tools.javap.JavapFileManager (in module jdk.jdeps) because module jdk.jdeps does not export com.sun.tools.javap to unnamed module @324e4822
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:687)
at java.base/java.lang.reflect.Method.invoke(Method.java:559)
at scala.tools.nsc.interpreter.shell.JavapTask.<init>(JavapClass.scala:498)
From what I understand, the complication is that we need to make javap read a class from the repl's in-memory representation / class loader.
It seems the only accessible API is ToolProvider
which only has a run
method. I assume we cannot make it search classes in a custom class loader through this.
Personally, I'd be fine throwing out :javap
in favor of :asmp
which would be easy to implement
scala> :power
Power mode enabled. :phase is at typer.
import scala.tools.nsc._, intp.global._, definitions._
Try :help or completions for vals._ and power._
scala> class HalloVelo
class HalloVelo
scala> scala.tools.nsc.backend.jvm.AsmUtils.traceClass(intp.classLoader.classBytes("HalloVelo"))
Bytecode for class $line31/$read$$iw$HalloVelo
// class version 52.0 (52)
// access flags 0x21
public class $line31/$read$$iw$HalloVelo {
// compiled from: <console>
ATTRIBUTE Scala : unknown
ATTRIBUTE ScalaInlineInfo : unknown
// access flags 0x1
public INNERCLASS $line31/$read$$iw $line31/$read $iw
// access flags 0x1
public INNERCLASS $line31/$read$$iw$HalloVelo $line31/$read$$iw HalloVelo
// access flags 0x1011
public final synthetic L$line31/$read$$iw; $outer
// access flags 0x1001
public synthetic $line31$$read$$iw$HalloVelo$$$outer()L$line31/$read$$iw;
L0
LINENUMBER 1 L0
ALOAD 0
GETFIELD $line31/$read$$iw$HalloVelo.$outer : L$line31/$read$$iw;
ARETURN
L1
LOCALVARIABLE this L$line31/$read$$iw$HalloVelo; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x1
public <init>(L$line31/$read$$iw;)V
// parameter final synthetic $outer
L0
LINENUMBER 1 L0
ALOAD 1
IFNONNULL L1
ACONST_NULL
ATHROW
L1
FRAME SAME
ALOAD 0
ALOAD 1
PUTFIELD $line31/$read$$iw$HalloVelo.$outer : L$line31/$read$$iw;
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L2
LOCALVARIABLE this L$line31/$read$$iw$HalloVelo; L0 L2 0
LOCALVARIABLE $outer L$line31/$read$$iw; L0 L2 1
MAXSTACK = 2
MAXLOCALS = 2
}