@@ -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