Skip to content

Commit 1a1f878

Browse files
committed
Merge pull request #378 from dotty-staging/ycheck-for-symbls
Check validity of symbols in Ycheck
2 parents c4fa153 + 3cde249 commit 1a1f878

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ object SymDenotations {
354354
final def isAnonymousFunction(implicit ctx: Context) =
355355
this.symbol.is(Method) && (initial.asSymDenotation.name startsWith nme.ANON_FUN)
356356

357+
final def isAnonymousModuleVal(implicit ctx: Context) =
358+
this.symbol.is(ModuleVal) && (initial.asSymDenotation.name startsWith nme.ANON_CLASS)
359+
357360
/** Is symbol a primitive value class? */
358361
def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains symbol
359362

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,47 @@ import scala.util.control.NonFatal
3535
* - After typer, identifiers and select nodes refer to terms only (all types should be
3636
* represented as TypeTrees then).
3737
*/
38-
class TreeChecker extends Phase {
38+
class TreeChecker extends Phase with SymTransformer {
3939
import ast.tpd._
4040

4141

42+
private val seenClasses = collection.mutable.HashMap[String, Symbol]()
43+
private 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+
4279
def phaseName: String = "Ycheck"
4380

4481
def run(implicit ctx: Context): Unit = {

0 commit comments

Comments
 (0)