// Note: Cyclic inheritance will not be executed, if there is a multiple inheritance in // the input file. Also if the input file tends to have both multiple inheritance and also // a cyclic inheritance, only multiple inheritance will bw executed. Cd_graph{ (@ void cyclic_Mult_Inher_Check(){ String strategy = "from Cd_graph bypassing {-> *, superclass, *} to-stop Adjacency"; //Set the super class parts of all the Adjacency objects in the Cd_graph // System.out.println("\n SetSupClassVisitor \n"); SetSupClassVisitor sscv = new SetSupClassVisitor(); Main.cg.traverse(this, strategy, sscv); // System.out.println("\n SuperClassChainVisitor \n"); SuperClassChainVisitor sccv = new SuperClassChainVisitor(); Main.cg.traverse(this, strategy, sccv); } @) } SuperClassChainVisitor{ (@ LinkedList hash = new LinkedList(); void before(Adjacency host){ // 'cycle' is a boolean variable is set when a cycle is detected. boolean cycle = false; // Add the current Adjacency, host, to the list in order to aid in the cycle check and // to make the printing of the participants in the cyclic inheritance easier when it is // detected. hash.add(host); Adjacency adj = host; //Traverse the superclass chain and add the super classes found while(adj.get_superclass() != null){ if(hash.contains(adj.get_superclass())){ hash.add(adj.get_superclass()); cycle = true; break; } else { hash.add(adj.get_superclass()); adj = adj.get_superclass(); } } if(cycle){ printCycle(hash); System.exit(1); } hash.clear(); } //Small utility method for printing out the contents of the hash container void printCycle(LinkedList hash){ Iterator iter = hash.iterator(); Vertex v; String vName; //Note: I chose to print out the cycle this way to make the output nice //So, I do the following to print the first class in the cycle if(iter.hasNext()){ v = ((Adjacency)iter.next()).get_source(); vName = v.get_vertex_name().toString(); System.out.println("\n Cyclic inheritance detected from CLASS " + vName); } //Print out the rest of the Cycle while(iter.hasNext()){ v = ((Adjacency)iter.next()).get_source(); vName = v.get_vertex_name().toString(); System.out.print(" to CLASS " + vName); } System.out.println("\n"); } @) } SetSupClassVisitor{ (@ void before (Adjacency host){ String strategy = "from Adjacency bypassing {-> *, superclass, *} through Term_Bar_list bypassing {-> *, supers, *} to Vertex "; String allAdjacencies = "from Cd_graph bypassing {-> *, superclass, *} to Adjacency"; //get all the subclass vertices of the Adjacency, 'host' Iterator subClassIter = Main.cg.gather(host, strategy).iterator(); //get the list of the Adjacency objects that we are going tosearch in order to find // the one whose source is the same as the subClassIter.next() Adjacency1Visitor adjv = new Adjacency1Visitor(); Main.cg.traverse(Main.cd, allAdjacencies, adjv); HashSet llist = adjv.getHashSet(); //Here, search for the adjacency whose source matches the subclass vertex object while(subClassIter.hasNext()){ Vertex sub = (Vertex)subClassIter.next(); Iterator adjList = llist.iterator(); //Attempt set the Super classes of the subclasses of the Adjacency, host. At the same time, check for MULTIPLE INHERITANCE while(adjList.hasNext()){ Adjacency adj = (Adjacency) adjList.next(); String sourceName = adj.get_source().get_vertex_name().toString(); String subName = sub.get_vertex_name().toString(); //if equality exists, set the superclass part of the Adjacency, host if(sourceName.equals(subName)){ if(! adj.get_state()){ adj.set_superclass(host); adj.set_state(true); break; } else { String firstSuper = adj.get_superclass().get_source().get_vertex_name().toString(); String secondSuper = host.get_source().get_vertex_name().toString(); System.out.println(subName + " has the following MULTIPLE SUPER-CLASSES: " + firstSuper + " and " + secondSuper); System.exit(1); } } } } } @) } Adjacency1Visitor{ (@ LinkedList list = new LinkedList(); HashSet hash = new HashSet(); void before(Adjacency host){ list.add(host); hash.add(host); } LinkedList getLinkedList(){ return list; } HashSet getHashSet(){ return hash; } @) } Adjacency{ (@ boolean state = false; Adjacency superclass = null; boolean get_state(){ return state; } void set_state(boolean status){ state = status; } Adjacency get_superclass(){ return superclass; } void set_superclass(Adjacency sup){ superclass = sup; } @) }