[Fb-contrib-commit] SF.net SVN: fb-contrib: [538] trunk/fb-contrib/etc
Brought to you by:
dbrosius
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. |