-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add transparent methods - untyped trees version #4616
Changes from all commits
bba562a
8b70e37
44a5de1
9d7fff9
f8f82e1
34bc5c4
d7a3430
097043f
4aeeed6
5896f28
dc5c3a0
de8f2fd
632abc1
cbb7573
b7f8302
67e9fef
8e5eaca
8fe1a0e
812d22d
bdf2b54
b666323
a125c67
e96c20f
a019a4e
31f6db7
7f48ed1
19aa394
dd29dc6
25a2cc9
1f12ce2
33e60bc
8d03e44
9bee4c0
dea6772
6f65a20
e78fc79
cd87085
3b98431
4b7a240
e4a7e60
22d6f66
59ede6d
2336ae1
ed7f10c
dbaf124
44feda7
57853b0
0b7710a
beca150
39cd368
5d84486
1112b5e
1e9e474
e486384
33523d1
43f4b55
bf5e9c8
101daf5
52e0560
d827f65
3bee284
88e7d18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -589,6 +589,7 @@ object Trees { | |
case class Inlined[-T >: Untyped] private[ast] (call: tpd.Tree, bindings: List[MemberDef[T]], expansion: Tree[T]) | ||
extends Tree[T] { | ||
type ThisTree[-T >: Untyped] = Inlined[T] | ||
override def initialPos = call.pos | ||
} | ||
|
||
/** A type tree that represents an existing or inferred type */ | ||
|
@@ -922,6 +923,11 @@ object Trees { | |
case ys => Thicket(ys) | ||
} | ||
|
||
/** Extractor for the synthetic scrutinee tree of an implicit match */ | ||
object ImplicitScrutinee { | ||
def apply() = Ident(nme.IMPLICITkw) | ||
def unapply(id: Ident): Boolean = id.name == nme.IMPLICITkw && !id.isInstanceOf[BackquotedIdent] | ||
} | ||
// ----- Helper classes for copying, transforming, accumulating ----------------- | ||
|
||
val cpy: TreeCopier | ||
|
@@ -1109,6 +1115,10 @@ object Trees { | |
case tree: Annotated if (arg eq tree.arg) && (annot eq tree.annot) => tree | ||
case _ => finalize(tree, untpd.Annotated(arg, annot)) | ||
} | ||
def UntypedSplice(tree: Tree)(splice: untpd.Tree) = tree match { | ||
case tree: tpd.UntypedSplice if tree.splice `eq` splice => tree | ||
case _ => finalize(tree, tpd.UntypedSplice(splice)) | ||
} | ||
def Thicket(tree: Tree)(trees: List[Tree]): Thicket = tree match { | ||
case tree: Thicket if trees eq tree.trees => tree | ||
case _ => finalize(tree, untpd.Thicket(trees)) | ||
|
@@ -1146,7 +1156,7 @@ object Trees { | |
*/ | ||
protected def inlineContext(call: Tree)(implicit ctx: Context): Context = ctx | ||
|
||
abstract class TreeMap(val cpy: TreeCopier = inst.cpy) { | ||
abstract class TreeMap(val cpy: TreeCopier = inst.cpy) { self => | ||
|
||
def transform(tree: Tree)(implicit ctx: Context): Tree = { | ||
Stats.record(s"TreeMap.transform $getClass") | ||
|
@@ -1245,8 +1255,8 @@ object Trees { | |
case Thicket(trees) => | ||
val trees1 = transform(trees) | ||
if (trees1 eq trees) tree else Thicket(trees1) | ||
case _ if ctx.reporter.errorsReported => | ||
tree | ||
case _ => | ||
transformMoreCases(tree) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was there a specific reason to add it as an extra method? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Performance. If we add a rare case, we only override |
||
} | ||
} | ||
|
||
|
@@ -1258,9 +1268,26 @@ object Trees { | |
transform(tree).asInstanceOf[Tr] | ||
def transformSub[Tr <: Tree](trees: List[Tr])(implicit ctx: Context): List[Tr] = | ||
transform(trees).asInstanceOf[List[Tr]] | ||
|
||
protected def transformMoreCases(tree: Tree)(implicit ctx: Context): Tree = tree match { | ||
case tpd.UntypedSplice(usplice) => | ||
// For a typed tree map: homomorphism on the untyped part with | ||
// recursive mapping of typed splices. | ||
// The case is overridden in UntypedTreeMap.## | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, why define this case here instead of in TypedTreeMap? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no |
||
val untpdMap = new untpd.UntypedTreeMap { | ||
override def transform(tree: untpd.Tree)(implicit ctx: Context): untpd.Tree = tree match { | ||
case untpd.TypedSplice(tsplice) => | ||
untpd.cpy.TypedSplice(tree)(self.transform(tsplice).asInstanceOf[tpd.Tree]) | ||
// the cast is safe, since the UntypedSplice case is overridden in UntypedTreeMap. | ||
case _ => super.transform(tree) | ||
} | ||
} | ||
cpy.UntypedSplice(tree)(untpdMap.transform(usplice)) | ||
case _ if ctx.reporter.errorsReported => tree | ||
} | ||
} | ||
|
||
abstract class TreeAccumulator[X] { | ||
abstract class TreeAccumulator[X] { self => | ||
// Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. | ||
def apply(x: X, tree: Tree)(implicit ctx: Context): X | ||
|
||
|
@@ -1355,14 +1382,29 @@ object Trees { | |
this(this(x, arg), annot) | ||
case Thicket(ts) => | ||
this(x, ts) | ||
case _ if ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive) => | ||
// In interactive mode, errors might come from previous runs. | ||
// In case of errors it may be that typed trees point to untyped ones. | ||
// The IDE can still traverse inside such trees, either in the run where errors | ||
// are reported, or in subsequent ones. | ||
x | ||
case _ => | ||
foldMoreCases(x, tree) | ||
} | ||
} | ||
|
||
def foldMoreCases(x: X, tree: Tree)(implicit ctx: Context): X = tree match { | ||
case tpd.UntypedSplice(usplice) => | ||
// For a typed tree accumulator: skip the untyped part and fold all typed splices. | ||
// The case is overridden in UntypedTreeAccumulator. | ||
val untpdAcc = new untpd.UntypedTreeAccumulator[X] { | ||
override def apply(x: X, tree: untpd.Tree)(implicit ctx: Context): X = tree match { | ||
case untpd.TypedSplice(tsplice) => self(x, tsplice) | ||
case _ => foldOver(x, tree) | ||
} | ||
} | ||
untpdAcc(x, usplice) | ||
case _ if ctx.reporter.errorsReported || ctx.mode.is(Mode.Interactive) => | ||
// In interactive mode, errors might come from previous runs. | ||
// In case of errors it may be that typed trees point to untyped ones. | ||
// The IDE can still traverse inside such trees, either in the run where errors | ||
// are reported, or in subsequent ones. | ||
x | ||
} | ||
} | ||
|
||
abstract class TreeTraverser extends TreeAccumulator[Unit] { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a less complete version of what
tpd.desugarIdentPrefix
doesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.