Skip to content

Refactor MacroAnnotations.callMacro #18581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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