[Fb-contrib-commit] SF.net SVN: fb-contrib:[1743] trunk/fb-contrib
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2013-04-18 18:17:00
|
Revision: 1743
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1743&view=rev
Author: dbrosius
Date: 2013-04-18 18:16:49 +0000 (Thu, 18 Apr 2013)
Log Message:
-----------
merge from github
Modified Paths:
--------------
trunk/fb-contrib/etc/findbugs.xml
trunk/fb-contrib/etc/messages.xml
trunk/fb-contrib/htdocs/index.shtml
trunk/fb-contrib/samples/CU_Sample.java
trunk/fb-contrib/samples/JAO_Sample.java
trunk/fb-contrib/samples/PRMC_Sample.java
trunk/fb-contrib/samples/PSC_Sample.java
trunk/fb-contrib/samples/SPP_Sample.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/FBContrib.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JUnitAssertionOddities.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonOwnedSynchronization.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousJDKVersionUse.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/WriteOnlyCollection.java
Modified: trunk/fb-contrib/etc/findbugs.xml
===================================================================
--- trunk/fb-contrib/etc/findbugs.xml 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/etc/findbugs.xml 2013-04-18 18:16:49 UTC (rev 1743)
@@ -132,7 +132,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousComparatorReturnValues" speed="fast" reports="SC_SUSPICIOUS_COMPARATOR_RETURN_VALUES" />
<Detector class="com.mebigfatguy.fbcontrib.detect.SillynessPotPourri" speed="fast"
- reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN,SPP_USE_BIGDECIMAL_STRING_CTOR,SPP_STRINGBUFFER_WITH_EMPTY_STRING,SPP_EQUALS_ON_ENUM,SPP_INVALID_BOOLEAN_NULL_CHECK,SPP_USE_CHARAT,SPP_USELESS_TRINARY,SPP_SUSPECT_STRING_TEST,SPP_USE_STRINGBUILDER_LENGTH,SPP_INVALID_CALENDAR_COMPARE,SPP_USE_CONTAINSKEY,SPP_USE_ISEMPTY,SPP_USE_GETPROPERTY,SPP_USELESS_CASING,SPP_NON_ARRAY_PARM,SPP_EMPTY_CASING,SPP_TEMPORARY_TRIM,SPP_STRINGBUILDER_IS_MUTABLE" />
+ reports="SPP_NEGATIVE_BITSET_ITEM,SPP_INTERN_ON_CONSTANT,SPP_NO_CHAR_SB_CTOR,SPP_USE_MATH_CONSTANT,SPP_STUTTERED_ASSIGNMENT,SPP_USE_ISNAN,SPP_USE_BIGDECIMAL_STRING_CTOR,SPP_STRINGBUFFER_WITH_EMPTY_STRING,SPP_EQUALS_ON_ENUM,SPP_INVALID_BOOLEAN_NULL_CHECK,SPP_USE_CHARAT,SPP_USELESS_TRINARY,SPP_SUSPECT_STRING_TEST,SPP_USE_STRINGBUILDER_LENGTH,SPP_INVALID_CALENDAR_COMPARE,SPP_USE_CONTAINSKEY,SPP_USE_ISEMPTY,SPP_USE_GETPROPERTY,SPP_USELESS_CASING,SPP_NON_ARRAY_PARM,SPP_EMPTY_CASING,SPP_TEMPORARY_TRIM,SPP_STRINGBUILDER_IS_MUTABLE,SPP_USE_GET0,SPP_DOUBLE_APPENDED_LITERALS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.BloatedAssignmentScope" speed="fast" reports="BAS_BLOATED_ASSIGNMENT_SCOPE" hidden="true" />
@@ -157,7 +157,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.ConfusingFunctionSemantics" speed="fast" reports="CFS_CONFUSING_FUNCTION_SEMANTICS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.JUnitAssertionOddities" speed="fast"
- reports="JAO_JUNIT_ASSERTION_ODDITIES_ACTUAL_CONSTANT,JAO_JUNIT_ASSERTION_ODDITIES_INEXACT_DOUBLE,JAO_JUNIT_ASSERTION_ODDITIES_BOOLEAN_ASSERT,JAO_JUNIT_ASSERTION_ODDITIES_IMPOSSIBLE_NULL" />
+ reports="JAO_JUNIT_ASSERTION_ODDITIES_ACTUAL_CONSTANT,JAO_JUNIT_ASSERTION_ODDITIES_INEXACT_DOUBLE,JAO_JUNIT_ASSERTION_ODDITIES_BOOLEAN_ASSERT,JAO_JUNIT_ASSERTION_ODDITIES_IMPOSSIBLE_NULL,JAO_JUNIT_ASSERTION_ODDITIES_ASSERT_USED,JAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_EQUALS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.SuspiciousCloneAlgorithm" speed="fast" reports="SCA_SUSPICIOUS_CLONE_ALGORITHM" />
@@ -234,12 +234,16 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.BackportReusePublicIdentifiers" speed="fast" reports="BRPI_BACKPORT_REUSE_PUBLIC_IDENTIFIERS" />
- <Detector class="com.mebigfatguy.fbcontrib.detect.CloneUsability" speed="fast" reports="CU_CLONE_USABILITY_OBJECT_RETURN,CU_CLONE_USABILITY_THROWS" />
+ <Detector class="com.mebigfatguy.fbcontrib.detect.CloneUsability" speed="fast" reports="CU_CLONE_USABILITY_OBJECT_RETURN,CU_CLONE_USABILITY_MISMATCHED_RETURN,CU_CLONE_USABILITY_THROWS" />
<Detector class="com.mebigfatguy.fbcontrib.detect.ConfusingArrayAsList" speed="fast" reports="CAAL_CONFUSING_ARRAY_AS_LIST" />
<Detector class="com.mebigfatguy.fbcontrib.detect.PresizeCollections" speed="fast" reports="PSC_PRESIZE_COLLECTIONS" />
+ <Detector class="com.mebigfatguy.fbcontrib.detect.UnboundMethodTemplateParameter" speed="fast" reports="UMTP_UNBOUND_METHOD_TEMPLATE_PARAMETER" />
+
+ <Detector class="com.mebigfatguy.fbcontrib.detect.NonProductiveMethodCall" speed="fast" reports="NPMC_NON_PRODUCTIVE_METHOD_CALL" />
+
<!-- BugPattern -->
<BugPattern abbrev="ISB" type="ISB_INEFFICIENT_STRING_BUFFERING" category="PERFORMANCE" />
@@ -338,6 +342,8 @@
<BugPattern abbrev="SPP" type="SPP_EMPTY_CASING" category="STYLE" />
<BugPattern abbrev="SPP" type="SPP_TEMPORARY_TRIM" category="STYLE" />
<BugPattern abbrev="SPP" type="SPP_STRINGBUILDER_IS_MUTABLE" category="CORRECTNESS" />
+ <BugPattern abbrev="SPP" type="SPP_USE_GET0" category="PERFORMANCE" />
+ <BugPattern abbrev="SPP" type="SPP_DOUBLE_APPENDED_LITERALS" category="PERFORMANCE" />
<BugPattern abbrev="BAS" type="BAS_BLOATED_ASSIGNMENT_SCOPE" category="PERFORMANCE" />
<BugPattern abbrev="SCII" type="SCII_SPOILED_CHILD_INTERFACE_IMPLEMENTOR" category="STYLE" />
<BugPattern abbrev="DWI" type="DWI_DELETING_WHILE_ITERATING" category="CORRECTNESS" />
@@ -355,7 +361,9 @@
<BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_ACTUAL_CONSTANT" category="STYLE" />
<BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_INEXACT_DOUBLE" category="STYLE" />
<BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_BOOLEAN_ASSERT" category="STYLE" />
- <BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_IMPOSSIBLE_NULL" category="CORRECTNESS" />
+ <BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_IMPOSSIBLE_NULL" category="CORRECTNESS" />
+ <BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_ASSERT_USED" category="CORRECTNESS" />
+ <BugPattern abbrev="JAO" type="JAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_EQUALS" category="CORRECTNESS" />
<BugPattern abbrev="SCA" type="SCA_SUSPICIOUS_CLONE_ALGORITHM" category="CORRECTNESS" />
<BugPattern abbrev="WEM" type="WEM_WEAK_EXCEPTION_MESSAGING" category="STYLE" />
<BugPattern abbrev="SCSS" type="SCSS_SUSPICIOUS_CLUSTERED_SESSION_SUPPORT" category="CORRECTNESS" />
@@ -415,7 +423,10 @@
<BugPattern abbrev="CCNE" type="CCNE_COMPARE_CLASS_EQUALS_NAME" category="CORRECTNESS" />
<BugPattern abbrev="BRPI" type="BRPI_BACKPORT_REUSE_PUBLIC_IDENTIFIERS" category ="PERFORMANCE" />
<BugPattern abbrev="CU" type="CU_CLONE_USABILITY_OBJECT_RETURN" category="STYLE" />
+ <BugPattern abbrev="CU" type="CU_CLONE_USABILITY_MISMATCHED_RETURN" category="STYLE" />
<BugPattern abbrev="CU" type="CU_CLONE_USABILITY_THROWS" category="STYLE" />
<BugPattern abbrev="CAAL" type="CAAL_CONFUSING_ARRAY_AS_LIST" category="CORRECTNESS" />
<BugPattern abbrev="PSC" type="PSC_PRESIZE_COLLECTIONS" category="PERFORMANCE" />
+ <BugPattern abbrev="UMTP" type="UMTP_UNBOUND_METHOD_TEMPLATE_PARAMETER" category="CORRECTNESS" />
+ <BugPattern abbrev="NPMC" type="NPMC_NON_PRODUCTIVE_METHOD_CALL" category="CORRECTNESS" />
</FindbugsPlugin>
Modified: trunk/fb-contrib/etc/messages.xml
===================================================================
--- trunk/fb-contrib/etc/messages.xml 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/etc/messages.xml 2013-04-18 18:16:49 UTC (rev 1743)
@@ -74,8 +74,8 @@
<Details>
<![CDATA[
<p> Looks for for loops that iterate over a java.util.List using an integer index, and get,
- rather than using an Iterator. An iterator may perform better depending List implementation,
- but more importantly will allow the code to be converted to other collections type.</p>
+ rather than using an Iterator. An iterator may perform better depending on List implementation,
+ but more importantly will allow the code to be converted to other collection types.</p>
<p>It is a moderately fast detector</p>
]]>
</Details>
@@ -85,7 +85,7 @@
<Details>
<![CDATA[
<p> Looks for collections or arrays that hold objects that are unrelated thru class or
- interface inheritance other than java.lang.Object. Doing so, makes for brittle code,
+ interface inheritance other than java.lang.Object. Doing so makes for brittle code,
relying either on positional correspondence for type, or a reliance on instanceof to
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
@@ -101,7 +101,7 @@
<p> Looks for methods that declare Runtime exceptions in their throws clause. While doing
so is not illegal, it may represent a misunderstanding as to the exception in question.
If a RuntimeException is declared, it implies that this exception type is expected to happen,
- which if true, should be handled in code, and not propogated. </p>
+ which if true should be handled in code, and not propagated. </p>
<p>It is a fast detector</p>
]]>
</Details>
@@ -159,7 +159,8 @@
<![CDATA[
<p> Looks for classes that maintain two or more lists or arrays associated one-for-one through the same index
to hold two or more pieces of related information. It would be better to create a new class that holds
- all of these pieces of information, and place instances of this class in one list.</p>
+ all of these pieces of information, and place instances of this class in one list. Or if the two list are
+ related in key/value fashion, then a map.</p>
<p>It is a fast detector</p>
]]>
</Details>
@@ -293,8 +294,8 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.NeedlessAutoboxing">
<Details>
<![CDATA[
- <p> Looks for methods that pass a primitive wrapper class object, to the
- same classes Constructor. Patterns found are:
+ <p> Looks for methods that pass a primitive wrapper class object to the
+ same class' Constructor. Patterns found are:
<ul>
<li>new Boolean(Boolean)</li>
<li>new Byte(Byte)</li>
@@ -317,7 +318,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.UnnecessaryStoreBeforeReturn">
<Details>
<![CDATA[
- <p>Looks for methods that store the return result in a local variable, and
+ <p>Looks for methods that store the return result in a local variable and
then immediately returns that local variable.</p>
<p>It is a fast detector</p>
]]>
@@ -622,7 +623,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.LostExceptionStackTrace">
<Details>
<![CDATA[
- <p>Looks for methods that catch exceptions, and then throw a different exception,
+ <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>
@@ -710,7 +711,7 @@
<Details>
<![CDATA[
<p>Looks for classes that implement interfaces by relying on methods being
- implemented in superclasses, even tho the superclass knows nothing about
+ implemented in superclasses, even though the superclass knows nothing about
the interface being implemented by the child.</p>
<p>It is a fast detector.</p>
]]>
@@ -836,6 +837,7 @@
<li>Passing a constant as the second (actual) parameter</li>
<li>not using the three parameter version of asserts for doubles</li>
<li>Passing true or false as the first parameter instead of using assertTrue, or assertFalse</li>
+ <li>Using the assert keyword</li>
</ul>
</p>
<p>It is a fast detector</p>
@@ -1098,7 +1100,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.ReflectionOnObjectMethods">
<Details>
<![CDATA[
- <p>This detector looks for reflective calls on methods that are found java.lang.Object.
+ <p>This detector looks for reflective calls on methods that are found in the class java.lang.Object.
As these methods are always available, there is no reason to use reflection to call them.
</p>
<p>It is a fast detector</p>
@@ -1295,7 +1297,7 @@
</Detector>
<Detector class="com.mebigfatguy.fbcontrib.detect.PresizeCollections">
- <Details>
+ <Details>
<![CDATA[
<p> Looks for methods that create collections using the default constructor,
even though the number of elements that will be placed in the collection is known
@@ -1307,6 +1309,30 @@
</Details>
</Detector>
+ <Detector class="com.mebigfatguy.fbcontrib.detect.UnboundMethodTemplateParameter">
+ <Details>
+ <![CDATA[
+ <p> Looks for methods that declare method level template parameter(s) that are not bound to any of the
+ method's parameters, and thus is not adding any validation/type safety to the method, and is
+ just confusing.
+ </p>
+ <p>It is a fast detector</p>
+ ]]>
+ </Details>
+ </Detector>
+
+ <Detector class="com.mebigfatguy.fbcontrib.detect.NonProductiveMethodCall">
+ <Details>
+ <![CDATA[
+ <p> Looks for common methods that are non mutating where the return value is ignored. As these methods
+ do not change the object they are called on, calling this methods is pointless. They can be removed.
+ </p>
+ <p>It is a fast detector</p>
+ ]]>
+ </Details>
+ </Detector>
+
+
<!-- BugPattern -->
<BugPattern type="ISB_INEFFICIENT_STRING_BUFFERING">
@@ -1314,7 +1340,7 @@
<LongDescription>Method {1} passes simple concatenating string in StringBuffer or StringBuilder append</LongDescription>
<Details>
<![CDATA[
- <p> This method uses StringBuffer or StringBuilder append to concatenate strings. However, it passes the result
+ <p> This method uses StringBuffer or StringBuilder's append method to concatenate strings. However, it passes the result
of doing a simple String concatenation to one of these append calls, thus removing any performance gains
of using the StringBuffer or StringBuilder class.</p>
]]>
@@ -2568,6 +2594,28 @@
]]>
</Details>
</BugPattern>
+
+ <BugPattern type="SPP_USE_GET0">
+ <ShortDescription>Method uses iterator().next() on a List to get the first item</ShortDescription>
+ <LongDescription>Method {1} uses iterator().next() on a List to get the first item</LongDescription>
+ <Details>
+ <![CDATA[
+ This Method calls myList.iterator().next() on a List to get the first item. It is more performant
+ to just use myList.get(0).
+ ]]>
+ </Details>
+ </BugPattern>
+
+ <BugPattern type="SPP_DOUBLE_APPENDED_LITERALS">
+ <ShortDescription>Method appends two literal strings back to back to a StringBuilder</ShortDescription>
+ <LongDescription>Method {1} appends two literal strings back to back to a StringBuilder</LongDescription>
+ <Details>
+ <![CDATA[
+ This method appends two literal strings to a StringBuilder back to back. This can be done with just
+ one append call, and may avoid intermediate reallocations of the StringBuilders backing store.
+ ]]>
+ </Details>
+ </BugPattern>
<BugPattern type="BAS_BLOATED_ASSIGNMENT_SCOPE">
<ShortDescription>Method assigns a variable in a larger scope then is needed</ShortDescription>
@@ -2804,6 +2852,30 @@
]]>
</Details>
</BugPattern>
+
+ <BugPattern type="JAO_JUNIT_ASSERTION_ODDITIES_ASSERT_USED">
+ <ShortDescription>Method uses java asserts rather than a junit assertion</ShortDescription>
+ <LongDescription>Method {1} uses java asserts rather than a junit assertion</LongDescription>
+ <Details>
+ <![CDATA[
+ <p>This method uses a java assert to assure that a certain state is in effect. As this is
+ a junit test it makes more sense to either check this condition with a junit assert, or allow
+ a following exception to occur.</p>
+ ]]>
+ </Details>
+ </BugPattern>
+
+ <BugPattern type="JAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_EQUALS">
+ <ShortDescription>Method passes boolean expression to Assert.assertTrue</ShortDescription>
+ <LongDescription>Method {1} passes boolean expression to Assert.assertTrue</LongDescription>
+ <Details>
+ <![CDATA[
+ <p>This method evaluates a boolean expression and passes that to Assert.assertTrue. It is better
+ to pass the two values that are being equated to the Assert.assertEquals method so that the
+ junit failure method is more meaningful of the intended test.</p>
+ ]]>
+ </Details>
+ </BugPattern>
<BugPattern type="SCA_SUSPICIOUS_CLONE_ALGORITHM">
<ShortDescription>Clone method stores a new value to member field of source object</ShortDescription>
@@ -3529,6 +3601,18 @@
]]>
</Details>
</BugPattern>
+
+ <BugPattern type="CU_CLONE_USABILITY_MISMATCHED_RETURN">
+ <ShortDescription>Clone method declares it returns an type different then the owning class</ShortDescription>
+ <LongDescription>Clone method {1} declares it returns an type different then the owning class</LongDescription>
+ <Details>
+ <![CDATA[
+ <p> This class implements the Cloneable interface but defines its clone method to return a type
+ that is different than the class itself, or any interfaces that the class implements.
+ </p>
+ ]]>
+ </Details>
+ </BugPattern>
<BugPattern type="CU_CLONE_USABILITY_THROWS">
<ShortDescription>Clone method declares it throws CloneNotSupportedException</ShortDescription>
@@ -3570,7 +3654,31 @@
</p>
]]>
</Details>
- </BugPattern>"
+ </BugPattern>
+
+ <BugPattern type="UMTP_UNBOUND_METHOD_TEMPLATE_PARAMETER">
+ <ShortDescription>Method declares unbound method template parameter(s)</ShortDescription>
+ <LongDescription>Method {1} declares unbound method template parameter(s)</LongDescription>
+ <Details>
+ <![CDATA[
+ <p>This method declares a method level template parameter that is not bound by any parameter of this
+ method. Therefore the template parameter adds no validation or type safety and can be removed, as it's
+ just confusing to the reader.
+ ]]>
+ </Details>
+ </BugPattern>
+
+ <BugPattern type="NPMC_NON_PRODUCTIVE_METHOD_CALL">
+ <ShortDescription>Method ignores return value of a non mutating method</ShortDescription>
+ <LongDescription>Method {1} ignores return value of a non mutating method</LongDescription>
+ <Details>
+ <![CDATA[
+ <p>This method ignores the return value of a common method that is assumed to be none mutating.
+ If this method does in fact not modify the object it is called on, there is no reason to call
+ this method, and it can be removed.
+ ]]>
+ </Details>
+ </BugPattern>
<!-- BugCode -->
@@ -3682,4 +3790,6 @@
<BugCode abbrev="CU">Clone Usability</BugCode>
<BugCode abbrev="CAAL">Confusing Array asList</BugCode>
<BugCode abbrev="PSC">Presize Collection</BugCode>
+ <BugCode abbrev="UMTP">Unbound Method Template Parameter</BugCode>
+ <BugCode abbrev="NPMC">Non Productive Method Call</BugCode>
</MessageCollection>
Modified: trunk/fb-contrib/htdocs/index.shtml
===================================================================
--- trunk/fb-contrib/htdocs/index.shtml 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/htdocs/index.shtml 2013-04-18 18:16:49 UTC (rev 1743)
@@ -86,6 +86,22 @@
same kind of exception, and throw the same exception always. These blocks can
be coalesced into one.
</li>
+ <li><b>[PSC] Presize Collections</b><br/>
+ Looks for methods that create and populate collections, and while knowing
+ the end size of those collections, does not pre allocate the collection
+ to be big enough. This just causes unneeded reallocations putting strain
+ on the garbage collector.
+ </li>
+ <li><b>[UMTP] Unbound Method Template Parameter</b><br/>
+ Looks for methods that declare method level template parameter(s) that are not bound to any of
+ the method's parameters, and thus is not adding any validation/type safety to the method,
+ and is just confusing.
+ </li>
+ <li><b>[NPMC] Non Productive Method Call</b><br/>
+ Looks for common methods that are believed to be non mutating, where the value
+ is discarded. Since the method makes no changes to the object, calling this method
+ is useless. The method call can be removed.
+ </li>
</ul>
</div>
<hr/>
Modified: trunk/fb-contrib/samples/CU_Sample.java
===================================================================
--- trunk/fb-contrib/samples/CU_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/samples/CU_Sample.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -14,4 +14,27 @@
}
}
}
+
+ class Unrelated implements Cloneable {
+ public String clone() {
+ try {
+ return (String) super.clone();
+ } catch (CloneNotSupportedException cnse) {
+ throw new Error("Won't happen");
+ }
+ }
+ }
+
+ class FPCloneInterface implements Cloneable, Runnable {
+ public Runnable clone() {
+ try {
+ return (Runnable) super.clone();
+ } catch (CloneNotSupportedException cnse) {
+ throw new Error("Won't happen");
+ }
+ }
+
+ public void run() {
+ }
+ }
}
Modified: trunk/fb-contrib/samples/JAO_Sample.java
===================================================================
--- trunk/fb-contrib/samples/JAO_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/samples/JAO_Sample.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -3,35 +3,45 @@
-public class JAO_Sample extends TestCase
+public class JAO_Sample extends TestCase
{
-
+
public void testExactDoubles(double d1, double d2)
{
Assert.assertEquals(d1, d2);
}
-
+
public void testTrue(boolean b)
{
Assert.assertEquals(true, b);
}
-
+
public void testFalse(boolean b)
{
Assert.assertEquals("Wow this is bad", false, b);
}
-
+
public void testWrongOrder(int i)
{
Assert.assertEquals(i, 10);
}
-
+
public void testAutoBoxNotNull(int i)
{
Assert.assertNotNull(i);
Assert.assertNotNull(i == 3);
}
+
+ public void testAssertUsed(String s)
+ {
+ assert s != null;
+ }
+ public void testUseAssertEquals(String s, String s2) {
+ Assert.assertTrue(s.equals(s2));
+ Assert.assertTrue(s.length() == s.length());
+ }
+
public void test3ArgNP(float foo)
{
Assert.assertEquals(1.0f, foo, 0.1);
Modified: trunk/fb-contrib/samples/PRMC_Sample.java
===================================================================
--- trunk/fb-contrib/samples/PRMC_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/samples/PRMC_Sample.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -92,4 +92,35 @@
}
enum FPEnum { fee, fi, fo, fum };
+
+
+ public boolean validChainedFields(Chain c1) {
+ return c1.chainedField.toString().equals(c1.chainedField.toString());
+ }
+
+ public boolean fpChainedFieldsOfDiffBases(Chain c1, Chain c2)
+ {
+ return c1.chainedField.toString().equals(c2.chainedField.toString());
+ }
+
+ class Chain
+ {
+ public Chain chainedField;
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("--");
+ sb.append("XX");
+ sb.append("--");
+ sb.append("XX");
+ sb.append("--");
+ sb.append("XX");
+ sb.append("--");
+ sb.append("XX");
+ sb.append("--");
+ sb.append("XX");
+ sb.append("--");
+ return sb.toString();
+ }
+ }
}
Modified: trunk/fb-contrib/samples/PSC_Sample.java
===================================================================
--- trunk/fb-contrib/samples/PSC_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/samples/PSC_Sample.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -1,8 +1,13 @@
+import java.io.BufferedReader;
+import java.io.IOException;
import java.util.ArrayDeque;
+import java.util.ArrayList;
import java.util.Deque;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
@@ -36,10 +41,55 @@
commonWords.add("them");
}
- public void testFPDontHaveCollectionForSizing(Iterator<Long> it) {
+ public void fpDontHaveCollectionForSizing(Iterator<Long> it) {
Deque<Long> ad = new ArrayDeque<Long>();
while (it.hasNext()) {
ad.add(it.next());
}
}
+
+ public void fpConditionalInLoop(Set<String> source) {
+ List<String> dest = new ArrayList<String>();
+ for (String s : source) {
+ if (s.length() > 0) {
+ dest.add(s);
+ }
+ }
+ }
+
+ public void fpSwitchInLoop(Set<Integer> source) {
+ List<Integer> dest = new ArrayList<Integer>();
+ for (Integer s : source) {
+ switch (s.intValue()) {
+ case 0:
+ dest.add(s);
+ break;
+ case 1:
+ dest.remove(s);
+ break;
+ }
+ }
+ }
+
+ public void fpAllocationInLoop(Map<String, String> source) {
+ Map<String, List<String>> dest = new HashMap<String, List<String>>();
+
+ for (Map.Entry<String, String> entry : source.entrySet()) {
+
+ List<String> l = new ArrayList<String>();
+ l.add(entry.getValue());
+ dest.put(entry.getKey(), l);
+ }
+ }
+
+ public List<String> fpUnknownSrcSize(BufferedReader br) throws IOException {
+ List<String> l = new ArrayList<String>();
+ String line;
+ while ((line = br.readLine()) != null) {
+ l.add(line);
+ }
+
+ return l;
+
+ }
}
Modified: trunk/fb-contrib/samples/SPP_Sample.java
===================================================================
--- trunk/fb-contrib/samples/SPP_Sample.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/samples/SPP_Sample.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -111,6 +111,13 @@
{
return (b ? true : false);
}
+
+ public void testDoubleAppendLiteral(StringBuilder sb, String s)
+ {
+ sb.append("hello").append("there");
+ sb.append("Hello").append(s).append("there");
+ }
+
public boolean testFPUselessTrinary(boolean a, boolean b)
{
@@ -337,4 +344,8 @@
sb = sb.append("foo");
sb = sb.append("foo").append("boo").append("hoo");
}
+
+ public String testListFirst(List<String> l) {
+ return l.iterator().next();
+ }
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/FBContrib.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/FBContrib.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/FBContrib.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2013 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
@@ -24,11 +24,11 @@
{
/**
* shows the simple help
- *
+ *
* @param args standard command line args
*/
public static void main(final String[] args) {
- JOptionPane.showMessageDialog( null, "To use fb-contrib, copy this jar file into your local FindBugs plugin directory, and use FindBugs as usual.\n\nfb-contrib is a trademark of MeBigFatGuy.com\nFindBugs is a trademark of the University of Maryland", "fb-contrib: copyright 2005-2008", JOptionPane.INFORMATION_MESSAGE);
+ JOptionPane.showMessageDialog( null, "To use fb-contrib, copy this jar file into your local FindBugs plugin directory, and use FindBugs as usual.\n\nfb-contrib is a trademark of MeBigFatGuy.com\nFindBugs is a trademark of the University of Maryland", "fb-contrib: copyright 2005-2013", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -308,7 +308,7 @@
} else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) {
int pc = getPC();
int[] offsets = getSwitchOffsets();
- List<Integer> targets = new ArrayList<Integer>();
+ List<Integer> targets = new ArrayList<Integer>(offsets.length);
for (int offset : offsets) {
targets.add(Integer.valueOf(offset + pc));
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CloneUsability.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -47,6 +47,7 @@
}
private BugReporter bugReporter;
+ private JavaClass cls;
private String clsName;
/**
@@ -64,13 +65,15 @@
*/
public void visitClassContext(ClassContext classContext) {
try {
- JavaClass cls = classContext.getJavaClass();
+ cls = classContext.getJavaClass();
if (cls.implementationOf(CLONE_CLASS)) {
clsName = cls.getClassName();
cls.accept(this);
}
} catch (ClassNotFoundException cnfe) {
bugReporter.reportMissingClass(cnfe);
+ } finally {
+ cls = null;
}
}
@@ -81,24 +84,37 @@
*/
@Override
public void visitMethod(Method obj) {
- if (obj.isPublic() && !obj.isSynthetic() && obj.getName().equals("clone") && (obj.getArgumentTypes().length == 0)) {
+ try {
+ if (obj.isPublic() && !obj.isSynthetic() && obj.getName().equals("clone") && (obj.getArgumentTypes().length == 0)) {
- String returnClsName = obj.getReturnType().getSignature();
- returnClsName = returnClsName.substring(1, returnClsName.length() - 1).replaceAll("/", ".");
- if (!clsName.equals(returnClsName))
- {
- bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_OBJECT_RETURN", NORMAL_PRIORITY)
+ String returnClsName = obj.getReturnType().getSignature();
+ returnClsName = returnClsName.substring(1, returnClsName.length() - 1).replaceAll("/", ".");
+ if (!clsName.equals(returnClsName))
+ {
+ if ("java.lang.Object".equals(returnClsName)) {
+ bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_OBJECT_RETURN", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this));
+ } else {
+ JavaClass cloneClass = Repository.lookupClass(returnClsName);
+ if (!cls.instanceOf(cloneClass)) {
+ bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_MISMATCHED_RETURN", HIGH_PRIORITY)
.addClass(this)
.addMethod(this));
- }
+ }
+ }
+ }
- ExceptionTable et = obj.getExceptionTable();
+ ExceptionTable et = obj.getExceptionTable();
- if ((et != null) && (et.getLength() > 0)) {
- bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_THROWS", NORMAL_PRIORITY)
- .addClass(this)
- .addMethod(this));
+ if ((et != null) && (et.getLength() > 0)) {
+ bugReporter.reportBug(new BugInstance(this, "CU_CLONE_USABILITY_THROWS", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this));
+ }
}
+ } catch (ClassNotFoundException cnfe) {
+ bugReporter.reportMissingClass(cnfe);
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2013 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
@@ -60,8 +60,8 @@
private boolean srcInited;
private SourceLineAnnotation srcLineAnnotation;
private String[] sourceLines;
-
-
+
+
/**
* constructs a FP detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -69,10 +69,10 @@
public FinalParameters(final BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/**
* overrides the visitor to initialize the 'has source' flag
- *
+ *
* @param classContext the context object for the currently parsed class
*/
@Override
@@ -80,14 +80,14 @@
srcInited = false;
super.visitClassContext(classContext);
}
-
+
/**
* overrides the visitor capture source lines for the method
- *
+ *
* @param obj the method object for the currently parsed method
*/
@Override
- public void visitMethod(final Method obj) {
+ public void visitMethod(final Method obj) {
methodName = obj.getName();
if ("<clinit>".equals(methodName) || "<init>".equals(methodName))
return;
@@ -97,35 +97,35 @@
isStatic = (obj.getAccessFlags() & Constants.ACC_STATIC) != 0;
isAbstract = (obj.getAccessFlags() & Constants.ACC_ABSTRACT) != 0;
parmCount = Type.getArgumentTypes(obj.getSignature()).length;
-
+
super.visitMethod(obj);
srcLineAnnotation = null;
sourceLines = null;
}
-
+
/**
* reads the sourcefile based on the source line annotation for the method
- *
+ *
* @param obj the method object for the currently parsed method
- *
+ *
* @return an array of source lines for the method
*/
private String[] getSourceLines(Method obj) {
-
+
BufferedReader sourceReader = null;
-
+
if (srcInited)
return sourceLines;
-
+
try {
srcLineAnnotation = SourceLineAnnotation.forEntireMethod(getClassContext().getJavaClass(), obj);
if (srcLineAnnotation != null)
- {
+ {
SourceFinder sourceFinder = AnalysisContext.currentAnalysisContext().getSourceFinder();
SourceFile sourceFile = sourceFinder.findSourceFile(srcLineAnnotation.getPackageName(), srcLineAnnotation.getSourceFile());
sourceReader = new BufferedReader(new InputStreamReader(sourceFile.getInputStream()));
-
- List<String> lines = new ArrayList<String>();
+
+ List<String> lines = new ArrayList<String>(100);
String line;
while ((line = sourceReader.readLine()) != null)
lines.add(line);
@@ -145,20 +145,20 @@
srcInited = true;
return sourceLines;
}
-
+
/**
* overrides the visitor to find the source lines for the method header, to find non final parameters
- *
+ *
* @param obj the code object for the currently parsed method
*/
@Override
public void visitCode(final Code obj) {
if (sourceLines == null)
return;
-
+
if (isAbstract)
return;
-
+
if ("<clinit>".equals(methodName) || "<init>".equals(methodName))
return;
@@ -174,7 +174,7 @@
if (methodLine < 0)
return;
-
+
for (int i = methodLine; i <= methodStart; i++) {
if ((i < 0) || (i >= sourceLines.length))
return;
@@ -182,21 +182,21 @@
if (line.indexOf("final") >= 0)
return;
}
-
+
changedParms = new HashSet<Integer>();
super.visitCode(obj);
-
+
BugInstance bi = null;
for (int i = 0; i < parmCount; i++) {
if (changedParms.remove(Integer.valueOf(i)))
continue;
-
+
int reg;
if (!isStatic)
reg = i + 1;
else
reg = i;
-
+
String parmName = getRegisterName(obj, reg);
if (bi == null) {
bi = new BugInstance(this, "FP_FINAL_PARAMETERS", LOW_PRIORITY)
@@ -209,10 +209,10 @@
}
changedParms = null;
}
-
+
/**
* overrides the visitor to find local variable reference stores to store them as changed
- *
+ *
* @param seen the currently parsed opcode
*/
@Override
@@ -223,13 +223,13 @@
changedParms.add(Integer.valueOf(parm));
}
}
-
+
/**
* returns the variable name of the specified register slot
- *
+ *
* @param obj the currently parsed code object
* @param reg the variable register of interest
- *
+ *
* @return the variable name of the specified register
*/
private String getRegisterName(final Code obj, final int reg) {
@@ -241,25 +241,25 @@
}
return String.valueOf(reg);
}
-
+
/**
* return the register number that is be stored
- *
+ *
* @param seen the opcode of the currently parsed statement
- *
+ *
* @return the register number being stored
*/
private int getAStoreParameter(final int seen) {
int reg = RegisterUtils.getAStoreReg(this, seen);
-
+
if (!isStatic)
reg--;
-
+
if (reg >= parmCount)
reg = -1;
-
+
return reg;
-
+
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/IncorrectInternalClassUse.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -44,6 +44,7 @@
internalPackages.add("org/apache/xerces/");
internalPackages.add("org/apache/xalan/");
externalPackages.add("com/sun/jersey");
+ externalPackages.add("com/sun/xsom");
externalPackages.add("org/apache/xerces/xni/");
externalPackages.add("org/apache/xerces/xs/");
externalPackages.add("org/apache/xalan/extensions");
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JUnitAssertionOddities.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JUnitAssertionOddities.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/JUnitAssertionOddities.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2013 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
@@ -38,8 +38,10 @@
import edu.umd.cs.findbugs.ba.ClassContext;
/** looks for odd uses of the Assert class of the JUnit framework */
-public class JUnitAssertionOddities extends BytecodeScanningDetector
+public class JUnitAssertionOddities extends BytecodeScanningDetector
{
+ private enum State {SAW_NOTHING, SAW_IF_ICMPNE, SAW_ICONST_1, SAW_GOTO, SAW_ICONST_0, SAW_EQUALS};
+
private static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
private static final String TEST_ANNOTATION_SIGNATURE = "Lorg/junit/Test;";
private static final String OLD_ASSERT_CLASS = "junit/framework/Assert";
@@ -62,7 +64,8 @@
private OpcodeStack stack;
private boolean isTestCaseDerived;
private boolean isAnnotationCapable;
-
+ private State state;
+
/**
* constructs a JOA detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -70,10 +73,10 @@
public JUnitAssertionOddities(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/**
* override the visitor to see if this class could be a test class
- *
+ *
* @param classContext the context object of the currently parsed class
*/
@Override
@@ -92,12 +95,12 @@
stack = null;
}
}
-
+
@Override
public void visitCode(Code obj) {
Method m = getMethod();
boolean isTestMethod = isTestCaseDerived && m.getName().startsWith("test");
-
+
if (!isTestMethod && isAnnotationCapable) {
Attribute[] atts = m.getAttributes();
for (Attribute att : atts) {
@@ -123,20 +126,21 @@
}
}
}
-
+
if (isTestMethod) {
stack.resetForMethodEntry(this);
+ state = State.SAW_NOTHING;
super.visitCode(obj);
}
}
-
+
@Override
public void sawOpcode(int seen) {
String userValue = null;
-
+
try {
stack.mergeJumps(this);
-
+
if (seen == INVOKESTATIC) {
String clsName = getClassConstantOperand();
if (OLD_ASSERT_CLASS.equals(clsName) || NEW_ASSERT_CLASS.equals(clsName)) {
@@ -147,7 +151,7 @@
if (argTypes.length == 2) {
if (argTypes[0].equals(Type.STRING) && argTypes[1].equals(Type.STRING))
return;
-
+
if (stack.getStackDepth() >= 2) {
OpcodeStack.Item item1 = stack.getStackItem(1);
Object cons1 = item1.getConstant();
@@ -157,7 +161,7 @@
.addMethod(this)
.addSourceLine(this));
return;
- }
+ }
OpcodeStack.Item item0 = stack.getStackItem(0);
if (item0.getConstant() != null) {
bugReporter.reportBug(new BugInstance(this, "JAO_JUNIT_ASSERTION_ODDITIES_ACTUAL_CONSTANT", NORMAL_PRIORITY)
@@ -186,6 +190,13 @@
.addSourceLine(this));
}
}
+ } else if ("assertTrue".equals(methodName)) {
+ if ((state == State.SAW_ICONST_0) || (state == State.SAW_EQUALS)) {
+ bugReporter.reportBug(new BugInstance(this, "JAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_EQUALS", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this));
+ }
}
} else {
String methodName = getNameConstantOperand();
@@ -196,7 +207,63 @@
userValue = "valueOf";
}
}
+ } else if (seen == ATHROW) {
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ String throwClass = item.getSignature();
+ if ("Ljava/lang/AssertionError;".equals(throwClass)) {
+ bugReporter.reportBug(new BugInstance(this, "JAO_JUNIT_ASSERTION_ODDITIES_ASSERT_USED", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this));
+ }
+ }
}
+
+ switch (state) {
+ case SAW_NOTHING:
+ case SAW_EQUALS:
+ if (seen == IF_ICMPNE)
+ state = State.SAW_IF_ICMPNE;
+ else
+ state = State.SAW_NOTHING;
+ break;
+
+ case SAW_IF_ICMPNE:
+ if (seen == ICONST_1)
+ state = State.SAW_ICONST_1;
+ else
+ state = State.SAW_NOTHING;
+ break;
+
+ case SAW_ICONST_1:
+ if (seen == GOTO)
+ state = State.SAW_GOTO;
+ else
+ state = State.SAW_NOTHING;
+ break;
+
+ case SAW_GOTO:
+ if (seen == ICONST_0)
+ state = State.SAW_ICONST_0;
+ else
+ state = State.SAW_NOTHING;
+ break;
+
+ default:
+ state = State.SAW_NOTHING;
+ break;
+ }
+
+ if (seen == INVOKEVIRTUAL) {
+ String methodName = getNameConstantOperand();
+ String sig = getSigConstantOperand();
+ if ("equals".equals(methodName) && "(Ljava/lang/Object;)Z".equals(sig)) {
+ state = State.SAW_EQUALS;
+ }
+ }
+
+
} finally {
TernaryPatcher.pre(stack, seen);
stack.sawOpcode(this, seen);
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonOwnedSynchronization.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonOwnedSynchronization.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonOwnedSynchronization.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -55,7 +55,8 @@
/**
* constructs a NOS detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
- */ public NonOwnedSynchronization(BugReporter bugReporter) {
+ */
+ public NonOwnedSynchronization(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -182,6 +182,8 @@
*/
@Override
public void sawOpcode(int seen) {
+ String userValue = null;
+
try {
stack.mergeJumps(this);
if (branchTargets.remove(Integer.valueOf(getPC()))) {
@@ -200,7 +202,31 @@
} else if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) {
localMethodCalls.remove(Integer.valueOf(RegisterUtils.getAStoreReg(this, seen)));
} else if (seen == PUTFIELD) {
- fieldMethodCalls.remove(getNameConstantOperand());
+ String fieldSource = "";
+
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ fieldSource = (String) item.getUserValue();
+ if (fieldSource == null)
+ fieldSource = "";
+ }
+ fieldMethodCalls.remove(fieldSource + ":" + getNameConstantOperand());
+ } else if (seen == GETFIELD) {
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ userValue = (String) item.getUserValue();
+ if (userValue == null) {
+ int reg = item.getRegisterNumber();
+ if (reg >= 0) {
+ userValue = String.valueOf(reg);
+ } else {
+ XField xf = item.getXField();
+ if (xf != null) {
+ userValue = xf.getName();
+ }
+ }
+ }
+ }
} else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE) || (seen == INVOKESTATIC)) {
String signature = getSigConstantOperand();
int parmCount = Type.getArgumentTypes(signature).length;
@@ -232,7 +258,10 @@
if (reg >= 0) {
mc = localMethodCalls.get(Integer.valueOf(reg));
} else if (field != null) {
- mc = fieldMethodCalls.get(field.getName());
+ String fieldSource = (String) obj.getUserValue();
+ if (fieldSource == null)
+ fieldSource = "";
+ mc = fieldMethodCalls.get(fieldSource + ":" + field.getName());
} else {
return;
}
@@ -267,7 +296,16 @@
if (reg >= 0) {
localMethodCalls.remove(Integer.valueOf(reg));
} else if (field != null) {
- fieldMethodCalls.remove(field.getName());
+ String fieldSource = "";
+
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ fieldSource = (String) item.getUserValue();
+ if (fieldSource == null)
+ fieldSource = "";
+ }
+
+ fieldMethodCalls.remove(fieldSource + ":" + field.getName());
}
}
} else {
@@ -277,7 +315,11 @@
if (reg >= 0) {
localMethodCalls.put(Integer.valueOf(reg), new MethodCall(methodName, signature, parmConstants));
} else if (field != null) {
- fieldMethodCalls.put(field.getName(), new MethodCall(methodName, signature, parmConstants));
+ OpcodeStack.Item obj = stack.getStackItem(parmCount);
+ String fieldSource = (String) obj.getUserValue();
+ if (fieldSource == null)
+ fieldSource = "";
+ fieldMethodCalls.put(fieldSource + ":" + field.getName(), new MethodCall(methodName, signature, parmConstants));
}
}
}
@@ -285,6 +327,12 @@
}
} finally {
stack.sawOpcode(this, seen);
+ if (userValue != null) {
+ if (stack.getStackDepth() > 0) {
+ OpcodeStack.Item item = stack.getStackItem(0);
+ item.setUserValue(userValue);
+ }
+ }
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PresizeCollections.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -52,14 +52,15 @@
PRESIZEABLE_COLLECTIONS.add("java/util/LinkedHashSet");
PRESIZEABLE_COLLECTIONS.add("java/util/PriorityBlockingQueue");
PRESIZEABLE_COLLECTIONS.add("java/util/PriorityQueue");
- PRESIZEABLE_COLLECTIONS.add("java/util/TreeSet");
PRESIZEABLE_COLLECTIONS.add("java/util/Vector");
}
private BugReporter bugReporter;
private OpcodeStack stack;
private int allocNumber;
+ private Map<Integer, Integer> allocLocation;
private Map<Integer, List<Integer>> allocToAddPCs;
+ private List<DownBranch> downBranches;
public PresizeCollections(BugReporter bugReporter) {
this.bugReporter = bugReporter;
@@ -73,11 +74,15 @@
public void visitClassContext(ClassContext classContext) {
try {
stack = new OpcodeStack();
+ allocLocation = new HashMap<Integer, Integer>();
allocToAddPCs = new HashMap<Integer, List<Integer>>();
+ downBranches = new ArrayList<DownBranch>();
super.visitClassContext(classContext);
} finally {
stack = null;
+ allocLocation = null;
allocToAddPCs = null;
+ downBranches = null;
}
}
@@ -89,7 +94,9 @@
public void visitCode(Code obj) {
stack.resetForMethodEntry(this);
allocNumber = 0;
+ allocLocation.clear();
allocToAddPCs.clear();
+ downBranches.clear();
super.visitCode(obj);
for (List<Integer> pcs : allocToAddPCs.values()) {
@@ -146,24 +153,60 @@
}
break;
+ case LOOKUPSWITCH:
+ case TABLESWITCH:
+ int[] offsets = getSwitchOffsets();
+ if (offsets.length > 1) {
+ int secondCase = offsets[1] + getPC();
+ DownBranch db = new DownBranch(getPC(), secondCase);
+ downBranches.add(db);
+ }
+ break;
+
+ case IFEQ:
+ case IFNE:
+ case IFLT:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case IF_ICMPEQ:
+ case IF_ICMPNE:
+ case IF_ICMPLT:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case IFNULL:
+ case IFNONNULL:
case GOTO:
case GOTO_W:
if (getBranchOffset() < 0) {
int target = getBranchTarget();
- Iterator<List<Integer>> it = allocToAddPCs.values().iterator();
+ Iterator<Map.Entry<Integer, List<Integer>>> it = allocToAddPCs.entrySet().iterator();
while (it.hasNext()) {
- List<Integer> pcs = it.next();
- for (Integer pc : pcs) {
- if (pc > target) {
- bugReporter.reportBug(new BugInstance(this, "PSC_PRESIZE_COLLECTIONS", NORMAL_PRIORITY)
- .addClass(this)
- .addMethod(this)
- .addSourceLine(this, pc));
- it.remove();
- break;
+ Map.Entry<Integer, List<Integer>> entry = it.next();
+ Integer allocLoc = allocLocation.get(entry.getKey());
+ if ((allocLoc != null) && (allocLoc.intValue() < target)) {
+ List<Integer> pcs = entry.getValue();
+ for (Integer pc : pcs) {
+ if (pc > target) {
+ int numDownBranches = countDownBranches(target, pc);
+ if (numDownBranches <= 1) {
+ bugReporter.reportBug(new BugInstance(this, "PSC_PRESIZE_COLLECTIONS", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this)
+ .addSourceLine(this, pc));
+ it.remove();
+ }
+ break;
+ }
}
}
}
+ } else {
+ DownBranch db = new DownBranch(getPC(), getBranchTarget());
+ downBranches.add(db);
}
}
} finally {
@@ -171,9 +214,37 @@
if (sawAlloc) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
- item.setUserValue(Integer.valueOf(++allocNumber));
+ ++allocNumber;
+ item.setUserValue(Integer.valueOf(allocNumber));
+ allocLocation.put(Integer.valueOf(allocNumber), Integer.valueOf(getPC()));
}
}
}
}
+
+ private int countDownBranches(int loopTop, int addPC) {
+ int numDownBranches = 0;
+ for (DownBranch db : downBranches) {
+ if ((db.fromPC > loopTop) && (db.fromPC < addPC) && (db.toPC > addPC)) {
+ numDownBranches++;
+ }
+ }
+
+ return numDownBranches;
+ }
+
+ static class DownBranch {
+ public int fromPC;
+ public int toPC;
+
+ public DownBranch(int from, int to) {
+ fromPC = from;
+ toPC = to;
+ }
+
+ @Override
+ public String toString() {
+ return "DownBranch[From: " + fromPC + " To: " + toPC + "]";
+ }
+ }
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2013-03-04 04:47:55 UTC (rev 1742)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SillynessPotPourri.java 2013-04-18 18:16:49 UTC (rev 1743)
@@ -23,6 +23,8 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.Code;
@@ -62,6 +64,8 @@
collectionInterfaces.add("java/util/Map");
collectionInterfaces.add("java/util/SortedMap");
}
+
+ private static final Pattern APPEND_PATTERN = Pattern.compile("append:([0-9]+):(.*)");
private static JavaClass calendarClass;
static {
@@ -347,16 +351,21 @@
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
String mName = (String) item.getUserValue();
- if ("trim".equals(mName)) {
- item.setUserValue(null);
- } else if ((mName != null) && (mName.startsWith("append:"))) {
- int appendReg = Integer.parseInt(mName.substring("append:".length()));
- if (reg == appendReg) {
- ...
[truncated message content] |