@@ -1109,6 +1109,10 @@ object Trees {
1109
1109
case tree : Annotated if (arg eq tree.arg) && (annot eq tree.annot) => tree
1110
1110
case _ => finalize(tree, untpd.Annotated (arg, annot))
1111
1111
}
1112
+ def UntypedSplice (tree : Tree )(splice : untpd.Tree ) = tree match {
1113
+ case tree : tpd.UntypedSplice if tree.splice `eq` splice => tree
1114
+ case _ => finalize(tree, tpd.UntypedSplice (splice))
1115
+ }
1112
1116
def Thicket (tree : Tree )(trees : List [Tree ]): Thicket = tree match {
1113
1117
case tree : Thicket if trees eq tree.trees => tree
1114
1118
case _ => finalize(tree, untpd.Thicket (trees))
@@ -1146,10 +1150,7 @@ object Trees {
1146
1150
*/
1147
1151
protected def inlineContext (call : Tree )(implicit ctx : Context ): Context = ctx
1148
1152
1149
- abstract class TreeMap (val cpy : TreeCopier = inst.cpy) {
1150
-
1151
- protected def handleMoreCases (tree : Tree )(implicit ctx : Context ): Tree =
1152
- if (ctx.reporter.errorsReported) tree else throw new MatchError (tree)
1153
+ abstract class TreeMap (val cpy : TreeCopier = inst.cpy) { self =>
1153
1154
1154
1155
def transform (tree : Tree )(implicit ctx : Context ): Tree = {
1155
1156
Stats .record(s " TreeMap.transform $getClass" )
@@ -1249,7 +1250,7 @@ object Trees {
1249
1250
val trees1 = transform(trees)
1250
1251
if (trees1 eq trees) tree else Thicket (trees1)
1251
1252
case _ =>
1252
- handleMoreCases (tree)
1253
+ transformMoreCases (tree)
1253
1254
}
1254
1255
}
1255
1256
@@ -1261,9 +1262,26 @@ object Trees {
1261
1262
transform(tree).asInstanceOf [Tr ]
1262
1263
def transformSub [Tr <: Tree ](trees : List [Tr ])(implicit ctx : Context ): List [Tr ] =
1263
1264
transform(trees).asInstanceOf [List [Tr ]]
1265
+
1266
+ protected def transformMoreCases (tree : Tree )(implicit ctx : Context ): Tree = tree match {
1267
+ case tpd.UntypedSplice (usplice) =>
1268
+ // For a typed tree map: homomorphism on the untyped part with
1269
+ // recursive mapping of typed splices.
1270
+ // The case is overridden in UntypedTreeMap.##
1271
+ val untpdMap = new untpd.UntypedTreeMap {
1272
+ override def transform (tree : untpd.Tree )(implicit ctx : Context ): untpd.Tree = tree match {
1273
+ case untpd.TypedSplice (tsplice) =>
1274
+ untpd.cpy.TypedSplice (tree)(self.transform(tsplice).asInstanceOf [tpd.Tree ])
1275
+ // the cast is safe, since the UntypedSplice case is overridden in UntypedTreeMap.
1276
+ case _ => super .transform(tree)
1277
+ }
1278
+ }
1279
+ cpy.UntypedSplice (tree)(untpdMap.transform(usplice))
1280
+ case _ if ctx.reporter.errorsReported => tree
1281
+ }
1264
1282
}
1265
1283
1266
- abstract class TreeAccumulator [X ] {
1284
+ abstract class TreeAccumulator [X ] { self =>
1267
1285
// Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node.
1268
1286
def apply (x : X , tree : Tree )(implicit ctx : Context ): X
1269
1287
@@ -1358,14 +1376,29 @@ object Trees {
1358
1376
this (this (x, arg), annot)
1359
1377
case Thicket (ts) =>
1360
1378
this (x, ts)
1361
- case _ if ctx.reporter.errorsReported || ctx.mode.is(Mode .Interactive ) =>
1362
- // In interactive mode, errors might come from previous runs.
1363
- // In case of errors it may be that typed trees point to untyped ones.
1364
- // The IDE can still traverse inside such trees, either in the run where errors
1365
- // are reported, or in subsequent ones.
1366
- x
1379
+ case _ =>
1380
+ foldMoreCases(x, tree)
1367
1381
}
1368
1382
}
1383
+
1384
+ def foldMoreCases (x : X , tree : Tree )(implicit ctx : Context ): X = tree match {
1385
+ case tpd.UntypedSplice (usplice) =>
1386
+ // For a typed tree accumulator: skip the untyped part and fold all typed splices.
1387
+ // The case is overridden in UntypedTreeAccumulator.
1388
+ val untpdAcc = new untpd.UntypedTreeAccumulator [X ] {
1389
+ override def apply (x : X , tree : untpd.Tree )(implicit ctx : Context ): X = tree match {
1390
+ case untpd.TypedSplice (tsplice) => self(x, tsplice)
1391
+ case _ => foldOver(x, tree)
1392
+ }
1393
+ }
1394
+ untpdAcc(x, usplice)
1395
+ case _ if ctx.reporter.errorsReported || ctx.mode.is(Mode .Interactive ) =>
1396
+ // In interactive mode, errors might come from previous runs.
1397
+ // In case of errors it may be that typed trees point to untyped ones.
1398
+ // The IDE can still traverse inside such trees, either in the run where errors
1399
+ // are reported, or in subsequent ones.
1400
+ x
1401
+ }
1369
1402
}
1370
1403
1371
1404
abstract class TreeTraverser extends TreeAccumulator [Unit ] {
0 commit comments