Thread: [Fb-contrib-commit] SF.net SVN: fb-contrib: [426] trunk/fb-contrib/etc
Brought to you by:
dbrosius
From: <dbr...@us...> - 2006-04-09 20:11:21
|
Revision: 426 Author: dbrosius Date: 2006-04-09 13:11:12 -0700 (Sun, 09 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=426&view=rev Log Message: ----------- Initial checkin NonRecycleableTaglibs -- not even close to working. :) Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-09 20:09:29 UTC (rev 425) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-09 20:11:12 UTC (rev 426) @@ -179,6 +179,11 @@ speed="fast" reports="NOS_NON_OWNED_SYNCHRONIZATION" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.NonRecycleableTaglibs" + speed="moderate" + reports="NRTL_NON_RECYCLEABLE_TAG_LIBS" + hidden="true" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -215,11 +220,12 @@ <BugPattern abbrev="AWCBR" type="AWCBR_ARRAY_WRAPPED_CALL_BY_REFERENCE" category="STYLE" /> <BugPattern abbrev="SG" type="SG_SLUGGISH_GUI" category="PERFORMANCE" /> <BugPattern abbrev="NIR" type="NIR_NEEDLESS_INSTANCE_RETRIEVAL" category="PERFORMANCE" /> - <BugPattern abbrev="DDC" type="DDC_DOUBLE_DATE_COMPARISON" category="PERFORMANCE" experimental="true" /> - <BugPattern abbrev="SWCO" type="SWCO_SUSPICIOUS_WAIT_ON_CONCURRENT_OBJECT" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="JVR" type="JVR_JDBC_VENDOR_RELIANCE" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="PMB" type="PMB_POSSIBLE_MEMORY_BLOAT" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="LSYC" type="LSYC_LOCAL_SYNCHRONIZED_COLLECTION" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="DDC" type="DDC_DOUBLE_DATE_COMPARISON" category="PERFORMANCE" /> + <BugPattern abbrev="SWCO" type="SWCO_SUSPICIOUS_WAIT_ON_CONCURRENT_OBJECT" category="CORRECTNESS" /> + <BugPattern abbrev="JVR" type="JVR_JDBC_VENDOR_RELIANCE" category="CORRECTNESS" /> + <BugPattern abbrev="PMB" type="PMB_POSSIBLE_MEMORY_BLOAT" category="CORRECTNESS" /> + <BugPattern abbrev="LSYC" type="LSYC_LOCAL_SYNCHRONIZED_COLLECTION" category="CORRECTNESS" /> <BugPattern abbrev="FCBL" type="FCBL_FIELD_COULD_BE_LOCAL" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="NOS" type="NOS_NON_OWNED_SYNCHRONIZATION" category="STYLE" experimental="true" /> + <BugPattern abbrev="NRTL" type="NRTL_NON_RECYCLEABLE_TAG_LIB" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-09 20:09:29 UTC (rev 425) +++ trunk/fb-contrib/etc/messages.xml 2006-04-09 20:11:12 UTC (rev 426) @@ -517,6 +517,16 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.NonRecycleableTaglibs"> + <Details> + <![CDATA[ + <p>looks for tag libraries that are not recycleable because backing members + of taglib attributes are set in areas besides the setter method for the attribute.</p> + <p>It is a moderately fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1057,6 +1067,21 @@ ]]> </Details> </BugPattern> + + <BugPattern type="NRTL_NON_RECYCLEABLE_TAG_LIB"> + <ShortDescription>Tag library is not recycleable</ShortDescription> + <LongDescription>Tag library {0} is not recycleable</LongDescription> + <Details> + <![CDATA[ + <p>This Tag library class implements an attribute who's associated backing store field + is modified at another point in the tag library. In order for a taglibrary to be + recycleable, only the container is allowed to change this attribute, through the use + of the setXXX method of the taglib. By modifying the value programmatically, the + container will not initialize the attribute correctly on reuse.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1100,4 +1125,5 @@ <BugCode abbrev="LSYC">Local Synchronized Collection</BugCode> <BugCode abbrev="FCBL">Field Could Be Local</BugCode> <BugCode abbrev="NOS">Non Owned Synchronization</BugCode> + <BugCode abbrev="NRTL">Non Recycleable Taglib</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java 2006-04-09 20:11:12 UTC (rev 426) @@ -0,0 +1,143 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.Method; + +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.StatelessDetector; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for tag libraries that are not recycleable because backing members of taglib attributes are + * set in areas besides the setter method for the attribute. + */ +public class NonRecycleableTaglibs extends BytecodeScanningDetector implements StatelessDetector { + private static final int MAX_ATTRIBUTE_CODE_LENGTH = 60; + + private static final Set<String> tagClasses = new HashSet<String>(); + static { + tagClasses.add("javax.servlet.jsp.tagext.TagSupport"); + tagClasses.add("javax.servlet.jsp.tagext.BodyTagSupport"); + } + private BugReporter bugReporter; + private Map<String, String> attributes; + private boolean isAttribute; + private boolean sawPut; + + /** + * constructs a NRTL detector given the reporter to report bugs on. + + * @param bugReporter the sync of bug reports + */ + public NonRecycleableTaglibs(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + /** + * clone this detector so that it can be a StatelessDetector. + * + * @return a clone of this object + * @throws CloneNotSupportedException never + */ + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + /** + * implements the visitor to look for classes that extend the TagSupport or BodyTagSupport class + * + * @param classContext the context object for the currently parsed class + */ + @Override + public void visitClassContext(ClassContext classContext) { + try { + JavaClass cls = classContext.getJavaClass(); + JavaClass[] superClasses = cls.getSuperClasses(); + for (JavaClass superCls : superClasses) { + if (tagClasses.contains(superCls.getClassName())) { + attributes = getAttributes(cls); + if (attributes.size() > 0) { + super.visitClassContext(classContext); + reportBugs(); + } + break; + } + } + + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } + finally { + attributes = null; + } + } + + /** + * collect all possible attributes given the name of methods available. + * + * @return the map of possible attributes/types + */ + private Map<String, String> getAttributes(JavaClass cls) { + Map<String, String> attributes = new HashMap<String, String>(); + Method[] methods = cls.getMethods(); + for (Method m : methods) { + String name = m.getName(); + if (name.startsWith("get") && m.isPublic() && !m.isStatic()) { + String sig = m.getSignature(); + if (sig.startsWith("()")) { + String retSig = sig.substring(sig.indexOf(")")+1); + if ((retSig.charAt(0) != 'L') && ("Ljava/lang/String;".equals(retSig))) { + Code code = m.getCode(); + if ((code != null) && code.getCode().length > MAX_ATTRIBUTE_CODE_LENGTH) { + attributes.put(name.substring("get".length()), retSig); + isAttribute = true; + sawPut = false; + super.visitMethod(m); + } + } + } + } + } + return attributes; + } + + /** + * implements the visitor to + * + * @param obj the context object for the currently parsed code object + */ + @Override + public void visitCode(Code obj) { + super.visitCode(obj); + } + + @Override + public void sawOpcode(int seen) { + if (isAttribute) { + sawAttributeOpcode(seen); + } + } + + private void sawAttributeOpcode(int seen) { + if (seen == PUTFIELD) { + String sig = getSigConstantOperand(); + + + } + } + + /** + * generates all the bug reports for attributes that are not recycleable + */ + private void reportBugs() { + + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-09 21:44:16
|
Revision: 431 Author: dbrosius Date: 2006-04-09 14:44:03 -0700 (Sun, 09 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=431&view=rev Log Message: ----------- NRTL is starting to hobble along Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-09 21:02:41 UTC (rev 430) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-09 21:44:03 UTC (rev 431) @@ -181,8 +181,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.NonRecycleableTaglibs" speed="moderate" - reports="NRTL_NON_RECYCLEABLE_TAG_LIBS" - hidden="true" /> + reports="NRTL_NON_RECYCLEABLE_TAG_LIBS" /> <!-- BugPattern --> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java 2006-04-09 21:02:41 UTC (rev 430) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java 2006-04-09 21:44:03 UTC (rev 431) @@ -10,8 +10,11 @@ import org.apache.bcel.classfile.Method; 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.FieldAnnotation; +import edu.umd.cs.findbugs.SourceLineAnnotation; import edu.umd.cs.findbugs.StatelessDetector; import edu.umd.cs.findbugs.ba.ClassContext; @@ -43,9 +46,15 @@ } private BugReporter bugReporter; + /** + * methodname:methodsig -> type of setter methods + */ private Map<String, String> attributes; - private boolean isAttribute; - private boolean sawSet; + /** + * methodname:methodsig -> (fieldname:fieldtype)s + */ + private Map<String, Set<String>> methodWrites; + private Map<String, FieldAnnotation> fieldAnnotations; /** * constructs a NRTL detector given the reporter to report bugs on. @@ -80,7 +89,10 @@ for (JavaClass superCls : superClasses) { if (tagClasses.contains(superCls.getClassName())) { attributes = getAttributes(cls); + if (attributes.size() > 0) { + methodWrites = new HashMap<String, Set<String>>(); + fieldAnnotations = new HashMap<String, FieldAnnotation>(); super.visitClassContext(classContext); reportBugs(); } @@ -93,6 +105,8 @@ } finally { attributes = null; + methodWrites = null; + fieldAnnotations = null; } } @@ -114,12 +128,8 @@ String parmSig = args[0].getSignature(); if (validAttrTypes.contains(parmSig)) { Code code = m.getCode(); - if ((code != null) && code.getCode().length < MAX_ATTRIBUTE_CODE_LENGTH) { - attributes.put(name.substring("set".length()), parmSig); - isAttribute = true; - sawSet = false; - super.visitMethod(m); - } + if ((code != null) && code.getCode().length < MAX_ATTRIBUTE_CODE_LENGTH) + attributes.put(name + ":" + sig, parmSig); } } } @@ -134,28 +144,59 @@ */ @Override public void visitCode(Code obj) { + Method m = getMethod(); + String attName = m.getName() + ":" + m.getSignature(); super.visitCode(obj); } @Override public void sawOpcode(int seen) { - if (isAttribute) { - sawAttributeOpcode(seen); - } - } - - private void sawAttributeOpcode(int seen) { if (seen == PUTFIELD) { - String sig = getSigConstantOperand(); - - + String methodInfo = getMethodName() + ":" + getMethodSig(); + Set<String> fields = methodWrites.get(methodInfo); + if (fields == null) { + fields = new HashSet<String>(); + methodWrites.put(methodInfo, fields); + } + String fieldName = getNameConstantOperand(); + String fieldSig = getSigConstantOperand(); + FieldAnnotation fa = new FieldAnnotation(getClassName(), fieldName, fieldSig, false); + fa.setSourceLines(SourceLineAnnotation.fromVisitedInstruction(this)); + fieldAnnotations.put(fieldName, fa); + fields.add(fieldName + ":" + fieldSig); } } - + /** * generates all the bug reports for attributes that are not recycleable */ private void reportBugs() { - + for (Map.Entry<String, String> entry : attributes.entrySet()) { + String methodInfo = entry.getKey(); + String attType = entry.getValue(); + + Set<String> fields = methodWrites.get(methodInfo); + if (fields.size() != 1) + continue; + + String fieldInfo = fields.iterator().next(); + String fieldName = fieldInfo.substring(0, fieldInfo.indexOf(":")); + String fieldType = fieldInfo.substring(fieldInfo.indexOf(":")+1); + + if (!attType.equals(fieldType)) + continue; + + int cnt = 0; + for (Set<String> allFields : methodWrites.values()) { + if (allFields.contains(fieldInfo)) + cnt++; + } + + if (cnt > 1) { + bugReporter.reportBug(new BugInstance(this, "NRTL_NON_RECYCLEABLE_TAG_LIB", NORMAL_PRIORITY) + .addClass(this) + .addField(fieldAnnotations.get(fieldName))); + } + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-10 03:08:52
|
Revision: 437 Author: dbrosius Date: 2006-04-09 20:08:45 -0700 (Sun, 09 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=437&view=rev Log Message: ----------- adjust documented detector timings based on experimentation Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-10 02:53:59 UTC (rev 436) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-10 03:08:45 UTC (rev 437) @@ -18,7 +18,7 @@ reports="ISB_INEFFICIENT_STRING_BUFFERING" /> <Detector class="com.mebigfatguy.fbcontrib.detect.SyncCollectionIterators" - speed="fast" + speed="slow" reports="SCI_SYNCHRONIZED_COLLECTION_ITERATORS" /> <Detector class="com.mebigfatguy.fbcontrib.detect.CyclomaticComplexity" @@ -26,7 +26,7 @@ reports="CC_CYCLOMATIC_COMPLEXITY" /> <Detector class="com.mebigfatguy.fbcontrib.detect.OverlyConcreteParameter" - speed="fast" + speed="moderate" reports="OCP_OVERLY_CONCRETE_PARAMETER" /> <Detector class="com.mebigfatguy.fbcontrib.detect.ListIndexedIterating" @@ -34,7 +34,7 @@ reports="LII_LIST_INDEXED_ITERATING" /> <Detector class="com.mebigfatguy.fbcontrib.detect.UnrelatedCollectionContents" - speed="moderate" + speed="fast" reports="UCC_UNRELATED_COLLECTION_CONTENTS" /> <Detector class="com.mebigfatguy.fbcontrib.detect.DeclaredRuntimeException" @@ -42,12 +42,12 @@ reports="DRE_DECLARED_RUNTIME_EXCEPTION" /> <Detector class="com.mebigfatguy.fbcontrib.detect.ClassEnvy" - speed="moderate" + speed="fast" reports="CE_CLASS_ENVY" disabled="true" /> <Detector class="com.mebigfatguy.fbcontrib.detect.LiteralStringComparison" - speed="moderate" + speed="fast" reports="LSC_LITERAL_STRING_COMPARISON" /> <Detector class="com.mebigfatguy.fbcontrib.detect.PartiallyConstructedObjectAccess" @@ -63,7 +63,7 @@ reports="PL_PARALLEL_LISTS" /> <Detector class="com.mebigfatguy.fbcontrib.detect.FinalParameters" - speed="fast" + speed="slow" reports="FP_FINAL_PARAMETERS" /> <Detector class="com.mebigfatguy.fbcontrib.detect.AbstractClassEmptyMethods" @@ -107,7 +107,7 @@ reports="USBR_UNNECESSARY_STORE_BEFORE_RETURN" /> <Detector class="com.mebigfatguy.fbcontrib.detect.CopiedOverriddenMethod" - speed="moderate" + speed="fast" reports="COM_COPIED_OVERRIDDEN_METHOD" /> <Detector class="com.mebigfatguy.fbcontrib.detect.ArrayBasedCollections" @@ -123,7 +123,7 @@ reports="AOM_ABSTRACT_OVERRIDDEN_METHOD" /> <Detector class="com.mebigfatguy.fbcontrib.detect.CustomBuiltXML" - speed="moderate" + speed="fast" reports="CBX_CUSTOM_BUILT_XML" /> <Detector class="com.mebigfatguy.fbcontrib.detect.BloatedSynchronizedBlock" @@ -160,7 +160,7 @@ reports="SWCO_SUSPICIOUS_WAIT_ON_CONCURRENT_OBJECT" /> <Detector class="com.mebigfatguy.fbcontrib.detect.JDBCVendorReliance" - speed="moderate" + speed="fast" reports="JVR_JDBC_VENDOR_RELIANCE" /> <Detector class="com.mebigfatguy.fbcontrib.detect.PossibleMemoryBloat" @@ -168,11 +168,11 @@ reports="PMB_POSSIBLE_MEMORY_BLOAT" /> <Detector class="com.mebigfatguy.fbcontrib.detect.LocalSynchronizedCollection" - speed="fast" + speed="moderate" reports="LSYC_LOCAL_SYNCHRONIZED_COLLECTION" /> <Detector class="com.mebigfatguy.fbcontrib.detect.FieldCouldBeLocal" - speed="fast" + speed="slow" reports="FCBL_FIELD_COULD_BE_LOCAL" /> <Detector class="com.mebigfatguy.fbcontrib.detect.NonOwnedSynchronization" @@ -180,7 +180,7 @@ reports="NOS_NON_OWNED_SYNCHRONIZATION" /> <Detector class="com.mebigfatguy.fbcontrib.detect.NonRecycleableTaglibs" - speed="moderate" + speed="fast" reports="NRTL_NON_RECYCLEABLE_TAG_LIBS" /> <!-- BugPattern --> Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-10 02:53:59 UTC (rev 436) +++ trunk/fb-contrib/etc/messages.xml 2006-04-10 03:08:45 UTC (rev 437) @@ -37,7 +37,7 @@ <p> As the collection in question was built thru Collections.synchronizedXXX, an assumption is made that this collection must be multithreaded safe. However, iterator access is used, which is explicitly unsafe. When iterators are to be used, synchronization should be done manually.</p> - <p>It is a fast detector</p> + <p>It is a slow detector</p> ]]> </Details> </Detector> @@ -58,7 +58,7 @@ <p> Looks for parameters that are defined by classes, but only use methods defined by an implemented interface or super class. Relying on concrete classes in public signatures causes cohesion, and makes low impact changes more difficult.</p> - <p>It is a fast detector</p> + <p>It is a moderately fast detector</p> ]]> </Details> </Detector> @@ -83,7 +83,7 @@ determine type. A better design usually can be had by creating a seperate class, which defines the different types required, and add an instance of that class to the collection, or array.</p> - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> @@ -108,7 +108,7 @@ methods. When this is the case, it is often better to implement this method in that other class, by refactoring the class to accept parameters it needs from the source class. The reporting percentage can be set with system property 'fb-contrib.ce.percent'.</p> - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> @@ -119,7 +119,7 @@ <p> Looks for methods that compare strings against literal strings, where the literal string is passed as the parameter. If the .equals or .compareTo is called on the literal itself, passing the variable as the parameter, you avoid the possibility of a NullPointerException.</p> - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> @@ -320,7 +320,7 @@ <![CDATA[ <p>Looks for methods that are direct copies of the implementation in the super class</p> </p> - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> @@ -366,7 +366,7 @@ and custom values together. Doing so makes brittle code, that is difficult to modify, validate and understand. It is cleaner to create external xml files that are transformed at runtime, using parameters set through Transformer.setParameter. - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> @@ -377,7 +377,7 @@ <p>Looks for methods that are implemented using synchronized blocks, but are overly synchronized because the beginning of the block only accesses local variables, and not member variables, or this.</p> - <p>It is a fast detector</p> + <p>It is a slow detector</p> ]]> </Details> </Detector> @@ -466,7 +466,7 @@ <![CDATA[ <p>Looks for uses of jdbc vendor specific classes and methods making the database access code non portable.</p> - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> @@ -489,7 +489,7 @@ variables, and never stored in fields or returned from methods. As local variables are by definition thread safe, using synchronized collections in this context makes no sense.</p> - <p>It is a fast detector</p> + <p>It is a moderately fast detector</p> ]]> </Details> </Detector> @@ -500,7 +500,7 @@ <p>looks for classes that define fields that are used in a locals only fashion, specifically private fields that are accessed first in each method with a store vs. a load.</p> - <p>It is a fast detector</p> + <p>It is a slow detector</p> ]]> </Details> </Detector> @@ -523,7 +523,7 @@ <![CDATA[ <p>looks for tag libraries that are not recycleable because backing members of taglib attributes are set in areas besides the setter method for the attribute.</p> - <p>It is a moderately fast detector</p> + <p>It is a fast detector</p> ]]> </Details> </Detector> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-23 00:22:18
|
Revision: 498 Author: dbrosius Date: 2006-04-22 17:22:03 -0700 (Sat, 22 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=498&view=rev Log Message: ----------- Initial checkin - S508C detector - very premature Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/S508C_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-22 19:20:11 UTC (rev 497) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-23 00:22:03 UTC (rev 498) @@ -183,6 +183,10 @@ speed="fast" reports="NRTL_NON_RECYCLEABLE_TAG_LIBS" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.Section508Compliance" + speed="fast" + reports="S508C_NULL_LAYOUT" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -227,4 +231,5 @@ <BugPattern abbrev="FCBL" type="FCBL_FIELD_COULD_BE_LOCAL" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="NOS" type="NOS_NON_OWNED_SYNCHRONIZATION" category="STYLE" experimental="true" /> <BugPattern abbrev="NRTL" type="NRTL_NON_RECYCLEABLE_TAG_LIB" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="S508C" type="S508C_NULL_LAYOUT" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-22 19:20:11 UTC (rev 497) +++ trunk/fb-contrib/etc/messages.xml 2006-04-23 00:22:03 UTC (rev 498) @@ -527,6 +527,16 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.Section508Compliance"> + <Details> + <![CDATA[ + <p>looks for violation of Section 508, Accessibility for People with disabilities Act. + </p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1082,6 +1092,19 @@ </Details> </BugPattern> + <BugPattern type="S508C_NULL_LAYOUT"> + <ShortDescription>Gui uses absolute layout</ShortDescription> + <LongDescription>Gui {0} uses absolute layout</LongDescription> + <Details> + <![CDATA[ + <p>This class passes null to setLayout, which specifies that components are + to be laid out using absolute coordinates. This makes making changes for + font sizes, etc, difficult as items will not reposition + </p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1126,4 +1149,5 @@ <BugCode abbrev="FCBL">Field Could Be Local</BugCode> <BugCode abbrev="NOS">Non Owned Synchronization</BugCode> <BugCode abbrev="NRTL">Non Recycleable Taglib</BugCode> + <BugCode abbrev="S508C">Section 508 Compliance Violations</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/S508C_Sample.java =================================================================== --- trunk/fb-contrib/samples/S508C_Sample.java (rev 0) +++ trunk/fb-contrib/samples/S508C_Sample.java 2006-04-23 00:22:03 UTC (rev 498) @@ -0,0 +1,11 @@ +import java.awt.Container; + +import javax.swing.JFrame; + +public class S508C_Sample extends JFrame +{ + public S508C_Sample() { + Container cp = getContentPane(); + cp.setLayout(null); + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-23 00:22:03 UTC (rev 498) @@ -0,0 +1,107 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.Field; + +import com.mebigfatguy.fbcontrib.utils.RegisterUtils; + +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 interfaces that ignore 508 compliance, including not using JLabel.setLabelFor, + * Using null layouts, + */ +public class Section508Compliance extends BytecodeScanningDetector +{ + private BugReporter bugReporter; + private OpcodeStack stack; + private Set<String> fieldLabels; + private Set<Integer> localLabels; + + /** + * constructs a S508C detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public Section508Compliance(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + @Override + public void visitField(Field obj) { + String fieldSig = obj.getSignature(); + if ("java/awt/Label".equals(fieldSig) || "javax/swing/JLabel".equals(fieldSig)) { + fieldLabels.add(obj.getName()); + } + } + + /** + * implements the visitor to create and clear the stack + * + * @param classContext the context object of the currently visited class + */ + @Override + public void visitClassContext(ClassContext classContext) { + try { + stack = new OpcodeStack(); + fieldLabels = new HashSet<String>(); + localLabels = new HashSet<Integer>(); + super.visitClassContext(classContext); + } finally { + stack = null; + fieldLabels = null; + localLabels = null; + } + } + + /** + * implements the visitor to reset the stack + * + * @param obj the context object for the currently visited code block + */ + @Override + public void visitCode(Code obj) { + stack.resetForMethodEntry(this); + localLabels.clear(); + super.visitCode(obj); + } + + /** + * implements the visitor to find 508 compliance concerns + * + * @param seen the opcode of the currently parsed instruction + */ + @Override + public void sawOpcode(int seen) { + try { + stack.mergeJumps(this); + if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { + int reg = RegisterUtils.getAStoreReg(this, seen); + } else if (seen == INVOKEVIRTUAL) { + String className = getClassConstantOperand(); + String methodName = getNameConstantOperand(); + + if ("java/awt/Container".equals(className)) { + if ("setLayout".equals(methodName)) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + if (item.isNull()) + bugReporter.reportBug(new BugInstance(this, "S508C_NULL_LAYOUT", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + } + } finally { + stack.sawOpcode(this, seen); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-23 01:39:16
|
Revision: 499 Author: dbrosius Date: 2006-04-22 18:39:07 -0700 (Sat, 22 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=499&view=rev Log Message: ----------- more checks - far from complete Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/S508C_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-23 00:22:03 UTC (rev 498) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-23 01:39:07 UTC (rev 499) @@ -185,7 +185,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.Section508Compliance" speed="fast" - reports="S508C_NULL_LAYOUT" /> + reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR" /> <!-- BugPattern --> @@ -232,4 +232,5 @@ <BugPattern abbrev="NOS" type="NOS_NON_OWNED_SYNCHRONIZATION" category="STYLE" experimental="true" /> <BugPattern abbrev="NRTL" type="NRTL_NON_RECYCLEABLE_TAG_LIB" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NULL_LAYOUT" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-23 00:22:03 UTC (rev 498) +++ trunk/fb-contrib/etc/messages.xml 2006-04-23 01:39:07 UTC (rev 499) @@ -1105,6 +1105,18 @@ </Details> </BugPattern> + <BugPattern type="S508C_NO_SETLABELFOR"> + <ShortDescription>JLabel doesn't specify what it's labeling</ShortDescription> + <LongDescription>JLabel doesn't specify what it's labeling</LongDescription> + <Details> + <![CDATA[ + <p>This class uses JLabels that do not specify what fields are being labeled. + This hampers screen readers from given appropriate feed back to users. + </p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/S508C_Sample.java =================================================================== --- trunk/fb-contrib/samples/S508C_Sample.java 2006-04-23 00:22:03 UTC (rev 498) +++ trunk/fb-contrib/samples/S508C_Sample.java 2006-04-23 01:39:07 UTC (rev 499) @@ -1,11 +1,20 @@ import java.awt.Container; import javax.swing.JFrame; +import javax.swing.JLabel; public class S508C_Sample extends JFrame { + private JLabel fLabel = new JLabel("Hello"); + public S508C_Sample() { Container cp = getContentPane(); cp.setLayout(null); + + cp.add(fLabel); + JLabel lLabel = new JLabel("there"); + cp.add(lLabel); + + setSize(300, 200); } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-23 00:22:03 UTC (rev 498) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-23 01:39:07 UTC (rev 499) @@ -1,6 +1,8 @@ package com.mebigfatguy.fbcontrib.detect; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import org.apache.bcel.classfile.Code; @@ -11,7 +13,9 @@ import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.FieldAnnotation; import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.SourceLineAnnotation; import edu.umd.cs.findbugs.ba.ClassContext; /** @@ -22,8 +26,8 @@ { private BugReporter bugReporter; private OpcodeStack stack; - private Set<String> fieldLabels; - private Set<Integer> localLabels; + private Set<FieldAnnotation> fieldLabels; + private Map<Integer, SourceLineAnnotation> localLabels; /** * constructs a S508C detector given the reporter to report bugs on @@ -33,14 +37,6 @@ this.bugReporter = bugReporter; } - @Override - public void visitField(Field obj) { - String fieldSig = obj.getSignature(); - if ("java/awt/Label".equals(fieldSig) || "javax/swing/JLabel".equals(fieldSig)) { - fieldLabels.add(obj.getName()); - } - } - /** * implements the visitor to create and clear the stack * @@ -50,9 +46,14 @@ public void visitClassContext(ClassContext classContext) { try { stack = new OpcodeStack(); - fieldLabels = new HashSet<String>(); - localLabels = new HashSet<Integer>(); + fieldLabels = new HashSet<FieldAnnotation>(); + localLabels = new HashMap<Integer, SourceLineAnnotation>(); super.visitClassContext(classContext); + for (FieldAnnotation fa : fieldLabels) { + bugReporter.reportBug(new BugInstance(this, "S508C_NO_SETLABELFOR", NORMAL_PRIORITY) + .addClass(this) + .addField(fa)); + } } finally { stack = null; fieldLabels = null; @@ -61,6 +62,20 @@ } /** + * looks for fields that are JLabels and stores them in a set + * + * @param obj the field object of the current field + */ + @Override + public void visitField(Field obj) { + String fieldSig = obj.getSignature(); + if ("Ljavax/swing/JLabel;".equals(fieldSig)) { + FieldAnnotation fa = FieldAnnotation.fromVisitedField(this); + fieldLabels.add(fa); + } + } + + /** * implements the visitor to reset the stack * * @param obj the context object for the currently visited code block @@ -70,6 +85,16 @@ stack.resetForMethodEntry(this); localLabels.clear(); super.visitCode(obj); + for (SourceLineAnnotation sla : localLabels.values()) { + BugInstance bug = new BugInstance(this, "S508C_NO_SETLABELFOR", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this); + + if (sla != null) + bug.addSourceLine(sla); + + bugReporter.reportBug(bug); + } } /** @@ -82,7 +107,13 @@ try { stack.mergeJumps(this); if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { - int reg = RegisterUtils.getAStoreReg(this, seen); + if (stack.getStackDepth() > 0) { + OpcodeStack.Item item = stack.getStackItem(0); + if ("Ljavax/swing/JLabel;".equals(item.getSignature())) { + int reg = RegisterUtils.getAStoreReg(this, seen); + localLabels.put(new Integer(reg), SourceLineAnnotation.fromVisitedInstruction(this)); + } + } } else if (seen == INVOKEVIRTUAL) { String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); @@ -98,6 +129,21 @@ .addSourceLine(this)); } } + } else if ("javax/swing/JLabel".equals(className)) { + if ("setLabelFor".equals(methodName)) { + if (stack.getStackDepth() > 1) { + OpcodeStack.Item item = stack.getStackItem(1); + FieldAnnotation fa = item.getField(); + if (fa != null) + fieldLabels.remove(fa.getFieldName()); + else { + int reg = item.getRegisterNumber(); + if (reg >= 0) { + localLabels.remove(new Integer(reg)); + } + } + } + } } } } finally { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-23 02:00:40
|
Revision: 500 Author: dbrosius Date: 2006-04-22 19:00:31 -0700 (Sat, 22 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=500&view=rev Log Message: ----------- add setSize checks for Windows Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-23 01:39:07 UTC (rev 499) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-23 02:00:31 UTC (rev 500) @@ -185,7 +185,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.Section508Compliance" speed="fast" - reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR" /> + reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR,S508C_NO_SETSIZE" /> <!-- BugPattern --> @@ -233,4 +233,5 @@ <BugPattern abbrev="NRTL" type="NRTL_NON_RECYCLEABLE_TAG_LIB" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NULL_LAYOUT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="S508C" type="S508C_NO_SETSIZE" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-23 01:39:07 UTC (rev 499) +++ trunk/fb-contrib/etc/messages.xml 2006-04-23 02:00:31 UTC (rev 500) @@ -1117,6 +1117,18 @@ </Details> </BugPattern> + <BugPattern type="S508C_NO_SETSIZE"> + <ShortDescription>Window sets size manually, and doesn't use pack</ShortDescription> + <LongDescription>Window sets size manually, and doesn't use pack</LongDescription> + <Details> + <![CDATA[ + <p>This class creates a window, and sizes the window using setSize. It is better + to handle font size changes to use the pack method. + </p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-23 01:39:07 UTC (rev 499) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-23 02:00:31 UTC (rev 500) @@ -5,8 +5,11 @@ import java.util.Map; import java.util.Set; +import org.apache.bcel.Repository; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.Field; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.generic.Type; import com.mebigfatguy.fbcontrib.utils.RegisterUtils; @@ -24,6 +27,14 @@ */ public class Section508Compliance extends BytecodeScanningDetector { + private static JavaClass windowClass; + static { + try { + windowClass = Repository.lookupClass("java/awt/Window"); + } catch (ClassNotFoundException cnfe) { + windowClass = null; + } + } private BugReporter bugReporter; private OpcodeStack stack; private Set<FieldAnnotation> fieldLabels; @@ -144,8 +155,24 @@ } } } + } else if ("java/awt/Component".equals(className)) { + if ("setSize".equals(methodName)) { + int argCount = Type.getArgumentTypes(getSigConstantOperand()).length; + if ((windowClass != null) && (stack.getStackDepth() > argCount)) { + OpcodeStack.Item item = stack.getStackItem(argCount); + JavaClass cls = item.getJavaClass(); + if (cls.instanceOf(windowClass)) { + bugReporter.reportBug(new BugInstance(this, "S508C_NO_SETSIZE", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } } } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); } finally { stack.sawOpcode(this, seen); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-25 17:35:57
|
Revision: 502 Author: dbrosius Date: 2006-04-25 10:35:42 -0700 (Tue, 25 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=502&view=rev Log Message: ----------- add check for JComponent derived classes that don't implement the Accessible interface Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/S508C_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-25 17:19:19 UTC (rev 501) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-25 17:35:42 UTC (rev 502) @@ -185,7 +185,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.Section508Compliance" speed="fast" - reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR,S508C_NO_SETSIZE" /> + reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR,S508C_NO_SETSIZE,S508C_NON_ACCESSIBLE_JCOMPONENT" /> <!-- BugPattern --> @@ -234,4 +234,5 @@ <BugPattern abbrev="S508C" type="S508C_NULL_LAYOUT" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NO_SETSIZE" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="S508C" type="S508C_NON_ACCESSIBLE_JCOMPONENT" category="CORRECTNESS" experimental="true"/> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-25 17:19:19 UTC (rev 501) +++ trunk/fb-contrib/etc/messages.xml 2006-04-25 17:35:42 UTC (rev 502) @@ -1129,6 +1129,18 @@ </Details> </BugPattern> + <BugPattern type="S508C_NON_ACCESSIBLE_JCOMPONENT"> + <ShortDescription>Class extends JComponent but does not implement Accessible interface</ShortDescription> + <LongDescription>Class {0} extends JComponent but does not implement Accessible interface</LongDescription> + <Details> + <![CDATA[ + <p>This class extends the JComponent gui control but does not implement the Accessibility interface. + This makes this control unable to be processed by screen readers, etc, for people with reading/vision + difficulties</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> Modified: trunk/fb-contrib/samples/S508C_Sample.java =================================================================== --- trunk/fb-contrib/samples/S508C_Sample.java 2006-04-25 17:19:19 UTC (rev 501) +++ trunk/fb-contrib/samples/S508C_Sample.java 2006-04-25 17:35:42 UTC (rev 502) @@ -1,11 +1,13 @@ import java.awt.Container; +import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; public class S508C_Sample extends JFrame { private JLabel fLabel = new JLabel("Hello"); + private JComponent c = new MyComponent(); public S508C_Sample() { Container cp = getContentPane(); @@ -14,7 +16,13 @@ cp.add(fLabel); JLabel lLabel = new JLabel("there"); cp.add(lLabel); + cp.add(c); setSize(300, 200); } } + +class MyComponent extends JComponent +{ + +} Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-25 17:19:19 UTC (rev 501) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-25 17:35:42 UTC (rev 502) @@ -28,12 +28,24 @@ public class Section508Compliance extends BytecodeScanningDetector { private static JavaClass windowClass; + private static JavaClass jcomponentClass; + private static JavaClass accessibleClass; static { try { windowClass = Repository.lookupClass("java/awt/Window"); } catch (ClassNotFoundException cnfe) { windowClass = null; } + try { + jcomponentClass = Repository.lookupClass("javax/swing/JComponent"); + } catch (ClassNotFoundException cnfe) { + jcomponentClass = null; + } + try { + accessibleClass = Repository.lookupClass("javax.accessibility.Accessible"); + } catch (ClassNotFoundException cnfe) { + accessibleClass = null; + } } private BugReporter bugReporter; private OpcodeStack stack; @@ -56,6 +68,16 @@ @Override public void visitClassContext(ClassContext classContext) { try { + if ((jcomponentClass != null) && (accessibleClass != null)) { + JavaClass cls = classContext.getJavaClass(); + if (cls.instanceOf(jcomponentClass)) { + if (!cls.implementationOf(accessibleClass)) { + bugReporter.reportBug(new BugInstance(this, "S508C_NON_ACCESSIBLE_JCOMPONENT", NORMAL_PRIORITY) + .addClass(cls)); + } + } + } + stack = new OpcodeStack(); fieldLabels = new HashSet<FieldAnnotation>(); localLabels = new HashMap<Integer, SourceLineAnnotation>(); @@ -65,6 +87,8 @@ .addClass(this) .addField(fa)); } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); } finally { stack = null; fieldLabels = null; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-28 03:08:22
|
Revision: 505 Author: dbrosius Date: 2006-04-27 20:07:55 -0700 (Thu, 27 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=505&view=rev Log Message: ----------- initial checkin - new UEC Detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/UEC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseEnumCollections.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-27 03:27:09 UTC (rev 504) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-28 03:07:55 UTC (rev 505) @@ -187,6 +187,10 @@ speed="fast" reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR,S508C_NO_SETSIZE,S508C_NON_ACCESSIBLE_JCOMPONENT" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.UseEnumCollections" + speed="fast" + reports="UEC_USE_ENUM_COLLECTIONS" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -235,4 +239,5 @@ <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NO_SETSIZE" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NON_ACCESSIBLE_JCOMPONENT" category="CORRECTNESS" experimental="true"/> + <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-27 03:27:09 UTC (rev 504) +++ trunk/fb-contrib/etc/messages.xml 2006-04-28 03:07:55 UTC (rev 505) @@ -537,6 +537,15 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.UseEnumCollections"> + <Details> + <![CDATA[ + <p>looks for use of sets and maps using enums. It is more efficient to use EnumSet or EnumMap</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1141,6 +1150,17 @@ </Details> </BugPattern> + <BugPattern type="UEC_USE_ENUM_COLLECTIONS"> + <ShortDescription>Class uses an ordinary set or map with an enum class as the key</ShortDescription> + <LongDescription>Class {0} uses an ordinary set or map with an enum class as the key</LongDescription> + <Details> + <![CDATA[ + <p>This class uses an ordinary set or map collection and uses an enum class as the key type. + It is better performant to use the jdk 1.5 EnumSet or EnumMap classes.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1186,4 +1206,5 @@ <BugCode abbrev="NOS">Non Owned Synchronization</BugCode> <BugCode abbrev="NRTL">Non Recycleable Taglib</BugCode> <BugCode abbrev="S508C">Section 508 Compliance Violations</BugCode> + <BugCode abbrev="UEC">Use Enum Collections</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/UEC_Sample.java =================================================================== --- trunk/fb-contrib/samples/UEC_Sample.java (rev 0) +++ trunk/fb-contrib/samples/UEC_Sample.java 2006-04-28 03:07:55 UTC (rev 505) @@ -0,0 +1,31 @@ +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + + +public class UEC_Sample +{ + enum Suite { Spades, Hearts, Clubs, Diamonds }; + + private Set<Suite> wildSuites = new HashSet<Suite>(); + private EnumSet<Suite> eWildSuites = EnumSet.noneOf(Suite.class); + + public Map<Suite, Integer> deal() { + Map<Suite, Integer> hand = new HashMap<Suite, Integer>(); + hand.put(Suite.Spades, new Integer(10)); + hand.put(Suite.Hearts, new Integer(9)); + + return hand; + } + + public EnumMap<Suite, Integer> eDeal() { + EnumMap<Suite, Integer> hand = new EnumMap(Suite.class); + hand.put(Suite.Spades, new Integer(10)); + hand.put(Suite.Hearts, new Integer(9)); + + return hand; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseEnumCollections.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseEnumCollections.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseEnumCollections.java 2006-04-28 03:07:55 UTC (rev 505) @@ -0,0 +1,108 @@ +package com.mebigfatguy.fbcontrib.detect; + +import org.apache.bcel.Constants; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.Method; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for uses of sets or maps where the key is an enum. In these cases, it is + * more efficient to use EnumSet or EnumMap. It is a jdk1.5 only detector. + */ +public class UseEnumCollections extends BytecodeScanningDetector +{ + private static final int SEEN_NOTHING = 0; + private static final int SEEN_BIPUSH = 1; + private static final int SEEN_NEWINT = 2; + + private BugReporter bugReporter; + private int state; + private boolean methodReported; + /** + * constructs a UEC detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public UseEnumCollections(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + /** + * implements the visitor to check that the class is greater or equal than 1.5 + * + * @param classContext the context object for the currently parsed class + */ + public void visitClassContext(ClassContext classContext) { + try { + JavaClass cls = classContext.getJavaClass(); + if (cls.getMajor() >= Constants.MAJOR_1_5) { + super.visitClassContext(classContext); + } + } finally { + + } + } + + /** + * implements the visitor to reset the state + * + * @param obj the context object for the currently parsed method + */ + public void visitMethod(Method obj) { + state = SEEN_NOTHING; + methodReported = false; + super.visitMethod(obj); + } + + public void sawOpcode(int seen) { + if (methodReported) + return; + + switch (state) { + case SEEN_NOTHING: + if (seen == BIPUSH) + state = SEEN_BIPUSH; + break; + + case SEEN_BIPUSH: + if ((seen == INVOKESPECIAL) + && ("java/lang/Integer".equals(getClassConstantOperand()) + && ("<init>".equals(getNameConstantOperand()) + && ("(I)V".equals(getSigConstantOperand()))))) + state = SEEN_NEWINT; + else + state = SEEN_NOTHING; + break; + + case SEEN_NEWINT: + boolean bug = false; + if (seen == INVOKEINTERFACE) { + String clsName = getClassConstantOperand(); + String methodName = getNameConstantOperand(); + String signature = getSigConstantOperand(); + if (("java/util/Map".equals(clsName)) + && ("put".equals(methodName)) + && ("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;".equals(signature))) { + bug = true; + } else if (("java/util/Set".equals(clsName)) + && ("add".equals(methodName)) + && ("(Ljava/lang/Object;)Ljava/lang/Object;".equals(signature))) { + bug = true; + } + + if (bug) { + bugReporter.reportBug(new BugInstance(this, "UEC_USE_ENUM_COLLECTIONS", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + methodReported = true; + } + } + state = SEEN_NOTHING; + break; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-04-29 23:22:26
|
Revision: 509 Author: dbrosius Date: 2006-04-29 16:22:15 -0700 (Sat, 29 Apr 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=509&view=rev Log Message: ----------- new S508C bugpattern for setting explicit colors for controls Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/S508C_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-04-29 04:17:26 UTC (rev 508) +++ trunk/fb-contrib/etc/findbugs.xml 2006-04-29 23:22:15 UTC (rev 509) @@ -185,7 +185,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.Section508Compliance" speed="fast" - reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR,S508C_NO_SETSIZE,S508C_NON_ACCESSIBLE_JCOMPONENT" /> + reports="S508C_NULL_LAYOUT,S508C_NO_SETLABELFOR,S508C_NO_SETSIZE,S508C_NON_ACCESSIBLE_JCOMPONENT,S508C_SET_COMP_COLOR" /> <Detector class="com.mebigfatguy.fbcontrib.detect.UseEnumCollections" speed="fast" @@ -239,5 +239,6 @@ <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NO_SETSIZE" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="S508C" type="S508C_NON_ACCESSIBLE_JCOMPONENT" category="CORRECTNESS" experimental="true"/> + <BugPattern abbrev="S508C" type="S508C_SET_COMP_COLOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-04-29 04:17:26 UTC (rev 508) +++ trunk/fb-contrib/etc/messages.xml 2006-04-29 23:22:15 UTC (rev 509) @@ -1150,6 +1150,18 @@ </Details> </BugPattern> + <BugPattern type="S508C_SET_COMP_COLOR"> + <ShortDescription>Method explicitly sets the color of a Component</ShortDescription> + <LongDescription>Method {1} Method explicitly sets the color of a Component</LongDescription> + <Details> + <![CDATA[ + <p>This method sets a Components explicitly foreground or background color which may + cause difficulty with people with visions problems from using this application. + Colors should be allowed to be set from the operating system.</p> + ]]> + </Details> + </BugPattern> + <BugPattern type="UEC_USE_ENUM_COLLECTIONS"> <ShortDescription>Class uses an ordinary set or map with an enum class as the key</ShortDescription> <LongDescription>Class {0} uses an ordinary set or map with an enum class as the key</LongDescription> Modified: trunk/fb-contrib/samples/S508C_Sample.java =================================================================== --- trunk/fb-contrib/samples/S508C_Sample.java 2006-04-29 04:17:26 UTC (rev 508) +++ trunk/fb-contrib/samples/S508C_Sample.java 2006-04-29 23:22:15 UTC (rev 509) @@ -1,3 +1,4 @@ +import java.awt.Color; import java.awt.Container; import javax.swing.JComponent; @@ -15,6 +16,8 @@ cp.add(fLabel); JLabel lLabel = new JLabel("there"); + lLabel.setBackground(new Color(255, 0, 0)); + lLabel.setForeground(new Color(255, 255, 100)); cp.add(lLabel); cp.add(c); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-29 04:17:26 UTC (rev 508) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/Section508Compliance.java 2006-04-29 23:22:15 UTC (rev 509) @@ -28,6 +28,7 @@ public class Section508Compliance extends BytecodeScanningDetector { private static JavaClass windowClass; + private static JavaClass componentClass; private static JavaClass jcomponentClass; private static JavaClass accessibleClass; static { @@ -37,6 +38,11 @@ windowClass = null; } try { + componentClass = Repository.lookupClass("javax/awt/Component"); + } catch (ClassNotFoundException cnfe) { + componentClass = null; + } + try { jcomponentClass = Repository.lookupClass("javax/swing/JComponent"); } catch (ClassNotFoundException cnfe) { jcomponentClass = null; @@ -191,6 +197,22 @@ .addSourceLine(this)); } } + } + + if ("setBackground".equals(methodName) + || "setForeground".equals(methodName)) { + int argCount = Type.getArgumentTypes(getSigConstantOperand()).length; + if (stack.getStackDepth() > argCount) { + OpcodeStack.Item item = stack.getStackItem(argCount); + JavaClass cls = item.getJavaClass(); + if (((jcomponentClass != null) && cls.instanceOf(jcomponentClass)) + || ((componentClass != null) && cls.instanceOf(componentClass))) { + bugReporter.reportBug(new BugInstance(this, "S508C_SET_COMP_COLOR", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } } } } catch (ClassNotFoundException cnfe) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-05-05 05:52:05
|
Revision: 516 Author: dbrosius Date: 2006-05-04 22:51:49 -0700 (Thu, 04 May 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=516&view=rev Log Message: ----------- Initial checkin: SIL detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/SIL_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SQLInLoop.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-05-02 02:24:14 UTC (rev 515) +++ trunk/fb-contrib/etc/findbugs.xml 2006-05-05 05:51:49 UTC (rev 516) @@ -191,6 +191,10 @@ speed="fast" reports="UEC_USE_ENUM_COLLECTIONS" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.SQLInLoop" + speed="fast" + reports="SIL_SQL_IN_LOOP" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -232,13 +236,14 @@ <BugPattern abbrev="JVR" type="JVR_JDBC_VENDOR_RELIANCE" category="CORRECTNESS" /> <BugPattern abbrev="PMB" type="PMB_POSSIBLE_MEMORY_BLOAT" category="CORRECTNESS" /> <BugPattern abbrev="LSYC" type="LSYC_LOCAL_SYNCHRONIZED_COLLECTION" category="CORRECTNESS" /> - <BugPattern abbrev="FCBL" type="FCBL_FIELD_COULD_BE_LOCAL" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="NOS" type="NOS_NON_OWNED_SYNCHRONIZATION" category="STYLE" experimental="true" /> - <BugPattern abbrev="NRTL" type="NRTL_NON_RECYCLEABLE_TAG_LIB" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="S508C" type="S508C_NULL_LAYOUT" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="S508C" type="S508C_NO_SETSIZE" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="S508C" type="S508C_NON_ACCESSIBLE_JCOMPONENT" category="CORRECTNESS" experimental="true"/> - <BugPattern abbrev="S508C" type="S508C_SET_COMP_COLOR" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="FCBL" type="FCBL_FIELD_COULD_BE_LOCAL" category="CORRECTNESS" /> + <BugPattern abbrev="NOS" type="NOS_NON_OWNED_SYNCHRONIZATION" category="STYLE" /> + <BugPattern abbrev="NRTL" type="NRTL_NON_RECYCLEABLE_TAG_LIB" category="CORRECTNESS" /> + <BugPattern abbrev="S508C" type="S508C_NULL_LAYOUT" category="CORRECTNESS" /> + <BugPattern abbrev="S508C" type="S508C_NO_SETLABELFOR" category="CORRECTNESS" /> + <BugPattern abbrev="S508C" type="S508C_NO_SETSIZE" category="CORRECTNESS" /> + <BugPattern abbrev="S508C" type="S508C_NON_ACCESSIBLE_JCOMPONENT" category="CORRECTNESS" /> + <BugPattern abbrev="S508C" type="S508C_SET_COMP_COLOR" category="CORRECTNESS" /> + <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" /> + <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-05-02 02:24:14 UTC (rev 515) +++ trunk/fb-contrib/etc/messages.xml 2006-05-05 05:51:49 UTC (rev 516) @@ -546,6 +546,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.SQLInLoop"> + <Details> + <![CDATA[ + <p>looks for the execution of sql queries inside a loop. This pattern tends to be inefficient, + and often can be improved upon, by collecting all the keys needed for the query and issuing just + one query using an in clause with all the keys for all the queries previously needed in the loop.</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1173,6 +1184,20 @@ </Details> </BugPattern> + <BugPattern type="SIL_SQL_IN_LOOP"> + <ShortDescription>Method executes sql queries inside of loops</ShortDescription> + <LongDescription>Method {1} executes sql queries inside of loops</LongDescription> + <Details> + <![CDATA[ + <p>This method executes sql queries inside of a loop. This pattern is often inefficient + as the number of queries may mushroom in fencepost cases. It is probably more performant + to loop over the input and collect the key data needed for the query for all items, and + issue one query using an in clause, or similar construct, and then loop over this result + set, and fetch all the data at once. + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1219,4 +1244,5 @@ <BugCode abbrev="NRTL">Non Recycleable Taglib</BugCode> <BugCode abbrev="S508C">Section 508 Compliance Violations</BugCode> <BugCode abbrev="UEC">Use Enum Collections</BugCode> + <BugCode abbrev="SIL">SQL In Loop</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/SIL_Sample.java =================================================================== --- trunk/fb-contrib/samples/SIL_Sample.java (rev 0) +++ trunk/fb-contrib/samples/SIL_Sample.java 2006-05-05 05:51:49 UTC (rev 516) @@ -0,0 +1,20 @@ +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class SIL_Sample +{ + public void test(ResultSet rs) throws SQLException + { + Connection c = rs.getStatement().getConnection(); + PreparedStatement ps = c.prepareStatement("select foo from boo where moo = ?"); + + while (rs.next()) + { + int key = rs.getInt(1); + ps.setInt(1, key); + ResultSet mrs = ps.executeQuery(); + } + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SQLInLoop.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SQLInLoop.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SQLInLoop.java 2006-05-05 05:51:49 UTC (rev 516) @@ -0,0 +1,97 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.bcel.classfile.Code; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.ba.ClassContext; + +public class SQLInLoop extends BytecodeScanningDetector +{ + private static final Set<String> queryClasses = new HashSet<String>(); + static { + queryClasses.add("java/sql/Statement"); + queryClasses.add("java/sql/PreparedStatement"); + queryClasses.add("java/sql/CallableStatement"); + } + private static final Set<String> queryMethods = new HashSet<String>(); + static { + queryMethods.add("execute"); + queryMethods.add("executeQuery"); + }; + + private BugReporter bugReporter; + List<Integer> queryLocations; + List<LoopLocation> loops; + + public SQLInLoop(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + @Override + public void visitClassContext(ClassContext classContext) { + try { + queryLocations = new ArrayList<Integer>(); + loops = new ArrayList<LoopLocation>(); + super.visitClassContext(classContext); + } finally { + queryLocations = null; + loops = null; + } + } + + @Override + public void visitCode(Code obj) { + queryLocations.clear(); + loops.clear(); + super.visitCode(obj); + for (Integer qLoc : queryLocations) { + for (LoopLocation lLoc : loops) { + if (lLoc.isInLoop(qLoc.intValue())) { + bugReporter.reportBug(new BugInstance(this, "SIL_SQL_IN_LOOP", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this, qLoc.intValue())); + break; + } + } + } + } + + @Override + public void sawOpcode(int seen) { + if (seen == INVOKEINTERFACE) { + String clsName = getClassConstantOperand(); + String methodName = getNameConstantOperand(); + + if (queryClasses.contains(clsName) && queryMethods.contains(methodName)) + queryLocations.add(new Integer(getPC())); + } else if ((seen == GOTO) || (seen == GOTO_W)) { + int branchTarget = getBranchTarget(); + int pc = getPC(); + if (branchTarget < pc) { + loops.add(new LoopLocation(branchTarget, pc)); + } + } + } + + private static class LoopLocation { + private int startPC; + private int endPC; + + public LoopLocation(int start, int end) { + startPC = start; + endPC = end; + } + + public boolean isInLoop(int pc) { + return (pc >= startPC) && (pc <= endPC); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-05-09 07:26:05
|
Revision: 523 Author: dbrosius Date: 2006-05-09 00:25:51 -0700 (Tue, 09 May 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=523&view=rev Log Message: ----------- add xml infrastructure for NMCS Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessMemberCollectionSynchronization.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-05-09 07:25:19 UTC (rev 522) +++ trunk/fb-contrib/etc/findbugs.xml 2006-05-09 07:25:51 UTC (rev 523) @@ -195,6 +195,10 @@ speed="fast" reports="SIL_SQL_IN_LOOP" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.NeedlessMemberCollectionSynchronization" + speed="moderate" + reports="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -246,4 +250,5 @@ <BugPattern abbrev="S508C" type="S508C_SET_COMP_COLOR" category="CORRECTNESS" /> <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" /> <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-05-09 07:25:19 UTC (rev 522) +++ trunk/fb-contrib/etc/messages.xml 2006-05-09 07:25:51 UTC (rev 523) @@ -557,6 +557,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.NeedlessMemberCollectionSynchronization"> + <Details> + <![CDATA[ + <p>looks for classes that define private synchronized collections as static or instance + members, that are only altered in a static initializer or constructor. Since the multithreaded + use of this collection is read-only, the use of synchronization is unnecessary.</p> + <p>It is a moderately fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1193,11 +1204,24 @@ as the number of queries may mushroom in fencepost cases. It is probably more performant to loop over the input and collect the key data needed for the query for all items, and issue one query using an in clause, or similar construct, and then loop over this result - set, and fetch all the data at once. + set, and fetch all the data at once.</p> ]]> </Details> </BugPattern> + <BugPattern type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION"> + <ShortDescription>Class defines unneeded synchronization on member collection</ShortDescription> + <LongDescription>Class {0} defines unneeded synchronization on member collection</LongDescription> + <Details> + <![CDATA[ + <p>This class defines a private collection member as synchronized. It appears however + that this collection isn't only modified in a static initializer, or constructor. As these + two areas are guaranteed to be thread safe, defining this collection as synchronized is + unnecessary and a potential performance bottleneck.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1245,4 +1269,5 @@ <BugCode abbrev="S508C">Section 508 Compliance Violations</BugCode> <BugCode abbrev="UEC">Use Enum Collections</BugCode> <BugCode abbrev="SIL">SQL In Loop</BugCode> + <BugCode abbrev="NMCS">Needless Member Collection Synchronization</BugCode> </MessageCollection> \ No newline at end of file Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessMemberCollectionSynchronization.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessMemberCollectionSynchronization.java 2006-05-09 07:25:19 UTC (rev 522) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessMemberCollectionSynchronization.java 2006-05-09 07:25:51 UTC (rev 523) @@ -103,7 +103,7 @@ String signature = obj.getSignature(); if (signature.charAt(0) == 'L') { try { - JavaClass cls = Repository.lookupClass(signature); + JavaClass cls = Repository.lookupClass(signature.substring(1, signature.length() - 1)); if (cls.implementationOf(collectionClass)) { FieldAnnotation fa = FieldAnnotation.fromVisitedField(this); if (obj.isStatic()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-05-15 03:27:08
|
Revision: 535 Author: dbrosius Date: 2006-05-14 20:26:53 -0700 (Sun, 14 May 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=535&view=rev Log Message: ----------- initial checkin - new ITC Detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/ITC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InheritanceTypeChecking.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-05-15 02:06:52 UTC (rev 534) +++ trunk/fb-contrib/etc/findbugs.xml 2006-05-15 03:26:53 UTC (rev 535) @@ -199,6 +199,10 @@ speed="moderate" reports="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.InheritanceTypeChecking" + speed="moderate" + reports="ITC_INHERITANCE_TYPE_CHECKING" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -251,4 +255,5 @@ <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" /> <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-05-15 02:06:52 UTC (rev 534) +++ trunk/fb-contrib/etc/messages.xml 2006-05-15 03:26:53 UTC (rev 535) @@ -568,6 +568,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.InheritanceTypeChecking"> + <Details> + <![CDATA[ + <p>looks for if/else blocks where a series of them use instanceof on the same + variable to determine what do to. If these classes are related by inheritance, + this often is better handled through calling a single overridden method.</p> + <p>It is a moderately fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1222,6 +1233,19 @@ </Details> </BugPattern> + <BugPattern type="ITC_INHERITANCE_TYPE_CHECKING"> + <ShortDescription>Method uses instanceof on multiple types to arbitrate logic</ShortDescription> + <LongDescription>Method {1} uses instanceof on multiple types to arbitrate logic</LongDescription> + <Details> + <![CDATA[ + <p>This method uses the instanceof operator in a series of if/else statements to + differentiate blocks of code based on type. If these types are related by inheritance, + it is cleaner to just define a method in the base class, and use overridden methods + in these classes.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1270,4 +1294,5 @@ <BugCode abbrev="UEC">Use Enum Collections</BugCode> <BugCode abbrev="SIL">SQL In Loop</BugCode> <BugCode abbrev="NMCS">Needless Member Collection Synchronization</BugCode> + <BugCode abbrev="ITC">Inheritance Type Checking</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/ITC_Sample.java =================================================================== --- trunk/fb-contrib/samples/ITC_Sample.java (rev 0) +++ trunk/fb-contrib/samples/ITC_Sample.java 2006-05-15 03:26:53 UTC (rev 535) @@ -0,0 +1,19 @@ +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; + +public class ITC_Sample +{ + public String test(List<String> l) + { + if (l instanceof ArrayList) + return (String)((ArrayList)l).remove(0); + else if (l instanceof LinkedList) + return (String)((LinkedList) l).removeFirst(); + else if (l instanceof Vector) + return (String)((Vector) l).remove(0); + else + return null; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InheritanceTypeChecking.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InheritanceTypeChecking.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InheritanceTypeChecking.java 2006-05-15 03:26:53 UTC (rev 535) @@ -0,0 +1,172 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 Dave Brosius + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.bcel.classfile.Code; + +import com.mebigfatguy.fbcontrib.utils.RegisterUtils; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for if/else blocks where a series of them use instanceof on the same + * variable to determine what do to. If these classes are related by inheritance, + * this often is better handled through calling a single overridden method. + */ +public class InheritanceTypeChecking extends BytecodeScanningDetector +{ + private BugReporter bugReporter; + private Set<IfStatement> ifStatements; + + /** + * constructs a ITC detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public InheritanceTypeChecking(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + /** + * implements the visitor to allocate and clear the ifStatements set + * + * @param classContext the context object of the currently parsed class + */ + @Override + public void visitClassContext(ClassContext classContext) { + try { + ifStatements = new HashSet<IfStatement>(); + super.visitClassContext(classContext); + } finally { + ifStatements = null; + } + } + + /** + * implements the visitor to clear the ifStatements set + * + * @param obj the context object of the currently parsed code block + */ + @Override + public void visitCode(Code obj) { + ifStatements.clear(); + super.visitCode(obj); + } + + /** + * implements the visitor to find if/else code that checks types using + * instanceof, and these types are related by inheritance. + * + * @param seen the opcode of the currently parsed instruction + */ + @Override + public void sawOpcode(int seen) { + boolean processed = false; + Iterator<IfStatement> isi = ifStatements.iterator(); + while (isi.hasNext()) { + int action = isi.next().processOpcode(this, bugReporter, seen); + if (action == IfStatement.REMOVE_ACTION) + isi.remove(); + else if (action == IfStatement.PROCESSED_ACTION) + processed = true; + } + + if (!processed) { + if ((seen == ALOAD) + || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) { + IfStatement is = new IfStatement(this, seen); + ifStatements.add(is); + } + } + } + + private static class IfStatement { + public static final int NO_ACTION = 0; + public static final int REMOVE_ACTION = 1; + public static final int PROCESSED_ACTION = 2; + + private final static int SEEN_ALOAD = 1; + private final static int SEEN_INSTANCEOF = 2; + private final static int SEEN_IFEQ = 3; + + private int state; + private int reg; + private int firstPC; + private int branchTarget; + private int matchCount; + private Set<String> instanceOfTypes; + + public IfStatement(BytecodeScanningDetector bsd, int seen) { + state = SEEN_ALOAD; + reg = RegisterUtils.getALoadReg(bsd, seen); + matchCount = 0; + firstPC = bsd.getPC(); + } + + public int processOpcode(BytecodeScanningDetector bsd, BugReporter bugReporter, int seen) { + switch (state) { + case SEEN_ALOAD: + if (seen == INSTANCEOF) { + if (instanceOfTypes == null) + instanceOfTypes = new HashSet<String>(); + instanceOfTypes.add(bsd.getClassConstantOperand()); + state = SEEN_INSTANCEOF; + return PROCESSED_ACTION; + } + break; + + case SEEN_INSTANCEOF: + if (seen == IFEQ) { + branchTarget = bsd.getBranchTarget(); + state = SEEN_IFEQ; + matchCount++; + return PROCESSED_ACTION; + } + break; + + case SEEN_IFEQ: + if (bsd.getPC() == branchTarget) { + if ((seen == ALOAD) + || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) { + if (reg == RegisterUtils.getALoadReg(bsd, seen)) { + state = SEEN_ALOAD; + return PROCESSED_ACTION; + } + } + if (matchCount > 1) { + bugReporter.reportBug(new BugInstance(bsd, "ITC_INHERITANCE_TYPE_CHECKING", NORMAL_PRIORITY) + .addClass(bsd) + .addMethod(bsd) + .addSourceLine(bsd, firstPC)); + return REMOVE_ACTION; + } + } + return NO_ACTION; + } + + return REMOVE_ACTION; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-05-16 04:17:46
|
Revision: 538 Author: dbrosius Date: 2006-05-15 21:17:35 -0700 (Mon, 15 May 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=538&view=rev Log Message: ----------- initial checkin - new SACM Detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/SACM_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StaticArrayCreatedInMethod.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-05-16 03:10:39 UTC (rev 537) +++ trunk/fb-contrib/etc/findbugs.xml 2006-05-16 04:17:35 UTC (rev 538) @@ -203,6 +203,10 @@ speed="moderate" reports="ITC_INHERITANCE_TYPE_CHECKING" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.StaticArrayCreatedInMethod" + speed="fast" + reports="SACM_STATIC_ARRAY_CREATED_IN_METHOD" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -256,4 +260,5 @@ <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" experimental="true" /> + <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-05-16 03:10:39 UTC (rev 537) +++ trunk/fb-contrib/etc/messages.xml 2006-05-16 04:17:35 UTC (rev 538) @@ -579,6 +579,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.StaticArrayCreatedInMethod"> + <Details> + <![CDATA[ + <p>looks for creation of arrays in methods using constant values. These arrays + will need to be recreated each time the method is called. These arrays should probably + be defined as static fields, instead</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1246,6 +1257,18 @@ </Details> </BugPattern> + <BugPattern type="SACM_STATIC_ARRAY_CREATED_IN_METHOD"> + <ShortDescription>Method creates array using constants</ShortDescription> + <LongDescription>Method {1} creates array using constants</LongDescription> + <Details> + <![CDATA[ + <p>This method creates an initialized by constants. Each time this method is called + this array will be recreated. It would be more performant to define the array as a + static field of the class instead.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1295,4 +1318,5 @@ <BugCode abbrev="SIL">SQL In Loop</BugCode> <BugCode abbrev="NMCS">Needless Member Collection Synchronization</BugCode> <BugCode abbrev="ITC">Inheritance Type Checking</BugCode> + <BugCode abbrev="SACM">Static Array Created in Method</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/SACM_Sample.java =================================================================== --- trunk/fb-contrib/samples/SACM_Sample.java (rev 0) +++ trunk/fb-contrib/samples/SACM_Sample.java 2006-05-16 04:17:35 UTC (rev 538) @@ -0,0 +1,12 @@ + +public class SACM_Sample +{ + public String test(int i) + { + String[] giantSounds = new String[] { "fee", "fi", "fo", "fum", "burp", "fart" }; + if ((i < 0) || (i >= giantSounds.length)) + return ""; + + return giantSounds[i]; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StaticArrayCreatedInMethod.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StaticArrayCreatedInMethod.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/StaticArrayCreatedInMethod.java 2006-05-16 04:17:35 UTC (rev 538) @@ -0,0 +1,136 @@ +package com.mebigfatguy.fbcontrib.detect; + +import org.apache.bcel.classfile.Code; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for creation of arrays where the contents are constants, or static + * fields, and the array isn't further modified. These arrays should probably + * be defined as static fields so the method doesn't constantly recreate the array + * each time it is called. + */ +public class StaticArrayCreatedInMethod extends BytecodeScanningDetector +{ + private static final int SEEN_NOTHING = 0; + private static final int SEEN_ARRAY_SIZE = 1; + private static final int SEEN_NEWARRAY = 2; + private static final int SEEN_DUP = 3; + private static final int SEEN_INDEX = 4; + private static final int SEEN_LDC = 5; + private static final int SEEN_INDEX_STORE = 6; + + private BugReporter bugReporter; + private int arraySize; + private int storeCount; + private int state; + + public StaticArrayCreatedInMethod(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + @Override + public void visitClassContext(ClassContext classContext) { + try { + super.visitClassContext(classContext); + } finally { + + } + } + + /** + * implements the visitor by forwarding calls for methods that are the static initializer + * + * @obj the context object of the currently parsed code block + */ + @Override + public void visitCode(Code obj) { + if (!"<clinit>".equals(getMethodName())) { + state = SEEN_NOTHING; + super.visitCode(obj); + } + } + + /** + * implements the visitor to look for creation of local arrays using constant values + * + * @param seen the opcode of the currently parsed instruction + */ + @Override + public void sawOpcode(int seen) { + int index; + + switch (state) { + case SEEN_NOTHING: + if (seen == BIPUSH) { + arraySize = getIntConstant(); + state = SEEN_ARRAY_SIZE; + }else if ((seen >= ICONST_M1) && (seen <= ICONST_5)) { + arraySize = seen - ICONST_M1 - 1; + state = SEEN_ARRAY_SIZE; + } + break; + + case SEEN_ARRAY_SIZE: + if ((seen == ANEWARRAY) || (seen == NEWARRAY)) { + state = SEEN_NEWARRAY; + storeCount = 0; + } + else + state = SEEN_NOTHING; + break; + + case SEEN_NEWARRAY: + if (seen == DUP) + state = SEEN_DUP; + else + state = SEEN_NOTHING; + break; + + case SEEN_DUP: + if (seen == BIPUSH) + index = getIntConstant(); + else if ((seen >= ICONST_M1) && (seen <= ICONST_5)) + index = seen - ICONST_M1 - 1; + else { + state = SEEN_NOTHING; + return; + } + if (index != storeCount) + state = SEEN_NOTHING; + else + state = SEEN_INDEX; + break; + + case SEEN_INDEX: + if (seen == LDC) + state = SEEN_LDC; + else + state = SEEN_NOTHING; + break; + + case SEEN_LDC: + if ((seen >= IASTORE) && (seen <= SASTORE)) { + if ((++storeCount) == arraySize) + state = SEEN_INDEX_STORE; + else + state = SEEN_NEWARRAY; + } + break; + + case SEEN_INDEX_STORE: + if ((seen == ASTORE) + || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { + bugReporter.reportBug(new BugInstance(this, "SACM_STATIC_ARRAY_CREATED_IN_METHOD", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this, getPC())); + } + state = SEEN_NOTHING; + break; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-06-06 04:13:31
|
Revision: 548 Author: dbrosius Date: 2006-06-05 21:13:16 -0700 (Mon, 05 Jun 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=548&view=rev Log Message: ----------- Initial Checkin new RMC detector. Likely to have many false positives at present. Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/RMC_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-06-04 03:43:32 UTC (rev 547) +++ trunk/fb-contrib/etc/findbugs.xml 2006-06-06 04:13:16 UTC (rev 548) @@ -207,6 +207,10 @@ speed="fast" reports="SACM_STATIC_ARRAY_CREATED_IN_METHOD" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.RedundantMethodCalls" + speed="fast" + reports="RMC_REDUNDANT_METHOD_CALLS" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -261,4 +265,5 @@ <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" experimental="true" /> <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="RMC" type="RMC_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-06-04 03:43:32 UTC (rev 547) +++ trunk/fb-contrib/etc/messages.xml 2006-06-06 04:13:16 UTC (rev 548) @@ -589,7 +589,17 @@ <p>It is a fast detector</p> ]]> </Details> - </Detector> + </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.RedundantMethodCalls"> + <Details> + <![CDATA[ + <p>looks for calls of the same method on the same object when that object hasn't changed. + This often is redundant, and the second call can be removed, or combined.</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1270,6 +1280,20 @@ </Details> </BugPattern> + <BugPattern type="RMC_REDUNDANT_METHOD_CALLS"> + <ShortDescription>Method calls the same method on the same object redundantly</ShortDescription> + <LongDescription>Method {1} calls the same method on the same object redundantly</LongDescription> + <Details> + <![CDATA[ + <p>This method makes two consecutive calls to the same method using the same constant + parameters, on the same instance without any intervening changes to the objects. If this + method does not make changes to the object, which it appears it doesn't, then making + two calls is just a waste. These method calls could be combined by assigning the + result into a temporary, and using the temporary the second time. + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1320,4 +1344,5 @@ <BugCode abbrev="NMCS">Needless Member Collection Synchronization</BugCode> <BugCode abbrev="ITC">Inheritance Type Checking</BugCode> <BugCode abbrev="SACM">Static Array Created in Method</BugCode> + <BugCode abbrev="RMC">Redundant Method Calls</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/RMC_Sample.java =================================================================== --- trunk/fb-contrib/samples/RMC_Sample.java (rev 0) +++ trunk/fb-contrib/samples/RMC_Sample.java 2006-06-06 04:13:16 UTC (rev 548) @@ -0,0 +1,14 @@ +import java.util.Calendar; +import java.util.Date; + +public class RMC_Sample +{ + public boolean test1(Calendar c) + { + Date d = c.getTime(); + long l = d.getTime(); + Date e = c.getTime(); + long j = e.getTime(); + return l == j; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/RedundantMethodCalls.java 2006-06-06 04:13:16 UTC (rev 548) @@ -0,0 +1,167 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.generic.Type; + +import com.mebigfatguy.fbcontrib.utils.Integer14; +import com.mebigfatguy.fbcontrib.utils.RegisterUtils; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; +import edu.umd.cs.findbugs.FieldAnnotation; +import edu.umd.cs.findbugs.OpcodeStack; +import edu.umd.cs.findbugs.ba.ClassContext; + +/** + * looks for calls of the same method on the same object when that object hasn't changed. + * This often is redundant, and the second call can be removed, or combined. + */ +public class RedundantMethodCalls extends BytecodeScanningDetector +{ + private static Set<String> riskyMethodNameContents = new HashSet<String>(); + static { + riskyMethodNameContents.add("next"); + riskyMethodNameContents.add("add"); + riskyMethodNameContents.add("put"); + riskyMethodNameContents.add("remove"); + } + private BugReporter bugReporter; + private OpcodeStack stack = null; + private Map<Integer, MethodCall> localMethodCalls = null; + private Map<String, MethodCall> fieldMethodCalls = null; + private Set<Integer> branchTargets = null; + + public RedundantMethodCalls(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + public void visitClassContext(ClassContext classContext) { + try { + stack = new OpcodeStack(); + localMethodCalls = new HashMap<Integer, MethodCall>(); + fieldMethodCalls = new HashMap<String, MethodCall>(); + branchTargets = new HashSet<Integer>(); + super.visitClassContext(classContext); + } finally { + stack = null; + localMethodCalls = null; + fieldMethodCalls = null; + branchTargets = null; + } + } + public void visitCode(Code obj) { + stack.resetForMethodEntry(this); + localMethodCalls.clear(); + fieldMethodCalls.clear(); + super.visitCode(obj); + } + + public void sawOpcode(int seen) { + try { + stack.mergeJumps(this); + if (branchTargets.remove(Integer14.valueOf(getPC()))) { + localMethodCalls.clear(); + fieldMethodCalls.clear(); + } + + if (((seen >= IFEQ) && (seen <= GOTO)) || ((seen >= IFNULL) && (seen <= GOTO_W))) { + branchTargets.add(Integer14.valueOf(getBranchTarget())); + } else if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { + localMethodCalls.remove(Integer14.valueOf(RegisterUtils.getAStoreReg(this, seen))); + } else if (seen == PUTFIELD) { + fieldMethodCalls.remove(getNameConstantOperand()); + } else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) { + String methodName = getNameConstantOperand(); + String signature = getSigConstantOperand(); + int parmCount = Type.getArgumentTypes(signature).length; + if (stack.getStackDepth() > parmCount) { + Object[] parmConstants = new Object[parmCount]; + for (int i = 0; i < parmCount; i++) { + OpcodeStack.Item parm = stack.getStackItem(i); + parmConstants[i] = parm.getConstant(); + if (parmConstants[i] == null) + return; + } + OpcodeStack.Item obj = stack.getStackItem(parmCount); + int reg = obj.getRegisterNumber(); + FieldAnnotation fa = obj.getField(); + + MethodCall mc; + if (reg >= 0) { + mc = localMethodCalls.get(Integer14.valueOf(reg)); + } else if (fa != null) { + mc = fieldMethodCalls.get(fa.getFieldName()); + } else + return; + + if (mc != null) { + if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(methodName)) { + Object[] parms = mc.getParms(); + if (Arrays.equals(parms, parmConstants)) { + bugReporter.reportBug(new BugInstance(this, "RMC_REDUNDANT_METHOD_CALLS", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + if (reg >= 0) { + localMethodCalls.remove(Integer14.valueOf(reg)); + } else { + fieldMethodCalls.remove(fa.getFieldName()); + } + } else { + if (reg >= 0) { + localMethodCalls.put(Integer14.valueOf(reg), new MethodCall(methodName, signature, parmConstants)); + } else if (fa != null) { + fieldMethodCalls.put(fa.getFieldName(), new MethodCall(methodName, signature, parmConstants)); + } + } + } + } + } finally { + stack.sawOpcode(this, seen); + } + } + + private boolean isRiskyName(String methodName) { + methodName = methodName.toLowerCase(Locale.ENGLISH); + for (String riskyName : riskyMethodNameContents) { + if (methodName.indexOf(riskyName) >= 0) + return true; + } + return false; + } + + private static class MethodCall + { + private String methodName; + private String methodSignature; + private Object[] methodParms; + + private MethodCall(String name, String signature, Object[] parms) { + methodName = name; + methodSignature = signature; + methodParms = parms; + } + + private String getName() { + return methodName; + } + + private String getSignature() { + return methodSignature; + } + + private Object[] getParms() { + return methodParms; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-06-09 02:04:41
|
Revision: 562 Author: dbrosius Date: 2006-06-08 19:04:31 -0700 (Thu, 08 Jun 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=562&view=rev Log Message: ----------- add ISB_EMPTY_STRING_APPENDING bug pattern to ISB Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml trunk/fb-contrib/samples/ISB_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-06-08 17:52:39 UTC (rev 561) +++ trunk/fb-contrib/etc/findbugs.xml 2006-06-09 02:04:31 UTC (rev 562) @@ -15,7 +15,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.InefficientStringBuffering" speed="fast" - reports="ISB_INEFFICIENT_STRING_BUFFERING" /> + reports="ISB_INEFFICIENT_STRING_BUFFERING,ISB_EMPTY_STRING_APPENDING" /> <Detector class="com.mebigfatguy.fbcontrib.detect.SyncCollectionIterators" speed="slow" @@ -214,6 +214,7 @@ <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> + <BugPattern abbrev="ISB" type="ISB_EMPTY_STRING_APPENDING" category="PERFORMANCE" /> <BugPattern abbrev="SCI" type="SCI_SYNCHRONIZED_COLLECTION_ITERATORS" category="CORRECTNESS" /> <BugPattern abbrev="CC" type="CC_CYCLOMATIC_COMPLEXITY" category="STYLE" /> <BugPattern abbrev="OCP" type="OCP_OVERLY_CONCRETE_PARAMETER" category="STYLE" /> Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-06-08 17:52:39 UTC (rev 561) +++ trunk/fb-contrib/etc/messages.xml 2006-06-09 02:04:31 UTC (rev 562) @@ -615,6 +615,19 @@ </Details> </BugPattern> + <BugPattern type="ISB_EMPTY_STRING_APPENDING"> + <ShortDescription>method concatenates an empty string to effect type conversion</ShortDescription> + <LongDescription>method {1} concatenates an empty string to effect type conversion</LongDescription> + <Details> + <![CDATA[ + <p> This method concatenates an empty string with a literal value, in order to convert + the literal value into a string. It is more efficient to use String.valueOf() to do the same + thing as you do not incur the cost of creating a StringBuffer/Builder and calling methods on it + to accomplish this.</p> + ]]> + </Details> + </BugPattern> + <BugPattern type="SCI_SYNCHRONIZED_COLLECTION_ITERATORS"> <ShortDescription>method creates iterators on synchronized collections</ShortDescription> <LongDescription>method {1} creates iterators on synchronized collections</LongDescription> Modified: trunk/fb-contrib/samples/ISB_Sample.java =================================================================== --- trunk/fb-contrib/samples/ISB_Sample.java 2006-06-08 17:52:39 UTC (rev 561) +++ trunk/fb-contrib/samples/ISB_Sample.java 2006-06-09 02:04:31 UTC (rev 562) @@ -38,6 +38,11 @@ return msg; } + public String testISB8(int a) + { + return "" + a; + } + public String toString() { String a = System.getProperty("foo"); Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java 2006-06-08 17:52:39 UTC (rev 561) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/InefficientStringBuffering.java 2006-06-09 02:04:31 UTC (rev 562) @@ -19,6 +19,8 @@ package com.mebigfatguy.fbcontrib.detect; import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.Constant; +import org.apache.bcel.classfile.ConstantString; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; @@ -75,6 +77,26 @@ .addSourceLine(this)); } } + } else if (seen == INVOKEVIRTUAL) { + String calledClass = getClassConstantOperand(); + if (("java/lang/StringBuffer".equals(calledClass) + || "java/lang/StringBuilder".equals(calledClass)) + && "append".equals(getNameConstantOperand()) + && getSigConstantOperand().startsWith("(Ljava/lang/String;)")) { + if (opStack.getStackDepth() > 0) { + OpcodeStack.Item itm = opStack.getStackItem(0); + Object cons = itm.getConstant(); + if ((cons instanceof String) && (itm.getRegisterNumber() < 0)) { + if (((String)cons).length() == 0) { + bugReporter.reportBug( + new BugInstance(this, "ISB_EMPTY_STRING_APPENDING", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + } } else if (seen == GOTO) { int depth = opStack.getStackDepth(); for (int i = 0; i < depth; i++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-06-19 00:06:12
|
Revision: 564 Author: dbrosius Date: 2006-06-18 17:05:58 -0700 (Sun, 18 Jun 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=564&view=rev Log Message: ----------- start working on UTA - not working yet. Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/UTA_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/MapEntry.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-06-09 03:29:47 UTC (rev 563) +++ trunk/fb-contrib/etc/findbugs.xml 2006-06-19 00:05:58 UTC (rev 564) @@ -211,6 +211,11 @@ speed="fast" reports="RMC_REDUNDANT_METHOD_CALLS" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.UseToArray" + speed="fast" + reports="UTA_USE_TO_ARRAY" + hidden="true" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -267,4 +272,5 @@ <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" experimental="true" /> <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" experimental="true" /> <BugPattern abbrev="RMC" type="RMC_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="UTA" type="UTA_USE_TO_ARRAY" category="STYLE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-06-09 03:29:47 UTC (rev 563) +++ trunk/fb-contrib/etc/messages.xml 2006-06-19 00:05:58 UTC (rev 564) @@ -600,6 +600,18 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.UseToArray"> + <Details> + <![CDATA[ + <p>looks for code that builds an array of values from a collection, by manually looping + over the elements of the collection, and adding them to the array. It is simpler and + cleaner to use mycollection.toArray(new type[mycollection.size()].</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> + <!-- BugPattern --> @@ -1307,6 +1319,19 @@ </Details> </BugPattern> + <BugPattern type="UTA_USE_TO_ARRAY"> + <ShortDescription>Method manually creates array from collection</ShortDescription> + <LongDescription>Method {1} manually creates array from collection</LongDescription> + <Details> + <![CDATA[ + <p>This method manually loops over a collection, pulling each element out and storing + it in an array to build an array from the collection. It is easier, and clearer to use + the built in collections method toArray. Given a collection 'mycollection' of type T, use + mycollection.toArray(new T[mycollection.size()]); + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1358,4 +1383,5 @@ <BugCode abbrev="ITC">Inheritance Type Checking</BugCode> <BugCode abbrev="SACM">Static Array Created in Method</BugCode> <BugCode abbrev="RMC">Redundant Method Calls</BugCode> + <BugCode abbrev="UTA">Use toArray</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/UTA_Sample.java =================================================================== --- trunk/fb-contrib/samples/UTA_Sample.java (rev 0) +++ trunk/fb-contrib/samples/UTA_Sample.java 2006-06-19 00:05:58 UTC (rev 564) @@ -0,0 +1,23 @@ +import java.util.List; + +public class UTA_Sample +{ + public String[] testList1(List<String> l) + { + String[] data = new String[l.size()]; + for (int i = 0; i < l.size(); i++) + data[i] = l.get(i); + + return data; + } + + public Integer[] testList2(List<Integer> l) + { + int size = l.size(); + Integer[] data = new Integer[size]; + for (int i = 0; i < size; i++) + data[i] = l.get(i); + + return data; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java 2006-06-19 00:05:58 UTC (rev 564) @@ -0,0 +1,197 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 Dave Brosius + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +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 com.mebigfatguy.fbcontrib.utils.Integer14; +import com.mebigfatguy.fbcontrib.utils.MapEntry; +import com.mebigfatguy.fbcontrib.utils.RegisterUtils; + +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; + +public class UseToArray extends BytecodeScanningDetector +{ + private static JavaClass collectionClass; + private static ClassNotFoundException ex; + static { + try { + collectionClass = Repository.lookupClass("java/util/Collection"); + } catch (ClassNotFoundException cnfe) { + collectionClass = null; + ex = cnfe; + } + } + + private BugReporter bugReporter; + private OpcodeStack stack; + private Map<Integer, Object> userValues; + /** map of pc of loop starts to map entry of index register to collection register */ + private Map<Integer, Map.Entry<Integer, Integer>> loopStarts; + + + /** + * constructs a UTA detector given the reporter to report bugs on + * @param bugReporter the sync of bug reports + */ + public UseToArray(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + public void visitClassContext(ClassContext classContext) { + if (collectionClass == null) { + if (ex != null) { + bugReporter.reportMissingClass(ex); + ex = null; + } + return; + } + + try { + stack = new OpcodeStack(); + super.visitClassContext(classContext); + } finally { + stack = null; + } + } + + @Override + public void visitCode(Code obj) { + try { + stack.resetForMethodEntry(this); + userValues = new HashMap<Integer, Object>(); + loopStarts = new HashMap<Integer, Map.Entry<Integer, Integer>>(); + super.visitCode(obj); + } finally { + userValues = null; + loopStarts = null; + } + } + + @Override + public void sawOpcode(int seen) { + int reg = -1; + Object uValue = null; + boolean sawSize = false; + boolean sawLoad = false; + boolean sawNewArray = false; + + try { + if (seen == INVOKEINTERFACE) { + if ("size".equals(getNameConstantOperand()) && "()I".equals(getSigConstantOperand())) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + reg = isLocalCollection(itm); + if (reg >= 0) { + sawSize = true; + } + } + } + } else if (((seen == ISTORE) || ((seen >= ISTORE_0) && (seen <= ISTORE_3))) + || ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3)))) { + if (stack.getStackDepth() > 0) { + reg = Integer14.valueOf(RegisterUtils.getStoreReg(this, seen)); + uValue = stack.getStackItem(0).getUserValue(); + userValues.put(reg, uValue); + } + } else if (((seen == ILOAD) || ((seen >= ILOAD_0) && (seen <= ILOAD_3))) + || ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3)))) { + sawLoad = true; + } else if (seen == ANEWARRAY) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + uValue = itm.getUserValue(); + sawNewArray = true; + } + } else if (seen == IF_ICMPGE) { + if (stack.getStackDepth() > 1) { + OpcodeStack.Item itm1 = stack.getStackItem(1); + OpcodeStack.Item itm2 = stack.getStackItem(0); + Object const1 = itm1.getConstant(); + reg = itm1.getRegisterNumber(); + if ((reg >= 0) && (const1 instanceof Integer)) { + if (0 == ((Integer) const1).intValue()) { + uValue = itm2.getUserValue(); + if (uValue != null) { + loopStarts.put(Integer14.valueOf(getPC()), new MapEntry<Integer, Integer>(Integer14.valueOf(reg), (Integer)uValue)); + } + } + } + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } finally { + stack.sawOpcode(this, seen); + if (sawSize) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + itm.setUserValue(Integer14.valueOf(reg)); + } + } else if (sawLoad) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + reg = itm.getRegisterNumber(); + if (reg >= 0) { + uValue = userValues.get(Integer14.valueOf(reg)); + itm.setUserValue(uValue); + } + } + } else if (sawNewArray) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + itm.setUserValue(uValue); + } + } + } + } + + /** + * determines if the stack item refers to a collection that is stored in a local variable + * + * param item the stack item to check + * + * @return the register number of the local variable that this collection refers to, or -1 + * @throws ClassNotFoundException if the items class cannot be found + */ + private int isLocalCollection(OpcodeStack.Item item) throws ClassNotFoundException { + Integer aliasReg = (Integer)item.getUserValue(); + if (aliasReg != null) + return aliasReg.intValue(); + + int reg = item.getRegisterNumber(); + if (reg < 0) + return -1; + + JavaClass cls = item.getJavaClass(); + if (cls.implementationOf(collectionClass)) + return reg; + + return -1; + } + +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/MapEntry.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/MapEntry.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/MapEntry.java 2006-06-19 00:05:58 UTC (rev 564) @@ -0,0 +1,55 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 Dave Brosius + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.mebigfatguy.fbcontrib.utils; + +import java.util.Map.Entry; + +/** + * a simple implementation of the Map.Entry interface + */ +public class MapEntry<K,V> implements Entry<K,V> { + + private K key; + private V value; + + public MapEntry() { + key = null; + value = null; + } + + public MapEntry(K k, V v) { + key = k; + value = v; + } + + public K getKey() { + return key; + } + + public V getValue() { + return value; + } + + public V setValue(V v) { + V temp = value; + value = v; + return temp; + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-06-19 05:28:47
|
Revision: 566 Author: dbrosius Date: 2006-06-18 22:28:38 -0700 (Sun, 18 Jun 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=566&view=rev Log Message: ----------- UTA starting to work for integer indexing, todo using iterators Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-06-19 05:09:54 UTC (rev 565) +++ trunk/fb-contrib/etc/findbugs.xml 2006-06-19 05:28:38 UTC (rev 566) @@ -213,8 +213,7 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.UseToArray" speed="fast" - reports="UTA_USE_TO_ARRAY" - hidden="true" /> + reports="UTA_USE_TO_ARRAY" /> <!-- BugPattern --> Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java 2006-06-19 05:09:54 UTC (rev 565) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java 2006-06-19 05:28:38 UTC (rev 566) @@ -29,6 +29,7 @@ import com.mebigfatguy.fbcontrib.utils.MapEntry; import com.mebigfatguy.fbcontrib.utils.RegisterUtils; +import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; @@ -50,9 +51,6 @@ private BugReporter bugReporter; private OpcodeStack stack; private Map<Integer, Object> userValues; - /** map of pc of loop starts to map entry of index register to collection register */ - private Map<Integer, Map.Entry<Integer, Integer>> loopStarts; - /** * constructs a UTA detector given the reporter to report bugs on @@ -84,11 +82,9 @@ try { stack.resetForMethodEntry(this); userValues = new HashMap<Integer, Object>(); - loopStarts = new HashMap<Integer, Map.Entry<Integer, Integer>>(); super.visitCode(obj); } finally { userValues = null; - loopStarts = null; } } @@ -96,20 +92,30 @@ public void sawOpcode(int seen) { int reg = -1; Object uValue = null; - boolean sawSize = false; + boolean sawAlias = false; boolean sawLoad = false; boolean sawNewArray = false; try { if (seen == INVOKEINTERFACE) { - if ("size".equals(getNameConstantOperand()) && "()I".equals(getSigConstantOperand())) { + String methodName = getNameConstantOperand(); + String signature = getSigConstantOperand(); + if ("size".equals(methodName) && "()I".equals(signature)) { if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); reg = isLocalCollection(itm); if (reg >= 0) { - sawSize = true; + sawAlias = true; } } + } else if ("get".equals(methodName) && "(I)Ljava/lang/Object;".equals(signature)) { + if (stack.getStackDepth() > 1) { + OpcodeStack.Item itm = stack.getStackItem(1); + reg = isLocalCollection(itm); + if (reg >= 0) { + sawAlias = true; + } + } } } else if (((seen == ISTORE) || ((seen >= ISTORE_0) && (seen <= ISTORE_3))) || ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3)))) { @@ -131,23 +137,44 @@ if (stack.getStackDepth() > 1) { OpcodeStack.Item itm1 = stack.getStackItem(1); OpcodeStack.Item itm2 = stack.getStackItem(0); - Object const1 = itm1.getConstant(); reg = itm1.getRegisterNumber(); - if ((reg >= 0) && (const1 instanceof Integer)) { - if (0 == ((Integer) const1).intValue()) { - uValue = itm2.getUserValue(); - if (uValue != null) { - loopStarts.put(Integer14.valueOf(getPC()), new MapEntry<Integer, Integer>(Integer14.valueOf(reg), (Integer)uValue)); - } + if ((reg >= 0) && (itm1.couldBeZero())) { + uValue = itm2.getUserValue(); + if (uValue != null) { + userValues.put(Integer14.valueOf(reg), uValue); } } } + } else if ((seen >= IASTORE) && (seen <= SASTORE)) { + if (stack.getStackDepth() > 2) { + OpcodeStack.Item arItem = stack.getStackItem(2); + OpcodeStack.Item idxItem = stack.getStackItem(1); + OpcodeStack.Item valueItem = stack.getStackItem(0); + reg = isLocalCollection(arItem); + if ((reg >= 0) + && (idxItem.getUserValue() != null) + && (valueItem.getUserValue() != null)) { + bugReporter.reportBug(new BugInstance(this, "UTA_USE_TO_ARRAY", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } else if (seen == CHECKCAST) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + uValue = itm.getUserValue(); + if (uValue instanceof Integer) { + reg = ((Integer)uValue).intValue(); + sawAlias = true; + } + } } } catch (ClassNotFoundException cnfe) { bugReporter.reportMissingClass(cnfe); } finally { stack.sawOpcode(this, seen); - if (sawSize) { + if (sawAlias) { if (stack.getStackDepth() > 0) { OpcodeStack.Item itm = stack.getStackItem(0); itm.setUserValue(Integer14.valueOf(reg)); @@ -188,7 +215,7 @@ return -1; JavaClass cls = item.getJavaClass(); - if (cls.implementationOf(collectionClass)) + if ((cls != null) && cls.implementationOf(collectionClass)) return reg; return -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-08-04 06:05:43
|
Revision: 579 Author: dbrosius Date: 2006-08-03 23:05:37 -0700 (Thu, 03 Aug 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=579&view=rev Log Message: ----------- describe the collector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-08-04 06:00:56 UTC (rev 578) +++ trunk/fb-contrib/etc/findbugs.xml 2006-08-04 06:05:37 UTC (rev 579) @@ -10,9 +10,24 @@ defaultenabled="true" provider="fb-contrib project" website="http://fb-contrib.sourceforge.net"> - + + <!-- Passes --> + + <OrderingConstraints> + <SplitPass> + <Earlier class="com.mebigfatguy.fbcontrib.collect.CollectStatistics"/> + <LaterCategory name="reporting" spanplugins="false"/> + </SplitPass> + </OrderingConstraints> + <!-- Detectors --> + <Detector class="com.mebigfatguy.fbcontrib.collect.CollectStatistics" + speed="fast" + reports="" + hidden="true" /> + + <Detector class="com.mebigfatguy.fbcontrib.detect.InefficientStringBuffering" speed="fast" reports="ISB_INEFFICIENT_STRING_BUFFERING,ISB_EMPTY_STRING_APPENDING" /> Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-08-04 06:00:56 UTC (rev 578) +++ trunk/fb-contrib/etc/messages.xml 2006-08-04 06:05:37 UTC (rev 579) @@ -16,6 +16,14 @@ <!-- Detectors --> + <Detector class="com.mebigfatguy.fbcontrib.collect.CollectStatistics"> + <Details> + <![CDATA[ + <p>Collects statistics for other detectors</p> + ]]> + </Details> + </Detector> + <Detector class="com.mebigfatguy.fbcontrib.detect.InefficientStringBuffering"> <Details> <![CDATA[ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-08-08 03:59:48
|
Revision: 590 Author: dbrosius Date: 2006-08-07 20:59:39 -0700 (Mon, 07 Aug 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=590&view=rev Log Message: ----------- add info for LEST Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-08-08 03:19:37 UTC (rev 589) +++ trunk/fb-contrib/etc/findbugs.xml 2006-08-08 03:59:39 UTC (rev 590) @@ -230,6 +230,10 @@ speed="fast" reports="UTA_USE_TO_ARRAY" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.LostExceptionStackTrace" + speed="moderate" + reports="LEST_LOST_EXCEPTION_STACK_TRACE" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -283,8 +287,9 @@ <BugPattern abbrev="UEC" type="UEC_USE_ENUM_COLLECTIONS" category="PERFORMANCE" /> <BugPattern abbrev="SIL" type="SIL_SQL_IN_LOOP" category="PERFORMANCE" /> <BugPattern abbrev="NMCS" type="NMCS_NEEDLESS_MEMBER_COLLECTION_SYNCHRONIZATION" category="PERFORMANCE" /> - <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" experimental="true" /> - <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" experimental="true" /> - <BugPattern abbrev="RMC" type="RMC_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" experimental="true" /> - <BugPattern abbrev="UTA" type="UTA_USE_TO_ARRAY" category="STYLE" experimental="true" /> + <BugPattern abbrev="ITC" type="ITC_INHERITANCE_TYPE_CHECKING" category="STYLE" /> + <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" /> + <BugPattern abbrev="RMC" type="RMC_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" /> + <BugPattern abbrev="UTA" type="UTA_USE_TO_ARRAY" category="STYLE" /> + <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-08-08 03:19:37 UTC (rev 589) +++ trunk/fb-contrib/etc/messages.xml 2006-08-08 03:59:39 UTC (rev 590) @@ -619,6 +619,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.LostExceptionStackTrace"> + <Details> + <![CDATA[ + <p>looks for methods that catch exceptions, and then throw a different exception, + without embedding the original exception in the thrown one. Doing so, hides the real + source of the exception, making debugging and fixing these problems difficult.</p> + <p>It is a moderately fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1340,6 +1351,19 @@ </Details> </BugPattern> + <BugPattern type="LEST_LOST_EXCEPTION_STACK_TRACE"> + <ShortDescription>Method throws alternative exception from catch block without history</ShortDescription> + <LongDescription>Method {1} throws alternative exception from catch block without history</LongDescription> + <Details> + <![CDATA[ + <p>This method catches an exception, and throws a different exception, without incorporating the + original exception. Doing so hides the original source of the exception making debugging and fixing + these problems difficult. It is better to use the constructor of this new exception that takes an + original exception so that this detail can be passed along to the user.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1392,4 +1416,5 @@ <BugCode abbrev="SACM">Static Array Created in Method</BugCode> <BugCode abbrev="RMC">Redundant Method Calls</BugCode> <BugCode abbrev="UTA">Use toArray</BugCode> + <BugCode abbrev="LEST">Lost Exception Stack Trace</BugCode> </MessageCollection> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-08-10 04:21:36
|
Revision: 600 Author: dbrosius Date: 2006-08-09 21:21:25 -0700 (Wed, 09 Aug 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=600&view=rev Log Message: ----------- Initial checkin UCPM detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/UCPM_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseCharacterParameterizedMethod.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-08-10 01:04:23 UTC (rev 599) +++ trunk/fb-contrib/etc/findbugs.xml 2006-08-10 04:21:25 UTC (rev 600) @@ -234,6 +234,10 @@ speed="moderate" reports="LEST_LOST_EXCEPTION_STACK_TRACE" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.UseCharacterParameterizedMethod" + speed="fast" + reports="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -291,5 +295,6 @@ <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" /> <BugPattern abbrev="RMC" type="RMC_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" /> <BugPattern abbrev="UTA" type="UTA_USE_TO_ARRAY" category="STYLE" /> - <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" /> + <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="UCPM" type="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-08-10 01:04:23 UTC (rev 599) +++ trunk/fb-contrib/etc/messages.xml 2006-08-10 04:21:25 UTC (rev 600) @@ -630,6 +630,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.UseCharacterParameterizedMethod"> + <Details> + <![CDATA[ + <p>looks for methods that pass single character string constants as parameters to + methods that alternatively have an overridden method that accepts a character instead. + It is easier for the method to handle a single character than a String.</p> + <p>It is a fast detector.</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1364,6 +1375,18 @@ </Details> </BugPattern> + <BugPattern type="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD"> + <ShortDescription>Method passes constant String of length 1 to character overridden method</ShortDescription> + <LongDescription>Method {1} passes constant String of length 1 to character overridden method</LongDescription> + <Details> + <![CDATA[ + <p>This method passes a constant literal String of length 1 as a parameter to a method, that + exposes a similar method that takes a character. It is simpler and more expedient to handle one + character, rather than pass a string.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1417,4 +1440,5 @@ <BugCode abbrev="RMC">Redundant Method Calls</BugCode> <BugCode abbrev="UTA">Use toArray</BugCode> <BugCode abbrev="LEST">Lost Exception Stack Trace</BugCode> + <BugCode abbrev="UCPM">Use Character Parameterized Method</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/UCPM_Sample.java =================================================================== --- trunk/fb-contrib/samples/UCPM_Sample.java (rev 0) +++ trunk/fb-contrib/samples/UCPM_Sample.java 2006-08-10 04:21:25 UTC (rev 600) @@ -0,0 +1,13 @@ + +public class UCPM_Sample +{ + public int testUcpm1(String s) + { + return s.indexOf("*") * 10; + } + + public String testUcpm2(String s) + { + return s.startsWith("*") ? s.substring(1) : s; + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseCharacterParameterizedMethod.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseCharacterParameterizedMethod.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseCharacterParameterizedMethod.java 2006-08-10 04:21:25 UTC (rev 600) @@ -0,0 +1,118 @@ +package com.mebigfatguy.fbcontrib.detect; + +import java.util.BitSet; +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.Constants; +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.Method; + +import com.mebigfatguy.fbcontrib.utils.Integer14; + +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 methods that pass single character string constants as parameters to + * methods that alternatively have an overridden method that accepts a character instead. + * It is easier for the method to handle a single character than a String. + */ +public class UseCharacterParameterizedMethod extends BytecodeScanningDetector +{ + private static Map<String, Integer> characterMethods = new HashMap<String, Integer>(); + static { + //characterMethods.put("java/lang/StringBuffer:append:(Ljava/lang/String;)Ljava/lang/StringBuffer;", Integer14.valueOf(0)); + //characterMethods.put("java/lang/StringBuilder:append:(Ljava/lang/String;)Ljava/lang/StringBuilder;", Integer14.valueOf(0)); + characterMethods.put("java/lang/String:indexOf:(Ljava/lang/String;)I", Integer14.valueOf(0)); + characterMethods.put("java/lang/String:indexOf:(Ljava/lang/String;I)I", Integer14.valueOf(1)); + characterMethods.put("java/lang/String:lastIndexOf:(Ljava/lang/String;)I", Integer14.valueOf(0)); + characterMethods.put("java/lang/String:lastIndexOf:(Ljava/lang/String;I)I", Integer14.valueOf(1)); + characterMethods.put("java/lang/String:startsWith:(Ljava/lang/String;)Z", Integer14.valueOf(0)); + } + + private BugReporter bugReporter; + private OpcodeStack stack; + + /** + * constructs a UCPM detector given the reporter to report bugs on + + * @param bugReporter the sync of bug reports + */ + public UseCharacterParameterizedMethod(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + /** + * overrides the visitor to create and clear the opcode stack + * + * @param context the context object for the currently parsed class + */ + @Override + public void visitClassContext(final ClassContext context) { + try { + stack = new OpcodeStack(); + super.visitClassContext(context); + } finally { + stack = null; + } + } + + /** + * looks for methods that contain a LDC opcode + * + * @param method the context object of the current method + * @return if the class uses LDC instructions + */ + + private boolean prescreen(Method obj) { + BitSet bytecodeSet = getClassContext().getBytecodeSet(obj); + return (bytecodeSet != null) && (bytecodeSet.get(Constants.LDC)); + } + + /** + * implement the visitor prescreen the method, and reset the stack + * + * @param obj the context object for the currently parsed method + */ + @Override + public void visitCode(Code obj) { + if (prescreen(getMethod())) { + stack.resetForMethodEntry(this); + super.visitCode(obj); + } + } + + /** + * implements the visitor to look for method calls that pass a constant string as a parameter when + * the string is only one character long, and there is an alternate method passing a character. + */ + @Override + public void sawOpcode(int seen) { + try { + stack.mergeJumps(this); + if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) { + String key = getClassConstantOperand() + ":" + getNameConstantOperand() + ":" + getSigConstantOperand(); + Integer parmPos =characterMethods.get(key); + if (parmPos != null) { + int stackPos = parmPos.intValue(); + if (stack.getStackDepth() > stackPos) { + OpcodeStack.Item itm = stack.getStackItem(stackPos); + String con = (String)itm.getConstant(); + if ((con != null) && (con.length() == 1)) { + bugReporter.reportBug(new BugInstance(this, "UCPM_USE_CHARACTER_PARAMETERIZED_METHOD", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + } + } finally { + stack.sawOpcode(this, seen); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-08-12 15:21:30
|
Revision: 612 Author: dbrosius Date: 2006-08-12 08:20:44 -0700 (Sat, 12 Aug 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=612&view=rev Log Message: ----------- initial checkin, new TR detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Added Paths: ----------- trunk/fb-contrib/samples/TR_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-08-12 13:38:45 UTC (rev 611) +++ trunk/fb-contrib/etc/findbugs.xml 2006-08-12 15:20:44 UTC (rev 612) @@ -238,6 +238,10 @@ speed="fast" reports="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.TailRecursion" + speed="fast" + reports="TR_TAIL_RECURSION" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -297,4 +301,5 @@ <BugPattern abbrev="UTA" type="UTA_USE_TO_ARRAY" category="STYLE" /> <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="UCPM" type="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="TR" type="TR_TAIL_RECURSION" category="PERFORMANCE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-08-12 13:38:45 UTC (rev 611) +++ trunk/fb-contrib/etc/messages.xml 2006-08-12 15:20:44 UTC (rev 612) @@ -641,6 +641,17 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.TailRecursion"> + <Details> + <![CDATA[ + <p>looks for methods that make a recursive call to itself as the last statement in the + method. This tail recursion could be converted into a simple loop which would improve + the performance and stack requirements.</p> + <p>It is a fast detector.</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1387,6 +1398,18 @@ </Details> </BugPattern> + <BugPattern type="TR_TAIL_RECURSION"> + <ShortDescription>Method employs tail recursion</ShortDescription> + <LongDescription>Method {1} employs tail recursion</LongDescription> + <Details> + <![CDATA[ + <p>This method recursively calls itself as the last statement of the method + (Tail Recursion). This method can be easily refactored into a simple loop, which + will make it more performant, and reduce the stack size requirements. + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1441,4 +1464,5 @@ <BugCode abbrev="UTA">Use toArray</BugCode> <BugCode abbrev="LEST">Lost Exception Stack Trace</BugCode> <BugCode abbrev="UCPM">Use Character Parameterized Method</BugCode> + <BugCode abbrev="TR">Tail Recursion</BugCode> </MessageCollection> \ No newline at end of file Added: trunk/fb-contrib/samples/TR_Sample.java =================================================================== --- trunk/fb-contrib/samples/TR_Sample.java (rev 0) +++ trunk/fb-contrib/samples/TR_Sample.java 2006-08-12 15:20:44 UTC (rev 612) @@ -0,0 +1,11 @@ + +public class TR_Sample +{ + public int factorial(int n) + { + if (n == 1) + return 1; + + return n * factorial(n-1); + } +} Added: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java (rev 0) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TailRecursion.java 2006-08-12 15:20:44 UTC (rev 612) @@ -0,0 +1,94 @@ +/* + * fb-contrib - Auxilliary detectors for Java programs + * Copyright (C) 2005-2006 Dave Brosius + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.mebigfatguy.fbcontrib.detect; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.Method; + +import edu.umd.cs.findbugs.BugInstance; +import edu.umd.cs.findbugs.BugReporter; +import edu.umd.cs.findbugs.BytecodeScanningDetector; + +/** + * looks for methods that make a recursive call to itself as the last statement in the + * method. This tail recursion could be converted into a simple loop which would improve + * the performance and stack requirements. + */ +public class TailRecursion extends BytecodeScanningDetector +{ + public static final int TAILRECURSIONFUDGE = 6; + + private BugReporter bugReporter; + private int trPCPos; + private boolean possibleTailRecursion; + /** + * constructs a TR detector given the reporter to report bugs on + + * @param bugReporter the sync of bug reports + */ + public TailRecursion(BugReporter bugReporter) { + this.bugReporter = bugReporter; + } + + /** + * implements the visitor to figure the pc where the method call must occur + * depending on whether the method returns a value, or not. + * + * @param obj the context object of the currently parsed method + */ + @Override + public void visitMethod(Method obj) { + Code c = obj.getCode(); + if (c != null) { + byte[] opcodes = c.getCode(); + if (opcodes != null) { + trPCPos = c.getCode().length - 1; + if (!obj.getSignature().endsWith("V")) { + trPCPos -= 1; + } + trPCPos -= TAILRECURSIONFUDGE; + possibleTailRecursion = true; + super.visitMethod(obj); + } + } + } + + /** + * implements the visitor to find methods that employ tail recursion + * + * @param seen the opcode of the currently parsed instruction + */ + @Override + public void sawOpcode(int seen) { + if (seen == INVOKEVIRTUAL) { + boolean isRecursion = (getMethodName().equals(getNameConstantOperand())) + && (getMethodSig().equals(getSigConstantOperand())) + && (getClassName().equals(getClassConstantOperand())); + + if (isRecursion && possibleTailRecursion && (getPC() >= trPCPos)) { + bugReporter.reportBug(new BugInstance(this, "TR_TAIL_RECURSION", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + else + possibleTailRecursion = false; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-10-28 17:48:39
|
Revision: 675 http://svn.sourceforge.net/fb-contrib/?rev=675&view=rev Author: dbrosius Date: 2006-10-28 10:47:13 -0700 (Sat, 28 Oct 2006) Log Message: ----------- add sc to the xml files Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-10-27 05:27:56 UTC (rev 674) +++ trunk/fb-contrib/etc/findbugs.xml 2006-10-28 17:47:13 UTC (rev 675) @@ -249,6 +249,11 @@ <Detector class="com.mebigfatguy.fbcontrib.detect.PossibleIncompleteSerialization" speed="fast" reports="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" /> + + <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousComparator" + speed="fast" + reports="SC_SUSPICIOUS_COMPARATOR"/> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -306,11 +311,12 @@ <BugPattern abbrev="SACM" type="SACM_STATIC_ARRAY_CREATED_IN_METHOD" category="PERFORMANCE" /> <BugPattern abbrev="PRMC" type="PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS" category="PERFORMANCE" /> <BugPattern abbrev="UTA" type="UTA_USE_TO_ARRAY" category="STYLE" /> - <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" experimental="true" /> - <BugPattern abbrev="UCPM" type="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" category="PERFORMANCE" experimental="true" /> - <BugPattern abbrev="TR" type="TR_TAIL_RECURSION" category="PERFORMANCE" experimental="true" /> - <BugPattern abbrev="URV" type="URV_UNRELATED_RETURN_VALUES" category="STYLE" experimental="true" /> - <BugPattern abbrev="URV" type="URV_CHANGE_RETURN_TYPE" category="STYLE" experimental="true" /> - <BugPattern abbrev="URV" type="URV_INHERITED_METHOD_WITH_RELATED_TYPES" category="STYLE" experimental="true" /> - <BugPattern abbrev="PIS" type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" category="CORRECTNESS" experimental="true" /> + <BugPattern abbrev="LEST" type="LEST_LOST_EXCEPTION_STACK_TRACE" category="CORRECTNESS" /> + <BugPattern abbrev="UCPM" type="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" category="PERFORMANCE" /> + <BugPattern abbrev="TR" type="TR_TAIL_RECURSION" category="PERFORMANCE" /> + <BugPattern abbrev="URV" type="URV_UNRELATED_RETURN_VALUES" category="STYLE" /> + <BugPattern abbrev="URV" type="URV_CHANGE_RETURN_TYPE" category="STYLE" /> + <BugPattern abbrev="URV" type="URV_INHERITED_METHOD_WITH_RELATED_TYPES" category="STYLE" /> + <BugPattern abbrev="PIS" type="PIS_POSSIBLE_INCOMPLETE_SERIALIZATION" category="CORRECTNESS" /> + <BugPattern abbrev="SC" type="SC_SUSPICIOUS_COMPARATOR" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-10-27 05:27:56 UTC (rev 674) +++ trunk/fb-contrib/etc/messages.xml 2006-10-28 17:47:13 UTC (rev 675) @@ -675,6 +675,16 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousComparator"> + <Details> + <![CDATA[ + <p>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).</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1486,6 +1496,18 @@ </Details> </BugPattern> + <BugPattern type="SC_SUSPICIOUS_COMPARATOR"> + <ShortDescription>Comparator method doesn't seem to return all ordering values</ShortDescription> + <LongDescription>Comparator method {1} doesn't seem to return all ordering values</LongDescription> + <Details> + <![CDATA[ + <p>This compareTo or compare method returns constant values for to represent less than, + equals and greater than. However it does not return each type. Given that comparators + are transitive, this seems incorrect.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1543,4 +1565,5 @@ <BugCode abbrev="TR">Tail Recursion</BugCode> <BugCode abbrev="URV">Unrelated Return Values</BugCode> <BugCode abbrev="PIS">Possible Incomplete Serialization</BugCode> + <BugCode abbrev="SC">Suspicious Comparator</BugCode> </MessageCollection> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2006-12-10 05:04:17
|
Revision: 715 http://svn.sourceforge.net/fb-contrib/?rev=715&view=rev Author: dbrosius Date: 2006-12-09 21:04:14 -0800 (Sat, 09 Dec 2006) Log Message: ----------- initial checkin - SCII detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2006-12-10 04:13:12 UTC (rev 714) +++ trunk/fb-contrib/etc/findbugs.xml 2006-12-10 05:04:14 UTC (rev 715) @@ -262,6 +262,10 @@ speed="fast" reports="BAS_BLOATED_ASSIGNMENT_SCOPE" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.SpoiledChildInterfaceImplementor" + speed="fast" + reports="SCI_SPOILED_CHILD_INTERFACE_IMPLEMENTOR" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -335,4 +339,5 @@ <BugPattern abbrev="SPP" type="SPP_USE_ISNAN" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="SPP" type="SPP_USE_BIGDECIMAL_STRING_CTOR" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="BAS" type="BAS_BLOATED_ASSIGNMENT_SCOPE" category="PERFORMANCE" experimental="true" /> + <BugPattern abbrev="SCII" type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTATOR" category="STYLE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2006-12-10 04:13:12 UTC (rev 714) +++ trunk/fb-contrib/etc/messages.xml 2006-12-10 05:04:14 UTC (rev 715) @@ -702,6 +702,16 @@ ]]> </Details> </Detector> + + <Detector class="com.mebigfatguy.fbcontrib.detect.SpoiledChildInterfaceImplementor"> + <Details> + <![CDATA[ + <p>looks for classes that implement interfaces by relying on methods being + implemented in superclasses, even tho the superclass knows nothing about + the interface being implemented by the child.</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -1618,6 +1628,20 @@ </Details> </BugPattern> + <BugPattern type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTATOR"> + <ShortDescription>Class implements interface by relying on unknowing superclass methods</ShortDescription> + <LongDescription>Class {0} implements interface by relying on unknowing superclass methods</LongDescription> + <Details> + <![CDATA[ + <p>This class declares that it implements an interface, but does so by relying on methods supplied + by superclasses, even though those superclasses know nothing about the interface in question. If you wish + to have the child not implement all the methods of the interface, it would probably be better to declare + the superclass as implementing the interface, and if that class does not provide all the methods, then declare + that superclass abstract.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1678,5 +1702,5 @@ <BugCode abbrev="SCRV">Suspicious Comparator Return Values</BugCode> <BugCode abbrev="SPP">Sillyness Pot Pourri</BugCode> <BugCode abbrev="BAS">Bloated Assignment Scope</BugCode> - + <BugCode abbrev="SCII">Spoiled Child Interface Implementor</BugCode> </MessageCollection> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2007-09-15 04:31:26
|
Revision: 900 http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=900&view=rev Author: dbrosius Date: 2007-09-14 21:31:29 -0700 (Fri, 14 Sep 2007) Log Message: ----------- initial checkin - MRC detector Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2007-09-15 04:30:57 UTC (rev 899) +++ trunk/fb-contrib/etc/findbugs.xml 2007-09-15 04:31:29 UTC (rev 900) @@ -283,6 +283,10 @@ speed="fast" reports="UAA_USE_ADD_ALL" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.MethodReturnsConstant" + speed="fast" + reports="MRC_METHOD_RETURNS_CONSTANT" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -372,4 +376,5 @@ <BugPattern abbrev="USS" type="USS_USE_STRING_SPLIT" category="STYLE" /> <BugPattern abbrev="SJVU" type="SJVU_SUSPICIOUS_JDK_VERSION_USE" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="UAA" type="UAA_USE_ADD_ALL" category="STYLE" experimental="true" /> + <BugPattern abbrev="MRC" type="MRC_METHOD_RETURNS_CONSTANT" category="STYLE" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2007-09-15 04:30:57 UTC (rev 899) +++ trunk/fb-contrib/etc/messages.xml 2007-09-15 04:31:29 UTC (rev 900) @@ -767,6 +767,17 @@ </Details> </Detector> + <Detector class="com.mebigfatguy.fbcontrib.detect.MethodReturnsConstant"> + <Details> + <![CDATA[ + <p>looks for private methods that only return one constant value. Since there is no + chance for derived classes overriding this behavior, the return of a constant value + seems dubious.</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> + <!-- BugPattern --> <BugPattern type="ISB_INEFFICIENT_STRING_BUFFERING"> @@ -1922,6 +1933,19 @@ </Details> </BugPattern> + <BugPattern type="MRC_METHOD_RETURNS_CONSTANT"> + <ShortDescription>private method only returns one constant value</ShortDescription> + <LongDescription>private method {1} only returns one constant value</LongDescription> + <Details> + <![CDATA[ + <p>This private method only returns one constant value. As this method is private, + it's behavior can't be overridden, and thus the return of a constant value seems dubious. + Either the method should be changed to return no value, or perhaps another return value + was expected to be returned in another code path in this method.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -1987,4 +2011,5 @@ <BugCode abbrev="USS">Use String Split</BugCode> <BugCode abbrev="SJVU">Suspicious JDK Version Use</BugCode> <BugCode abbrev="UAA">Use Add All</BugCode> + <BugCode abbrev="MRC">Method Returns Constant</BugCode> </MessageCollection> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dbr...@us...> - 2008-06-02 07:31:20
|
Revision: 1030 http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1030&view=rev Author: dbrosius Date: 2008-06-02 00:31:29 -0700 (Mon, 02 Jun 2008) Log Message: ----------- Initial checkin of SCSS detector - not even close to working Modified Paths: -------------- trunk/fb-contrib/etc/findbugs.xml trunk/fb-contrib/etc/messages.xml Modified: trunk/fb-contrib/etc/findbugs.xml =================================================================== --- trunk/fb-contrib/etc/findbugs.xml 2008-06-02 07:04:19 UTC (rev 1029) +++ trunk/fb-contrib/etc/findbugs.xml 2008-06-02 07:31:29 UTC (rev 1030) @@ -316,6 +316,10 @@ speed="fast" reports="WEM_WEAK_EXCEPTION_MESSAGING" /> + <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousClusteredSessionSupport" + speed="fast" + reports="SCSS_SUSPICIOUS_CLUSTERED_SESSION_SUPPORT" /> + <!-- BugPattern --> <BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" /> @@ -421,4 +425,5 @@ <BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_BOOLEAN_ASSERT" category="STYLE" experimental="true" /> <BugPattern abbrev="SCA" type="SCA_SUSPICIOUS_CLONE_ALGORITHM" category="CORRECTNESS" experimental="true" /> <BugPattern abbrev="WEM" type="WEM_WEAK_EXCEPTION_MESSAGING" category="STYLE" experimental="true" /> + <BugPattern abbrev="SCSS" type="SCSS_SUSPICIOUS_CLUSTERED_SESSION_SUPPORT" category="CORRECTNESS" experimental="true" /> </FindbugsPlugin> \ No newline at end of file Modified: trunk/fb-contrib/etc/messages.xml =================================================================== --- trunk/fb-contrib/etc/messages.xml 2008-06-02 07:04:19 UTC (rev 1029) +++ trunk/fb-contrib/etc/messages.xml 2008-06-02 07:31:29 UTC (rev 1030) @@ -863,12 +863,22 @@ <![CDATA[ <p>looks for exceptions that are thrown with static strings as messages. Using static strings doesn't differentiate one use of this method versus another, and so it may be difficult - to determine how this exception occurred without showing context.<p> + to determine how this exception occurred without showing context.</p> <p>It is a fast detector</p> ]]> </Details> </Detector> + <Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousClusteredSessionSupport"> + <Details> + <![CDATA[ + <p>looks for code that fetches a complex object from an HttpSession attribute, modifies the + object, but does not call setAttribute again on this object. This will not inform the application server + that this object has changed, and thus will not correctly replicate these changes across the cluster.</p> + <p>It is a fast detector</p> + ]]> + </Details> + </Detector> <!-- BugPattern --> @@ -2232,6 +2242,19 @@ </Details> </BugPattern> + <BugPattern type="SCSS_SUSPICIOUS_CLUSTERED_SESSION_SUPPORT"> + <ShortDescription>method modifies http session attribute without calling setAttribute</ShortDescription> + <LongDescription>method {1} modifies http session attribute without calling setAttribute</LongDescription> + <Details> + <![CDATA[ + <p>This method fetches a complex object from an HttpSession object, modifies this object, but does + not call setAttribute, to inform the application server that this attribute has been changed. This will + cause this attribute not to be updated in other servers in a clustered environment, as only changes marked + by a call to setAttribute are replicated.</p> + ]]> + </Details> + </BugPattern> + <!-- BugCode --> <BugCode abbrev="ISB">Inefficient String Buffering</BugCode> @@ -2305,4 +2328,5 @@ <BugCode abbrev="JAO">JUnit Assertion Oddities</BugCode> <BugCode abbrev="SCA">Suspicious Clone Algorithm</BugCode> <BugCode abbrev="WEM">Weak Exception Messaging</BugCode> + <BugCode abbrev="SCSS">Suspicious Clustered Session Support</BugCode> </MessageCollection> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |