@@ -42,10 +42,6 @@ class TreeChecker extends Phase with SymTransformer {
4242 private val seenClasses = collection.mutable.HashMap [String , Symbol ]()
4343 private val seenModuleVals = collection.mutable.HashMap [String , Symbol ]()
4444
45- def isValidJVMName (name : Name ): Boolean = name.toString.forall(isValidJVMChar)
46-
47- def isValidJVMMethodName (name : Name ): Boolean = name.toString.forall(isValidJVMMethodChar)
48-
4945 val NoSuperClassFlags : FlagSet = Trait | Package
5046
5147 def testDuplicate (sym : Symbol , registry : mutable.Map [String , Symbol ], typ : String )(using Context ): Unit = {
@@ -150,7 +146,78 @@ class TreeChecker extends Phase with SymTransformer {
150146 }
151147 }
152148
149+ /**
150+ * Checks that `New` nodes are always wrapped inside `Select` nodes.
151+ */
152+ def assertSelectWrapsNew (tree : Tree )(using Context ): Unit =
153+ (new TreeAccumulator [tpd.Tree ] {
154+ override def apply (parent : Tree , tree : Tree )(using Context ): Tree = {
155+ tree match {
156+ case tree : New if ! parent.isInstanceOf [tpd.Select ] =>
157+ assert(assertion = false , i " `New` node must be wrapped in a `Select`: \n parent = ${parent.show}\n child = ${tree.show}" )
158+ case _ : Annotated =>
159+ // Don't check inside annotations, since they're allowed to contain
160+ // somewhat invalid trees.
161+ case _ =>
162+ foldOver(tree, tree) // replace the parent when folding over the children
163+ }
164+ parent // return the old parent so that my siblings see it
165+ }
166+ })(tpd.EmptyTree , tree)
167+ }
168+
169+ object TreeChecker {
170+ /** - Check that TypeParamRefs and MethodParams refer to an enclosing type.
171+ * - Check that all type variables are instantiated.
172+ */
173+ def checkNoOrphans (tp0 : Type , tree : untpd.Tree = untpd.EmptyTree )(using Context ): Type = new TypeMap () {
174+ val definedBinders = new java.util.IdentityHashMap [Type , Any ]
175+ def apply (tp : Type ): Type = {
176+ tp match {
177+ case tp : BindingType =>
178+ definedBinders.put(tp, tp)
179+ mapOver(tp)
180+ definedBinders.remove(tp)
181+ case tp : ParamRef =>
182+ assert(definedBinders.get(tp.binder) != null , s " orphan param: ${tp.show}, hash of binder = ${System .identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0" )
183+ case tp : TypeVar =>
184+ assert(tp.isInstantiated, s " Uninstantiated type variable: ${tp.show}, tree = ${tree.show}" )
185+ apply(tp.underlying)
186+ case _ =>
187+ mapOver(tp)
188+ }
189+ tp
190+ }
191+ }.apply(tp0)
192+
193+ /** Run some additional checks on the nodes of the trees. Specifically:
194+ *
195+ * - TypeTree can only appear in TypeApply args, New, Typed tpt, Closure
196+ * tpt, SeqLiteral elemtpt, ValDef tpt, DefDef tpt, and TypeDef rhs.
197+ */
198+ object TreeNodeChecker extends untpd.TreeTraverser :
199+ import untpd ._
200+ def traverse (tree : Tree )(using Context ) = tree match
201+ case t : TypeTree => assert(assertion = false , i " TypeTree not expected: $t" )
202+ case t @ TypeApply (fun, _targs) => traverse(fun)
203+ case t @ New (_tpt) =>
204+ case t @ Typed (expr, _tpt) => traverse(expr)
205+ case t @ Closure (env, meth, _tpt) => traverse(env); traverse(meth)
206+ case t @ SeqLiteral (elems, _elemtpt) => traverse(elems)
207+ case t @ ValDef (_, _tpt, _) => traverse(t.rhs)
208+ case t @ DefDef (_, paramss, _tpt, _) => for params <- paramss do traverse(params); traverse(t.rhs)
209+ case t @ TypeDef (_, _rhs) =>
210+ case t @ Template (constr, parents, self, _) => traverse(constr); traverse(parents); traverse(self); traverse(t.body)
211+ case t => traverseChildren(t)
212+ end traverse
213+
214+ private [TreeChecker ] def isValidJVMName (name : Name ): Boolean = name.toString.forall(isValidJVMChar)
215+
216+ private [TreeChecker ] def isValidJVMMethodName (name : Name ): Boolean = name.toString.forall(isValidJVMMethodChar)
217+
218+
153219 class Checker (phasesToCheck : Seq [Phase ]) extends ReTyper with Checking {
220+ import ast .tpd ._
154221
155222 private val nowDefinedSyms = util.HashSet [Symbol ]()
156223 private val patBoundSyms = util.HashSet [Symbol ]()
@@ -657,69 +724,4 @@ class TreeChecker extends Phase with SymTransformer {
657724
658725 override def simplify (tree : Tree , pt : Type , locked : TypeVars )(using Context ): tree.type = tree
659726 }
660-
661- /**
662- * Checks that `New` nodes are always wrapped inside `Select` nodes.
663- */
664- def assertSelectWrapsNew (tree : Tree )(using Context ): Unit =
665- (new TreeAccumulator [tpd.Tree ] {
666- override def apply (parent : Tree , tree : Tree )(using Context ): Tree = {
667- tree match {
668- case tree : New if ! parent.isInstanceOf [tpd.Select ] =>
669- assert(assertion = false , i " `New` node must be wrapped in a `Select`: \n parent = ${parent.show}\n child = ${tree.show}" )
670- case _ : Annotated =>
671- // Don't check inside annotations, since they're allowed to contain
672- // somewhat invalid trees.
673- case _ =>
674- foldOver(tree, tree) // replace the parent when folding over the children
675- }
676- parent // return the old parent so that my siblings see it
677- }
678- })(tpd.EmptyTree , tree)
679- }
680-
681- object TreeChecker {
682- /** - Check that TypeParamRefs and MethodParams refer to an enclosing type.
683- * - Check that all type variables are instantiated.
684- */
685- def checkNoOrphans (tp0 : Type , tree : untpd.Tree = untpd.EmptyTree )(using Context ): Type = new TypeMap () {
686- val definedBinders = new java.util.IdentityHashMap [Type , Any ]
687- def apply (tp : Type ): Type = {
688- tp match {
689- case tp : BindingType =>
690- definedBinders.put(tp, tp)
691- mapOver(tp)
692- definedBinders.remove(tp)
693- case tp : ParamRef =>
694- assert(definedBinders.get(tp.binder) != null , s " orphan param: ${tp.show}, hash of binder = ${System .identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0" )
695- case tp : TypeVar =>
696- assert(tp.isInstantiated, s " Uninstantiated type variable: ${tp.show}, tree = ${tree.show}" )
697- apply(tp.underlying)
698- case _ =>
699- mapOver(tp)
700- }
701- tp
702- }
703- }.apply(tp0)
704-
705- /** Run some additional checks on the nodes of the trees. Specifically:
706- *
707- * - TypeTree can only appear in TypeApply args, New, Typed tpt, Closure
708- * tpt, SeqLiteral elemtpt, ValDef tpt, DefDef tpt, and TypeDef rhs.
709- */
710- object TreeNodeChecker extends untpd.TreeTraverser :
711- import untpd ._
712- def traverse (tree : Tree )(using Context ) = tree match
713- case t : TypeTree => assert(assertion = false , i " TypeTree not expected: $t" )
714- case t @ TypeApply (fun, _targs) => traverse(fun)
715- case t @ New (_tpt) =>
716- case t @ Typed (expr, _tpt) => traverse(expr)
717- case t @ Closure (env, meth, _tpt) => traverse(env); traverse(meth)
718- case t @ SeqLiteral (elems, _elemtpt) => traverse(elems)
719- case t @ ValDef (_, _tpt, _) => traverse(t.rhs)
720- case t @ DefDef (_, paramss, _tpt, _) => for params <- paramss do traverse(params); traverse(t.rhs)
721- case t @ TypeDef (_, _rhs) =>
722- case t @ Template (constr, parents, self, _) => traverse(constr); traverse(parents); traverse(self); traverse(t.body)
723- case t => traverseChildren(t)
724- end traverse
725727}
0 commit comments