// Behaviour file for determining LoD violations. // There are two type of violations checked. They are simplified // violations becasue true violations would require the methods // and method signatures for all classes in the system including those // in the inhertance hierarchy. Because there is no convenient access // to the java.* classes, the violations were simplified. // Type 1 violations are those violations with a calling chain larger than 1. // For example, o.a().b() is a violation. // Type 2 violations are those violations where a call is made to a class // that is not either in the set of data members of the calss, passed in // as an argument to the method, or created (with new) within the method. // Violations of this type look like: // H h = o.a(); // h.foo(); // where H is not a legal class to call. CompilationUnits { int SysType1LoD() to UnmodifiedClassDeclaration { (@ int total = 0; @) before UnmodifiedClassDeclaration (@ total = total + host.Type1LoD(); @) return (@ total; @) } int SysType2LoD() to UnmodifiedClassDeclaration { (@ int total = 0; @) before UnmodifiedClassDeclaration (@ total = total + host.Type2LoD(host); @) return (@ total; @) } } // End CompilationUnits UnmodifiedClassDeclaration{ // Returns a hashtable of the data members of the class. The object // name is the key and class name is value. Hashtable CollectDataMembers() to FieldDeclaration { (@ Hashtable ht = new Hashtable(); String className; Vector objNames = new Vector(); @) before FieldDeclaration (@ className = host.get_type().getName(); if (className == null) className = "primitive"; if (false) System.out.println("At member of class " +className); objNames = host.get_variabledeclarators().getObjNames(); Enumeration e = objNames.elements(); while (e.hasMoreElements()) { ht.put((String)e.nextElement(),className); } @) return Hashtable (@ ht @) } int Type1LoD() to PrimarySuffixes { (@ int i = 0; @) before PrimarySuffixes (@ if (false) { System.out.println("Inside a PrimarySuffixes..."); PrintVisitor pv = new PrintVisitor(System.out); host.Type1LoDtrav(pv); pv.get_out().flush(); } if (host.countIdents() > 0) i = i + 1; @) return int (@ i @) } } // End UCD MethodDeclaration { // Counts the number of Type 2 violations by traversing to all // the method calls within a method and looking the object // up in the legal hashtable. int countType2LoDViolations(Hashtable legals) through PrimaryExpression to Arguments { (@ int i = 0; StringBuffer objectName; boolean again;@) before PrimaryExpression (@ if (host.getObjName() != null) { objectName = new StringBuffer(host.getObjName()); if (false) System.out.println("Visiting PrimaryExpression: " + host.getObjName()); again = true; } @) before Arguments (@ // Only process the first set of arguments after the beginning of // the expression if (again) { again = false; if (false) System.out.println("Legal are: " + legals.toString()); if (false) System.out.println("Looking for " + objectName.toString()); if( objectName != null) { if (!legals.containsKey(objectName.toString())) { i = i + 1; if (true) System.out.println("Found Type 2 violation at " + objectName.toString()); objectName = null; } } } @) return int (@ i @) } // Returns a hashtable of the object created (with new) in a method. // The object name is the key and class name is value. Hashtable CollectNewObjs() through {LocalVariableDeclaration, VariableDeclaratorId} to AllocationExpression { (@ Hashtable ht = new Hashtable(); String className, objName; @) before LocalVariableDeclaration (@ if (false) System.out.println("Found a local variable"); className = host.get_type().getName(); objName = host.getObjName(); if (className == null) className = "primitive"; @) before AllocationExpression (@ if (objName != null) { if (false) System.out.println("Inside CollectNewObjs and found: " + objName + ", " + className); ht.put(objName, className); } @) return (@ ht @) } // Returns a hashtable of the arguments passed into a method. // The object name is the key and class name is value. Hashtable CollectArgs() to FormalParameter { (@ Hashtable ht = new Hashtable(); String className, objName; @) before FormalParameter (@ className = host.get_type().getName(); if (className == null) className = "primitive"; if (false) System.out.println("At argument class " +className); objName = host.get_variabledeclaratorid().getObjName(); ht.put(objName,className); @) return (@ ht @) } } //End MethodDeclaration PrimarySuffixes { traversal Type1LoDtrav(UniversalVisitor) { to dotIdent; } // Counts the length of a call chain. int countIdents() to dotIdent { (@ int i = 0 ; @) before dotIdent (@ i = i + 1; if (false) System.out.println("Counting dotIdent: " + host.get_identifier().get_ident().toString());@) return int (@ i @) } } //End PrimarySuffixes