-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for companion in MacroAnnotations
- Loading branch information
1 parent
54d67e0
commit 2cbc56f
Showing
74 changed files
with
637 additions
and
347 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
compiler/src/dotty/tools/dotc/ast/TreeMapWithTrackedStats.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package dotty.tools.dotc | ||
package ast | ||
|
||
import tpd.* | ||
import core.Contexts.* | ||
import core.Symbols.* | ||
import util.Property | ||
|
||
import scala.collection.mutable | ||
|
||
abstract class TreeMapWithTrackedStats extends TreeMapWithImplicits: | ||
|
||
import TreeMapWithTrackedStats.* | ||
|
||
// 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 | ||
|
||
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(tree: Tree)(using Context): Tree = | ||
tree match | ||
case tree: MemberDef => | ||
trackedTrees.update(tree.symbol, tree) | ||
tree | ||
case _ => tree | ||
end updateTracked | ||
|
||
private final def withUpdatedTree(stats: List[Tree])(using Context) = | ||
val trackedTrees = TreeMapWithTrackedStats.trackedTrees | ||
stats.mapConserve: | ||
case tree: MemberDef if trackedTrees.contains(tree.symbol) => | ||
trackedTrees(tree.symbol) | ||
case stat => stat | ||
|
||
override def transform(tree: Tree)(using Context): Tree = | ||
tree match | ||
case PackageDef(_, stats) => | ||
// Step I: Collect and memoize all the stats | ||
inContext(trackedTreesCtx(stats)): | ||
// Step II: Transform the tree | ||
val result = super.transform(tree) | ||
// Step III: Reconcile between the symbols in syms and the tree | ||
(result: @unchecked) match | ||
case pkg@PackageDef(pid, stats) => | ||
cpy.PackageDef(pkg)(pid = pid, stats = withUpdatedTree(stats)) | ||
case block: Block => | ||
// Step I: Collect all the member definitions in the block | ||
inContext(trackedTreesCtx(block.stats)): | ||
// Step II: Transform the tree | ||
val result = super.transform(tree) | ||
// Step III: Reconcile between the symbols in syms and the tree | ||
(result: @unchecked) match | ||
case b@Block(stats, expr) => | ||
cpy.Block(b)(expr = expr, stats = withUpdatedTree(stats)) | ||
case TypeDef(_, impl: Template) => | ||
// Step I: Collect and memoize all the stats | ||
inContext(trackedTreesCtx(impl.body)): | ||
// Step II: Transform the tree | ||
val result = super.transform(tree) | ||
// Step III: Reconcile between the symbols in syms and the tree | ||
(result : @unchecked) match | ||
case tree@TypeDef(name, impl: Template) => | ||
cpy.TypeDef(tree)(rhs = cpy.Template(impl)(body = withUpdatedTree(impl.body))) | ||
case _ => super.transform(tree) | ||
|
||
end TreeMapWithTrackedStats | ||
|
||
object TreeMapWithTrackedStats: | ||
private val TrackedTrees = new Property.Key[mutable.Map[Symbol, tpd.MemberDef]] | ||
|
||
private def trackedTrees(using Context): mutable.Map[Symbol, MemberDef] = | ||
ctx.property(TrackedTrees).get | ||
|
||
private def trackedTreesCtx(stats: List[Tree])(using Context): Context = | ||
val treesToTrack = stats.collect { case m: MemberDef => (m.symbol, m) } | ||
ctx.fresh.setProperty(TrackedTrees, mutable.Map(treesToTrack*)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.