[Fb-contrib-commit] SF.net SVN: fb-contrib: [674] trunk/fb-contrib
Brought to you by:
dbrosius
From: <dbr...@us...> - 2006-10-27 05:28:07
|
Revision: 674 http://svn.sourceforge.net/fb-contrib/?rev=674&view=rev Author: dbrosius Date: 2006-10-26 22:27:56 -0700 (Thu, 26 Oct 2006) Log Message: ----------- Initial checkin SC detector (no xml support yet) Added Paths: ----------- trunk/fb-contrib/samples/SC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java Added: trunk/fb-contrib/samples/SC_Sample.java =================================================================== --- trunk/fb-contrib/samples/SC_Sample.java (rev 0) +++ trunk/fb-contrib/samples/SC_Sample.java 2006-10-27 05:27:56 UTC (rev 674) @@ -0,0 +1,28 @@ +import java.util.Comparator; + +public class SC_Sample +{ + public static final int T1 = 0; + public static final int T2 = 1; + + int t = 0; + class SampleComparator implements Comparator<SC_Sample> + { + public int compare(SC_Sample arg0, SC_Sample arg1) { + if (arg0.t == arg1.t) + return 0; + + return -1; + } + } + + class SampleComparable implements Comparable<SC_Sample> + { + public int compareTo(SC_Sample arg0) { + if (t == arg0.t) + return 0; + + return 1; + } + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparator.java 2006-10-27 05:27:56 UTC (rev 674) @@ -0,0 +1,120 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.Repository; +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.JavaClass; +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.ba.ClassContext; + +/** + * looks for class that implement Comparator or Comparable, and whose compare or compareTo + * methods return constant values only, but that don't represent the three possible choice + * (a negative number, 0, and a positive number). + */ +public class SuspiciousComparator extends BytecodeScanningDetector +{ + private static Map<JavaClass, String> compareClasses = new HashMap<JavaClass, String>(); + static { + try { + compareClasses.put(Repository.lookupClass("java/lang/Comparable"), "compare:2:I");; + compareClasses.put(Repository.lookupClass("java.lang/Comparator"), "compareTo:1:I"); + } catch (ClassNotFoundException cnfe) { + } + } + + private OpcodeStack stack; + private BugReporter bugReporter; + private String[] methodInfo; + private boolean indeterminate; + private boolean seenNegative; + private boolean seenPositive; + private boolean seenZero; + + + /** + * constructs a DRE detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public SuspiciousComparator(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + public void visitClassContext(ClassContext classContext) { + try { + JavaClass cls = classContext.getJavaClass(); + for (Map.Entry<JavaClass, String> entry : compareClasses.entrySet()) { + if (cls.implementationOf(entry.getKey())) { + methodInfo = entry.getValue().split(":"); + stack = new OpcodeStack(); + super.visitClassContext(classContext); + break; + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } finally { + methodInfo = null; + stack = null; + } + } + + public void visitCode(Code obj) { + String methodName = getMethodName(); + String methodSig = getMethodSig(); + if (methodName.equals(methodInfo[0]) + && methodSig.endsWith(methodInfo[2]) + && (Type.getArgumentTypes(methodSig).length == Integer.valueOf(methodInfo[1]))) { + stack.resetForMethodEntry(this); + indeterminate = false; + seenNegative = false; + seenPositive = false; + seenZero = false; + super.visitCode(obj); + if (!indeterminate) { + boolean seenAll = seenNegative & seenPositive & seenZero; + if (!seenAll) { + bugReporter.reportBug(new BugInstance(this, "SC_SUSPICIOUS_COMPARATOR", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this, 0)); + } + } + } + } + + public void sawOpcode(int seen) { + try { + if (indeterminate) + return; + + if (seen == IRETURN) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + Integer returnValue = (Integer)item.getConstant(); + if (returnValue == null) + indeterminate = true; + else { + int v = returnValue.intValue(); + if (v < 0) + seenNegative = true; + else if (v > 0) + seenPositive = true; + else + seenZero = true; + } + } else + indeterminate = true; + } + } finally { + stack.sawOpcode(this, seen); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |