@@ -27,7 +27,8 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
27
27
var myClassLoader : AbstractFileClassLoader = uninitialized
28
28
29
29
/** (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
31
32
32
33
/** Class loader used to load compiled code */
33
34
private [repl] def classLoader ()(using Context ) =
@@ -46,45 +47,6 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
46
47
}
47
48
48
49
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
- }
88
50
myClassLoader
89
51
}
90
52
@@ -95,7 +57,17 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
95
57
96
58
/** Return a String representation of a value we got from `classLoader()`. */
97
59
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
99
71
100
72
/** Load the value of the symbol using reflection.
101
73
*
0 commit comments