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 org.apache.bcel.Repository; 26 import org.apache.bcel.classfile.*; 27 28 public class IteratorIdioms extends BytecodeScanningDetector implements StatelessDetector { 29 30 private JavaClass iteratorClass; 31 private BugReporter bugReporter; 32 33 public IteratorIdioms(BugReporter bugReporter) { 34 this.bugReporter = bugReporter; 35 } 36 37 38 39 @Override 40 public void visitClassContext(ClassContext classContext) { 41 findJavaUtilIterator(); 42 43 if (iteratorClass == null) 44 return; 45 try { 46 JavaClass cls = classContext.getJavaClass(); 47 if (cls.implementationOf(iteratorClass)) 48 super.visitClassContext(classContext); 49 } 50 catch (ClassNotFoundException cnfe) { 51 } 53 } 54 55 private void findJavaUtilIterator() { 56 if (iteratorClass == null) { 57 try { 58 iteratorClass = Repository.lookupClass("java.util.Iterator"); 59 } catch (ClassNotFoundException cnfe) { 60 iteratorClass = null; 61 bugReporter.reportMissingClass(cnfe); 62 } 63 } 64 } 65 66 boolean sawNoSuchElement; 67 boolean sawCall; 68 69 @Override 70 public void visit(Code obj) { 71 if (getMethodName().equals("next") 72 && getMethodSig().equals("()Ljava/lang/Object;")) { 73 sawNoSuchElement = false; 74 sawCall = false; 75 super.visit(obj); 76 if (!sawNoSuchElement) 77 78 bugReporter.reportBug(new BugInstance(this, "IT_NO_SUCH_ELEMENT", sawCall ? LOW_PRIORITY : NORMAL_PRIORITY).addClassAndMethod(this)); 79 } 80 } 81 82 83 @Override 84 public void sawOpcode(int seen) { 85 if (seen == NEW 86 && getClassConstantOperand().equals("java/util/NoSuchElementException")) 87 sawNoSuchElement = true; 88 else if (seen == INVOKESPECIAL 89 || seen == INVOKEVIRTUAL 90 || seen == INVOKEINTERFACE) { 91 sawCall = true; 92 if (getNameConstantOperand().toLowerCase().indexOf("next") >= 0 || getNameConstantOperand().toLowerCase().indexOf("previous") >= 0 ) 94 sawNoSuchElement = true; 95 } 96 } 97 } 98 | Popular Tags |