Skip to content

Commit

Permalink
Refactor MacroAnnotations.callMacro (#18581)
Browse files Browse the repository at this point in the history
Move error handling into call macro This method should handle the
reflective calls and their errors.
  • Loading branch information
nicolasstucki authored Oct 12, 2023
2 parents 7dc9798 + 4c3502d commit 98215d3
Showing 1 changed file with 25 additions and 26 deletions.
51 changes: 25 additions & 26 deletions compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,7 @@ class MacroAnnotations:
debug.println(i"Expanding macro annotation: ${annot}")

// Interpret call to `new myAnnot(..).transform(using <Quotes>)(<tree>)`
val transformedTrees =
try callMacro(macroInterpreter, tree, annot)
catch
// TODO: Replace this case when scala.annaotaion.MacroAnnotation is no longer experimental and reflectiveSelectable is not used
// Replace this case with the nested cases.
case ex0: InvocationTargetException =>
ex0.getCause match
case ex: scala.quoted.runtime.StopMacroExpansion =>
if !ctx.reporter.hasErrors then
report.error("Macro expansion was aborted by the macro without any errors reported. Macros should issue errors to end-users when aborting a macro expansion with StopMacroExpansion.", annot.tree)
List(tree)
case Interpreter.MissingClassDefinedInCurrentRun(sym) =>
Interpreter.suspendOnMissing(sym, annot.tree)
case NonFatal(ex) =>
val stack0 = ex.getStackTrace.takeWhile(_.getClassName != "dotty.tools.dotc.transform.MacroAnnotations")
val stack = stack0.take(1 + stack0.lastIndexWhere(_.getMethodName == "transform"))
val msg =
em"""Failed to evaluate macro.
| Caused by ${ex.getClass}: ${if (ex.getMessage == null) "" else ex.getMessage}
| ${stack.mkString("\n ")}
|"""
report.error(msg, annot.tree)
List(tree)
case _ =>
throw ex0
val transformedTrees = callMacro(macroInterpreter, tree, annot)
transformedTrees.span(_.symbol != tree.symbol) match
case (prefixed, newTree :: suffixed) =>
allTrees ++= prefixed
Expand Down Expand Up @@ -117,7 +93,30 @@ class MacroAnnotations:
assert(annotInstance.getClass.getClassLoader.loadClass("scala.annotation.MacroAnnotation").isInstance(annotInstance))

val quotes = QuotesImpl()(using SpliceScope.contextWithNewSpliceScope(tree.symbol.sourcePos)(using MacroExpansion.context(tree)).withOwner(tree.symbol.owner))
annotInstance.transform(using quotes)(tree.asInstanceOf[quotes.reflect.Definition])
try annotInstance.transform(using quotes)(tree.asInstanceOf[quotes.reflect.Definition])
catch
// TODO: Replace this case when scala.annaotaion.MacroAnnotation is no longer experimental and reflectiveSelectable is not used
// Replace this case with the nested cases.
case ex0: InvocationTargetException =>
ex0.getCause match
case ex: scala.quoted.runtime.StopMacroExpansion =>
if !ctx.reporter.hasErrors then
report.error("Macro expansion was aborted by the macro without any errors reported. Macros should issue errors to end-users when aborting a macro expansion with StopMacroExpansion.", annot.tree)
List(tree)
case Interpreter.MissingClassDefinedInCurrentRun(sym) =>
Interpreter.suspendOnMissing(sym, annot.tree)
case NonFatal(ex) =>
val stack0 = ex.getStackTrace.takeWhile(_.getClassName != "dotty.tools.dotc.transform.MacroAnnotations")
val stack = stack0.take(1 + stack0.lastIndexWhere(_.getMethodName == "transform"))
val msg =
em"""Failed to evaluate macro.
| Caused by ${ex.getClass}: ${if (ex.getMessage == null) "" else ex.getMessage}
| ${stack.mkString("\n ")}
|"""
report.error(msg, annot.tree)
List(tree)
case _ =>
throw ex0

/** Check that this tree can be added by the macro annotation */
private def checkMacroDef(newTree: DefTree, annotatedTree: Tree, annot: Annotation)(using Context) =
Expand Down

0 comments on commit 98215d3

Please sign in to comment.