Skip to content

Commit bcae8fb

Browse files
committed
.
1 parent 919f02c commit bcae8fb

File tree

1 file changed

+8
-13
lines changed

1 file changed

+8
-13
lines changed

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,13 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
3434
.render
3535

3636
try
37-
// normally, if we used vanilla JDK and layered classloaders, we wouldnt need reflection.
38-
// however PPrint works by runtime type testing to deconstruct values. This is
39-
// sensitive to which classloader instantiates the object under test, i.e.
40-
// `value` is constructed inside the repl classloader. Testing for
41-
// `value.isInstanceOf[scala.Product]` in this classloader fails (JDK AppClassLoader),
42-
// because repl classloader has two layers where it can redefine `scala.Product`:
43-
// - `new URLClassLoader` constructed with contents of the `-classpath` setting
44-
// - `AbstractFileClassLoader` also might instrument the library code to support interrupt.
45-
// Due the possible interruption instrumentation, it is unlikely that we can get
46-
// rid of reflection here.
37+
// PPrint needs to do type-tests against scala-library classes, but the `classLoader()`
38+
// used in the REPL typically has a its own copy of such classes to support
39+
// `-XreplInterruptInstrumentation`. Thus we need to use the copy of PPrint from the
40+
// REPL-line `classLoader()` rather than our own REPL-impl classloader in order for it
41+
// to work
4742
val cl = classLoader()
4843
val pprintCls = Class.forName("dotty.shaded.pprint.PPrinter$Color$", false, cl)
49-
val fansiStrCls = Class.forName("dotty.shaded.fansi.Str", false, cl)
5044
val Color = pprintCls.getField("MODULE$").get(null)
5145
val Color_apply = pprintCls.getMethod("apply",
5246
classOf[Any], // value
@@ -58,10 +52,11 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
5852
classOf[Boolean], // show field names
5953
)
6054

61-
val FansiStr_render = fansiStrCls.getMethod("render")
6255
val fansiStr = Color_apply.invoke(Color, value, width, height, 2, initialOffset, false, true)
63-
FansiStr_render.invoke(fansiStr).asInstanceOf[String]
56+
fansiStr.toString
6457
catch
58+
// If classloading fails for whatever reason, try to fallback to our own version
59+
// of PPrint. Won't be as good, but better than blowing up with an exception
6560
case ex: ClassNotFoundException => fallback()
6661
case ex: NoSuchMethodException => fallback()
6762
}

0 commit comments

Comments
 (0)