From d2c3db00c7f2de2a5b718f41c0d9d9215c42c35a Mon Sep 17 00:00:00 2001 From: Hamza REMMAL Date: Sun, 14 Apr 2024 18:17:39 +0200 Subject: [PATCH] Add support for companion in MacroAnnotations --- .../dotty/tools/dotc/transform/Inlining.scala | 174 ++++++++++++++---- .../dotc/transform/MacroAnnotations.scala | 135 ++++++++------ .../scala/annotation/MacroAnnotation.scala | 27 +-- .../annot-accessIndirect/Macro_1.scala | 4 +- .../annot-accessIndirect/Macro_2.scala | 6 +- tests/neg-macros/annot-crash/Macro_1.scala | 2 +- .../annot-empty-result/Macro_1.scala | 2 +- .../annot-error-annot/Macro_1.scala | 6 +- .../neg-macros/annot-ill-abort/Macro_1.scala | 2 +- .../Macro_1.scala | 8 +- .../annot-mod-class-add-top-val/Macro_1.scala | 8 +- .../Macro_1.scala | 4 +- .../Macro_1.scala | 4 +- tests/neg-macros/annot-on-type/Macro_1.scala | 4 +- .../annot-result-owner/Macro_1.scala | 6 +- .../annot-suspend-cycle/Macro.scala | 4 +- tests/neg-macros/i18677-a/Macro_1.scala | 9 +- tests/neg-macros/i18677-b/Macro_1.scala | 9 +- tests/neg-macros/i18825/Macro_1.scala | 10 +- tests/neg-macros/wrong-owner.check | 2 +- tests/neg-macros/wrong-owner/Macro_1.scala | 10 +- .../Macro_1.scala | 10 + .../Test_2.scala | 3 + .../pos-macros/annot-in-object/Macro_1.scala | 6 +- tests/pos-macros/annot-suspend/Macro_1.scala | 4 +- .../annot-then-inline/Macro_1.scala | 8 +- tests/pos-macros/i19537/Macro_1.scala | 3 +- tests/pos-macros/i19539/Macro_1.scala | 3 +- .../macro-annot-with-companion/Macro_1.scala | 15 ++ .../macro-annot-with-companion/Test_2.scala | 15 ++ .../annot-add-global-class/Macro_1.scala | 8 +- .../annot-add-global-object/Macro_1.scala | 8 +- .../annot-add-local-class/Macro_1.scala | 8 +- .../annot-add-local-object/Macro_1.scala | 8 +- .../annot-add-nested-class/Macro_1.scala | 8 +- .../annot-add-nested-object/Macro_1.scala | 8 +- .../annot-annot-order/Macro_1.scala | 10 +- tests/run-macros/annot-bind/Macro_1.scala | 8 +- .../run-macros/annot-changeVal/Macro_1.scala | 6 +- .../annot-concrete-class/Macro_1.scala | 2 +- tests/run-macros/annot-export/Macro_1.scala | 6 +- tests/run-macros/annot-gen2/Macro_1.scala | 8 +- tests/run-macros/annot-gen2/Macro_2.scala | 8 +- tests/run-macros/annot-generate/Macro_1.scala | 4 +- tests/run-macros/annot-generate/Macro_2.scala | 8 +- .../run-macros/annot-macro-main/Macro_1.scala | 10 +- tests/run-macros/annot-memo/Macro_1.scala | 10 +- .../annot-mod-class-add-def/Macro_1.scala | 10 +- .../Macro_1.scala | 10 +- .../Macro_1.scala | 10 +- .../Macro_1.scala | 10 +- .../annot-mod-class-add-val/Macro_1.scala | 10 +- .../annot-mod-class-add-var/Macro_1.scala | 10 +- .../annot-mod-class-data/Macro_1.scala | 10 +- .../annot-mod-class-equals/Macro_1.scala | 10 +- .../annot-mod-class-mod-def/Macro_1.scala | 10 +- .../annot-mod-class-mod-val/Macro_1.scala | 10 +- .../Macro_1.scala | 10 +- .../Macro_1.scala | 10 +- .../Macro_1.scala | 10 +- .../annot-result-order/Macro_1.scala | 4 +- .../run-macros/annot-simple-fib/Macro_1.scala | 8 +- .../run-macros/annot-unrollLast/Macro_1.scala | 2 +- tests/run-macros/i18806/Macro_1.scala | 10 +- tests/run-macros/i19676.check | 6 + tests/run-macros/i19676/Macro_1.scala | 27 +++ tests/run-macros/i19676/Test_2.scala | 36 ++++ tests/run/quotes-add-erased/Macro_1.scala | 2 +- 68 files changed, 554 insertions(+), 302 deletions(-) create mode 100644 tests/pos-macros/annot-dependency-between-modules/Macro_1.scala create mode 100644 tests/pos-macros/annot-dependency-between-modules/Test_2.scala create mode 100644 tests/pos/macro-annot-with-companion/Macro_1.scala create mode 100644 tests/pos/macro-annot-with-companion/Test_2.scala create mode 100644 tests/run-macros/i19676.check create mode 100644 tests/run-macros/i19676/Macro_1.scala create mode 100644 tests/run-macros/i19676/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/transform/Inlining.scala b/compiler/src/dotty/tools/dotc/transform/Inlining.scala index 94df114290e4..e4839bd2c659 100644 --- a/compiler/src/dotty/tools/dotc/transform/Inlining.scala +++ b/compiler/src/dotty/tools/dotc/transform/Inlining.scala @@ -1,20 +1,23 @@ package dotty.tools.dotc package transform +import ast.tpd +import ast.Trees.* +import ast.TreeMapWithImplicits import core.* import Flags.* +import Decorators.* import Contexts.* import Symbols.* +import Decorators.* +import config.Printers.inlining +import DenotTransformers.IdentityDenotTransformer +import inlines.Inlines +import quoted.* +import staging.StagingLevel +import util.Property -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.ast.Trees.* -import dotty.tools.dotc.quoted.* -import dotty.tools.dotc.inlines.Inlines -import dotty.tools.dotc.ast.TreeMapWithImplicits -import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer -import dotty.tools.dotc.staging.StagingLevel - -import scala.collection.mutable.ListBuffer +import scala.collection.mutable /** Inlines all calls to inline methods that are not in an inline method or a quote */ class Inlining extends MacroTransform, IdentityDenotTransformer { @@ -56,38 +59,96 @@ class Inlining extends MacroTransform, IdentityDenotTransformer { def newTransformer(using Context): Transformer = new Transformer { override def transform(tree: tpd.Tree)(using Context): tpd.Tree = - new InliningTreeMap().transform(tree) + InliningTreeMap().transform(tree) } - private class InliningTreeMap extends TreeMapWithImplicits { + private class MemoizeStatsTreeMap extends TreeMapWithImplicits { + + // It is safe to assume that the companion of a tree is in the same scope + // Therefore, when expanding MacroAnnotations, we will only keep track of + // the trees in the same scope as the current transformed tree + + private val TrackedTrees = new Property.Key[mutable.Map[Symbol, tpd.MemberDef]] + + private def trackedTreesCtx(trees: mutable.Map[Symbol, tpd.MemberDef])(using Context): Context = + ctx.fresh.setProperty(TrackedTrees, trees) + + private def trackedTrees(using Context): mutable.Map[Symbol, MemberDef] = + ctx.property(TrackedTrees).getOrElse(mutable.Map.empty) + + protected final def getTracked(sym: Symbol)(using Context): Option[MemberDef] = + for trees <- ctx.property(TrackedTrees); tree <- trees.get(sym) yield tree + + protected final def updateTracked(sym: Symbol, tree: MemberDef)(using Context): Unit = + for trees <- ctx.property(TrackedTrees) do trees.update(sym, tree) + + override def transform(tree: Tree)(using Context): Tree = + tree match + case PackageDef(_, stats) => + // Phase I: Collect and memoize all the stats + val treesToTrack = stats.collect { case m: MemberDef => (m.symbol, m) } + val withTrackedTreeCtx = trackedTreesCtx(mutable.Map(treesToTrack*)) + // Phase II & III: Transform the tree with this definitions and reconcile them with the tracked trees + super.transform(tree)(using withTrackedTreeCtx) match + case pkg@PackageDef(pid, stats) => + val trackedTree = trackedTrees(using withTrackedTreeCtx) + val updatedStats = stats.mapConserve: + case tree: MemberDef if trackedTree.contains(tree.symbol) => + trackedTree(tree.symbol) + case stat => stat + cpy.PackageDef(pkg)(pid = pid, stats = updatedStats) + case tree => tree + case block: Block => + // Phase I: Fetch all the member definitions in the block + val trees = block.stats.collect { case m: MemberDef => (m.symbol, m) } + val withTrackedTreeCtx = trackedTreesCtx(mutable.Map(trees*)) + + // Phase II / III: Transform the tree and Reconcile between the symbols in syms and the tree + // TODO: Should we define a substitution method where we change the trees + // and not the symbols (see Tree::subst) + // result.subst(MacroAnnotations.trackedTrees(using withTrackedTreeCtx)) + super.transform(tree)(using withTrackedTreeCtx) match + case b@Block(stats, expr) => + val trackedTree = trackedTrees(using withTrackedTreeCtx) + cpy.Block(b)( + expr = expr, + stats = stats.mapConserve: + case ddef: MemberDef if trackedTree.contains(ddef.symbol) => + trackedTree(ddef.symbol) + case stat => stat + ) + case tree => tree + case TypeDef(_, impl: Template) => + // Phase I: Collect and memoize all the stats + val trees = impl.body.collect { case m: MemberDef => (m.symbol, m) } + val withTrackedTreeCtx = trackedTreesCtx(mutable.Map(trees*)) + // Phase II / III: Transform the tree and Reconcile between the symbols in syms and the tree + super.transform(tree)(using withTrackedTreeCtx) match + case tree@TypeDef(name, impl: Template) => + val trackedTree = trackedTrees(using withTrackedTreeCtx) + cpy.TypeDef(tree)( + name = name, + rhs = cpy.Template(impl)( + body = impl.body.mapConserve: + case ddef: MemberDef if trackedTree.contains(ddef.symbol) => + trackedTree(ddef.symbol) + case stat => stat + ) + ) + case tree => tree + case _ => super.transform(tree) + } + + private class InliningTreeMap extends MemoizeStatsTreeMap { /** List of top level classes added by macro annotation in a package object. * These are added to the PackageDef that owns this particular package object. */ - private val newTopClasses = MutableSymbolMap[ListBuffer[Tree]]() + private val newTopClasses = MutableSymbolMap[mutable.ListBuffer[Tree]]() override def transform(tree: Tree)(using Context): Tree = { tree match - case tree: MemberDef => - if tree.symbol.is(Inline) then tree - else if tree.symbol.is(Param) then super.transform(tree) - else if - !tree.symbol.isPrimaryConstructor - && StagingLevel.level == 0 - && MacroAnnotations.hasMacroAnnotation(tree.symbol) - then - val trees = (new MacroAnnotations(self)).expandAnnotations(tree) - val trees1 = trees.map(super.transform) - - // Find classes added to the top level from a package object - val (topClasses, trees2) = - if ctx.owner.isPackageObject then trees1.partition(_.symbol.owner == ctx.owner.owner) - else (Nil, trees1) - if topClasses.nonEmpty then - newTopClasses.getOrElseUpdate(ctx.owner.owner, new ListBuffer) ++= topClasses - - flatTree(trees2) - else super.transform(tree) + case tree: MemberDef => transformMemberDef(tree) case _: Typed | _: Block => super.transform(tree) case _: PackageDef => @@ -113,7 +174,56 @@ class Inlining extends MacroTransform, IdentityDenotTransformer { else Inlines.inlineCall(tree1) else super.transform(tree) } + + private def transformMemberDef(tree: MemberDef)(using Context) : Tree = + if tree.symbol.is(Inline) then tree + else if tree.symbol.is(Param) then + super.transform(tree) + else if + !tree.symbol.isPrimaryConstructor + && StagingLevel.level == 0 + && MacroAnnotations.hasMacroAnnotation(tree.symbol) + then + // Fetch the companion's tree + val companionTree = + getTracked( + sym = if tree.symbol.is(ModuleClass) then tree.symbol.companionClass + else if tree.symbol.is(ModuleVal) then NoSymbol + else tree.symbol.companionModule.moduleClass) + + // Fetch the latest tracked tree (It might have already been processed by its companion) + val latestTree = getTracked(tree.symbol).getOrElse(tree) + + // Expand and process MacroAnnotations + val (trees, companion) = + MacroAnnotations(self).expandAnnotations(latestTree, companionTree) + + // Update the tracked trees + for case tree : MemberDef <- trees do updateTracked(tree.symbol, tree) + for tree <- companion do updateTracked(tree.symbol, tree) + + // Perform inlining on the expansion of the annotations + val trees1 = trees.map(super.transform) + + for case tree: MemberDef <- trees1 do updateTracked(tree.symbol, tree) + + // Find classes added to the top level from a package object + val (topClasses, trees2) = + if ctx.owner.isPackageObject then trees1.partition(_.symbol.owner == ctx.owner.owner) + else (Nil, trees1) + if topClasses.nonEmpty then + newTopClasses.getOrElseUpdate(ctx.owner.owner, new mutable.ListBuffer) ++= topClasses + flatTree(trees2) + else + super.transform(tree) match + case tree: MemberDef => + updateTracked(tree.symbol, tree) + tree + case tree => tree + end transformMemberDef + } + } object Inlining: diff --git a/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala b/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala index c83e4d7b7819..88c7a0ff9926 100644 --- a/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala +++ b/compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala @@ -3,19 +3,19 @@ package transform import scala.language.unsafeNulls -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.ast.Trees.* -import dotty.tools.dotc.config.Printers.{macroAnnot => debug} -import dotty.tools.dotc.core.Annotations.* -import dotty.tools.dotc.core.Contexts.* -import dotty.tools.dotc.core.Decorators.* -import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer -import dotty.tools.dotc.core.Flags.* -import dotty.tools.dotc.core.MacroClassLoader -import dotty.tools.dotc.core.Symbols.* -import dotty.tools.dotc.core.Types.* -import dotty.tools.dotc.quoted.* -import dotty.tools.dotc.util.SrcPos +import ast.tpd +import ast.Trees.* +import config.Printers.macroAnnot as debug +import core.Annotations.* +import core.Contexts.* +import core.Decorators.* +import core.DenotTransformers.IdentityDenotTransformer +import core.Flags.* +import core.MacroClassLoader +import core.Symbols.* +import core.Types.* +import quoted.* +import util.SrcPos import scala.quoted.runtime.impl.{QuotesImpl, SpliceScope} import scala.quoted.Quotes @@ -31,82 +31,100 @@ class MacroAnnotations(phase: IdentityDenotTransformer): /** Expands every macro annotation that is on this tree. * Returns a list with transformed definition and any added definitions. */ - def expandAnnotations(tree: MemberDef)(using Context): List[DefTree] = + def expandAnnotations(tree: MemberDef, companion: Option[MemberDef])(using Context): (List[MemberDef], Option[MemberDef]) = if !hasMacroAnnotation(tree.symbol) then - List(tree) + (List(tree), companion) else if tree.symbol.is(Module) && !tree.symbol.isClass then // only class is transformed - List(tree) + (List(tree), companion) else if tree.symbol.isType && !tree.symbol.isClass then report.error("macro annotations are not supported on type", tree) - List(tree) + (List(tree), companion) else debug.println(i"Expanding macro annotations of:\n$tree") - val macroInterpreter = new Interpreter(tree.srcPos, MacroClassLoader.fromContext) - val allTrees = List.newBuilder[DefTree] - var insertedAfter: List[List[DefTree]] = Nil + val allTrees = List.newBuilder[MemberDef] + var insertedAfter: List[List[MemberDef]] = Nil // Apply all macro annotation to `tree` and collect new definitions in order - val transformedTree: DefTree = tree.symbol.annotations.foldLeft(tree) { (tree, annot) => - if isMacroAnnotation(annot) then - debug.println(i"Expanding macro annotation: ${annot}") - - // Interpret call to `new myAnnot(..).transform(using )()` - val transformedTrees = callMacro(macroInterpreter, tree, annot) - transformedTrees.span(_.symbol != tree.symbol) match - case (prefixed, newTree :: suffixed) => - allTrees ++= prefixed - insertedAfter = suffixed :: insertedAfter - for prefixedTree <- prefixed do - checkMacroDef(prefixedTree, tree, annot) - for suffixedTree <- suffixed do - checkMacroDef(suffixedTree, tree, annot) - TreeChecker.checkMacroGeneratedTree(tree, newTree) - newTree - case (Nil, Nil) => - report.error(i"Unexpected `Nil` returned by `(${annot.tree}).transform(..)` during macro expansion", annot.tree.srcPos) - tree - case (_, Nil) => - report.error(i"Transformed tree for ${tree} was not return by `(${annot.tree}).transform(..)` during macro expansion", annot.tree.srcPos) - tree - else - tree - } - + val (transformedTree, transformedCompanion) = + tree.symbol.annotations.foldLeft((tree, companion)): (lastResult, annot) => + val (tree, companion) = lastResult + if isMacroAnnotation(annot) then + debug.println(i"Expanding macro annotation: ${annot}") + // Interpret call to `new myAnnot(..).transform(using )(, )` + val (transformedTrees, transformedCompanion) = callMacro(macroInterpreter, tree, companion, annot) + transformedTrees.span(_.symbol != tree.symbol) match + case (prefixed, newTree :: suffixed) => + allTrees ++= prefixed + insertedAfter = suffixed :: insertedAfter + for prefixedTree <- prefixed do + checkMacroDef(prefixedTree, tree, annot) + for suffixedTree <- suffixed do + checkMacroDef(suffixedTree, tree, annot) + // Check the generate tree structure + TreeChecker.checkMacroGeneratedTree(tree, newTree) + (newTree, transformedCompanion) + case (Nil, Nil) => + report.error(i"Unexpected `Nil` returned by `(${annot.tree}).transform(..)` during macro expansion", annot.tree.srcPos) + (tree, transformedCompanion) + case (_, Nil) => + report.error(i"Transformed tree for ${tree} was not return by `(${annot.tree}).transform(..)` during macro expansion", annot.tree.srcPos) + (tree, transformedCompanion) + else + (tree, companion) + end val + + // Complete the list of transformed/generated definitions allTrees += transformedTree insertedAfter.foreach(allTrees.++=) val result = allTrees.result() for tree <- result do enterMissingSymbols(tree) debug.println(result.map(_.show).mkString("expanded to:\n", "\n", "")) - result + (result, transformedCompanion) - /** Interpret the code `new annot(..).transform(using )()` */ - private def callMacro(interpreter: Interpreter, tree: MemberDef, annot: Annotation)(using Context): List[MemberDef] = + /** Interpret the code `new annot(..).transform(using )(, )` */ + // TODO: Return the companion as a tuple with the list + private def callMacro(interpreter: Interpreter, tree: MemberDef, companion: Option[MemberDef], annot: Annotation)(using Context): (List[MemberDef], Option[MemberDef]) = // TODO: Remove when scala.annaotaion.MacroAnnotation is no longer experimental import scala.reflect.Selectable.reflectiveSelectable type MacroAnnotation = { - def transform(using Quotes)(tree: Object/*Erased type of quotes.refelct.Definition*/): List[MemberDef /*quotes.refelct.Definition known to be MemberDef in QuotesImpl*/] + def transform(using Quotes) + (tree: Object/*Erased type of quotes.reflect.Definition*/, companion: Option[Object/*Erased type of quotes.reflect.Definition*/]) + : List[MemberDef /*quotes.refelct.Definition known to be MemberDef in QuotesImpl*/] } // Interpret macro annotation instantiation `new myAnnot(..)` + // TODO: Make this error handling stronger (no error handling at the moment) val annotInstance = interpreter.interpret[MacroAnnotation](annot.tree).get + // TODO: Remove when scala.annaotaion.MacroAnnotation is no longer experimental 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)) - try annotInstance.transform(using quotes)(tree.asInstanceOf[quotes.reflect.Definition]) + try + val result = annotInstance.transform(using quotes)(tree, companion) + // Process the result based on if the companion was present or not + companion match + case None => (result, None) + case Some(tree) => result.partition(_.symbol == tree.symbol) match + case (Nil, result) => (result, companion) // companion didn't change + case (companion :: Nil, result) => (result, Some(companion)) + case (_, result) => + report.error("The transformed companion is present in the list more than once", annot.tree) + (result, companion) + catch - // TODO: Replace this case when scala.annaotaion.MacroAnnotation is no longer experimental and reflectiveSelectable is not used + // TODO: Replace this case when scala.annotation.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) + (List(tree), companion) case Interpreter.MissingClassValidInCurrentRun(sym, origin) => Interpreter.suspendOnMissing(sym, origin, annot.tree) case NonFatal(ex) => @@ -118,9 +136,10 @@ class MacroAnnotations(phase: IdentityDenotTransformer): | ${stack.mkString("\n ")} |""" report.error(msg, annot.tree) - List(tree) + (List(tree), companion) case _ => throw ex0 + end callMacro /** Check that this tree can be added by the macro annotation */ private def checkMacroDef(newTree: DefTree, annotatedTree: Tree, annot: Annotation)(using Context) = @@ -137,7 +156,7 @@ class MacroAnnotations(phase: IdentityDenotTransformer): /** * Enter the symbols generated by MacroAnnotations */ - private def enterMissingSymbols(tree: DefTree)(using Context) = new TreeTraverser { + private def enterMissingSymbols(tree: MemberDef)(using Context) = new TreeTraverser { def traverse(tree: tpd.Tree)(using Context): Unit = tree match case tdef @ TypeDef(_, template: Template) => val isSymbolInDecls = tdef.symbol.asClass.info.decls.toList.toSet @@ -150,7 +169,9 @@ class MacroAnnotations(phase: IdentityDenotTransformer): case _ => traverseChildren(tree) }.traverse(tree) -object MacroAnnotations: +end MacroAnnotations + +object MacroAnnotations { /** Is this an annotation that implements `scala.annation.MacroAnnotation` */ def isMacroAnnotation(annot: Annotation)(using Context): Boolean = @@ -159,3 +180,5 @@ object MacroAnnotations: /** Is this symbol annotated with an annotation that implements `scala.annation.MacroAnnotation` */ def hasMacroAnnotation(sym: Symbol)(using Context): Boolean = sym.getAnnotation(defn.MacroAnnotationClass).isDefined + +} diff --git a/library/src/scala/annotation/MacroAnnotation.scala b/library/src/scala/annotation/MacroAnnotation.scala index 02e9470f06fd..44e89a19cf14 100644 --- a/library/src/scala/annotation/MacroAnnotation.scala +++ b/library/src/scala/annotation/MacroAnnotation.scala @@ -45,9 +45,9 @@ trait MacroAnnotation extends StaticAnnotation: * import scala.collection.concurrent * * class memoize extends MacroAnnotation: - * def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + * def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = * import quotes.reflect.* - * tree match + * definition match * case DefDef(name, TermParamClause(param :: Nil) :: Nil, tpt, Some(rhsTree)) => * (param.tpt.tpe.asType, tpt.tpe.asType) match * case ('[t], '[u]) => @@ -58,16 +58,16 @@ trait MacroAnnotation extends StaticAnnotation: * '{ concurrent.TrieMap.empty[t, u] }.asTerm * val cacheVal = ValDef(cacheSymbol, Some(cacheRhs)) * val newRhs = - * given Quotes = tree.symbol.asQuotes + * given Quotes = definition.symbol.asQuotes * val cacheRefExpr = Ref(cacheSymbol).asExprOf[concurrent.Map[t, u]] * val paramRefExpr = Ref(param.symbol).asExprOf[t] * val rhsExpr = rhsTree.asExprOf[u] * '{ $cacheRefExpr.getOrElseUpdate($paramRefExpr, $rhsExpr) }.asTerm - * val newTree = DefDef.copy(tree)(name, TermParamClause(param :: Nil) :: Nil, tpt, Some(newRhs)) + * val newTree = DefDef.copy(definition)(name, TermParamClause(param :: Nil) :: Nil, tpt, Some(newRhs)) * List(cacheVal, newTree) * case _ => * report.error("Annotation only supported on `def` with a single argument are supported") - * List(tree) + * List(definition) * ``` * with this macro annotation a user can write * ```scala @@ -102,11 +102,11 @@ trait MacroAnnotation extends StaticAnnotation: * * @experimental * class equals extends MacroAnnotation: - * def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + * def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = * import quotes.reflect.* - * tree match + * definition match * case ClassDef(className, ctr, parents, self, body) => - * val cls = tree.symbol + * val cls = definition.symbol * * val constructorParameters = ctr.paramss.collect { case clause: TermParamClause => clause } * if constructorParameters.size != 1 || constructorParameters.head.params.isEmpty then @@ -139,10 +139,10 @@ trait MacroAnnotation extends StaticAnnotation: * val hashCodeOverrideDef = DefDef(hashCodeOverrideSym, _ => Some(Ref(hashSym))) * * val newBody = equalsOverrideDef :: hashVal :: hashCodeOverrideDef :: body - * List(ClassDef.copy(tree)(className, ctr, parents, self, newBody)) + * List(ClassDef.copy(definition)(className, ctr, parents, self, newBody)) * case _ => * report.error("Annotation only supports `class`") - * List(tree) + * List(definition) * * private def equalsExpr[T: Type](that: Expr[Any], thisFields: List[Expr[Any]])(using Quotes): Expr[Boolean] = * '{ @@ -204,9 +204,10 @@ trait MacroAnnotation extends StaticAnnotation: * override def hashCode(): Int = hash$macro$1 * ``` * - * @param Quotes Implicit instance of Quotes used for tree reflection - * @param tree Tree that will be transformed + * @param Quotes Implicit instance of Quotes used for tree reflection + * @param definition Tree that will be transformed + * @param companion Tree for the companion class or module if the definition is respectively a module or a class * * @syntax markdown */ - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] diff --git a/tests/neg-macros/annot-accessIndirect/Macro_1.scala b/tests/neg-macros/annot-accessIndirect/Macro_1.scala index 8679edcfc0c3..7f4136e10652 100644 --- a/tests/neg-macros/annot-accessIndirect/Macro_1.scala +++ b/tests/neg-macros/annot-accessIndirect/Macro_1.scala @@ -3,9 +3,9 @@ import scala.quoted._ @experimental class hello extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ val helloSymbol = Symbol.newVal(Symbol.spliceOwner, Symbol.freshName("hello"), TypeRepr.of[String], Flags.EmptyFlags, Symbol.noSymbol) val helloVal = ValDef(helloSymbol, Some(Literal(StringConstant("Hello, World!")))) - List(helloVal, tree) + List(helloVal, definition) } diff --git a/tests/neg-macros/annot-accessIndirect/Macro_2.scala b/tests/neg-macros/annot-accessIndirect/Macro_2.scala index d069175ce166..5fa2ba1aa2bf 100644 --- a/tests/neg-macros/annot-accessIndirect/Macro_2.scala +++ b/tests/neg-macros/annot-accessIndirect/Macro_2.scala @@ -3,16 +3,16 @@ import scala.quoted._ @experimental class foo extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ val s = '{@hello def foo1(x: Int): Int = x + 1;()}.asTerm val fooDef = s.asInstanceOf[Inlined].body.asInstanceOf[Block].statements.head.asInstanceOf[DefDef] val hello = Ref(Symbol.spliceOwner.declaredFields("hello").head).asExprOf[String] // error - tree match + definition match case DefDef(name, params, tpt, Some(t)) => val rhs = '{ ${t.asExprOf[String]} + $hello }.asTerm - val newDef = DefDef.copy(tree)(name, params, tpt, Some(rhs)) + val newDef = DefDef.copy(definition)(name, params, tpt, Some(rhs)) List(fooDef, newDef) } diff --git a/tests/neg-macros/annot-crash/Macro_1.scala b/tests/neg-macros/annot-crash/Macro_1.scala index f3d5b3f602f8..06fb08062181 100644 --- a/tests/neg-macros/annot-crash/Macro_1.scala +++ b/tests/neg-macros/annot-crash/Macro_1.scala @@ -3,6 +3,6 @@ import scala.quoted._ @experimental class crash extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = ??? } diff --git a/tests/neg-macros/annot-empty-result/Macro_1.scala b/tests/neg-macros/annot-empty-result/Macro_1.scala index ff3be61c05d2..9b22027ce929 100644 --- a/tests/neg-macros/annot-empty-result/Macro_1.scala +++ b/tests/neg-macros/annot-empty-result/Macro_1.scala @@ -3,6 +3,6 @@ import scala.quoted._ @experimental class nilAnnot extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = Nil } diff --git a/tests/neg-macros/annot-error-annot/Macro_1.scala b/tests/neg-macros/annot-error-annot/Macro_1.scala index d54b69903e02..6597a11be7d2 100644 --- a/tests/neg-macros/annot-error-annot/Macro_1.scala +++ b/tests/neg-macros/annot-error-annot/Macro_1.scala @@ -3,7 +3,7 @@ import scala.quoted._ @experimental class error extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = - quotes.reflect.report.error("MACRO ERROR", tree.pos) - List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + quotes.reflect.report.error("MACRO ERROR", definition.pos) + List(definition) } diff --git a/tests/neg-macros/annot-ill-abort/Macro_1.scala b/tests/neg-macros/annot-ill-abort/Macro_1.scala index 446ce0a5331b..4689ffbe2f2c 100644 --- a/tests/neg-macros/annot-ill-abort/Macro_1.scala +++ b/tests/neg-macros/annot-ill-abort/Macro_1.scala @@ -3,6 +3,6 @@ import scala.quoted._ @experimental class crash extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = throw new scala.quoted.runtime.StopMacroExpansion } diff --git a/tests/neg-macros/annot-mod-class-add-top-method/Macro_1.scala b/tests/neg-macros/annot-mod-class-add-top-method/Macro_1.scala index b5c49695ad2a..7dc8cb2c4479 100644 --- a/tests/neg-macros/annot-mod-class-add-top-method/Macro_1.scala +++ b/tests/neg-macros/annot-mod-class-add-top-method/Macro_1.scala @@ -4,14 +4,14 @@ import scala.collection.mutable @experimental class addTopLevelMethod extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => val methType = MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Int]) val methSym = Symbol.newMethod(Symbol.spliceOwner, Symbol.freshName("toLevelMethod"), methType, Flags.EmptyFlags, Symbol.noSymbol) val methDef = DefDef(methSym, _ => Some(Literal(IntConstant(1)))) - List(methDef, tree) + List(methDef, definition) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/neg-macros/annot-mod-class-add-top-val/Macro_1.scala b/tests/neg-macros/annot-mod-class-add-top-val/Macro_1.scala index c6f21e181879..12443d329108 100644 --- a/tests/neg-macros/annot-mod-class-add-top-val/Macro_1.scala +++ b/tests/neg-macros/annot-mod-class-add-top-val/Macro_1.scala @@ -4,13 +4,13 @@ import scala.collection.mutable @experimental class addTopLevelVal extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => val valSym = Symbol.newVal(Symbol.spliceOwner, Symbol.freshName("toLevelVal"), TypeRepr.of[Int], Flags.EmptyFlags, Symbol.noSymbol) val valDef = ValDef(valSym, Some(Literal(IntConstant(1)))) - List(valDef, tree) + List(valDef, definition) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/neg-macros/annot-mod-top-method-add-top-method/Macro_1.scala b/tests/neg-macros/annot-mod-top-method-add-top-method/Macro_1.scala index 45679b65c03b..8609af376ad7 100644 --- a/tests/neg-macros/annot-mod-top-method-add-top-method/Macro_1.scala +++ b/tests/neg-macros/annot-mod-top-method-add-top-method/Macro_1.scala @@ -5,9 +5,9 @@ import scala.collection.mutable @experimental // Assumes annotation is on top level def or val class addTopLevelMethodOutsidePackageObject extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ val methType = MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Int]) val methSym = Symbol.newMethod(Symbol.spliceOwner.owner, Symbol.freshName("toLevelMethod"), methType, Flags.EmptyFlags, Symbol.noSymbol) val methDef = DefDef(methSym, _ => Some(Literal(IntConstant(1)))) - List(methDef, tree) + List(methDef, definition) diff --git a/tests/neg-macros/annot-mod-top-method-add-top-val/Macro_1.scala b/tests/neg-macros/annot-mod-top-method-add-top-val/Macro_1.scala index c6c4c32afcb8..a9ae0efd76b4 100644 --- a/tests/neg-macros/annot-mod-top-method-add-top-val/Macro_1.scala +++ b/tests/neg-macros/annot-mod-top-method-add-top-val/Macro_1.scala @@ -5,8 +5,8 @@ import scala.collection.mutable @experimental // Assumes annotation is on top level def or val class addTopLevelValOutsidePackageObject extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ val valSym = Symbol.newVal(Symbol.spliceOwner.owner, Symbol.freshName("toLevelVal"), TypeRepr.of[Int], Flags.EmptyFlags, Symbol.noSymbol) val valDef = ValDef(valSym, Some(Literal(IntConstant(1)))) - List(valDef, tree) + List(valDef, definition) diff --git a/tests/neg-macros/annot-on-type/Macro_1.scala b/tests/neg-macros/annot-on-type/Macro_1.scala index 7468c5a200a6..631a5bcc201d 100644 --- a/tests/neg-macros/annot-on-type/Macro_1.scala +++ b/tests/neg-macros/annot-on-type/Macro_1.scala @@ -3,6 +3,6 @@ import scala.quoted._ @experimental class voidAnnot extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = - List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + List(definition) } diff --git a/tests/neg-macros/annot-result-owner/Macro_1.scala b/tests/neg-macros/annot-result-owner/Macro_1.scala index 34f7541f726b..af3d8dbb6656 100644 --- a/tests/neg-macros/annot-result-owner/Macro_1.scala +++ b/tests/neg-macros/annot-result-owner/Macro_1.scala @@ -3,9 +3,9 @@ import scala.quoted._ @experimental class insertVal extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ // Use of wrong owner - val valSym = Symbol.newVal(tree.symbol, Symbol.freshName("definitionWithWrongOwner"), TypeRepr.of[Unit], Flags.Private, Symbol.noSymbol) + val valSym = Symbol.newVal(definition.symbol, Symbol.freshName("definitionWithWrongOwner"), TypeRepr.of[Unit], Flags.Private, Symbol.noSymbol) val valDef = ValDef(valSym, Some('{}.asTerm)) - List(valDef, tree) + List(valDef, definition) diff --git a/tests/neg-macros/annot-suspend-cycle/Macro.scala b/tests/neg-macros/annot-suspend-cycle/Macro.scala index 4143e2c32062..e104a5d61c17 100644 --- a/tests/neg-macros/annot-suspend-cycle/Macro.scala +++ b/tests/neg-macros/annot-suspend-cycle/Macro.scala @@ -3,7 +3,7 @@ import scala.quoted._ @experimental class cycle extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = new Foo - List(tree) + List(definition) } diff --git a/tests/neg-macros/i18677-a/Macro_1.scala b/tests/neg-macros/i18677-a/Macro_1.scala index c3df616ed4e6..9420255e6d36 100644 --- a/tests/neg-macros/i18677-a/Macro_1.scala +++ b/tests/neg-macros/i18677-a/Macro_1.scala @@ -6,13 +6,14 @@ import quoted.* trait Foo class extendFoo extends MacroAnnotation : - override def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, + companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case ClassDef(name, ctr, p, self, body) => val parents = List(TypeTree.of[Foo]) - val newTree = ClassDef.copy(tree)(name, ctr, parents, self, body) + val newTree = ClassDef.copy(definition)(name, ctr, parents, self, body) newTree :: Nil case _ => report.error("@extendFoo can only annotate class definitions") - tree :: Nil \ No newline at end of file + definition :: Nil \ No newline at end of file diff --git a/tests/neg-macros/i18677-b/Macro_1.scala b/tests/neg-macros/i18677-b/Macro_1.scala index 9e1b9be5e696..3536114f430e 100644 --- a/tests/neg-macros/i18677-b/Macro_1.scala +++ b/tests/neg-macros/i18677-b/Macro_1.scala @@ -6,13 +6,14 @@ import quoted.* class Foo class extendFoo extends MacroAnnotation : - override def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, + companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case ClassDef(name, ctr, p, self, body) => val parents = List(TypeTree.of[Foo]) - val newTree = ClassDef.copy(tree)(name, ctr, parents, self, body) + val newTree = ClassDef.copy(definition)(name, ctr, parents, self, body) newTree :: Nil case _ => report.error("@extendFoo can only annotate class definitions") - tree :: Nil \ No newline at end of file + definition :: Nil \ No newline at end of file diff --git a/tests/neg-macros/i18825/Macro_1.scala b/tests/neg-macros/i18825/Macro_1.scala index c099954f3858..adeb320c1403 100644 --- a/tests/neg-macros/i18825/Macro_1.scala +++ b/tests/neg-macros/i18825/Macro_1.scala @@ -4,16 +4,16 @@ import scala.quoted.* @experimental class toString extends MacroAnnotation : - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val toStringSym = Symbol.requiredMethod("java.lang.Object.toString") val toStringOverrideSym = Symbol.newMethod(cls, "toString", toStringSym.info, Flags.Override, Symbol.noSymbol) val toStringDef = DefDef(toStringOverrideSym, _ => Some(Literal(StringConstant("Hello from macro")))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, toStringDef :: body) List(newClassDef) case _ => report.error("@toString can only be annotated on class definitions") - tree :: Nil + definition :: Nil diff --git a/tests/neg-macros/wrong-owner.check b/tests/neg-macros/wrong-owner.check index ca8751d0fe1c..26316d3fc687 100644 --- a/tests/neg-macros/wrong-owner.check +++ b/tests/neg-macros/wrong-owner.check @@ -17,6 +17,6 @@ | |Error: |assertion failed: bad owner; method toString has owner class String, expected was class Foo - |owner chain = method toString, class String, package java.lang, package java, package , ctxOwners = class Foo, class Foo, package , package , package , package , package , package , package , package , package , , , , , + |owner chain = method toString, class String, package java.lang, package java, package , ctxOwners = class Foo, class Foo, package , package , package , package , package , package , package , package , package , package , , , , , | |stacktrace available when compiling with `-Ydebug` diff --git a/tests/neg-macros/wrong-owner/Macro_1.scala b/tests/neg-macros/wrong-owner/Macro_1.scala index 85127b701f81..2e101f849802 100644 --- a/tests/neg-macros/wrong-owner/Macro_1.scala +++ b/tests/neg-macros/wrong-owner/Macro_1.scala @@ -4,16 +4,16 @@ import scala.quoted.* @experimental class wrongOwner extends MacroAnnotation : - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val toStringSym = Symbol.requiredMethod("java.lang.Object.toString") val toStringOverrideSym = Symbol.newMethod(Symbol.classSymbol("java.lang.String"), "toString", toStringSym.info, Flags.Override, Symbol.noSymbol) val toStringDef = DefDef(toStringOverrideSym, _ => Some(Literal(StringConstant("Hello from macro")))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, toStringDef :: body) List(newClassDef) case _ => report.error("@toString can only be annotated on class definitions") - tree :: Nil + definition :: Nil diff --git a/tests/pos-macros/annot-dependency-between-modules/Macro_1.scala b/tests/pos-macros/annot-dependency-between-modules/Macro_1.scala new file mode 100644 index 000000000000..c74fdce2b73d --- /dev/null +++ b/tests/pos-macros/annot-dependency-between-modules/Macro_1.scala @@ -0,0 +1,10 @@ +import scala.annotation.* +import scala.quoted.* + +@experimental +class void extends MacroAnnotation: + def transform(using Quotes)(definition: quotes.reflect.Definition, + companion: Option[quotes.reflect.Definition]) + : List[quotes.reflect.Definition] = + println(s"processing ${definition.show} with companion ${companion.map(_.show)}") + definition +: companion.toList diff --git a/tests/pos-macros/annot-dependency-between-modules/Test_2.scala b/tests/pos-macros/annot-dependency-between-modules/Test_2.scala new file mode 100644 index 000000000000..f809330af52d --- /dev/null +++ b/tests/pos-macros/annot-dependency-between-modules/Test_2.scala @@ -0,0 +1,3 @@ + +@void @void +class Foo \ No newline at end of file diff --git a/tests/pos-macros/annot-in-object/Macro_1.scala b/tests/pos-macros/annot-in-object/Macro_1.scala index 143bd46b8ecc..2086f9ec4cb1 100644 --- a/tests/pos-macros/annot-in-object/Macro_1.scala +++ b/tests/pos-macros/annot-in-object/Macro_1.scala @@ -6,9 +6,11 @@ import scala.quoted._ object Foo: @experimental class void extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + List(definition) object Bar: @experimental class void extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + List(definition) diff --git a/tests/pos-macros/annot-suspend/Macro_1.scala b/tests/pos-macros/annot-suspend/Macro_1.scala index 3c391a1a041f..4ae96186b777 100644 --- a/tests/pos-macros/annot-suspend/Macro_1.scala +++ b/tests/pos-macros/annot-suspend/Macro_1.scala @@ -5,5 +5,5 @@ import scala.quoted._ @experimental class void extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = - List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + List(definition) diff --git a/tests/pos-macros/annot-then-inline/Macro_1.scala b/tests/pos-macros/annot-then-inline/Macro_1.scala index 99fece18299a..f3226e24d4da 100644 --- a/tests/pos-macros/annot-then-inline/Macro_1.scala +++ b/tests/pos-macros/annot-then-inline/Macro_1.scala @@ -5,14 +5,14 @@ import scala.quoted._ @experimental class useInlinedIdentity extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case DefDef(name, params, tpt, Some(rhs)) => val newRhs = - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes '{ inlinedIdentity(${rhs.asExpr}) }.asTerm - List(DefDef.copy(tree)(name, params, tpt, Some(newRhs))) + List(DefDef.copy(definition)(name, params, tpt, Some(newRhs))) } inline def inlinedIdentity(x: Any): x.type = x diff --git a/tests/pos-macros/i19537/Macro_1.scala b/tests/pos-macros/i19537/Macro_1.scala index 932994657d24..a44c212599d3 100644 --- a/tests/pos-macros/i19537/Macro_1.scala +++ b/tests/pos-macros/i19537/Macro_1.scala @@ -3,4 +3,5 @@ import scala.quoted.* @experimental class annotation extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition) = List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + List(definition) diff --git a/tests/pos-macros/i19539/Macro_1.scala b/tests/pos-macros/i19539/Macro_1.scala index 932994657d24..a44c212599d3 100644 --- a/tests/pos-macros/i19539/Macro_1.scala +++ b/tests/pos-macros/i19539/Macro_1.scala @@ -3,4 +3,5 @@ import scala.quoted.* @experimental class annotation extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition) = List(tree) + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + List(definition) diff --git a/tests/pos/macro-annot-with-companion/Macro_1.scala b/tests/pos/macro-annot-with-companion/Macro_1.scala new file mode 100644 index 000000000000..28bde39997f7 --- /dev/null +++ b/tests/pos/macro-annot-with-companion/Macro_1.scala @@ -0,0 +1,15 @@ +import scala.annotation.MacroAnnotation + +import scala.quoted.* + +class transform extends MacroAnnotation: + override def transform(using Quotes) + (tree: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]) + : List[quotes.reflect.Definition] = { + import quotes.reflect.* + tree match + case ClassDef(name, constr, parents, selfOpt, body) => + println(s"tree: ${tree.show} has companion: ${companion.map(_.show)}") + List(tree) + case _ => List(tree) + } \ No newline at end of file diff --git a/tests/pos/macro-annot-with-companion/Test_2.scala b/tests/pos/macro-annot-with-companion/Test_2.scala new file mode 100644 index 000000000000..ddf73334389b --- /dev/null +++ b/tests/pos/macro-annot-with-companion/Test_2.scala @@ -0,0 +1,15 @@ + +@transform +class Foo + +@transform +class Bar + +@transform +object Foo + +@transform +class A + +@transform +object B \ No newline at end of file diff --git a/tests/run-macros/annot-add-global-class/Macro_1.scala b/tests/run-macros/annot-add-global-class/Macro_1.scala index 6ac77913e3ab..a6ebf1c64d9d 100644 --- a/tests/run-macros/annot-add-global-class/Macro_1.scala +++ b/tests/run-macros/annot-add-global-class/Macro_1.scala @@ -8,9 +8,9 @@ import scala.collection.mutable @experimental class addClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), tpt, Some(rhs)) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -25,8 +25,8 @@ class addClass extends MacroAnnotation: val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil) - val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(newCls, runSym), Nil))) + val newDef = DefDef.copy(definition)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(newCls, runSym), Nil))) List(clsDef, newDef) case _ => report.error("Annotation only supports `def` with one argument") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-add-global-object/Macro_1.scala b/tests/run-macros/annot-add-global-object/Macro_1.scala index f7c901a49aa5..c2fe5bbfe9e5 100644 --- a/tests/run-macros/annot-add-global-object/Macro_1.scala +++ b/tests/run-macros/annot-add-global-object/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable @experimental class addClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), tpt, Some(rhs)) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -23,8 +23,8 @@ class addClass extends MacroAnnotation: val modDef = ClassDef.module(mod, parents, body = List(runDef)) - val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil))) + val newDef = DefDef.copy(definition)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil))) modDef.toList ::: newDef :: Nil case _ => report.error("Annotation only supports `def` with one argument") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-add-local-class/Macro_1.scala b/tests/run-macros/annot-add-local-class/Macro_1.scala index 57a2d543ffbc..07f6d98e7c99 100644 --- a/tests/run-macros/annot-add-local-class/Macro_1.scala +++ b/tests/run-macros/annot-add-local-class/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable @experimental class addClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), tpt, Some(rhs)) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -22,8 +22,8 @@ class addClass extends MacroAnnotation: val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil) - val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(newCls, runSym), Nil))) + val newDef = DefDef.copy(definition)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(newCls, runSym), Nil))) List(clsDef, newDef) case _ => report.error("Annotation only supports `def` with one argument") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-add-local-object/Macro_1.scala b/tests/run-macros/annot-add-local-object/Macro_1.scala index 6f6e11e7361c..18534730e16b 100644 --- a/tests/run-macros/annot-add-local-object/Macro_1.scala +++ b/tests/run-macros/annot-add-local-object/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable @experimental class addClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), tpt, Some(rhs)) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -23,8 +23,8 @@ class addClass extends MacroAnnotation: val (modVal, clsDef) = ClassDef.module(mod, parents, body = List(runDef)) - val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil))) + val newDef = DefDef.copy(definition)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil))) List(modVal, clsDef, newDef) case _ => report.error("Annotation only supports `def` with one argument") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-add-nested-class/Macro_1.scala b/tests/run-macros/annot-add-nested-class/Macro_1.scala index e13e3841501a..631e3044a39c 100644 --- a/tests/run-macros/annot-add-nested-class/Macro_1.scala +++ b/tests/run-macros/annot-add-nested-class/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable @experimental class addClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), tpt, Some(rhs)) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -23,8 +23,8 @@ class addClass extends MacroAnnotation: val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil) - val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(newCls, runSym), Nil))) + val newDef = DefDef.copy(definition)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(newCls, runSym), Nil))) List(clsDef, newDef) case _ => report.error("Annotation only supports `def` with one argument") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-add-nested-object/Macro_1.scala b/tests/run-macros/annot-add-nested-object/Macro_1.scala index f8cde8de5bf0..0069a1010a78 100644 --- a/tests/run-macros/annot-add-nested-object/Macro_1.scala +++ b/tests/run-macros/annot-add-nested-object/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable @experimental class addClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), tpt, Some(rhs)) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -23,8 +23,8 @@ class addClass extends MacroAnnotation: val (modVal, clsDef) = ClassDef.module(mod, parents, body = List(runDef)) - val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil))) + val newDef = DefDef.copy(definition)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil))) List(modVal, clsDef, newDef) case _ => report.error("Annotation only supports `def` with one argument") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-annot-order/Macro_1.scala b/tests/run-macros/annot-annot-order/Macro_1.scala index 9d3e8e40c01a..a177225d635f 100644 --- a/tests/run-macros/annot-annot-order/Macro_1.scala +++ b/tests/run-macros/annot-annot-order/Macro_1.scala @@ -5,15 +5,15 @@ import scala.quoted._ @experimental class print(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, params, tpt, Some(rhsTree)) => - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes rhsTree.asExpr match case '{ $rhsExpr: t } => val newRhs = '{ println(${Expr(msg)}); $rhsExpr }.asTerm - List(DefDef.copy(tree)(name, params, tpt, Some(newRhs))) + List(DefDef.copy(definition)(name, params, tpt, Some(newRhs))) case _ => report.error("Annotation only supported on `def`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-bind/Macro_1.scala b/tests/run-macros/annot-bind/Macro_1.scala index 0997f35ccf4a..fd0aaf1343a0 100644 --- a/tests/run-macros/annot-bind/Macro_1.scala +++ b/tests/run-macros/annot-bind/Macro_1.scala @@ -5,15 +5,15 @@ import scala.quoted._ @experimental class bind(str: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ValDef(name, tpt, Some(rhsTree)) => val valSym = Symbol.newVal(Symbol.spliceOwner, Symbol.freshName(str), tpt.tpe, Flags.Private, Symbol.noSymbol) val valDef = ValDef(valSym, Some(rhsTree)) val newRhs = Ref(valSym) - val newTree = ValDef.copy(tree)(name, tpt, Some(newRhs)) + val newTree = ValDef.copy(definition)(name, tpt, Some(newRhs)) List(valDef, newTree) case _ => report.error("Annotation only supported on `val` with a single argument are supported") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-changeVal/Macro_1.scala b/tests/run-macros/annot-changeVal/Macro_1.scala index d55282f8c390..d32cbe85ef35 100644 --- a/tests/run-macros/annot-changeVal/Macro_1.scala +++ b/tests/run-macros/annot-changeVal/Macro_1.scala @@ -7,8 +7,8 @@ import scala.annotation.MacroAnnotation object ChangeVal: @experimental class change(i: Int) extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match - case ValDef(n, t, _) => List(ValDef.copy(tree)(n, t, Some(Literal(IntConstant(i))))) + definition match + case ValDef(n, t, _) => List(ValDef.copy(definition)(n, t, Some(Literal(IntConstant(i))))) } diff --git a/tests/run-macros/annot-concrete-class/Macro_1.scala b/tests/run-macros/annot-concrete-class/Macro_1.scala index e91f9c1ccafe..326b450088e6 100644 --- a/tests/run-macros/annot-concrete-class/Macro_1.scala +++ b/tests/run-macros/annot-concrete-class/Macro_1.scala @@ -5,7 +5,7 @@ import scala.quoted.* class implementAFoo extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(tree: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* tree match case ClassDef(name, cstr, parents, self, body) => diff --git a/tests/run-macros/annot-export/Macro_1.scala b/tests/run-macros/annot-export/Macro_1.scala index fbe97684079b..b135245790ba 100644 --- a/tests/run-macros/annot-export/Macro_1.scala +++ b/tests/run-macros/annot-export/Macro_1.scala @@ -6,10 +6,10 @@ import scala.collection.mutable.Map @experimental class returnClassName extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, params, tpt, _) => val rhs = Literal(StringConstant(Symbol.spliceOwner.name.stripSuffix("$"))) - List(DefDef.copy(tree)(name, params, tpt, Some(rhs))) + List(DefDef.copy(definition)(name, params, tpt, Some(rhs))) } diff --git a/tests/run-macros/annot-gen2/Macro_1.scala b/tests/run-macros/annot-gen2/Macro_1.scala index 05428aac7375..503d6e192cdd 100644 --- a/tests/run-macros/annot-gen2/Macro_1.scala +++ b/tests/run-macros/annot-gen2/Macro_1.scala @@ -5,14 +5,14 @@ import scala.quoted._ @experimental class hello extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, params, tpt, Some(t)) => - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes val rhs = '{ ${t.asExprOf[String]} + "hello" }.asTerm - val newDef = DefDef.copy(tree)(name, params, tpt, Some(rhs)) + val newDef = DefDef.copy(definition)(name, params, tpt, Some(rhs)) List(newDef) } diff --git a/tests/run-macros/annot-gen2/Macro_2.scala b/tests/run-macros/annot-gen2/Macro_2.scala index 3e2e228abb3e..9cb734dfdb00 100644 --- a/tests/run-macros/annot-gen2/Macro_2.scala +++ b/tests/run-macros/annot-gen2/Macro_2.scala @@ -5,11 +5,11 @@ import scala.quoted._ @experimental class foo extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, params, tpt, Some(t)) => - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes val s = Ref(params.head.params.head.symbol).asExprOf[String] val rhs = '{ @hello def foo1(s: String): String = ${ @@ -18,6 +18,6 @@ class foo extends MacroAnnotation { } foo1($s) }.asTerm - val newDef = DefDef.copy(tree)(name, params, tpt, Some(rhs)) + val newDef = DefDef.copy(definition)(name, params, tpt, Some(rhs)) List(newDef) } diff --git a/tests/run-macros/annot-generate/Macro_1.scala b/tests/run-macros/annot-generate/Macro_1.scala index b88cc62afb06..b64d888aab80 100644 --- a/tests/run-macros/annot-generate/Macro_1.scala +++ b/tests/run-macros/annot-generate/Macro_1.scala @@ -5,9 +5,9 @@ import scala.quoted._ @experimental class hello extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ val helloSymbol = Symbol.newVal(Symbol.spliceOwner, Symbol.freshName("hello"), TypeRepr.of[String], Flags.EmptyFlags, Symbol.noSymbol) val helloVal = ValDef(helloSymbol, Some(Literal(StringConstant("Hello, World!")))) - List(helloVal, tree) + List(helloVal, definition) } diff --git a/tests/run-macros/annot-generate/Macro_2.scala b/tests/run-macros/annot-generate/Macro_2.scala index 911625eac645..37c88459e3e1 100644 --- a/tests/run-macros/annot-generate/Macro_2.scala +++ b/tests/run-macros/annot-generate/Macro_2.scala @@ -5,15 +5,15 @@ import scala.quoted._ @experimental class foo extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, params, tpt, Some(t)) => - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes val rhs = '{ @hello def foo(x: Int): Int = x + 1 ${t.asExprOf[Int]} }.asTerm - val newDef = DefDef.copy(tree)(name, params, tpt, Some(rhs)) + val newDef = DefDef.copy(definition)(name, params, tpt, Some(rhs)) List(newDef) } diff --git a/tests/run-macros/annot-macro-main/Macro_1.scala b/tests/run-macros/annot-macro-main/Macro_1.scala index 2a585bee2bc1..4470febe1244 100644 --- a/tests/run-macros/annot-macro-main/Macro_1.scala +++ b/tests/run-macros/annot-macro-main/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable @experimental class mainMacro extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, List(TermParamClause(Nil)), _, _) => val parents = List(TypeTree.of[Object]) def decls(cls: Symbol): List[Symbol] = @@ -17,10 +17,10 @@ class mainMacro extends MacroAnnotation: val cls = Symbol.newClass(Symbol.spliceOwner.owner, name, parents = parents.map(_.tpe), decls, selfType = None) val mainSym = cls.declaredMethod("main").head - val mainDef = DefDef(mainSym, _ => Some(Apply(Ref(tree.symbol), Nil))) + val mainDef = DefDef(mainSym, _ => Some(Apply(Ref(definition.symbol), Nil))) val clsDef = ClassDef(cls, parents, body = List(mainDef)) - List(clsDef, tree) + List(clsDef, definition) case _ => report.error("Annotation only supports `def` without arguments") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-memo/Macro_1.scala b/tests/run-macros/annot-memo/Macro_1.scala index cd990e1d6cce..492f1e337dfb 100644 --- a/tests/run-macros/annot-memo/Macro_1.scala +++ b/tests/run-macros/annot-memo/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.concurrent @experimental class memoize extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, TermParamClause(param :: Nil) :: Nil, tpt, Some(rhsTree)) => (param.tpt.tpe.asType, tpt.tpe.asType) match case ('[t], '[u]) => @@ -19,13 +19,13 @@ class memoize extends MacroAnnotation: '{ concurrent.TrieMap.empty[t, u] }.asTerm val cacheVal = ValDef(cacheSymbol, Some(cacheRhs)) val newRhs = - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes val cacheRefExpr = Ref(cacheSymbol).asExprOf[concurrent.Map[t, u]] val paramRefExpr = Ref(param.symbol).asExprOf[t] val rhsExpr = rhsTree.asExprOf[u] '{ $cacheRefExpr.getOrElseUpdate($paramRefExpr, $rhsExpr) }.asTerm - val newTree = DefDef.copy(tree)(name, TermParamClause(param :: Nil) :: Nil, tpt, Some(newRhs)) + val newTree = DefDef.copy(definition)(name, TermParamClause(param :: Nil) :: Nil, tpt, Some(newRhs)) List(cacheVal, newTree) case _ => report.error("Annotation only supported on `def` with a single argument are supported") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-add-def/Macro_1.scala b/tests/run-macros/annot-mod-class-add-def/Macro_1.scala index 855dce06f279..acd878f7d556 100644 --- a/tests/run-macros/annot-mod-class-add-def/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-add-def/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class addIndirectToString(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val stringMethType = ByNameType.apply(TypeRepr.of[String]) val stringSym = Symbol.newMethod(cls, Symbol.freshName("string"), stringMethType, Flags.Private, Symbol.noSymbol) val stringDef = DefDef(stringSym, _ => Some(Literal(StringConstant(msg)))) @@ -20,9 +20,9 @@ class addIndirectToString(msg: String) extends MacroAnnotation: val toStringDef = DefDef(toStringOverrideSym, _ => Some(Ref(stringSym))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, stringDef :: toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, stringDef :: toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-add-inner-class/Macro_1.scala b/tests/run-macros/annot-mod-class-add-inner-class/Macro_1.scala index 395bfd7a28db..4294e44dd45b 100644 --- a/tests/run-macros/annot-mod-class-add-inner-class/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-add-inner-class/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class addInnerClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol def showClassDecls(showCls: Symbol): List[Symbol] = List(Symbol.newMethod(showCls, "showMe", MethodType(List("x"))(_ => List(cls.typeRef), _ => TypeRepr.of[String]))) @@ -27,9 +27,9 @@ class addInnerClass extends MacroAnnotation: val toStringOverrideSym = Symbol.newMethod(cls, "toString", toStringMethType, Flags.Override, Symbol.noSymbol) val toStringDef = DefDef(toStringOverrideSym, _ => Some(newShowCallShowMe)) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, showClass :: toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, showClass :: toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-add-lazy-val/Macro_1.scala b/tests/run-macros/annot-mod-class-add-lazy-val/Macro_1.scala index f72f28b610d6..c772f6cf43a6 100644 --- a/tests/run-macros/annot-mod-class-add-lazy-val/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-add-lazy-val/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class addMemoToString(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val stringLazyValSym = Symbol.newVal(cls, Symbol.freshName("string"), TypeRepr.of[String], Flags.Lazy | Flags.Private, Symbol.noSymbol) val toStringMethType = Symbol.requiredMethod("java.lang.Object.toString").info @@ -19,9 +19,9 @@ class addMemoToString(msg: String) extends MacroAnnotation: val stringLazyValDef = ValDef(stringLazyValSym, Some(Literal(StringConstant(msg)))) val toStringDef = DefDef(toStringOverrideSym, _ => Some(Ref(stringLazyValSym))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, stringLazyValDef :: toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, stringLazyValDef :: toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-add-local-class/Macro_1.scala b/tests/run-macros/annot-mod-class-add-local-class/Macro_1.scala index 0156812adeb1..50df9e86446d 100644 --- a/tests/run-macros/annot-mod-class-add-local-class/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-add-local-class/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class addInnerClass extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val toStringMethType = Symbol.requiredMethod("java.lang.Object.toString").info val toStringOverrideSym = Symbol.newMethod(cls, "toString", toStringMethType, Flags.Override, Symbol.noSymbol) @@ -28,9 +28,9 @@ class addInnerClass extends MacroAnnotation: val showClass = ClassDef(showClassSym, parents, body = List(showMeDef)) val toStringDef = DefDef(toStringOverrideSym, _ => Some(Block(List(showClass), newShowCallShowMe))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-add-val/Macro_1.scala b/tests/run-macros/annot-mod-class-add-val/Macro_1.scala index fc0294dcb051..cf69949dd8ad 100644 --- a/tests/run-macros/annot-mod-class-add-val/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-add-val/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class addMemoToString(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val stringValSym = Symbol.newVal(cls, Symbol.freshName("string"), TypeRepr.of[String], Flags.Private, Symbol.noSymbol) val toStringMethType = Symbol.requiredMethod("java.lang.Object.toString").info @@ -19,9 +19,9 @@ class addMemoToString(msg: String) extends MacroAnnotation: val stringValDef = ValDef(stringValSym, Some(Literal(StringConstant(msg)))) val toStringDef = DefDef(toStringOverrideSym, _ => Some(Ref(stringValSym))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, stringValDef :: toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, stringValDef :: toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-add-var/Macro_1.scala b/tests/run-macros/annot-mod-class-add-var/Macro_1.scala index be38689613e7..0eb8592accbf 100644 --- a/tests/run-macros/annot-mod-class-add-var/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-add-var/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class addCountToString(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val countVarSym = Symbol.newVal(cls, Symbol.freshName("count"), TypeRepr.of[Int], Flags.Mutable | Flags.Private, Symbol.noSymbol) val toStringMethType = Symbol.requiredMethod("java.lang.Object.toString").info @@ -26,9 +26,9 @@ class addCountToString(msg: String) extends MacroAnnotation: ) )) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, countVarDef :: toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, countVarDef :: toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-data/Macro_1.scala b/tests/run-macros/annot-mod-class-data/Macro_1.scala index a175eb274268..938b4d7d4bd6 100644 --- a/tests/run-macros/annot-mod-class-data/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-data/Macro_1.scala @@ -5,11 +5,11 @@ import scala.quoted.* @experimental class data extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case ClassDef(className, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val constructorParameters = ctr.paramss.collect { case clause: TermParamClause => clause } if constructorParameters.size != 1 || constructorParameters.head.params.isEmpty then @@ -51,10 +51,10 @@ class data extends MacroAnnotation: val equalsOverrideDef = DefDef(equalsOverrideSym, equalsOverrideDefBody) val newBody = toStringDef :: hashCodeOverrideDef :: equalsOverrideDef :: body - List(ClassDef.copy(tree)(className, ctr, parents, self, newBody)) + List(ClassDef.copy(definition)(className, ctr, parents, self, newBody)) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) private def toStringExpr(className: String, thisFields: List[Expr[Any]])(using Quotes): Expr[String] = val fieldsSeq = Expr.ofSeq(thisFields) diff --git a/tests/run-macros/annot-mod-class-equals/Macro_1.scala b/tests/run-macros/annot-mod-class-equals/Macro_1.scala index 10184eada1e2..625598d3911e 100644 --- a/tests/run-macros/annot-mod-class-equals/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-equals/Macro_1.scala @@ -5,11 +5,11 @@ import scala.quoted.* @experimental class equals extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect.* - tree match + definition match case ClassDef(className, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val constructorParameters = ctr.paramss.collect { case clause: TermParamClause => clause } if constructorParameters.size != 1 || constructorParameters.head.params.isEmpty then @@ -42,10 +42,10 @@ class equals extends MacroAnnotation: val hashCodeOverrideDef = DefDef(hashCodeOverrideSym, _ => Some(Ref(hashSym))) val newBody = equalsOverrideDef :: hashVal :: hashCodeOverrideDef :: body - List(ClassDef.copy(tree)(className, ctr, parents, self, newBody)) + List(ClassDef.copy(definition)(className, ctr, parents, self, newBody)) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) private def equalsExpr[T: Type](that: Expr[Any], thisFields: List[Expr[Any]])(using Quotes): Expr[Boolean] = '{ diff --git a/tests/run-macros/annot-mod-class-mod-def/Macro_1.scala b/tests/run-macros/annot-mod-class-mod-def/Macro_1.scala index 7a73b0a773e9..9c28d7427f9c 100644 --- a/tests/run-macros/annot-mod-class-mod-def/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-mod-def/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class modToString(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val toStringSym = cls.methodMember("toString").head val newBody = body.span(_.symbol != toStringSym) match @@ -21,7 +21,7 @@ class modToString(msg: String) extends MacroAnnotation: report.error("toString was not defined") body - List(ClassDef.copy(tree)(name, ctr, parents, self, newBody)) + List(ClassDef.copy(definition)(name, ctr, parents, self, newBody)) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-mod-val/Macro_1.scala b/tests/run-macros/annot-mod-class-mod-val/Macro_1.scala index fda7b5f037d8..0d07a6bd2006 100644 --- a/tests/run-macros/annot-mod-class-mod-val/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-mod-val/Macro_1.scala @@ -6,11 +6,11 @@ import scala.collection.mutable @experimental class setValue(field: String, value: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val valSym = cls.fieldMember(field) val newBody = body.span(_.symbol != valSym) match @@ -21,7 +21,7 @@ class setValue(field: String, value: String) extends MacroAnnotation: report.error(s"`val $field` was not defined") body - List(ClassDef.copy(tree)(name, ctr, parents, self, newBody)) + List(ClassDef.copy(definition)(name, ctr, parents, self, newBody)) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-override-def/Macro_1.scala b/tests/run-macros/annot-mod-class-override-def/Macro_1.scala index e6d7bba79d54..2e9b9356d845 100644 --- a/tests/run-macros/annot-mod-class-override-def/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-override-def/Macro_1.scala @@ -6,19 +6,19 @@ import scala.collection.mutable @experimental class genToString(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val toStringSym = Symbol.requiredMethod("java.lang.Object.toString") val toStringOverrideSym = Symbol.newMethod(cls, "toString", toStringSym.info, Flags.Override, Symbol.noSymbol) val toStringDef = DefDef(toStringOverrideSym, _ => Some(Literal(StringConstant(msg)))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, toStringDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, toStringDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-override-val/Macro_1.scala b/tests/run-macros/annot-mod-class-override-val/Macro_1.scala index d7409a649427..6ec02e349051 100644 --- a/tests/run-macros/annot-mod-class-override-val/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-override-val/Macro_1.scala @@ -6,18 +6,18 @@ import scala.collection.mutable @experimental class overrideField(field: String, value: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val overrideSym = Symbol.newVal(cls, field, TypeRepr.of[String], Flags.Override, Symbol.noSymbol) val valDef = ValDef(overrideSym, Some(Literal(StringConstant(value)))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, valDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, valDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-mod-class-unused-new-sym/Macro_1.scala b/tests/run-macros/annot-mod-class-unused-new-sym/Macro_1.scala index fbcb9049d947..6760714aaa5e 100644 --- a/tests/run-macros/annot-mod-class-unused-new-sym/Macro_1.scala +++ b/tests/run-macros/annot-mod-class-unused-new-sym/Macro_1.scala @@ -6,15 +6,15 @@ import scala.collection.mutable @experimental class newUnusedSymbol extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol val toStringMethType = Symbol.requiredMethod("java.lang.Object.toString").info val toStringOverrideSym = Symbol.newMethod(cls, "toString", toStringMethType, Flags.Override, Symbol.noSymbol) // Test that toStringOverrideSym is not accidentally entered in the class - List(tree) + List(definition) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/annot-result-order/Macro_1.scala b/tests/run-macros/annot-result-order/Macro_1.scala index c81641037b67..cb9121eb8d01 100644 --- a/tests/run-macros/annot-result-order/Macro_1.scala +++ b/tests/run-macros/annot-result-order/Macro_1.scala @@ -5,7 +5,7 @@ import scala.quoted._ @experimental class print(msg: String) extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ def printMsg(msg: String) = val valSym = Symbol.newVal(Symbol.spliceOwner, Symbol.freshName("print"), TypeRepr.of[Unit], Flags.Private, Symbol.noSymbol) @@ -13,4 +13,4 @@ class print(msg: String) extends MacroAnnotation: given Quotes = valSym.asQuotes '{ println(${Expr(msg)}) }.asTerm ValDef(valSym, Some(valRhs)) - List(printMsg(s"before: $msg"), tree, printMsg(s"after: $msg")) + List(printMsg(s"before: $msg"), definition, printMsg(s"after: $msg")) diff --git a/tests/run-macros/annot-simple-fib/Macro_1.scala b/tests/run-macros/annot-simple-fib/Macro_1.scala index e5852d5ce73c..f8a74663f775 100644 --- a/tests/run-macros/annot-simple-fib/Macro_1.scala +++ b/tests/run-macros/annot-simple-fib/Macro_1.scala @@ -6,9 +6,9 @@ import scala.collection.mutable.Map @experimental class memoize extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case DefDef(name, params, tpt, Some(fibTree)) => val cacheName = Symbol.freshName(name + "Cache") val cacheSymbol = Symbol.newVal(Symbol.spliceOwner, cacheName, TypeRepr.of[Map[Int, Int]], Flags.EmptyFlags, Symbol.noSymbol) @@ -17,7 +17,7 @@ class memoize extends MacroAnnotation { '{Map.empty[Int, Int]}.asTerm val cacheVal = ValDef(cacheSymbol, Some(cacheRhs)) val rhs = - given Quotes = tree.symbol.asQuotes + given Quotes = definition.symbol.asQuotes val fibCache = Ref(cacheSymbol).asExprOf[Map[Int, Int]] val n = Ref(params.head.params.head.symbol).asExprOf[Int] '{ @@ -28,6 +28,6 @@ class memoize extends MacroAnnotation { $fibCache($n) = res res }.asTerm - val newFib = DefDef.copy(tree)(name, params, tpt, Some(rhs)) + val newFib = DefDef.copy(definition)(name, params, tpt, Some(rhs)) List(cacheVal, newFib) } diff --git a/tests/run-macros/annot-unrollLast/Macro_1.scala b/tests/run-macros/annot-unrollLast/Macro_1.scala index e220811433e3..bcb2a94d5ac3 100644 --- a/tests/run-macros/annot-unrollLast/Macro_1.scala +++ b/tests/run-macros/annot-unrollLast/Macro_1.scala @@ -12,7 +12,7 @@ class unrollLast extends StaticAnnotation @experimental class unrollHelper extends MacroAnnotation { - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(tree: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ tree match case tree: DefDef => transformDefDef(tree) diff --git a/tests/run-macros/i18806/Macro_1.scala b/tests/run-macros/i18806/Macro_1.scala index 461080b67b95..06ab612ce416 100644 --- a/tests/run-macros/i18806/Macro_1.scala +++ b/tests/run-macros/i18806/Macro_1.scala @@ -3,11 +3,11 @@ import scala.quoted._ @experimental class gen1 extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(definition: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ - tree match + definition match case ClassDef(name, ctr, parents, self, body) => - val cls = tree.symbol + val cls = definition.symbol // val meth = cls.methodMember("foo").head // val fooTpe = cls.typeRef.memberType(meth) @@ -17,8 +17,8 @@ class gen1 extends MacroAnnotation: val fooDef = DefDef(fooOverrideSym, _ => Some(Literal(StringConstant("hi")))) - val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, fooDef :: body) + val newClassDef = ClassDef.copy(definition)(name, ctr, parents, self, fooDef :: body) List(newClassDef) case _ => report.error("Annotation only supports `class`") - List(tree) + List(definition) diff --git a/tests/run-macros/i19676.check b/tests/run-macros/i19676.check new file mode 100644 index 000000000000..a65a1d872879 --- /dev/null +++ b/tests/run-macros/i19676.check @@ -0,0 +1,6 @@ +InPackage: transformed by object +InPackage$: transformed by class +InBlock: transformed by object +InBlock$: transformed by class +InInnerClass: transformed by object +InInnerClass$: transformed by class diff --git a/tests/run-macros/i19676/Macro_1.scala b/tests/run-macros/i19676/Macro_1.scala new file mode 100644 index 000000000000..b815db47a722 --- /dev/null +++ b/tests/run-macros/i19676/Macro_1.scala @@ -0,0 +1,27 @@ +//> using options -experimental -Yno-experimental + +import scala.annotation.MacroAnnotation +import scala.quoted.* + +class companionToString(str: String) extends MacroAnnotation: + + def transform(using Quotes) + (definition: quotes.reflect.Definition, + companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = + + import quotes.reflect.* + companion match + case Some(cls@ClassDef(name, ctr, parents, self, body)) => + val symbol = cls.symbol + val toStringSym = Symbol.requiredMethod("java.lang.Object.toString") + val toStringOverrideSym = Symbol.newMethod(symbol, "toString", toStringSym.info, Flags.Override, Symbol.noSymbol) + val toStringDef = DefDef(toStringOverrideSym, _ => Some(Literal(StringConstant(s"$name: $str")))) + val newCompanion = ClassDef.copy(cls)(name, ctr, parents, self, toStringDef :: body) + List(definition, newCompanion) + case Some(unexpected) => + report.error(s"Unexpected companion: ${unexpected.show}") + List(definition) + case None => + report.error("Companion is not available to transform") + List(definition) + end transform \ No newline at end of file diff --git a/tests/run-macros/i19676/Test_2.scala b/tests/run-macros/i19676/Test_2.scala new file mode 100644 index 000000000000..c7e101a5eb25 --- /dev/null +++ b/tests/run-macros/i19676/Test_2.scala @@ -0,0 +1,36 @@ +//> using options -experimental -Yno-experimental + +@companionToString("transformed by class") +class InPackage + +@companionToString("transformed by object") +object InPackage + +val (cls: Any, obj: Any) = { + + @companionToString("transformed by class") + class InBlock + + @companionToString("transformed by object") + object InBlock + + (new InBlock, InBlock) +} + +object Wrapper { + + @companionToString("transformed by class") + class InInnerClass + + @companionToString("transformed by object") + object InInnerClass + +} + +@main def Test = + println((new InPackage).toString()) + println(InPackage.toString()) + println(cls.toString()) + println(obj.toString()) + println((new Wrapper.InInnerClass).toString()) + println(Wrapper.InInnerClass.toString()) diff --git a/tests/run/quotes-add-erased/Macro_1.scala b/tests/run/quotes-add-erased/Macro_1.scala index 5b95051a3744..66ec1c3642d8 100644 --- a/tests/run/quotes-add-erased/Macro_1.scala +++ b/tests/run/quotes-add-erased/Macro_1.scala @@ -7,7 +7,7 @@ import scala.quoted._ class NewAnnotation extends scala.annotation.Annotation class erasedParamsMethod extends MacroAnnotation: - def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + def transform(using Quotes)(tree: quotes.reflect.Definition, companion: Option[quotes.reflect.Definition]): List[quotes.reflect.Definition] = import quotes.reflect._ tree match case ClassDef(name, ctr, parents, self, body) =>