Skip to content

Commit 3ec5383

Browse files
authored
REPL - invoke pprint reflectively (#24119)
fixes #24111 load print function each time it is called, if cant load reflectively, then fallback to calling directly. before: ```scala scala -S 3.nightly Downloading Scala 3.8.0-RC1-bin-20251003-172687a-NIGHTLY compiler Downloading Scala 3.8.0-RC1-bin-20251003-172687a-NIGHTLY bridge Welcome to Scala 3.8.0-RC1-bin-20251003-172687a-NIGHTLY-git-172687a (17.0.14, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help. scala> (1, 2L, 3.0F, "hello", 'a') val res0: (Int, Long, Float, String, Char) = (1,2,3.0,hello,a) scala> ``` after: ```scala Welcome to Scala 3.8.0-RC1-bin-SNAPSHOT-git-ad52fbe (17.0.14, Java OpenJDK 64-Bit Server VM). Type in expressions for evaluation. Or try :help. scala> (1, 2L, 3.0F, "hello", 'a') val res0: (Int, Long, Float, String, Char) = (1, 2L, 3.0F, "hello", 'a') scala> ```
1 parent 2642b92 commit 3ec5383

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

compiler/src/dotty/tools/repl/Rendering.scala

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,35 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
2626

2727
var myClassLoader: AbstractFileClassLoader = uninitialized
2828

29+
private def pprintRender(value: Any, width: Int, height: Int, initialOffset: Int)(using Context): String = {
30+
def fallback() =
31+
dotty.shaded.pprint.PPrinter.BlackWhite
32+
.apply(value, width = width, height = height, initialOffset = initialOffset)
33+
.plainText
34+
try
35+
val cl = classLoader()
36+
val pprintCls = Class.forName("dotty.shaded.pprint.PPrinter$BlackWhite$", false, cl)
37+
val fansiStrCls = Class.forName("dotty.shaded.fansi.Str", false, cl)
38+
val BlackWhite = pprintCls.getField("MODULE$").get(null)
39+
val BlackWhite_apply = pprintCls.getMethod("apply",
40+
classOf[Any], // value
41+
classOf[Int], // width
42+
classOf[Int], // height
43+
classOf[Int], // indentation
44+
classOf[Int], // initialOffset
45+
classOf[Boolean], // escape Unicode
46+
classOf[Boolean], // show field names
47+
)
48+
val FansiStr_plainText = fansiStrCls.getMethod("plainText")
49+
val fansiStr = BlackWhite_apply.invoke(
50+
BlackWhite, value, width, height, 2, initialOffset, false, true
51+
)
52+
FansiStr_plainText.invoke(fansiStr).asInstanceOf[String]
53+
catch
54+
case _: ClassNotFoundException => fallback()
55+
case _: NoSuchMethodException => fallback()
56+
}
57+
2958

3059
/** Class loader used to load compiled code */
3160
private[repl] def classLoader()(using Context) =
@@ -55,14 +84,12 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
5584
/** Return a String representation of a value we got from `classLoader()`. */
5685
private[repl] def replStringOf(value: Object, prefixLength: Int)(using Context): String = {
5786
// pretty-print things with 100 cols 50 rows by default,
58-
dotty.shaded.pprint.PPrinter.BlackWhite
59-
.apply(
60-
value,
61-
width = 100,
62-
height = 50,
63-
initialOffset = prefixLength
64-
)
65-
.plainText
87+
pprintRender(
88+
value,
89+
width = 100,
90+
height = 50,
91+
initialOffset = prefixLength
92+
)
6693
}
6794

6895
/** Load the value of the symbol using reflection.

0 commit comments

Comments
 (0)