@@ -14,6 +14,7 @@ import dotc.core.Symbols.{Symbol, defn}
1414import dotc .core .StdNames .{nme , str }
1515import dotc .printing .ReplPrinter
1616import dotc .reporting .Diagnostic
17+ import dotc .transform .ValueClasses
1718
1819/** This rendering object uses `ClassLoader`s to accomplish crossing the 4th
1920 * wall (i.e. fetching back values from the compiled class files put into a
@@ -23,7 +24,7 @@ import dotc.reporting.Diagnostic
2324 * `ReplDriver#resetToInitial` is called, the accompanying instance of
2425 * `Rendering` is no longer valid.
2526 */
26- private [repl] class Rendering (parentClassLoader : Option [ClassLoader ] = None ) {
27+ private [repl] class Rendering (parentClassLoader : Option [ClassLoader ] = None ):
2728
2829 import Rendering ._
2930
@@ -80,43 +81,53 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None) {
8081 * then this bug will surface, so perhaps better not?
8182 * https://github.com/scala/bug/issues/12337
8283 */
83- private [repl] def truncate (str : String ): String = {
84+ private [repl] def truncate (str : String ): String =
8485 val showTruncated = " ... large output truncated, print value to show all"
8586 val ncp = str.codePointCount(0 , str.length) // to not cut inside code point
8687 if ncp <= MaxStringElements then str
8788 else str.substring(0 , str.offsetByCodePoints(0 , MaxStringElements - 1 )) + showTruncated
88- }
8989
9090 /** Return a String representation of a value we got from `classLoader()`. */
91- private [repl] def replStringOf (value : Object )(using Context ): String = {
91+ private [repl] def replStringOf (value : Object )(using Context ): String =
9292 assert(myReplStringOf != null ,
9393 " replStringOf should only be called on values creating using `classLoader()`, but `classLoader()` has not been called so far" )
9494 val res = myReplStringOf(value)
9595 if res == null then " null // non-null reference has null-valued toString" else truncate(res)
96- }
9796
9897 /** Load the value of the symbol using reflection.
9998 *
10099 * Calling this method evaluates the expression using reflection
101100 */
102- private def valueOf (sym : Symbol )(using Context ): Option [String ] = {
101+ private def valueOf (sym : Symbol )(using Context ): Option [String ] =
103102 val objectName = sym.owner.fullName.encode.toString.stripSuffix(" $" )
104103 val resObj : Class [? ] = Class .forName(objectName, true , classLoader())
105- val value =
106- resObj
107- .getDeclaredMethods.find(_.getName == sym.name.encode.toString )
108- .map(_.invoke( null ) )
109- val string = value.map(replStringOf(_))
104+ val symValue = resObj
105+ .getDeclaredMethods.find(_.getName == sym.name.encode.toString)
106+ .flatMap(result => rewrapValueClass( sym.info.classSymbol, result.invoke( null )) )
107+ val valueString = symValue .map(replStringOf )
108+
110109 if (! sym.is(Flags .Method ) && sym.info == defn.UnitType )
111110 None
112111 else
113- string .map { s =>
112+ valueString .map { s =>
114113 if (s.startsWith(REPL_WRAPPER_NAME_PREFIX ))
115114 s.drop(REPL_WRAPPER_NAME_PREFIX .length).dropWhile(c => c.isDigit || c == '$' )
116115 else
117116 s
118117 }
119- }
118+
119+ /** Rewrap value class to their Wrapper class
120+ *
121+ * @param sym Value Class symbol
122+ * @param value underlying value
123+ */
124+ private def rewrapValueClass (sym : Symbol , value : Object )(using Context ): Option [Object ] =
125+ if ValueClasses .isDerivedValueClass(sym) then
126+ val valueClassName = sym.flatName.encode.toString
127+ val valueClass = Class .forName(valueClassName, true , classLoader())
128+ valueClass.getConstructors.headOption.map(_.newInstance(value))
129+ else
130+ Some (value)
120131
121132 def renderTypeDef (d : Denotation )(using Context ): Diagnostic =
122133 infoDiagnostic(" // defined " ++ d.symbol.showUser, d)
@@ -171,9 +182,8 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None) {
171182 private def infoDiagnostic (msg : String , d : Denotation )(using Context ): Diagnostic =
172183 new Diagnostic .Info (msg, d.symbol.sourcePos)
173184
174- }
175185
176- object Rendering {
186+ object Rendering :
177187 final val REPL_WRAPPER_NAME_PREFIX = str.REPL_SESSION_LINE
178188
179189 extension (s : Symbol )
@@ -182,5 +192,3 @@ object Rendering {
182192 val text = printer.dclText(s)
183193 text.mkString(ctx.settings.pageWidth.value, ctx.settings.printLines.value)
184194 }
185-
186- }
0 commit comments