Skip to content

Commit

Permalink
REPL: Fix Rendering's rewrapValueClass
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand committed Nov 22, 2022
1 parent 439a17d commit 5759e66
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
15 changes: 12 additions & 3 deletions compiler/src/dotty/tools/repl/Rendering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import dotc.core.Contexts._
import dotc.core.Denotations.Denotation
import dotc.core.Flags
import dotc.core.Flags._
import dotc.core.NameOps.*
import dotc.core.Symbols.{Symbol, defn}
import dotc.core.StdNames.{nme, str}
import dotc.printing.ReplPrinter
import dotc.reporting.Diagnostic
import dotc.transform.ValueClasses

import scala.util.control.NonFatal

/** This rendering object uses `ClassLoader`s to accomplish crossing the 4th
* wall (i.e. fetching back values from the compiled class files put into a
* specific class loader capable of loading from memory) and rendering them.
Expand Down Expand Up @@ -106,7 +109,7 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
*
* Calling this method evaluates the expression using reflection
*/
private def valueOf(sym: Symbol)(using Context): Option[String] =
private def valueOf(sym: Symbol)(using Context): Option[String] = try
val objectName = sym.owner.fullName.encode.toString.stripSuffix("$")
val resObj: Class[?] = Class.forName(objectName, true, classLoader())
val symValue = resObj
Expand All @@ -123,6 +126,7 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
else
s
}
catch case e: ReflectiveOperationException => throw InvocationTargetException(e)

/** Rewrap value class to their Wrapper class
*
Expand All @@ -131,7 +135,13 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
*/
private def rewrapValueClass(sym: Symbol, value: Object)(using Context): Option[Object] =
if ValueClasses.isDerivedValueClass(sym) then
val valueClassName = sym.flatName.encode.toString
val pkg = sym.enclosingPackageClass
val pkgName = if pkg.isEmptyPackage then "" else s"${pkg.fullName.mangledString}."
val clsFlatName = if sym.isOneOf(JavaDefined | ConstructorProxy) then
// See ExtractDependencies.recordDependency
sym.flatName.stripModuleClassSuffix
else sym.flatName
val valueClassName = pkgName + clsFlatName.mangledString
val valueClass = Class.forName(valueClassName, true, classLoader())
valueClass.getConstructors.headOption.map(_.newInstance(value))
else
Expand Down Expand Up @@ -161,7 +171,6 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):

/** Force module initialization in the absence of members. */
def forceModule(sym: Symbol)(using Context): Seq[Diagnostic] =
import scala.util.control.NonFatal
def load() =
val objectName = sym.fullName.encode.toString
Class.forName(objectName, true, classLoader())
Expand Down
5 changes: 5 additions & 0 deletions compiler/test-resources/repl/i15493
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,8 @@ val res33: Outer.Foo = Outer$Foo@17
scala> res33.toString
val res34: String = Outer$Foo@17

scala> Vector.unapplySeq(Vector(2))
val res35: scala.collection.SeqFactory.UnapplySeqWrapper[Int] = scala.collection.SeqFactory$UnapplySeqWrapper@df507bfd

scala> new scala.concurrent.duration.DurationInt(5)
val res36: scala.concurrent.duration.package.DurationInt = scala.concurrent.duration.package$DurationInt@5

0 comments on commit 5759e66

Please sign in to comment.