diff options
Diffstat (limited to 'sources/scalac/checkers/CheckOwners.java')
-rw-r--r-- | sources/scalac/checkers/CheckOwners.java | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/sources/scalac/checkers/CheckOwners.java b/sources/scalac/checkers/CheckOwners.java new file mode 100644 index 0000000000..f23bcb4d7e --- /dev/null +++ b/sources/scalac/checkers/CheckOwners.java @@ -0,0 +1,168 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + +package scalac.checkers; + +import scalac.util.*; +import scalac.ast.*; +import scalac.symtab.*; +import scalac.Global; +import scalac.util.Debug; +import Tree.*; + +/** + * Check that the owner of symbols is set correctly. + * + * @author Michel Schinz + * @version 1.0 + */ + +public class CheckOwners extends Checker { + protected Symbol currentOwner; + + public CheckOwners(Global global) { + super(global); + currentOwner = global.definitions.ROOT_CLASS; + } + + protected void traverse(Tree tree, Symbol owner) { + Symbol prevOwner = currentOwner; + currentOwner = owner; + traverse(tree); + currentOwner = prevOwner; + } + + protected void traverse(Tree[] array, Symbol owner) { + Symbol prevOwner = currentOwner; + currentOwner = owner; + traverse(array); + currentOwner = prevOwner; + } + + protected void traverse(Tree[][] array, Symbol owner) { + Symbol prevOwner = currentOwner; + currentOwner = owner; + traverse(array); + currentOwner = prevOwner; + } + + protected void traverse(Template templ, Symbol owner) { + Symbol prevOwner = currentOwner; + if (owner.kind == Kinds.CLASS) + currentOwner = owner.constructor(); + traverse(templ.parents); + currentOwner = owner; + + Symbol templSymbol = templ.symbol(); + Tree[] body = templ.body; + for (int i = 0; i < body.length; ++i) { + switch (body[i]) { + case PackageDef(_,_): + case ClassDef(_,_,_,_,_,_): + case ModuleDef(_,_,_,_): + case DefDef(_,_,_,_,_,_): + case ValDef(_,_,_,_): + case TypeDef(_,_,_,_): + traverse(body[i], owner); + break; + default: + traverse(body[i], templSymbol); + } + } + + currentOwner = prevOwner; + } + + protected void checkOwner(Tree tree, Symbol sym) { + Symbol owner = sym.owner(); + verify(tree, + owner == currentOwner, + "owner", + "incorrect owner for " + Debug.toString(sym) + ":\n" + + " found: " + Debug.toString(owner) + "\n" + + " required: " + Debug.toString(currentOwner)); + } + + public void traverse(Tree tree) { + switch(tree) { + case PackageDef(Tree packaged, Template impl): + check(tree); + traverse(packaged); + traverse(impl, packaged.symbol()); + break; + + case ClassDef(int mods, + Name name, + TypeDef[] tparams, + ValDef[][] vparams, + Tree tpe, + Template impl): { + check(tree); + traverse(tparams, tree.symbol()); + traverse(vparams, tree.symbol()); + traverse(tpe); + traverse(impl, tree.symbol()); + } break; + + case ModuleDef(int mods, Name name, Tree tpe, Template impl): { + check(tree); + traverse(tpe); + traverse(impl, tree.symbol()); + } break; + + case DefDef(int mods, + Name name, + TypeDef[] tparams, + ValDef[][] vparams, + Tree tpe, + Tree rhs): { + check(tree); + traverse(tparams, tree.symbol()); + traverse(vparams, tree.symbol()); + traverse(tpe, tree.symbol()); + traverse(rhs, tree.symbol()); + } break; + + case ValDef(int mods, Name name, Tree tpe, Tree rhs): { + check(tree); + traverse(tpe); + traverse(rhs, tree.symbol()); + } break; + + case TypeDef(int mods, Name name, TypeDef[] tparams, Tree rhs): { + check(tree); + traverse(tparams, tree.symbol()); + traverse(rhs, tree.symbol()); + } break; + + default: + super.traverse(tree); + } + } + + public void check(Tree tree) { + switch (tree) { + case PackageDef(_,_): + case ClassDef(_,_,_,_,_,_): + case ModuleDef(_,_,_,_): + case DefDef(_,_,_,_,_,_): + case ValDef(_,_,_,_): + case TypeDef(_,_,_,_): { + Symbol sym = tree.symbol(); + if (sym != null && sym != Symbol.NONE) { + checkOwner(tree, sym); + if (sym.kind == Kinds.CLASS) + checkOwner(tree, sym.constructor()); + } + } break; + + default: + ; // nothing to do + } + } +} |