[Fb-contrib-commit] SF.net SVN: fb-contrib:[1662] trunk/fb-contrib/src/com/mebigfatguy/ fbcontrib/
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2011-04-22 05:14:38
|
Revision: 1662
http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=1662&view=rev
Author: dbrosius
Date: 2011-04-22 05:14:32 +0000 (Fri, 22 Apr 2011)
Log Message:
-----------
add find to the list of risky method names
Modified Paths:
--------------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2011-03-25 23:43:53 UTC (rev 1661)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java 2011-04-22 05:14:32 UTC (rev 1662)
@@ -1,17 +1,17 @@
/*
* fb-contrib - Auxiliary detectors for Java programs
* Copyright (C) 2005-2011 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
@@ -42,7 +42,7 @@
* 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 PossiblyRedundantMethodCalls extends BytecodeScanningDetector
+public class PossiblyRedundantMethodCalls extends BytecodeScanningDetector
{
public static final String PRMC_RISKY_FIELD_USER_KEY = "fbcontrib.PRMC.riskynames";
public static final String PRMC_RISKY_CLASS_USER_KEY = "fbcontrib.PRMC.riskyclasses";
@@ -50,18 +50,19 @@
public static final String PRMC_HIGH_METHODCALLS = "fbcontrib.PRMC.highmethodcalls";
public static final String PRMC_NORMAL_BYTECOUNT = "fbcontrib.PRMC.normalbytecount";
public static final String PRMC_NORMAL_METHODCALLS = "fbcontrib.PRMC.normalmethodcalls";
-
+
private static Set<String> riskyMethodNameContents = new HashSet<String>();
private static int highByteCountLimit = 200;
private static int highMethodCallLimit = 10;
private static int normalByteCountLimit = 50;
private static int normalMethodCallLimit = 4;
-
+
static {
riskyMethodNameContents.add("next");
riskyMethodNameContents.add("add");
riskyMethodNameContents.add("create");
riskyMethodNameContents.add("append");
+ riskyMethodNameContents.add("find");
riskyMethodNameContents.add("put");
riskyMethodNameContents.add("remove");
riskyMethodNameContents.add("read");
@@ -74,25 +75,30 @@
riskyMethodNameContents.add("close");
riskyMethodNameContents.add("copy");
riskyMethodNameContents.add("currentTimeMillis");
-
+
String userNameProp = System.getProperty(PRMC_RISKY_FIELD_USER_KEY);
if (userNameProp != null) {
String[] userNames = userNameProp.split("\\s*,\\s*");
- for (String name : userNames)
+ for (String name : userNames) {
riskyMethodNameContents.add(name);
+ }
}
Integer prop = Integer.getInteger(PRMC_HIGH_BYTECOUNT);
- if (prop != null)
+ if (prop != null) {
highByteCountLimit = prop.intValue();
+ }
prop = Integer.getInteger(PRMC_HIGH_METHODCALLS);
- if (prop != null)
+ if (prop != null) {
highMethodCallLimit = prop.intValue();
+ }
prop = Integer.getInteger(PRMC_NORMAL_BYTECOUNT);
- if (prop != null)
+ if (prop != null) {
normalByteCountLimit = prop.intValue();
+ }
prop = Integer.getInteger(PRMC_NORMAL_METHODCALLS);
- if (prop != null)
+ if (prop != null) {
normalMethodCallLimit = prop.intValue();
+ }
}
private static Set<String> riskyClassNames = new HashSet<String>();
static {
@@ -102,18 +108,19 @@
String userNameProp = System.getProperty(PRMC_RISKY_CLASS_USER_KEY);
if (userNameProp != null) {
String[] userNames = userNameProp.split("\\s*,\\s*");
- for (String name : userNames)
- riskyClassNames.add(name);
+ for (String name : userNames) {
+ riskyClassNames.add(name);
+ }
}
}
-
+
private final BugReporter bugReporter;
private OpcodeStack stack = null;
private Map<Integer, MethodCall> localMethodCalls = null;
private Map<String, MethodCall> fieldMethodCalls = null;
private Map<String, MethodCall> staticMethodCalls = null;
private Set<Integer> branchTargets = null;
-
+
/**
* constructs a PRMC detector given the reporter to report bugs on
* @param bugReporter the sync of bug reports
@@ -121,10 +128,10 @@
public PossiblyRedundantMethodCalls(BugReporter bugReporter) {
this.bugReporter = bugReporter;
}
-
+
/**
* implements the visitor to create and clear the stack, method call maps, and branch targets
- *
+ *
* @param classContext the context object of the currently visited class
*/
@Override
@@ -144,10 +151,10 @@
branchTargets = null;
}
}
-
+
/**
* implements the visitor to reset the stack, and method call maps for new method
- *
+ *
* @param obj the context object of the currently parsed code block
*/
@Override
@@ -163,11 +170,11 @@
}
super.visitCode(obj);
}
-
+
/**
* implements the visitor to look for repetitive calls to the same method on the same object
* using the same constant parameters. These methods must return a value.
- *
+ *
* @param seen the opcode of the currently parsed instruction
*/
@Override
@@ -178,7 +185,7 @@
localMethodCalls.clear();
fieldMethodCalls.clear();
}
-
+
if (((seen >= IFEQ) && (seen <= GOTO)) || ((seen >= IFNULL) && (seen <= GOTO_W))) {
branchTargets.add(Integer.valueOf(getBranchTarget()));
} else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) {
@@ -202,44 +209,46 @@
for (int i = 0; i < parmCount; i++) {
OpcodeStack.Item parm = stack.getStackItem(i);
parmConstants[i] = parm.getConstant();
- if (parmConstants[i] == null)
+ if (parmConstants[i] == null) {
return;
+ }
}
-
-
+
+
MethodCall mc;
int reg = -1;
XField field = null;
-
+
if (seen == INVOKESTATIC) {
mc = staticMethodCalls.get(className);
} else {
OpcodeStack.Item obj = stack.getStackItem(parmCount);
reg = obj.getRegisterNumber();
field = obj.getXField();
-
-
+
+
if (reg >= 0) {
mc = localMethodCalls.get(Integer.valueOf(reg));
} else if (field != null) {
mc = fieldMethodCalls.get(field.getName());
- } else
+ } else {
return;
+ }
}
-
+
if (mc != null) {
if (!signature.endsWith("V") && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName)) {
Object[] parms = mc.getParms();
if (Arrays.equals(parms, parmConstants)) {
Statistics statistics = Statistics.getStatistics();
Statistics.MethodInfo mi = statistics.getMethodStatistics(getClassConstantOperand(), methodName, signature);
-
- bugReporter.reportBug(new BugInstance(this, "PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS",
- (mi.numBytes >= highByteCountLimit || mi.numMethodCalls >= highMethodCallLimit) ?
+
+ bugReporter.reportBug(new BugInstance(this, "PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS",
+ ((mi.numBytes >= highByteCountLimit) || (mi.numMethodCalls >= highMethodCallLimit)) ?
HIGH_PRIORITY :
- (mi.numBytes >= normalByteCountLimit || mi.numMethodCalls >= normalMethodCallLimit) ?
+ ((mi.numBytes >= normalByteCountLimit) || (mi.numMethodCalls >= normalMethodCallLimit)) ?
NORMAL_PRIORITY :
- (mi.numBytes == 0 || mi.numMethodCalls == 0) ?
+ ((mi.numBytes == 0) || (mi.numMethodCalls == 0)) ?
LOW_PRIORITY :
EXP_PRIORITY)
.addClass(this)
@@ -248,7 +257,7 @@
.addString(methodName + signature));
}
}
-
+
if (seen == INVOKESTATIC) {
staticMethodCalls.remove(className);
} else {
@@ -275,7 +284,7 @@
stack.sawOpcode(this, seen);
}
}
-
+
/**
* returns true if the class or method name contains a pattern that is considered likely to be this modifying
*
@@ -284,16 +293,18 @@
* @return whether the method sounds like it modifies this
*/
private boolean isRiskyName(String className, String methodName) {
- if (riskyClassNames.contains(className))
- return true;
-
+ if (riskyClassNames.contains(className)) {
+ return true;
+ }
+
for (String riskyName : riskyMethodNameContents) {
- if (methodName.indexOf(riskyName) >= 0)
+ if (methodName.indexOf(riskyName) >= 0) {
return true;
+ }
}
return false;
}
-
+
/**
* contains information about a method call
*/
@@ -302,21 +313,21 @@
private final String methodName;
private final String methodSignature;
private final Object[] methodParms;
-
+
public MethodCall(String name, String signature, Object[] parms) {
methodName = name;
methodSignature = signature;
methodParms = parms;
}
-
+
public String getName() {
return methodName;
}
-
+
public String getSignature() {
return methodSignature;
}
-
+
public Object[] getParms() {
return methodParms;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|