Skip to content

Commit 543b133

Browse files
committed
Reuse TreeTraverser to traverse all tree children, with explicit exceptions
1 parent 7187197 commit 543b133

File tree

2 files changed

+18
-98
lines changed

2 files changed

+18
-98
lines changed

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,6 +1638,7 @@ object Trees {
16381638

16391639
abstract class TreeTraverser extends TreeAccumulator[Unit] {
16401640
def traverse(tree: Tree)(using Context): Unit
1641+
def traverse(trees: List[Tree])(using Context) = apply((), trees)
16411642
def apply(x: Unit, tree: Tree)(using Context): Unit = traverse(tree)
16421643
protected def traverseChildren(tree: Tree)(using Context): Unit = foldOver((), tree)
16431644
}

compiler/src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 17 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ class TreeChecker extends Phase with SymTransformer {
306306
sym.isEffectivelyErased && sym.is(Private) && !sym.initial.is(Private)
307307

308308
override def typed(tree: untpd.Tree, pt: Type = WildcardType)(using Context): Tree = {
309-
checkTreeNode(tree)
309+
TreeNodeChecker.run(tree)
310310
val tpdTree = super.typed(tree, pt)
311311
Typer.assertPositioned(tree)
312312
if (ctx.erasedTypes)
@@ -648,102 +648,21 @@ object TreeChecker {
648648
}
649649
}.apply(tp0)
650650

651-
private val PrivateErased = allOf(Private, Erased)
652-
653651
/** Check that the tree only contains legal children trees */
654-
def checkTreeNode(tree: untpd.Tree)(implicit ctx: Context): Unit = {
655-
def assertNotTypeTree(t: untpd.Tree): Unit = assert(!t.isInstanceOf[untpd.TypeTree], tree)
656-
657-
// TODO add many more sanity checks
658-
tree match {
659-
// case Ident(name) =>
660-
case Select(qualifier, name) =>
661-
// FIXME this assertion fails only in tests/run/scala2trait-lazyval.scala
662-
// assertNotTypeTree(qual)
663-
// case This(qual) =>
664-
//
665-
// case Super(qual, mix) =>
666-
case Apply(fun, args) =>
667-
assertNotTypeTree(fun)
668-
for (arg <- args) {
669-
assertNotTypeTree(arg)
670-
}
671-
case TypeApply(fun, args) =>
672-
assertNotTypeTree(fun)
673-
// case Literal(const) =>
674-
//
675-
// case New(tpt) =>
676-
case Typed(expr, tpt) =>
677-
assertNotTypeTree(expr)
678-
// case NamedArg(name, arg) =>
679-
case Assign(lhs, rhs) =>
680-
assertNotTypeTree(lhs)
681-
assertNotTypeTree(rhs)
682-
case Block(stats, expr) =>
683-
for (stat <- stats) {
684-
assertNotTypeTree(stat)
685-
}
686-
assertNotTypeTree(expr)
687-
case If(cond, thenp, elsep) =>
688-
assertNotTypeTree(cond)
689-
assertNotTypeTree(thenp)
690-
assertNotTypeTree(elsep)
691-
// case Closure(env, meth, tpt) =>
692-
case Match(selector, cases) =>
693-
assertNotTypeTree(selector)
694-
case CaseDef(pat, guard, body) =>
695-
assertNotTypeTree(guard)
696-
assertNotTypeTree(body)
697-
case Return(expr, from) =>
698-
assertNotTypeTree(expr)
699-
case Try(block, handler, finalizer) =>
700-
assertNotTypeTree(block)
701-
assertNotTypeTree(finalizer)
702-
case SeqLiteral(elems, elemtpt) =>
703-
for (elem <- elems) {
704-
assertNotTypeTree(elem)
705-
}
706-
case Inlined(call, bindings, expansion) =>
707-
assertNotTypeTree(call)
708-
// case TypeTree() =>
709-
//
710-
// case SingletonTypeTree(ref) =>
711-
//
712-
// case AndTypeTree(left, right) =>
713-
//
714-
// case OrTypeTree(left, right) =>
715-
//
716-
// case RefinedTypeTree(tpt, refinements) =>
717-
//
718-
// case AppliedTypeTree(tpt, args) =>
719-
//
720-
// case LambdaTypeTree(tparams, body) =>
721-
//
722-
// case ByNameTypeTree(result) =>
723-
//
724-
// case TypeBoundsTree(lo, hi) =>
725-
//
726-
// case Bind(name, body) =>
727-
//
728-
// case Alternative(trees) =>
729-
//
730-
// case UnApply(fun, implicits, patterns) =>
731-
case tree @ ValDef(name, tpt, _) =>
732-
assertNotTypeTree(tree.rhs)
733-
case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
734-
assertNotTypeTree(tree.rhs)
735-
// case TypeDef(name, rhs) =>
736-
//
737-
// case tree @ Template(constr, parents, self, _) =>
738-
//
739-
// case Import(expr, selectors) =>
740-
//
741-
// case PackageDef(pid, stats) =>
742-
//
743-
// case Annotated(arg, annot) =>
744-
//
745-
// case Thicket(ts) =>
746-
case _ =>
747-
}
748-
}
652+
object TreeNodeChecker extends untpd.TreeTraverser:
653+
import untpd._
654+
def run(tree: Tree)(using Context) = if !tree.isInstanceOf[TypeTree] then traverse(tree)
655+
def traverse(tree: Tree)(using Context) = tree match
656+
case t: TypeTree => assert(assertion = false, t)
657+
case t @ TypeApply(fun, _targs) => traverse(fun)
658+
case t @ New(_tpt) =>
659+
case t @ Typed(expr, _tpt) => traverse(expr)
660+
case t @ Closure(env, meth, _tpt) => traverse(env); traverse(meth)
661+
case t @ SeqLiteral(elems, _elemtpt) => traverse(elems)
662+
case t @ ValDef(_, _tpt, _) => traverse(t.rhs)
663+
case t @ DefDef(_, paramss, _tpt, _) => for params <- paramss do traverse(params); traverse(t.rhs)
664+
case t @ TypeDef(_, _rhs) =>
665+
case t @ Template(constr, _parents, self, _) => traverse(constr); traverse(self); traverse(t.body)
666+
case t => traverseChildren(t)
667+
end traverse
749668
}

0 commit comments

Comments
 (0)