1 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 org.apache.bcel.classfile.*; 26 27 33 public class PublicSemaphores extends BytecodeScanningDetector implements StatelessDetector 34 { 35 private static final int SEEN_NOTHING = 0; 36 private static final int SEEN_ALOAD_0 = 1; 37 38 private BugReporter bugReporter; 39 private int state; 40 private boolean alreadyReported; 41 42 public PublicSemaphores(BugReporter bugReporter) { 43 this.bugReporter = bugReporter; 44 } 45 46 47 48 @Override 49 public void visitClassContext(ClassContext classContext) { 50 JavaClass cls = classContext.getJavaClass(); 51 if ((!cls.isPublic()) || (cls.getClassName().indexOf("$") >= 0)) 52 return; 53 54 alreadyReported = false; 55 super.visitClassContext(classContext); 56 } 57 58 @Override 59 public void visit(Code obj) { 60 Method m = getMethod(); 61 if (m.isStatic() || alreadyReported) 62 return; 63 64 state = SEEN_NOTHING; 65 super.visit(obj); 66 } 67 68 @Override 69 public void sawOpcode(int seen) { 70 if (alreadyReported) 71 return; 72 73 switch (state) { 74 case SEEN_NOTHING: 75 if (seen == ALOAD_0) 76 state = SEEN_ALOAD_0; 77 break; 78 79 case SEEN_ALOAD_0: 80 if ((seen == INVOKEVIRTUAL) 81 && getClassConstantOperand().equals("java/lang/Object")) { 82 String methodName = getNameConstantOperand(); 83 if ("wait".equals(methodName) || "notify".equals(methodName) || "notifyAll".equals(methodName)) { 84 bugReporter.reportBug( new BugInstance( this, "PS_PUBLIC_SEMAPHORES", NORMAL_PRIORITY ) 85 .addClassAndMethod(this) 86 .addSourceLine(this)); 87 alreadyReported = true; 88 } 89 } 90 state = SEEN_NOTHING; 91 break; 92 } 93 94 } 95 96 } 97 | Popular Tags |