From 5759e66065fb94ac985a1f0d4b4831fd32b0668c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 22 Nov 2022 18:21:05 +0000 Subject: [PATCH] REPL: Fix Rendering's rewrapValueClass --- compiler/src/dotty/tools/repl/Rendering.scala | 15 ++++++++++++--- compiler/test-resources/repl/i15493 | 5 +++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/repl/Rendering.scala b/compiler/src/dotty/tools/repl/Rendering.scala index 5cba672ce7b0..0e54841afa65 100644 --- a/compiler/src/dotty/tools/repl/Rendering.scala +++ b/compiler/src/dotty/tools/repl/Rendering.scala @@ -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. @@ -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 @@ -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 * @@ -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 @@ -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()) diff --git a/compiler/test-resources/repl/i15493 b/compiler/test-resources/repl/i15493 index f543f5c1d0f7..670cf8ebcbd2 100644 --- a/compiler/test-resources/repl/i15493 +++ b/compiler/test-resources/repl/i15493 @@ -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