-
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 58fe2ac
Showing
75 changed files
with
630 additions
and
350 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
76 changes: 76 additions & 0 deletions
76
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,76 @@ | ||
package dotty.tools.dotc | ||
package ast | ||
|
||
import tpd.* | ||
import core.Contexts.* | ||
import core.Symbols.* | ||
import util.Property | ||
|
||
import scala.collection.mutable | ||
|
||
// 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 | ||
|
||
abstract class TreeMapWithTrackedStats extends TreeMapWithImplicits: | ||
|
||
import TreeMapWithTrackedStats.* | ||
|
||
/** Fetch the corresponding tracked tree for a given symbol */ | ||
protected final def getTracked(sym: Symbol)(using Context): Option[MemberDef] = | ||
for trees <- ctx.property(TrackedTrees) | ||
tree <- trees.get(sym) | ||
yield tree | ||
|
||
/** Update the tracked trees */ | ||
protected final def updateTracked(tree: Tree)(using Context): Tree = | ||
tree match | ||
case tree: MemberDef => | ||
trackedTrees.update(tree.symbol, tree) | ||
tree | ||
case _ => tree | ||
end updateTracked | ||
|
||
/** Process a list of trees and give the priority to trakced trees */ | ||
private final def withUpdatedTrackedTrees(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) => | ||
inContext(trackedDefinitionsCtx(stats)): // Step I: Collect and memoize all the definition trees | ||
// Step II: Transform the tree | ||
val pkg@PackageDef(pid, stats) = super.transform(tree): @unchecked | ||
// Step III: Reconcile between the symbols in syms and the tree | ||
cpy.PackageDef(pkg)(pid = pid, stats = withUpdatedTrackedTrees(stats)) | ||
case block: Block => | ||
inContext(trackedDefinitionsCtx(block.stats)): // Step I: Collect all the member definitions in the block | ||
// Step II: Transform the tree | ||
val b@Block(stats, expr) = super.transform(tree): @unchecked | ||
// Step III: Reconcile between the symbols in syms and the tree | ||
cpy.Block(b)(expr = expr, stats = withUpdatedTrackedTrees(stats)) | ||
case TypeDef(_, impl: Template) => | ||
inContext(trackedDefinitionsCtx(impl.body)): // Step I: Collect and memoize all the stats | ||
// Step II: Transform the tree | ||
val newTree@TypeDef(name, impl: Template) = super.transform(tree): @unchecked | ||
// Step III: Reconcile between the symbols in syms and the tree | ||
cpy.TypeDef(newTree)(rhs = cpy.Template(impl)(body = withUpdatedTrackedTrees(impl.body))) | ||
case _ => super.transform(tree) | ||
|
||
end TreeMapWithTrackedStats | ||
|
||
object TreeMapWithTrackedStats: | ||
private val TrackedTrees = new Property.Key[mutable.Map[Symbol, tpd.MemberDef]] | ||
|
||
/** Fetch the tracked trees in the cuurent context */ | ||
private def trackedTrees(using Context): mutable.Map[Symbol, MemberDef] = | ||
ctx.property(TrackedTrees).get | ||
|
||
/** Build a context and track the provided MemberDef trees */ | ||
private def trackedDefinitionsCtx(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.