@@ -9,7 +9,7 @@ import dotty.tools.dotc.config.Printers.{macroAnnot => debug}
9
9
import dotty .tools .dotc .core .Annotations .*
10
10
import dotty .tools .dotc .core .Contexts .*
11
11
import dotty .tools .dotc .core .Decorators .*
12
- import dotty .tools .dotc .core .DenotTransformers .DenotTransformer
12
+ import dotty .tools .dotc .core .DenotTransformers .IdentityDenotTransformer
13
13
import dotty .tools .dotc .core .Flags .*
14
14
import dotty .tools .dotc .core .MacroClassLoader
15
15
import dotty .tools .dotc .core .Symbols .*
@@ -23,7 +23,8 @@ import scala.util.control.NonFatal
23
23
24
24
import java .lang .reflect .InvocationTargetException
25
25
26
- class MacroAnnotations :
26
+ class MacroAnnotations (phase : IdentityDenotTransformer ):
27
+
27
28
import tpd .*
28
29
import MacroAnnotations .*
29
30
@@ -58,9 +59,11 @@ class MacroAnnotations:
58
59
case (prefixed, newTree :: suffixed) =>
59
60
allTrees ++= prefixed
60
61
insertedAfter = suffixed :: insertedAfter
61
- prefixed.foreach(checkMacroDef(_, tree, annot))
62
- suffixed.foreach(checkMacroDef(_, tree, annot))
63
- transform.TreeChecker .checkMacroGeneratedTree(tree, newTree)
62
+ for prefixedTree <- prefixed do
63
+ checkMacroDef(prefixedTree, tree, annot)
64
+ for suffixedTree <- suffixed do
65
+ checkMacroDef(suffixedTree, tree, annot)
66
+ TreeChecker .checkMacroGeneratedTree(tree, newTree)
64
67
newTree
65
68
case (Nil , Nil ) =>
66
69
report.error(i " Unexpected `Nil` returned by `( ${annot.tree}).transform(..)` during macro expansion " , annot.tree.srcPos)
@@ -76,6 +79,7 @@ class MacroAnnotations:
76
79
insertedAfter.foreach(allTrees.++= )
77
80
78
81
val result = allTrees.result()
82
+ for tree <- result do enterMissingSymbols(tree)
79
83
debug.println(result.map(_.show).mkString(" expanded to:\n " , " \n " , " " ))
80
84
result
81
85
@@ -120,7 +124,7 @@ class MacroAnnotations:
120
124
121
125
/** Check that this tree can be added by the macro annotation */
122
126
private def checkMacroDef (newTree : DefTree , annotatedTree : Tree , annot : Annotation )(using Context ) =
123
- transform. TreeChecker .checkMacroGeneratedTree(annotatedTree, newTree)
127
+ TreeChecker .checkMacroGeneratedTree(annotatedTree, newTree)
124
128
val sym = newTree.symbol
125
129
val annotated = annotatedTree.symbol
126
130
if sym.isType && ! sym.isClass then
@@ -130,6 +134,22 @@ class MacroAnnotations:
130
134
else if annotated.isClass && annotated.owner.is(Package ) /* && !sym.isClass*/ then
131
135
report.error(i " macro annotation can not add top-level ${sym.showKind}. $annot tried to add $sym. " , annot.tree)
132
136
137
+ /**
138
+ * Enter the symbols generated by MacroAnnotations
139
+ */
140
+ private def enterMissingSymbols (tree : DefTree )(using Context ) = new TreeTraverser {
141
+ def traverse (tree : tpd.Tree )(using Context ): Unit = tree match
142
+ case tdef @ TypeDef (_, template : Template ) =>
143
+ val isSymbolInDecls = tdef.symbol.asClass.info.decls.toList.toSet
144
+ for tree <- template.body do
145
+ if tree.symbol.owner != tdef.symbol then
146
+ report.error(em " Macro added a definition with the wrong owner - ${tree.symbol.owner} - ${tdef.symbol} in ${tree.source}" , tree.srcPos)
147
+ else if ! isSymbolInDecls(tree.symbol) then
148
+ tree.symbol.enteredAfter(phase)
149
+ traverseChildren(tree)
150
+ case _ => traverseChildren(tree)
151
+ }.traverse(tree)
152
+
133
153
object MacroAnnotations :
134
154
135
155
/** Is this an annotation that implements `scala.annation.MacroAnnotation` */
0 commit comments