-
Notifications
You must be signed in to change notification settings - Fork 1.1k
REPL - invoke pprint reflectively #24119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
REPL - invoke pprint reflectively #24119
Conversation
i think breakage in the interfaces would become clear as repl tests would fail. But to isolate the classpath issue in a test, perhaps sbt scripted test is appropriate? |
ad52fbe
to
549dcbd
Compare
another way i guess is compiling a header script with a wrapper print method and invoking that reflectively, or perhaps there is some way to manipulate the classloaders to avoid reflection? |
classOf[Int], // initialOffset | ||
classOf[Boolean], // escape Unicode | ||
classOf[Boolean], // show field names | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with methodHandle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't well suited because method handle is only optimised if its a static final field, but this is based on a dynamic class loader
fails with 2025-10-01T17:11:28.8699192Z [info] Test run dotty.tools.dotc.core.tasty.TastyHeaderUnpicklerTest finished: 0 failed, 0 ignored, 20 total, 0.014s
2025-10-01T17:11:28.8713906Z [info] Test run dotty.tools.repl.ReplCompilerTests started
2025-10-01T17:11:28.8719700Z [info] Test dotty.tools.repl.ReplCompilerTests.testSingletonPrint started
2025-10-01T17:11:29.0459423Z [error] Test dotty.tools.repl.ReplCompilerTests.testSingletonPrint failed: org.junit.ComparisonFailure: expected:<[val a: String = "hello"
2025-10-01T17:11:29.0487191Z [error] val x: a.type = "hello"]> but was:<[java.lang.ClassNotFoundException: dotty.shaded.pprint.PPrinter$BlackWhite$
2025-10-01T17:11:29.0488430Z [error] at dotty.tools.repl.AbstractFileClassLoader.findClass$$anonfun$1(AbstractFileClassLoader.scala:49)
2025-10-01T17:11:29.0489551Z [error] at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
2025-10-01T17:11:29.0490372Z [error] at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
2025-10-01T17:11:29.0491175Z [error] at scala.collection.immutable.List.foreach(List.scala:327)
2025-10-01T17:11:29.0492109Z [error] at dotty.tools.repl.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:46)
2025-10-01T17:11:29.0493100Z [error] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
2025-10-01T17:11:29.0493908Z [error] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
2025-10-01T17:11:29.0495180Z [error] at dotty.tools.repl.AbstractFileClassLoader.loadClass(AbstractFileClassLoader.scala:60)
2025-10-01T17:11:29.0496144Z [error] at java.base/java.lang.Class.forName0(Native Method)
2025-10-01T17:11:29.0496825Z [error] at java.base/java.lang.Class.forName(Class.java:467)
2025-10-01T17:11:29.0497564Z [error] at dotty.tools.repl.Rendering.pprintRender(Rendering.scala:36)
2025-10-01T17:11:29.0498344Z [error] at dotty.tools.repl.Rendering.replStringOf(Rendering.scala:86)
2025-10-01T17:11:29.0499132Z [error] at dotty.tools.repl.Rendering.valueOf$$anonfun$2(Rendering.scala:102) and again class not found exception in |
I guess we can check if the class exists in the classloader, and if not then fall back to the previous implementation? |
549dcbd
to
37a56a6
Compare
I pushed a change with the fallback option if the class loader doesn't have the class |
37a56a6
to
350733e
Compare
fixes scala#24111 reflectively load the function each time, (i.e. don't cache). As this is a rare event (i.e user interaction), any cost is less of a concern. if cant load reflectively, then fallback to calling directly.
350733e
to
bbbe580
Compare
now with no caching - meaning there is no complex state management anymore |
fixes #24111
reset the print function each time the classloader resets, if cant load reflectively, then fallback to calling directly.
before:
after: