[Fb-contrib-commit] fb-contrib/src/com/mebigfatguy/fbcontrib/detect ArrayBasedCollections.java,1.1,1
Brought to you by:
dbrosius
|
From: Dave B. <dbr...@us...> - 2005-12-21 05:13:51
|
Update of /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7035/src/com/mebigfatguy/fbcontrib/detect Modified Files: ArrayBasedCollections.java Log Message: if a class uses a TreeMap or TreeSet with a comparator, then call off the dogs when putting arrays in these containers. Index: ArrayBasedCollections.java =================================================================== RCS file: /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ArrayBasedCollections.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- ArrayBasedCollections.java 17 Dec 2005 08:27:01 -0000 1.1 +++ ArrayBasedCollections.java 21 Dec 2005 05:13:39 -0000 1.2 @@ -18,18 +18,27 @@ */ package com.mebigfatguy.fbcontrib.detect; +import java.util.ArrayList; +import java.util.List; + import org.apache.bcel.classfile.Code; +import org.apache.bcel.generic.Type; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; import edu.umd.cs.findbugs.StatelessDetector; +import edu.umd.cs.findbugs.ba.ClassContext; public class ArrayBasedCollections extends BytecodeScanningDetector implements StatelessDetector { private BugReporter bugReporter; private OpcodeStack stack = new OpcodeStack(); + private List<BugInstance> mapBugs = new ArrayList<BugInstance>(); + private List<BugInstance> setBugs = new ArrayList<BugInstance>(); + private boolean hasMapComparator; + private boolean hasSetComparator; public ArrayBasedCollections(BugReporter bugReporter) { this.bugReporter = bugReporter; @@ -41,6 +50,26 @@ } @Override + public void visitClassContext(ClassContext classContext) { + mapBugs.clear(); + setBugs.clear(); + hasMapComparator = false; + hasSetComparator = false; + super.visitClassContext(classContext); + if (!hasMapComparator) { + for (BugInstance bi : mapBugs) { + bugReporter.reportBug(bi); + } + } + + if (!hasSetComparator) { + for (BugInstance bi : setBugs) { + bugReporter.reportBug(bi); + } + } + } + + @Override public void visitCode(Code obj) { stack.resetForMethodEntry(this); super.visitCode(obj); @@ -54,6 +83,7 @@ String methodName = getNameConstantOperand(); String methodSig = getSigConstantOperand(); boolean found = false; + List<BugInstance> bugList = null; if ("java/util/Map".equals(className) && "put".equals(methodName) @@ -61,8 +91,10 @@ if (stack.getStackDepth() > 1) { OpcodeStack.Item itm = stack.getStackItem(1); String pushedSig = itm.getSignature(); - if (pushedSig.charAt(0) == '[') + if (pushedSig.charAt(0) == '[') { + bugList = mapBugs; found = true; + } } } else if ("java/util/Set".equals(className) && "add".equals(methodName) @@ -70,8 +102,10 @@ if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); String pushedSig = itm.getSignature(); - if (pushedSig.charAt(0) == '[') + if (pushedSig.charAt(0) == '[') { + bugList = setBugs; found = true; + } } } else if ("java/util/List".equals(className) && "contains".equals(methodName) @@ -85,12 +119,32 @@ } if (found) { - bugReporter.reportBug(new BugInstance(this, "ABC_ARRAY_BASED_COLLECTIONS", NORMAL_PRIORITY) - .addClass(this) - .addMethod(this) - .addSourceLine(this)); + BugInstance bi = new BugInstance(this, "ABC_ARRAY_BASED_COLLECTIONS", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this); + if (bugList != null) + bugList.add(bi); + else + bugReporter.reportBug(bi); } + } else if (seen == INVOKESPECIAL) { + String className = getClassConstantOperand(); + String methodName = getNameConstantOperand(); + String sig = getSigConstantOperand(); + + if ("<init>".equals(methodName)) { + if (!hasMapComparator && "java/util/TreeMap".equals(className)) { + Type[] parms = Type.getArgumentTypes(sig); + if ((parms.length == 1) && "Ljava/util/Comparator;".equals(parms[0].getSignature())) + hasMapComparator = true; + } else if (!hasSetComparator && "java/util/TreeSet".equals(className)) { + Type[] parms = Type.getArgumentTypes(sig); + if ((parms.length == 1) && "Ljava/util/Comparator;".equals(parms[0].getSignature())) + hasSetComparator = true; + } + } } } finally { stack.sawOpcode(this, seen); |