1 19 20 package edu.umd.cs.findbugs.detect; 21 22 23 import edu.umd.cs.findbugs.*; 24 import org.apache.bcel.classfile.*; 25 26 33 34 public class FindNakedNotify extends BytecodeScanningDetector implements StatelessDetector { 35 int stage = 0; 36 private BugReporter bugReporter; 37 boolean synchronizedMethod; 38 private int notifyPC; 39 40 public FindNakedNotify(BugReporter bugReporter) { 41 this.bugReporter = bugReporter; 42 } 43 44 45 46 @Override 47 public void visit(Method obj) { 48 int flags = obj.getAccessFlags(); 49 synchronizedMethod = (flags & ACC_SYNCHRONIZED) != 0; 50 } 51 52 @Override 53 public void visit(Code obj) { 54 stage = synchronizedMethod ? 1 : 0; 55 super.visit(obj); 56 if (synchronizedMethod && stage == 4) 57 bugReporter.reportBug(new BugInstance(this, "NN_NAKED_NOTIFY", NORMAL_PRIORITY) 58 .addClassAndMethod(this) 59 .addSourceLine(this, notifyPC)); 60 } 61 62 @Override 63 public void sawOpcode(int seen) { 64 switch (stage) { 65 case 0: 66 if (seen == MONITORENTER) 67 stage = 1; 68 break; 69 case 1: 70 stage = 2; 71 break; 72 case 2: 73 if (seen == INVOKEVIRTUAL 74 && (getNameConstantOperand().equals("notify") 75 || getNameConstantOperand().equals("notifyAll")) 76 && getSigConstantOperand().equals("()V")) { 77 stage = 3; 78 notifyPC = getPC(); 79 } else 80 stage = 0; 81 break; 82 case 3: 83 stage = 4; 84 break; 85 case 4: 86 if (seen == MONITOREXIT) { 87 bugReporter.reportBug(new BugInstance(this, "NN_NAKED_NOTIFY", NORMAL_PRIORITY) 88 .addClassAndMethod(this) 89 .addSourceLine(this, notifyPC)); 90 stage = 5; 91 } else 92 stage = 0; 93 break; 94 case 5: 95 break; 96 default: 97 assert false; 98 } 99 100 } 101 } 102 | Popular Tags |