@@ -47,6 +47,8 @@ object Splicer {
4747 interpretedExpr.fold(tree)(macroClosure => PickledQuotes .quotedExprToTree(macroClosure(QuoteContext ())))
4848 }
4949 catch {
50+ case ex : CompilationUnit .SuspendException =>
51+ throw ex
5052 case ex : StopInterpretation =>
5153 ctx.error(ex.msg, ex.pos)
5254 EmptyTree
@@ -322,20 +324,18 @@ object Splicer {
322324 try classLoader.loadClass(name)
323325 catch {
324326 case _ : ClassNotFoundException =>
325- val msg = s " Could not find class $name in classpath $extraMsg "
327+ val msg = s " Could not find class $name in classpath "
326328 throw new StopInterpretation (msg, pos)
327329 }
328330
329331 private def getMethod (clazz : Class [? ], name : Name , paramClasses : List [Class [? ]]): Method =
330332 try clazz.getMethod(name.toString, paramClasses : _* )
331333 catch {
332334 case _ : NoSuchMethodException =>
333- val msg = em " Could not find method ${clazz.getCanonicalName}. $name with parameters ( $paramClasses%, %) $extraMsg "
335+ val msg = em " Could not find method ${clazz.getCanonicalName}. $name with parameters ( $paramClasses%, %) "
334336 throw new StopInterpretation (msg, pos)
335337 }
336338
337- private def extraMsg = " . The most common reason for that is that you apply macros in the compilation run that defines them"
338-
339339 private def stopIfRuntimeException [T ](thunk : => T , method : Method ): T =
340340 try thunk
341341 catch {
@@ -348,21 +348,38 @@ object Splicer {
348348 sw.write(" \n " )
349349 throw new StopInterpretation (sw.toString, pos)
350350 case ex : InvocationTargetException =>
351- val sw = new StringWriter ()
352- sw.write(" Exception occurred while executing macro expansion.\n " )
353- val targetException = ex.getTargetException
354- if (! ctx.settings.Ydebug .value) {
355- val end = targetException.getStackTrace.lastIndexWhere { x =>
356- x.getClassName == method.getDeclaringClass.getCanonicalName && x.getMethodName == method.getName
357- }
358- val shortStackTrace = targetException.getStackTrace.take(end + 1 )
359- targetException.setStackTrace(shortStackTrace)
351+ ex.getTargetException match {
352+ case MissingClassDefinedInCurrentRun (sym) =>
353+ if (ctx.settings.XprintSuspension .value)
354+ ctx.echo(i " suspension triggered by a dependency on $sym" , pos)
355+ ctx.compilationUnit.suspend() // this throws a SuspendException
356+ case targetException =>
357+ val sw = new StringWriter ()
358+ sw.write(" Exception occurred while executing macro expansion.\n " )
359+ if (! ctx.settings.Ydebug .value) {
360+ val end = targetException.getStackTrace.lastIndexWhere { x =>
361+ x.getClassName == method.getDeclaringClass.getCanonicalName && x.getMethodName == method.getName
362+ }
363+ val shortStackTrace = targetException.getStackTrace.take(end + 1 )
364+ targetException.setStackTrace(shortStackTrace)
365+ }
366+ targetException.printStackTrace(new PrintWriter (sw))
367+ sw.write(" \n " )
368+ throw new StopInterpretation (sw.toString, pos)
360369 }
361- targetException.printStackTrace(new PrintWriter (sw))
362- sw.write(" \n " )
363- throw new StopInterpretation (sw.toString, pos)
364370 }
365371
372+ private object MissingClassDefinedInCurrentRun {
373+ def unapply (targetException : NoClassDefFoundError )(given ctx : Context ): Option [Symbol ] = {
374+ val className = targetException.getMessage
375+ if (className eq null ) None
376+ else {
377+ val sym = ctx.base.staticRef(className.toTypeName).symbol
378+ if (sym.isDefinedInCurrentRun) Some (sym) else None
379+ }
380+ }
381+ }
382+
366383 /** List of classes of the parameters of the signature of `sym` */
367384 private def paramsSig (sym : Symbol ): List [Class [? ]] = {
368385 def paramClass (param : Type ): Class [? ] = {
0 commit comments