import edu.neu.ccs.demeter.dj.*; import java.util.*; import edu.neu.ccs.demeter.*; class InhCycleVisitor extends Visitor { protected HashSet alreadyChecked; public HashSet get_alreadyChecked() { return alreadyChecked; } public void set_alreadyChecked(HashSet new_alreadyChecked) { alreadyChecked = new_alreadyChecked; } public InhCycleVisitor() { super(); } public InhCycleVisitor(HashSet alreadyChecked) { super(); set_alreadyChecked(alreadyChecked); } public static InhCycleVisitor parse(java.io.Reader in) throws ParseException { return new Parser(in)._InhCycleVisitor(); } public static InhCycleVisitor parse(java.io.InputStream in) throws ParseException { return new Parser(in)._InhCycleVisitor(); } public static InhCycleVisitor parse(String s) { try { return parse(new java.io.StringReader(s)); } catch (ParseException e) { throw new RuntimeException(e.toString()); } } public void start() { alreadyChecked = new HashSet(); } public void before(Adjacency a) { // Don't bother checking a if it's already been checked. if (! alreadyChecked.contains(a)) { // Local class Searcher performs the actual check. class Searcher { // inhPath stores all the objects in the hierarchy. HashSet inhPath; // Constructor which initializes inhPath. public Searcher() { inhPath = new HashSet(); } // Recrusive function which visits each object in the // hierarchy. A traversal strategy is not useful here since // we are checking for self-loops. public void search(Adjacency cur) { // Add cur to the alreadyChecked set. alreadyChecked.add(cur); // If cur has not parents, then there can't be an // inheritance cycle here. if (cur.fetchParents() != null) { // Iterate through each of cur's immediate superclasses. // We allow for the possiblity of multiple superclasses // here, even though Java does not support it. Multiple // inheritances is checked for elsewhere. Enumeration e = cur.fetchParents().elements(); while (e.hasMoreElements()) { // The variable p points to a parent. Adjacency p = (Adjacency) e.nextElement(); // If p is already contained in inhPath, then we have // an inheritance cycle. if (inhPath.contains(p)) { System.out.println( "*** Error: " + "Inheritance cycle. Class " + p.fetchIdent() + " is both a subclass and a superclass of class " + cur.fetchIdent() + "." + '\n' ); Main.ecount++; } // Else, add p to inhPath, and recurse. else { inhPath.add(p); search(p); } } } } } // End of local class Searcher. // Create a new Searcher and check a for multiple inheritances. Searcher s = new Searcher(); s.search(a); } } void universal_trv0_bef(UniversalVisitor _v_) { ((UniversalVisitor) _v_).before(this); } void universal_trv0_aft(UniversalVisitor _v_) { ((UniversalVisitor) _v_).after(this); } void universal_trv0(UniversalVisitor _v_) { universal_trv0_bef(_v_); ((UniversalVisitor) _v_).before_alreadyChecked(this, alreadyChecked); ((UniversalVisitor) _v_).after_alreadyChecked(this, alreadyChecked); universal_trv0_aft(_v_); } }