Skip to content

Commit a4cc58d

Browse files
committed
.
1 parent cb90ed2 commit a4cc58d

File tree

1 file changed

+13
-41
lines changed

1 file changed

+13
-41
lines changed

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

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
2727
var myClassLoader: AbstractFileClassLoader = uninitialized
2828

2929
/** (value, maxElements, maxCharacters) => String */
30-
var myReplStringOf: (Object, Int, Int) => String = uninitialized
30+
val myReplStringOf: (Object, Int, Int) => String =
31+
dotty.shaded.pprint.PPrinter.BlackWhite.apply(value).plainText
3132

3233
/** Class loader used to load compiled code */
3334
private[repl] def classLoader()(using Context) =
@@ -46,45 +47,6 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
4647
}
4748

4849
myClassLoader = new AbstractFileClassLoader(ctx.settings.outputDir.value, parent)
49-
myReplStringOf = {
50-
// We need to use the ScalaRunTime class coming from the scala-library
51-
// on the user classpath, and not the one available in the current
52-
// classloader, so we use reflection instead of simply calling
53-
// `ScalaRunTime.stringOf`. Also probe for new stringOf that does string quoting, etc.
54-
val scalaRuntime = Class.forName("scala.runtime.ScalaRunTime", true, myClassLoader)
55-
val renderer = "stringOf"
56-
val stringOfInvoker: (Object, Int) => String =
57-
def richStringOf: (Object, Int) => String =
58-
val method = scalaRuntime.getMethod(renderer, classOf[Object], classOf[Int], classOf[Boolean])
59-
val richly = java.lang.Boolean.TRUE // add a repl option for enriched output
60-
(value, maxElements) => method.invoke(null, value, maxElements, richly).asInstanceOf[String]
61-
def poorStringOf: (Object, Int) => String =
62-
try
63-
val method = scalaRuntime.getMethod(renderer, classOf[Object], classOf[Int])
64-
(value, maxElements) => method.invoke(null, value, maxElements).asInstanceOf[String]
65-
catch case _: NoSuchMethodException => (value, maxElements) => String.valueOf(value).take(maxElements)
66-
try richStringOf
67-
catch case _: NoSuchMethodException => poorStringOf
68-
def stringOfMaybeTruncated(value: Object, maxElements: Int): String = stringOfInvoker(value, maxElements)
69-
70-
// require value != null
71-
// `ScalaRuntime.stringOf` returns null iff value.toString == null, let caller handle that.
72-
// `ScalaRuntime.stringOf` may truncate the output, in which case we want to indicate that fact to the user
73-
// In order to figure out if it did get truncated, we invoke it twice - once with the `maxElements` that we
74-
// want to print, and once without a limit. If the first is shorter, truncation did occur.
75-
// Note that `stringOf` has new API in flight to handle truncation, see stringOfMaybeTruncated.
76-
(value: Object, maxElements: Int, maxCharacters: Int) =>
77-
stringOfMaybeTruncated(value, Int.MaxValue) match
78-
case null => null
79-
case notTruncated =>
80-
val maybeTruncated =
81-
val maybeTruncatedByElementCount = stringOfMaybeTruncated(value, maxElements)
82-
truncate(maybeTruncatedByElementCount, maxCharacters)
83-
// our string representation may have been truncated by element and/or character count
84-
// if so, append an info string - but only once
85-
if notTruncated.length == maybeTruncated.length then maybeTruncated
86-
else s"$maybeTruncated ... large output truncated, print value to show all"
87-
}
8850
myClassLoader
8951
}
9052

@@ -95,7 +57,17 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
9557

9658
/** Return a String representation of a value we got from `classLoader()`. */
9759
private[repl] def replStringOf(sym: Symbol, value: Object)(using Context): String =
98-
dotty.shaded.pprint.PPrinter.BlackWhite.apply(value).plainText
60+
assert(myReplStringOf != null,
61+
"replStringOf should only be called on values creating using `classLoader()`, but `classLoader()` has not been called so far")
62+
val maxPrintElements = ctx.settings.VreplMaxPrintElements.valueIn(ctx.settingsState)
63+
val maxPrintCharacters = ctx.settings.VreplMaxPrintCharacters.valueIn(ctx.settingsState)
64+
// stringOf returns null if value.toString returns null. Show some text as a fallback.
65+
def fallback = s"""null // result of "${sym.name}.toString" is null"""
66+
if value == null then "null" else
67+
myReplStringOf(value, maxPrintElements, maxPrintCharacters) match
68+
case null => fallback
69+
case res => res
70+
end if
9971

10072
/** Load the value of the symbol using reflection.
10173
*

0 commit comments

Comments
 (0)