@@ -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,14 @@ 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
+ enterMissingSymbols(prefixedTree)
65
+ for suffixedTree <- suffixed do
66
+ checkMacroDef(suffixedTree, tree, annot)
67
+ enterMissingSymbols(suffixedTree)
68
+ TreeChecker .checkMacroGeneratedTree(tree, newTree)
69
+ enterMissingSymbols(newTree)
64
70
newTree
65
71
case (Nil , Nil ) =>
66
72
report.error(i " Unexpected `Nil` returned by `( ${annot.tree}).transform(..)` during macro expansion " , annot.tree.srcPos)
@@ -120,7 +126,7 @@ class MacroAnnotations:
120
126
121
127
/** Check that this tree can be added by the macro annotation */
122
128
private def checkMacroDef (newTree : DefTree , annotatedTree : Tree , annot : Annotation )(using Context ) =
123
- transform. TreeChecker .checkMacroGeneratedTree(annotatedTree, newTree)
129
+ TreeChecker .checkMacroGeneratedTree(annotatedTree, newTree)
124
130
val sym = newTree.symbol
125
131
val annotated = annotatedTree.symbol
126
132
if sym.isType && ! sym.isClass then
@@ -130,6 +136,20 @@ class MacroAnnotations:
130
136
else if annotated.isClass && annotated.owner.is(Package ) /* && !sym.isClass*/ then
131
137
report.error(i " macro annotation can not add top-level ${sym.showKind}. $annot tried to add $sym. " , annot.tree)
132
138
139
+ private def enterMissingSymbols (tree : MemberDef )(using Context ) = new TreeTraverser {
140
+ def traverse (tree : tpd.Tree )(using Context ): Unit = tree match
141
+ case tdef @ TypeDef (_, template : Template ) =>
142
+ // for tree <- template.constr :: template.body do
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}" )
147
+ else if ! isSymbolInDecls(tree.symbol) then
148
+ tree.symbol.enteredAfter(phase)
149
+ traverseChildren(tree) // Taverse before or after dealing with this class?
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