@@ -3,18 +3,14 @@ package repl
3
3
4
4
import scala .language .unsafeNulls
5
5
6
- import java .lang .{ ClassLoader , ExceptionInInitializerError }
7
- import java .lang .reflect .InvocationTargetException
8
-
9
- import dotc .core .Contexts ._
10
- import dotc .core .Denotations .Denotation
11
- import dotc .core .Flags
12
- import dotc .core .Flags ._
13
- import dotc .core .Symbols .{Symbol , defn }
14
- import dotc .core .StdNames .{nme , str }
15
- import dotc .printing .ReplPrinter
16
- import dotc .reporting .Diagnostic
17
- import dotc .transform .ValueClasses
6
+ import dotc .* , core .*
7
+ import Contexts .* , Denotations .* , Flags .* , NameOps .* , StdNames .* , Symbols .*
8
+ import printing .ReplPrinter
9
+ import reporting .Diagnostic
10
+ import transform .ValueClasses
11
+ import util .StackTraceOps .*
12
+
13
+ import scala .util .control .NonFatal
18
14
19
15
/** This rendering object uses `ClassLoader`s to accomplish crossing the 4th
20
16
* wall (i.e. fetching back values from the compiled class files put into a
@@ -131,8 +127,7 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
131
127
*/
132
128
private def rewrapValueClass (sym : Symbol , value : Object )(using Context ): Option [Object ] =
133
129
if ValueClasses .isDerivedValueClass(sym) then
134
- val valueClassName = sym.flatName.encode.toString
135
- val valueClass = Class .forName(valueClassName, true , classLoader())
130
+ val valueClass = Class .forName(sym.binaryClassName, true , classLoader())
136
131
valueClass.getConstructors.headOption.map(_.newInstance(value))
137
132
else
138
133
Some (value)
@@ -148,35 +143,31 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
148
143
infoDiagnostic(d.symbol.showUser, d)
149
144
150
145
/** Render value definition result */
151
- def renderVal (d : Denotation )(using Context ): Either [InvocationTargetException , Option [Diagnostic ]] =
146
+ def renderVal (d : Denotation )(using Context ): Either [ReflectiveOperationException , Option [Diagnostic ]] =
152
147
val dcl = d.symbol.showUser
153
148
def msg (s : String ) = infoDiagnostic(s, d)
154
149
try
155
150
Right (
156
151
if d.symbol.is(Flags .Lazy ) then Some (msg(dcl))
157
152
else valueOf(d.symbol).map(value => msg(s " $dcl = $value" ))
158
153
)
159
- catch case e : InvocationTargetException => Left (e)
154
+ catch case e : ReflectiveOperationException => Left (e)
160
155
end renderVal
161
156
162
157
/** Force module initialization in the absence of members. */
163
158
def forceModule (sym : Symbol )(using Context ): Seq [Diagnostic ] =
164
- import scala .util .control .NonFatal
165
159
def load () =
166
160
val objectName = sym.fullName.encode.toString
167
161
Class .forName(objectName, true , classLoader())
168
162
Nil
169
163
try load()
170
164
catch
171
165
case e : ExceptionInInitializerError => List (renderError(e, sym.denot))
172
- case NonFatal (e) => List (renderError(InvocationTargetException (e) , sym.denot))
166
+ case NonFatal (e) => List (renderError(e , sym.denot))
173
167
174
168
/** Render the stack trace of the underlying exception. */
175
- def renderError (ite : InvocationTargetException | ExceptionInInitializerError , d : Denotation )(using Context ): Diagnostic =
176
- import dotty .tools .dotc .util .StackTraceOps ._
177
- val cause = ite.getCause match
178
- case e : ExceptionInInitializerError => e.getCause
179
- case e => e
169
+ def renderError (thr : Throwable , d : Denotation )(using Context ): Diagnostic =
170
+ val cause = rootCause(thr)
180
171
// detect
181
172
// at repl$.rs$line$2$.<clinit>(rs$line$2:1)
182
173
// at repl$.rs$line$2.res1(rs$line$2)
@@ -190,7 +181,6 @@ private[repl] class Rendering(parentClassLoader: Option[ClassLoader] = None):
190
181
private def infoDiagnostic (msg : String , d : Denotation )(using Context ): Diagnostic =
191
182
new Diagnostic .Info (msg, d.symbol.sourcePos)
192
183
193
-
194
184
object Rendering :
195
185
final val REPL_WRAPPER_NAME_PREFIX = str.REPL_SESSION_LINE
196
186
@@ -200,3 +190,12 @@ object Rendering:
200
190
val text = printer.dclText(s)
201
191
text.mkString(ctx.settings.pageWidth.value, ctx.settings.printLines.value)
202
192
}
193
+
194
+ def rootCause (x : Throwable ): Throwable = x match
195
+ case _ : ExceptionInInitializerError |
196
+ _ : java.lang.reflect.InvocationTargetException |
197
+ _ : java.lang.reflect.UndeclaredThrowableException |
198
+ _ : java.util.concurrent.ExecutionException
199
+ if x.getCause != null =>
200
+ rootCause(x.getCause)
201
+ case _ => x
0 commit comments