@@ -35,10 +35,47 @@ import scala.util.control.NonFatal
35
35
* - After typer, identifiers and select nodes refer to terms only (all types should be
36
36
* represented as TypeTrees then).
37
37
*/
38
- class TreeChecker extends Phase {
38
+ class TreeChecker extends Phase with SymTransformer {
39
39
import ast .tpd ._
40
40
41
41
42
+ val seenClasses = collection.mutable.HashMap [String , Symbol ]()
43
+ val seenModuleVals = collection.mutable.HashMap [String , Symbol ]()
44
+
45
+ def printError (str : String ) = {
46
+ println(Console .RED + " [error] " + Console .WHITE + str)
47
+ }
48
+
49
+ val NoSuperClass = Trait | Package
50
+
51
+ def testDuplicate (sym : Symbol , registry : mutable.Map [String , Symbol ], typ : String )(implicit ctx : Context ) = {
52
+ val name = sym.fullName.toString
53
+ if (registry.contains(name))
54
+ if (this .flatClasses || ! (sym.isAnonymousFunction || sym.isAnonymousClass || sym.isAnonymousModuleVal))
55
+ printError(s " $typ defined twice $sym ${sym.id} ${registry(name).id}" )
56
+ registry(name) = sym
57
+ }
58
+
59
+
60
+ def transformSym (symd : SymDenotation )(implicit ctx : Context ): SymDenotation = {
61
+ val sym = symd.symbol
62
+
63
+ if (sym.isClass) {
64
+ val validSuperclass = defn.ScalaValueClasses .contains(sym) || defn.syntheticCoreClasses.contains(sym) ||
65
+ (sym eq defn.ObjectClass ) || (sym is NoSuperClass ) || (sym.asClass.superClass.exists)
66
+ if (! validSuperclass)
67
+ printError(s " $sym has no superclass set " )
68
+
69
+ testDuplicate(sym, seenClasses, " class" )
70
+
71
+ } else if (sym is ModuleVal ) {
72
+ testDuplicate(sym, seenModuleVals, " module val" )
73
+ }
74
+
75
+
76
+ symd
77
+ }
78
+
42
79
def phaseName : String = " Ycheck"
43
80
44
81
def run (implicit ctx : Context ): Unit = {
0 commit comments