@@ -42,10 +42,6 @@ class TreeChecker extends Phase with SymTransformer {
42
42
private val seenClasses = collection.mutable.HashMap [String , Symbol ]()
43
43
private val seenModuleVals = collection.mutable.HashMap [String , Symbol ]()
44
44
45
- def isValidJVMName (name : Name ): Boolean = name.toString.forall(isValidJVMChar)
46
-
47
- def isValidJVMMethodName (name : Name ): Boolean = name.toString.forall(isValidJVMMethodChar)
48
-
49
45
val NoSuperClassFlags : FlagSet = Trait | Package
50
46
51
47
def testDuplicate (sym : Symbol , registry : mutable.Map [String , Symbol ], typ : String )(using Context ): Unit = {
@@ -150,7 +146,78 @@ class TreeChecker extends Phase with SymTransformer {
150
146
}
151
147
}
152
148
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
+
153
219
class Checker (phasesToCheck : Seq [Phase ]) extends ReTyper with Checking {
220
+ import ast .tpd ._
154
221
155
222
private val nowDefinedSyms = util.HashSet [Symbol ]()
156
223
private val patBoundSyms = util.HashSet [Symbol ]()
@@ -657,69 +724,4 @@ class TreeChecker extends Phase with SymTransformer {
657
724
658
725
override def simplify (tree : Tree , pt : Type , locked : TypeVars )(using Context ): tree.type = tree
659
726
}
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
725
727
}
0 commit comments