Skip to content

Commit 0a7b3b2

Browse files
committed
REPL - invoke pprint reflectively
fixes #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.
1 parent 5b02216 commit 0a7b3b2

File tree

1 file changed

+43
-8
lines changed

1 file changed

+43
-8
lines changed

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

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,43 @@ 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(
33+
value,
34+
width = width,
35+
height = height,
36+
initialOffset = initialOffset
37+
)
38+
.plainText
39+
dotty.shaded.pprint.PPrinter.BlackWhite.apply(
40+
value, width = width, height = height, initialOffset = initialOffset
41+
).plainText
42+
try
43+
val cl = classLoader()
44+
val pprintCls = Class.forName("dotty.shaded.pprint.PPrinter$BlackWhite$", false, cl)
45+
val fansiStrCls = Class.forName("dotty.shaded.fansi.Str", false, cl)
46+
val BlackWhite = pprintCls.getField("MODULE$").get(null)
47+
val BlackWhite_apply = pprintCls.getMethod("apply",
48+
classOf[Any], // value
49+
classOf[Int], // width
50+
classOf[Int], // height
51+
classOf[Int], // indentation
52+
classOf[Int], // initialOffset
53+
classOf[Boolean], // escape Unicode
54+
classOf[Boolean], // show field names
55+
)
56+
val FansiStr_plainText = fansiStrCls.getMethod("plainText")
57+
val fansiStr = BlackWhite_apply.invoke(
58+
BlackWhite, value, width, height, 2, initialOffset, false, true
59+
)
60+
FansiStr_plainText.invoke(fansiStr).asInstanceOf[String]
61+
catch
62+
case _: ClassNotFoundException => fallback()
63+
case _: NoSuchMethodException => fallback()
64+
}
65+
2966

3067
/** Class loader used to load compiled code */
3168
private[repl] def classLoader()(using Context) =
@@ -55,14 +92,12 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
5592
/** Return a String representation of a value we got from `classLoader()`. */
5693
private[repl] def replStringOf(value: Object, prefixLength: Int)(using Context): String = {
5794
// 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
95+
pprintRender(
96+
value,
97+
width = 100,
98+
height = 50,
99+
initialOffset = prefixLength
100+
)
66101
}
67102

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

0 commit comments

Comments
 (0)