1 20 21 package edu.umd.cs.findbugs.detect; 22 23 24 import edu.umd.cs.findbugs.*; 25 import edu.umd.cs.findbugs.ba.AnalysisContext; 26 import edu.umd.cs.findbugs.ba.ClassContext; 27 import org.apache.bcel.Repository; 28 import org.apache.bcel.classfile.*; 29 30 37 public class InefficientToArray extends BytecodeScanningDetector implements StatelessDetector { 38 private static final boolean DEBUG = SystemProperties.getBoolean("ita.debug"); 39 40 static final int SEEN_NOTHING = 0; 41 static final int SEEN_ICONST_0 = 1; 42 static final int SEEN_ANEWARRAY = 2; 43 44 private final static JavaClass collectionClass; 45 46 private BugReporter bugReporter; 47 private int state = SEEN_NOTHING; 48 49 static { 50 JavaClass tmp = null; 51 try { 52 tmp = AnalysisContext.lookupSystemClass("java.util.Collection"); 53 } catch (ClassNotFoundException cnfe) { 54 AnalysisContext.reportMissingClass(cnfe); 55 } 56 collectionClass = tmp; 57 } 58 59 public InefficientToArray(BugReporter bugReporter) { 60 this.bugReporter = bugReporter; 61 } 62 63 64 65 @Override 66 public void visitClassContext(ClassContext classContext) { 67 if (collectionClass != null) 68 classContext.getJavaClass().accept(this); 69 } 70 71 @Override 72 public void visit(Method obj) { 73 if (DEBUG) 74 System.out.println("------------------- Analyzing " + obj.getName() + " ----------------"); 75 state = SEEN_NOTHING; 76 super.visit(obj); 77 } 78 79 @Override 80 public void sawOpcode(int seen) { 81 if (DEBUG) System.out.println("State: " + state + " Opcode: " + OPCODE_NAMES[seen]); 82 83 switch (state) { 84 case SEEN_NOTHING: 85 if (seen == ICONST_0) 86 state = SEEN_ICONST_0; 87 break; 88 89 case SEEN_ICONST_0: 90 if (seen == ANEWARRAY) { 91 state = SEEN_ANEWARRAY; 92 } else 93 state = SEEN_NOTHING; 94 break; 95 96 case SEEN_ANEWARRAY: 97 if (((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) 98 && (getNameConstantOperand().equals("toArray")) 99 && (getSigConstantOperand().equals("([Ljava/lang/Object;)[Ljava/lang/Object;"))) { 100 try { 101 String clsName = getDottedClassConstantOperand(); 102 JavaClass cls = Repository.lookupClass(clsName); 103 if (cls.implementationOf(collectionClass)) 104 bugReporter.reportBug(new BugInstance(this, "ITA_INEFFICIENT_TO_ARRAY", LOW_PRIORITY) 105 .addClassAndMethod(this) 106 .addSourceLine(this)); 107 108 } catch (ClassNotFoundException cnfe) { 109 bugReporter.reportMissingClass(cnfe); 110 } 111 } 112 state = SEEN_NOTHING; 113 break; 114 115 default: 116 state = SEEN_NOTHING; 117 break; 118 } 119 } 120 } 121 122 | Popular Tags |