1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import edu.umd.cs.findbugs.ba.ClassContext; 25 import java.util.HashSet ; 26 import org.apache.bcel.classfile.Method; 27 28 31 public class FindUncalledPrivateMethods extends BytecodeScanningDetector implements StatelessDetector { 32 private BugReporter bugReporter; 33 private String className; 34 private HashSet <MethodAnnotation> definedPrivateMethods, calledMethods; 35 private HashSet <String > calledMethodNames; 36 37 public FindUncalledPrivateMethods(BugReporter bugReporter) { 38 this.bugReporter = bugReporter; 39 } 40 41 42 43 @Override 44 public void visitMethod(Method obj) { 45 super.visitMethod(obj); 46 if (obj.isPrivate() 47 && !getMethodName().equals("writeReplace") 48 && !getMethodName().equals("readResolve") 49 && !getMethodName().equals("readObject") 50 && !getMethodName().equals("readObjectNoData") 51 && !getMethodName().equals("writeObject") 52 && getMethodName().indexOf("debug") == -1 53 && getMethodName().indexOf("Debug") == -1 54 && getMethodName().indexOf("trace") == -1 55 && getMethodName().indexOf("Trace") == -1 56 && !getMethodName().equals("<init>") 57 && !getMethodName().equals("<clinit>") 58 ) 59 definedPrivateMethods.add(MethodAnnotation.fromVisitedMethod(this)); 60 } 61 62 @Override 63 public void sawOpcode(int seen) { 64 switch (seen) { 65 case INVOKEVIRTUAL: 66 case INVOKESPECIAL: 67 case INVOKESTATIC: 68 if (getDottedClassConstantOperand().equals(className)) { 69 String className = getDottedClassConstantOperand(); 70 MethodAnnotation called = new MethodAnnotation( 71 className, 72 getNameConstantOperand(), 73 getSigConstantOperand(), 74 seen == INVOKESTATIC); 75 calledMethods.add(called); 76 calledMethodNames.add(getNameConstantOperand().toLowerCase()); 77 79 } 80 break; 81 default: 82 break; 83 } 84 } 85 86 @Override 87 public void visitClassContext(ClassContext classContext) { 88 definedPrivateMethods = new HashSet <MethodAnnotation>(); 89 calledMethods = new HashSet <MethodAnnotation>(); 90 calledMethodNames = new HashSet <String >(); 91 className = classContext.getJavaClass().getClassName(); 92 93 super.visitClassContext(classContext); 94 95 definedPrivateMethods.removeAll(calledMethods); 96 97 for (MethodAnnotation m : definedPrivateMethods) { 98 int priority = LOW_PRIORITY; 100 String methodName = m.getMethodName(); 101 if (methodName.length() > 1 102 && calledMethodNames.contains(methodName.toLowerCase())) 103 priority = NORMAL_PRIORITY; 104 BugInstance bugInstance 105 = new BugInstance(this, "UPM_UNCALLED_PRIVATE_METHOD", 106 priority) 107 .addClass(this) 108 .addMethod(m); 109 bugReporter.reportBug(bugInstance); 110 } 111 112 definedPrivateMethods = null; 113 calledMethods = null; 114 } 115 } 116 117 | Popular Tags |