[Fb-contrib-commit] SF.net SVN: fb-contrib:[1794] trunk/fb-contrib
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2016-08-17 00:36:41
|
Revision: 1794
http://sourceforge.net/p/fb-contrib/code/1794
Author: dbrosius
Date: 2016-08-17 00:36:37 +0000 (Wed, 17 Aug 2016)
Log Message:
-----------
sync from github
Modified Paths:
--------------
trunk/fb-contrib/build.xml
trunk/fb-contrib/etc/findbugs.xml
trunk/fb-contrib/htdocs/index.shtml
trunk/fb-contrib/htdocs/repository.html
trunk/fb-contrib/pom.xml
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingFunctionSemantics.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CopiedOverriddenMethod.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CyclomaticComplexity.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DubiousMapCollection.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FindCircularDependencies.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FloatingPointLoops.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/HangingExecutors.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/MethodReturnsConstant.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ModifyingUnmodifiableCollection.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NeedlessMemberCollectionSynchronization.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/NonRecycleableTaglibs.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/OverlyConcreteParameter.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PartiallyConstructedObjectAccess.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PoorMansEnum.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossibleMemoryBloat.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/PossiblyRedundantMethodCalls.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SluggishGui.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SuspiciousComparatorReturnValues.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/TristateBooleanPattern.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnitTestAssertionOddities.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedCollectionContents.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnrelatedReturnValues.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UnusedParameter.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseAddAll.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseEnumCollections.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/UseToArray.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/BugType.java
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/QMethod.java
Added Paths:
-----------
trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/utils/StopOpcodeParsingException.java
Modified: trunk/fb-contrib/build.xml
===================================================================
--- trunk/fb-contrib/build.xml 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/build.xml 2016-08-17 00:36:37 UTC (rev 1794)
@@ -28,7 +28,7 @@
<property name="javac.deprecation" value="on" />
<property name="javac.debug" value="on" />
- <property name="fb-contrib.version" value="6.7.0-SNAPSHOT" />
+ <property name="fb-contrib.version" value="6.6.2" />
<property name="sonatype.dir" value="${user.home}/.fb-contrib-${fb-contrib.version}-sonatype" />
@@ -198,12 +198,13 @@
<include name="**/*.txt" />
<include name="**/*.md" />
<include name="**/*.xls" />
+ <include name="**/*.example" />
</fileset>
</zip>
</target>
<target name="javadoc" depends="-init" description="build the javadoc for the project">
- <javadoc packagenames="com.mebigfatguy.*" sourcepath="${src.dir}" classpathref="fb-contrib.classpath" destdir="${javadoc.dir}" windowtitle="fb-contrib api">
+ <javadoc packagenames="com.mebigfatguy.*" sourcepath="${src.dir}" classpathref="fb-contrib.classpath" destdir="${javadoc.dir}" windowtitle="fb-contrib api" access="private">
<doctitle><![CDATA[<h1>fb-contrib javadoc</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright © 2005-2016 MeBigFatGuy.com. All Rights Reserved.</i>]]></bottom>
</javadoc>
Modified: trunk/fb-contrib/etc/findbugs.xml
===================================================================
--- trunk/fb-contrib/etc/findbugs.xml 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/etc/findbugs.xml 2016-08-17 00:36:37 UTC (rev 1794)
@@ -20,7 +20,7 @@
<!-- Detectors -->
-<!-- COMMENT OUT FOR RELEASE -->
+<!-- COMMENT OUT FOR RELEASE
<Detector class="com.mebigfatguy.fbcontrib.debug.OCSDebugger" speed="fast"/>
@@ -30,7 +30,7 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.BloatedAssignmentScope" speed="fast" reports="BAS_BLOATED_ASSIGNMENT_SCOPE" hidden="true" />
-<!-- COMMENT OUT FOR RELEASE -->
+ COMMENT OUT FOR RELEASE -->
<Detector class="com.mebigfatguy.fbcontrib.collect.CollectStatistics" speed="fast" reports="" hidden="true" />
@@ -297,13 +297,13 @@
<Detector class="com.mebigfatguy.fbcontrib.detect.IOIssues" speed="fast" reports="IOI_DOUBLE_BUFFER_COPY,IOI_COPY_WITH_READER"/>
- <!-- COMMENT OUT FOR POINT RELEASE -->
+ <!-- COMMENT OUT FOR POINT RELEASE
<Detector class="com.mebigfatguy.fbcontrib.detect.DubiousMapCollection" speed="fast" reports="DMC_DUBIOUS_MAP_COLLECTION"/>
<Detector class="com.mebigfatguy.fbcontrib.detect.BuryingLogic" speed="fast" reports="BL_BURYING_LOGIC"/>
- <!-- COMMENT OUT FOR POINT RELEASE -->
+ COMMENT OUT FOR POINT RELEASE -->
<!-- BugPattern -->
Modified: trunk/fb-contrib/htdocs/index.shtml
===================================================================
--- trunk/fb-contrib/htdocs/index.shtml 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/htdocs/index.shtml 2016-08-17 00:36:37 UTC (rev 1794)
@@ -68,7 +68,7 @@
</li>
</ul>
</p>
- <p style="font-weight: bold;">The latest version of fb-contrib is 6.6.1 available for download
+ <p style="font-weight: bold;">The latest version of fb-contrib is 6.6.2 available for download
<a href="http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22fb-contrib%22">here</a>.</p>
<p style="font-weight: bold;">This version requires FindBugs 3.0.1 or better</p>
<p style="font-weight: bold;">Please note that active development for this project is now done on
Modified: trunk/fb-contrib/htdocs/repository.html
===================================================================
--- trunk/fb-contrib/htdocs/repository.html 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/htdocs/repository.html 2016-08-17 00:36:37 UTC (rev 1794)
@@ -22,7 +22,7 @@
<table style="margin-left: 40px; background-color: #A0A0FF; padding: 20px; border-width: 1px; border-style: outset; border-color: #000000;">
<tr><td><b>GroupId:</b></td><td>com.mebigfatguy.fb-contrib</td></tr>
<tr><td><b>ArtifactId:</b></td><td>fb-contrib</td></tr>
- <tr><td><b>Version:</b></td><td>6.6.1</td></tr>
+ <tr><td><b>Version:</b></td><td>6.6.2</td></tr>
</table>
</div>
Modified: trunk/fb-contrib/pom.xml
===================================================================
--- trunk/fb-contrib/pom.xml 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/pom.xml 2016-08-17 00:36:37 UTC (rev 1794)
@@ -8,7 +8,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.mebigfatguy.fb-contrib</groupId>
<artifactId>fb-contrib</artifactId>
- <version>6.7.0-SNAPSHOT</version>
+ <version>6.6.2</version>
<prerequisites>
<maven>2.2.1</maven>
@@ -77,6 +77,9 @@
<contributor>
<name>Richard Fearn</name>
</contributor>
+ <contributor>
+ <name>Mikkel Kjeldsen</name>
+ </contributor>
</contributors>
<licenses>
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/collect/CollectStatistics.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -18,6 +18,10 @@
*/
package com.mebigfatguy.fbcontrib.collect;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import org.apache.bcel.Constants;
@@ -25,12 +29,15 @@
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
+import org.objectweb.asm.Type;
+import com.mebigfatguy.fbcontrib.utils.QMethod;
import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.BytecodeScanningDetector;
import edu.umd.cs.findbugs.NonReportingDetector;
+import edu.umd.cs.findbugs.OpcodeStack;
import edu.umd.cs.findbugs.ba.ClassContext;
public class CollectStatistics extends BytecodeScanningDetector implements NonReportingDetector {
@@ -48,6 +55,9 @@
private int numMethodCalls;
private boolean modifiesState;
private boolean classHasAnnotation;
+ private OpcodeStack stack;
+ private Map<QMethod, Set<CalledMethod>> selfCallTree;
+ private QMethod curMethod;
public CollectStatistics(@SuppressWarnings("unused") BugReporter bugReporter) {
Statistics.getStatistics().clear();
@@ -55,10 +65,21 @@
@Override
public void visitClassContext(ClassContext classContext) {
- JavaClass cls = classContext.getJavaClass();
- AnnotationEntry[] annotations = cls.getAnnotationEntries();
- classHasAnnotation = (annotations != null) && (annotations.length > 0);
- super.visitClassContext(classContext);
+ try {
+ JavaClass cls = classContext.getJavaClass();
+ AnnotationEntry[] annotations = cls.getAnnotationEntries();
+ classHasAnnotation = (annotations != null) && (annotations.length > 0);
+ stack = new OpcodeStack();
+ selfCallTree = new HashMap<>();
+ super.visitClassContext(classContext);
+
+ performModifyStateClosure(classContext.getJavaClass());
+
+ } finally {
+ stack = null;
+ selfCallTree = null;
+ curMethod = null;
+ }
}
@Override
@@ -69,6 +90,8 @@
byte[] code = obj.getCode();
if (code != null) {
+ stack.resetForMethodEntry(this);
+ curMethod = null;
super.visitCode(obj);
String clsName = getClassName();
Method method = getMethod();
@@ -97,25 +120,104 @@
@Override
public void sawOpcode(int seen) {
- switch (seen) {
- case INVOKEVIRTUAL:
- case INVOKEINTERFACE:
- case INVOKESPECIAL:
- case INVOKESTATIC:
- case INVOKEDYNAMIC:
- numMethodCalls++;
- break;
+ try {
+ switch (seen) {
+ case INVOKEVIRTUAL:
+ case INVOKEINTERFACE:
+ case INVOKESPECIAL:
+ case INVOKESTATIC:
+ case INVOKEDYNAMIC:
+ numMethodCalls++;
- case PUTSTATIC:
- case PUTFIELD:
- modifiesState = true;
- break;
+ if (seen != INVOKESTATIC) {
+ int numParms = Type.getArgumentTypes(getSigConstantOperand()).length;
+ if (stack.getStackDepth() > numParms) {
+ OpcodeStack.Item itm = stack.getStackItem(numParms);
+ if (itm.getRegisterNumber() == 0) {
+ Set<CalledMethod> calledMethods;
- default:
- break;
+ if (curMethod == null) {
+ curMethod = new QMethod(getMethodName(), getMethodSig());
+ calledMethods = new HashSet<>();
+ selfCallTree.put(curMethod, calledMethods);
+ } else {
+ calledMethods = selfCallTree.get(curMethod);
+ }
+
+ calledMethods.add(new CalledMethod(new QMethod(getNameConstantOperand(), getSigConstantOperand()), seen == INVOKESPECIAL));
+ }
+ }
+ }
+ break;
+
+ case PUTSTATIC:
+ case PUTFIELD:
+ modifiesState = true;
+ break;
+
+ default:
+ break;
+ }
+ } finally {
+ stack.sawOpcode(this, seen);
}
}
+ private void performModifyStateClosure(JavaClass cls) {
+ boolean foundNewCall = true;
+ Statistics statistics = Statistics.getStatistics();
+
+ String clsName = cls.getClassName();
+ while (foundNewCall && !selfCallTree.isEmpty()) {
+ foundNewCall = false;
+
+ Iterator<Map.Entry<QMethod, Set<CalledMethod>>> callerIt = selfCallTree.entrySet().iterator();
+ while (callerIt.hasNext()) {
+ Map.Entry<QMethod, Set<CalledMethod>> callerEntry = callerIt.next();
+ QMethod caller = callerEntry.getKey();
+
+ MethodInfo callerMi = statistics.getMethodStatistics(clsName, caller.getMethodName(), caller.getSignature());
+ if (callerMi == null) {
+ // odd, shouldn't happen
+ foundNewCall = true;
+ } else if (callerMi.getModifiesState()) {
+ foundNewCall = true;
+ } else {
+
+ for (CalledMethod calledMethod : callerEntry.getValue()) {
+
+ if (calledMethod.isSuper) {
+ callerMi.setModifiesState(true);
+ foundNewCall = true;
+ break;
+ } else {
+ MethodInfo calleeMi = statistics.getMethodStatistics(clsName, calledMethod.callee.getMethodName(),
+ calledMethod.callee.getSignature());
+ if (calleeMi == null) {
+ // a super or sub class probably implements this method so just assume it modifies state
+ callerMi.setModifiesState(true);
+ foundNewCall = true;
+ break;
+ }
+
+ if (calleeMi.getModifiesState()) {
+ callerMi.setModifiesState(true);
+ foundNewCall = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (foundNewCall) {
+ callerIt.remove();
+ }
+ }
+ }
+
+ selfCallTree.clear();
+ }
+
private boolean isAssociationedWithAnnotations(Method m) {
if (classHasAnnotation) {
return true;
@@ -124,4 +226,30 @@
AnnotationEntry[] annotations = m.getAnnotationEntries();
return (annotations != null) && (annotations.length > 0);
}
+
+ static class CalledMethod {
+ private QMethod callee;
+ private boolean isSuper;
+
+ public CalledMethod(QMethod c, boolean s) {
+ callee = c;
+ isSuper = s;
+ }
+
+ @Override
+ public int hashCode() {
+ return callee.hashCode() & (isSuper ? 0 : 1);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CalledMethod)) {
+ return false;
+ }
+
+ CalledMethod that = (CalledMethod) obj;
+
+ return (isSuper == that.isSuper) && callee.equals(that.callee);
+ }
+ }
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/AbnormalFinallyBlockReturn.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -31,6 +31,7 @@
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.OpcodeUtils;
import com.mebigfatguy.fbcontrib.utils.RegisterUtils;
+import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.ToString;
import edu.umd.cs.findbugs.BugInstance;
@@ -73,7 +74,7 @@
try {
int majorVersion = classContext.getJavaClass().getMajor();
if (majorVersion >= MAJOR_1_4) {
- fbInfo = new ArrayList<FinallyBlockInfo>();
+ fbInfo = new ArrayList<>();
super.visitClassContext(classContext);
}
} finally {
@@ -102,7 +103,11 @@
}
if (!fbInfo.isEmpty()) {
- super.visitCode(obj);
+ try {
+ super.visitCode(obj);
+ } catch (StopOpcodeParsingException e) {
+ // no more finally blocks to check
+ }
}
}
@@ -114,9 +119,6 @@
*/
@Override
public void sawOpcode(int seen) {
- if (fbInfo.isEmpty()) {
- return;
- }
FinallyBlockInfo fbi = fbInfo.get(0);
@@ -128,7 +130,7 @@
if (OpcodeUtils.isAStore(seen)) {
fbi.exReg = RegisterUtils.getAStoreReg(this, seen);
} else {
- fbInfo.remove(0);
+ removeEarliestFinallyBlock();
sawOpcode(seen);
return;
}
@@ -140,14 +142,14 @@
} else if (seen == MONITOREXIT) {
fbi.monitorCount--;
if (fbi.monitorCount < 0) {
- fbInfo.remove(0);
+ removeEarliestFinallyBlock();
sawOpcode(seen);
return;
}
}
if ((seen == ATHROW) && (loadedReg == fbi.exReg)) {
- fbInfo.remove(0);
+ removeEarliestFinallyBlock();
sawOpcode(seen);
return;
} else if (OpcodeUtils.isALoad(seen)) {
@@ -159,7 +161,7 @@
if (OpcodeUtils.isReturn(seen) || (seen == ATHROW)) {
bugReporter.reportBug(new BugInstance(this, BugType.AFBR_ABNORMAL_FINALLY_BLOCK_RETURN.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
.addSourceLine(this));
- fbInfo.remove(0);
+ removeEarliestFinallyBlock();
} else if (OpcodeUtils.isInvoke(seen)) {
try {
JavaClass cls = Repository.lookupClass(getClassConstantOperand());
@@ -169,7 +171,7 @@
if ((et != null) && (et.getLength() > 0) && !catchBlockInFinally(fbi)) {
bugReporter.reportBug(new BugInstance(this, BugType.AFBR_ABNORMAL_FINALLY_BLOCK_RETURN.name(), LOW_PRIORITY).addClass(this)
.addMethod(this).addSourceLine(this));
- fbInfo.remove(0);
+ removeEarliestFinallyBlock();
}
}
} catch (ClassNotFoundException cnfe) {
@@ -179,6 +181,16 @@
}
/**
+ * removes the earliest finally block, as we've just concluded checking it, and if it's the last one then throw back to visitCode
+ */
+ private void removeEarliestFinallyBlock() {
+ fbInfo.remove(0);
+ if (fbInfo.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
+ }
+
+ /**
* finds the method in specified class by name and signature
*
* @param cls
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BloatedAssignmentScope.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -642,6 +642,8 @@
*
* @param sb
* the scope block to start with
+ * @param start
+ * the current pc
* @param target
* the target to look for
*
@@ -697,6 +699,10 @@
/**
* finds the scope block that is the active synchronized block
*
+ * @param sb
+ * the parent scope block to start with
+ * @param monitorEnterPC
+ * the pc where the current synchronized block starts
* @return the scope block
*/
private ScopeBlock findSynchronizedScopeBlock(ScopeBlock sb, int monitorEnterPC) {
@@ -933,6 +939,8 @@
* the register that was stored
* @param pc
* the instruction that did the store
+ * @param assocObject
+ * the the object that is associated with this store, usually the field from which this came
*/
public void addStore(int reg, int pc, UserObject assocObject) {
if (stores == null) {
@@ -1035,7 +1043,7 @@
if (assocs != null) {
for (Map.Entry<UserObject, Integer> entry : assocs.entrySet()) {
UserObject uo = entry.getKey();
- if ((uo.fieldFromReg == fieldFromReg) || ((uo.caller instanceof Integer) && (((Integer) uo.caller) == fieldFromReg))) {
+ if ((uo.fieldFromReg == fieldFromReg) || ((uo.caller instanceof Integer) && (((Integer) uo.caller).intValue() == fieldFromReg))) {
Integer preWrittenFromField = entry.getValue();
if (preWrittenFromField != null) {
if (stores != null) {
@@ -1049,6 +1057,9 @@
/**
* report stores that occur at scopes higher than associated loads that are not involved with loops
+ *
+ * @param parentUsedRegs
+ * the set of registers that where used by the parent scope block
*/
public void findBugs(Set<Integer> parentUsedRegs) {
if (isLoop) {
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BogusExceptionDeclaration.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -30,6 +30,7 @@
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.OpcodeUtils;
import com.mebigfatguy.fbcontrib.utils.SignatureUtils;
+import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet;
import com.mebigfatguy.fbcontrib.utils.Values;
@@ -139,14 +140,18 @@
}
}
if (!declaredCheckedExceptions.isEmpty()) {
- super.visitCode(obj);
- if (!declaredCheckedExceptions.isEmpty()) {
- BugInstance bi = new BugInstance(this, BugType.BED_BOGUS_EXCEPTION_DECLARATION.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
- .addSourceLine(this, 0);
- for (String ex : declaredCheckedExceptions) {
- bi.addString(ex.replaceAll("/", "."));
+ try {
+ super.visitCode(obj);
+ if (!declaredCheckedExceptions.isEmpty()) {
+ BugInstance bi = new BugInstance(this, BugType.BED_BOGUS_EXCEPTION_DECLARATION.name(), NORMAL_PRIORITY).addClass(this)
+ .addMethod(this).addSourceLine(this, 0);
+ for (String ex : declaredCheckedExceptions) {
+ bi.addString(ex.replaceAll("/", "."));
+ }
+ bugReporter.reportBug(bi);
}
- bugReporter.reportBug(bi);
+ } catch (StopOpcodeParsingException e) {
+ // no exceptions left
}
}
}
@@ -213,10 +218,6 @@
*/
@Override
public void sawOpcode(int seen) {
- if (declaredCheckedExceptions.isEmpty()) {
- return;
- }
-
try {
stack.precomputation(this);
@@ -245,14 +246,14 @@
}
if (!found) {
- declaredCheckedExceptions.clear();
+ clearExceptions();
}
} catch (ClassNotFoundException cnfe) {
bugReporter.reportMissingClass(cnfe);
- declaredCheckedExceptions.clear();
+ clearExceptions();
}
} else if ("wait".equals(getNameConstantOperand())) {
- declaredCheckedExceptions.remove("java.lang.InterruptedException");
+ removeException("java.lang.InterruptedException");
}
} else if (seen == ATHROW) {
if (stack.getStackDepth() > 0) {
@@ -261,7 +262,7 @@
String thrownException = SignatureUtils.stripSignature(exSig);
removeThrownExceptionHierarchy(thrownException);
} else {
- declaredCheckedExceptions.clear();
+ clearExceptions();
}
}
} finally {
@@ -280,9 +281,9 @@
try {
if (Values.DOTTED_JAVA_LANG_EXCEPTION.equals(thrownException)) {
// Exception can be thrown even tho the method isn't declared to throw Exception in the case of templated Exceptions
- declaredCheckedExceptions.clear();
+ clearExceptions();
} else {
- declaredCheckedExceptions.remove(thrownException);
+ removeException(thrownException);
JavaClass exCls = Repository.lookupClass(thrownException);
String clsName;
@@ -292,13 +293,35 @@
break;
}
clsName = exCls.getClassName();
- declaredCheckedExceptions.remove(clsName);
+ removeException(clsName);
} while (!declaredCheckedExceptions.isEmpty() && !Values.DOTTED_JAVA_LANG_EXCEPTION.equals(clsName)
&& !Values.DOTTED_JAVA_LANG_ERROR.equals(clsName));
}
+
} catch (ClassNotFoundException cnfe) {
bugReporter.reportMissingClass(cnfe);
- declaredCheckedExceptions.clear();
+ clearExceptions();
}
}
+
+ /**
+ * removes the declared checked exception, and if that was the last declared exception, stops opcode parsing by throwing exception
+ *
+ * @param clsName
+ * the name of the exception to remove
+ */
+ private void removeException(String clsName) {
+ declaredCheckedExceptions.remove(clsName);
+ if (declaredCheckedExceptions.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
+ }
+
+ /**
+ * clears all declared checked exceptions and throws an exception to stop opcode parsing
+ */
+ private void clearExceptions() {
+ declaredCheckedExceptions.clear();
+ throw new StopOpcodeParsingException();
+ }
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/BuryingLogic.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -29,6 +29,7 @@
import org.apache.bcel.generic.Type;
import com.mebigfatguy.fbcontrib.utils.BugType;
+import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.ToString;
import edu.umd.cs.findbugs.BugInstance;
@@ -53,7 +54,6 @@
private OpcodeStack stack;
private Deque<IfBlock> ifBlocks;
private IfBlock activeUnconditional;
- private boolean isReported;
private double lowBugRatioLimit;
private double normalBugRatioLimit;
private BitSet catchPCs;
@@ -72,7 +72,7 @@
lowBugRatioLimit = LOW_BUG_RATIO_LIMIT;
}
}
- } catch (Exception e) {
+ } catch (NumberFormatException e) {
lowBugRatioLimit = LOW_BUG_RATIO_LIMIT;
}
@@ -86,7 +86,7 @@
normalBugRatioLimit = NORMAL_BUG_RATIO_LIMIT;
}
}
- } catch (Exception e) {
+ } catch (NumberFormatException e) {
normalBugRatioLimit = NORMAL_BUG_RATIO_LIMIT;
}
}
@@ -116,7 +116,6 @@
stack.resetForMethodEntry(this);
ifBlocks.clear();
activeUnconditional = null;
- isReported = false;
CodeException[] ces = obj.getExceptionTable();
if ((ces == null) || (ces.length == 0)) {
@@ -128,14 +127,15 @@
}
}
gotoBranchPCs.clear();
- super.visitCode(obj);
+ try {
+ super.visitCode(obj);
+ } catch (StopOpcodeParsingException e) {
+ // reported an issue, so get out
+ }
}
@Override
public void sawOpcode(int seen) {
- if (isReported) {
- return;
- }
try {
@@ -181,7 +181,7 @@
bugReporter
.reportBug(new BugInstance(this, BugType.BL_BURYING_LOGIC.name(), ratio > normalBugRatioLimit ? NORMAL_PRIORITY : LOW_PRIORITY)
.addClass(this).addMethod(this).addSourceLineRange(this, activeUnconditional.getStart(), activeUnconditional.getEnd()));
- isReported = true;
+ throw new StopOpcodeParsingException();
}
} else if (!ifBlocks.isEmpty() && (getNextPC() == ifBlocks.getFirst().getEnd())) {
activeUnconditional = ifBlocks.getFirst();
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CommonsEqualsBuilderToEquals.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -30,8 +30,7 @@
import edu.umd.cs.findbugs.OpcodeStack;
/**
- * Find usage of EqualsBuilder from Apache commons, where the code invoke
- * equals() on the constructed object rather than isEquals()
+ * Find usage of EqualsBuilder from Apache commons, where the code invoke equals() on the constructed object rather than isEquals()
*
* <pre>
* new EqualsBuilder().append(this.name, other.name).equals(other);
@@ -56,10 +55,8 @@
}
/**
- * implements the visitor to pass through constructors and static
- * initializers to the byte code scanning code. These methods are not
- * reported, but are used to build SourceLineAnnotations for fields, if
- * accessed.
+ * implements the visitor to pass through constructors and static initializers to the byte code scanning code. These methods are not reported, but are used
+ * to build SourceLineAnnotations for fields, if accessed.
*
* @param obj
* the context object of the currently parsed code attribute
@@ -75,17 +72,20 @@
@Override
public void sawOpcode(int seen) {
- if (seen == INVOKEVIRTUAL) {
- String methodName = getNameConstantOperand();
- if ("equals".equals(methodName) && "(Ljava/lang/Object;)Z".equals(getSigConstantOperand()) && (stack.getStackDepth() > 1)) {
- String calledClass = stack.getStackItem(1).getSignature();
- if (LANG3_EQUALS_BUILDER.equals(calledClass) || LANG_EQUALS_BUILDER.equals(calledClass)) {
- bugReporter.reportBug(new BugInstance(this, BugType.CEBE_COMMONS_EQUALS_BUILDER_ISEQUALS.name(), HIGH_PRIORITY).addClass(this)
- .addMethod(this).addSourceLine(this));
+ try {
+ if (seen == INVOKEVIRTUAL) {
+ String methodName = getNameConstantOperand();
+ if ("equals".equals(methodName) && "(Ljava/lang/Object;)Z".equals(getSigConstantOperand()) && (stack.getStackDepth() > 1)) {
+ String calledClass = stack.getStackItem(1).getSignature();
+ if (LANG3_EQUALS_BUILDER.equals(calledClass) || LANG_EQUALS_BUILDER.equals(calledClass)) {
+ bugReporter.reportBug(new BugInstance(this, BugType.CEBE_COMMONS_EQUALS_BUILDER_ISEQUALS.name(), HIGH_PRIORITY).addClass(this)
+ .addMethod(this).addSourceLine(this));
+ }
}
}
+ } finally {
+ super.sawOpcode(seen);
+ stack.sawOpcode(this, seen);
}
- super.sawOpcode(seen);
- stack.sawOpcode(this, seen);
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CompareClassNameEquals.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -60,7 +60,7 @@
@Override
public void afterOpcode(int seen) {
super.afterOpcode(seen);
- if (flag == true) {
+ if (flag) {
stack.getStackItem(0).setUserValue(Boolean.TRUE);
flag = false;
}
@@ -84,6 +84,5 @@
}
}
}
- // stack.sawOpcode(this, seen);
}
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingFunctionSemantics.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingFunctionSemantics.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ConfusingFunctionSemantics.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -34,6 +34,7 @@
import com.mebigfatguy.fbcontrib.utils.OpcodeUtils;
import com.mebigfatguy.fbcontrib.utils.RegisterUtils;
import com.mebigfatguy.fbcontrib.utils.SignatureUtils;
+import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.ToString;
import edu.umd.cs.findbugs.BugInstance;
@@ -51,7 +52,7 @@
private static final Set<String> knownImmutables;
static {
- Set<String> ki = new HashSet<String>();
+ Set<String> ki = new HashSet<>();
ki.add("Ljava/lang/String;");
ki.add("Ljava/lang/Byte;");
ki.add("Ljava/lang/Character;");
@@ -89,7 +90,7 @@
public void visitClassContext(ClassContext classContext) {
try {
stack = new OpcodeStack();
- possibleParmRegs = new HashMap<Integer, ParmUsage>(10);
+ possibleParmRegs = new HashMap<>(10);
super.visitClassContext(classContext);
} finally {
stack = null;
@@ -130,14 +131,18 @@
}
}
- if (possibleParmRegs.size() > 0) {
- stack.resetForMethodEntry(this);
- super.visitCode(obj);
- for (ParmUsage pu : possibleParmRegs.values()) {
- if ((pu.returnPC >= 0) && (pu.alteredPC >= 0)) {
- bugReporter.reportBug(new BugInstance(this, BugType.CFS_CONFUSING_FUNCTION_SEMANTICS.name(), NORMAL_PRIORITY).addClass(this)
- .addMethod(this).addSourceLine(this, pu.returnPC).addSourceLine(this, pu.alteredPC));
+ if (!possibleParmRegs.isEmpty()) {
+ try {
+ stack.resetForMethodEntry(this);
+ super.visitCode(obj);
+ for (ParmUsage pu : possibleParmRegs.values()) {
+ if ((pu.returnPC >= 0) && (pu.alteredPC >= 0)) {
+ bugReporter.reportBug(new BugInstance(this, BugType.CFS_CONFUSING_FUNCTION_SEMANTICS.name(), NORMAL_PRIORITY).addClass(this)
+ .addMethod(this).addSourceLine(this, pu.returnPC).addSourceLine(this, pu.alteredPC));
+ }
}
+ } catch (StopOpcodeParsingException e) {
+ // no parm regs left
}
}
}
@@ -148,10 +153,6 @@
@Override
public void sawOpcode(int seen) {
- if (possibleParmRegs.isEmpty()) {
- return;
- }
-
try {
stack.precomputation(this);
@@ -176,6 +177,9 @@
} else if (OpcodeUtils.isAStore(seen)) {
int reg = RegisterUtils.getAStoreReg(this, seen);
possibleParmRegs.remove(Integer.valueOf(reg));
+ if (possibleParmRegs.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
} else if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) {
processInvoke();
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CopiedOverriddenMethod.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CopiedOverriddenMethod.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CopiedOverriddenMethod.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -38,6 +38,7 @@
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.SignatureUtils;
+import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.ToString;
import com.mebigfatguy.fbcontrib.utils.Values;
@@ -61,7 +62,6 @@
private int nextParmOffset;
private boolean sawAload0;
private boolean sawParentCall;
- private boolean ignore;
/**
* constructs a COM detector given the reporter to report bugs on
@@ -86,7 +86,7 @@
String superName = cls.getSuperclassName();
if (!Values.DOTTED_JAVA_LANG_OBJECT.equals(superName)) {
this.classContext = clsContext;
- superclassCode = new HashMap<String, CodeInfo>();
+ superclassCode = new HashMap<>();
JavaClass superCls = cls.getSuperClass();
childPoolGen = new ConstantPoolGen(cls.getConstantPool());
parentPoolGen = new ConstantPoolGen(superCls.getConstantPool());
@@ -130,26 +130,29 @@
*/
@Override
public void visitCode(Code obj) {
- Method m = getMethod();
- if ((!m.isPublic() && !m.isProtected()) || m.isAbstract() || m.isSynthetic()) {
- return;
- }
-
- CodeInfo superCode = superclassCode.remove(curMethodInfo);
- if (superCode != null) {
- if (sameAccess(getMethod().getAccessFlags(), superCode.getAccess()) && codeEquals(obj, superCode.getCode())) {
- bugReporter.reportBug(new BugInstance(this, BugType.COM_COPIED_OVERRIDDEN_METHOD.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
- .addSourceLine(classContext, this, getPC()));
+ try {
+ Method m = getMethod();
+ if ((!m.isPublic() && !m.isProtected()) || m.isAbstract() || m.isSynthetic()) {
return;
}
- parmTypes = getMethod().getArgumentTypes();
- ignore = false;
- nextParmIndex = 0;
- nextParmOffset = getMethod().isStatic() ? 0 : 1;
- sawAload0 = nextParmOffset == 0;
- sawParentCall = false;
- super.visitCode(obj);
+ CodeInfo superCode = superclassCode.remove(curMethodInfo);
+ if (superCode != null) {
+ if (sameAccess(getMethod().getAccessFlags(), superCode.getAccess()) && codeEquals(obj, superCode.getCode())) {
+ bugReporter.reportBug(new BugInstance(this, BugType.COM_COPIED_OVERRIDDEN_METHOD.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
+ .addSourceLine(classContext, this, getPC()));
+ return;
+ }
+
+ parmTypes = getMethod().getArgumentTypes();
+ nextParmIndex = 0;
+ nextParmOffset = getMethod().isStatic() ? 0 : 1;
+ sawAload0 = nextParmOffset == 0;
+ sawParentCall = false;
+ super.visitCode(obj);
+ }
+ } catch (StopOpcodeParsingException e) {
+ // method is unique
}
}
@@ -163,22 +166,19 @@
*/
@Override
public void sawOpcode(int seen) {
- if (ignore) {
- return;
- }
if (!sawAload0) {
if (seen == ALOAD_0) {
sawAload0 = true;
} else {
- ignore = true;
+ throw new StopOpcodeParsingException();
}
} else if (nextParmIndex < parmTypes.length) {
if (isExpectedParmInstruction(seen, nextParmOffset, parmTypes[nextParmIndex])) {
nextParmOffset += SignatureUtils.getSignatureSize(parmTypes[nextParmIndex].getSignature());
nextParmIndex++;
} else {
- ignore = true;
+ throw new StopOpcodeParsingException();
}
} else if (!sawParentCall) {
@@ -187,7 +187,7 @@
&& getSigConstantOperand().equals(getMethod().getSignature())) {
sawParentCall = true;
} else {
- ignore = true;
+ throw new StopOpcodeParsingException();
}
} else {
int expectedInstruction = getExpectedReturnInstruction(getMethod().getReturnType());
@@ -195,7 +195,7 @@
bugReporter.reportBug(
new BugInstance(this, BugType.COM_PARENT_DELEGATED_CALL.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
} else {
- ignore = true;
+ throw new StopOpcodeParsingException();
}
}
}
@@ -242,7 +242,9 @@
* determines if two access flags contain the same access modifiers
*
* @param parentAccess
+ * the access flags of the parent method
* @param childAccess
+ * the access flats of the child method
* @return whether the access modifiers are the same
*/
private static boolean sameAccess(int parentAccess, int childAccess) {
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CyclomaticComplexity.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CyclomaticComplexity.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/CyclomaticComplexity.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -120,6 +120,7 @@
while (bbi.hasNext()) {
BasicBlock bb = bbi.next();
Iterator<Edge> iei = cfg.outgoingEdgeIterator(bb);
+ int lastSwitchTargetBlockLabel = Integer.MIN_VALUE;
while (iei.hasNext()) {
Edge e = iei.next();
int edgeType = e.getType();
@@ -130,6 +131,12 @@
exceptionNodeTargets.set(nodeTarget);
branches++;
}
+ } else if ((edgeType == EdgeTypes.SWITCH_EDGE) || (edgeType == EdgeTypes.SWITCH_DEFAULT_EDGE)) {
+ int nodeTarget = e.getTarget().getLabel();
+ if (nodeTarget != lastSwitchTargetBlockLabel) {
+ branches++;
+ }
+ lastSwitchTargetBlockLabel = nodeTarget;
} else {
branches++;
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DeletingWhileIterating.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -76,7 +76,7 @@
}
try {
- exceptionClasses = new HashSet<JavaClass>(2);
+ exceptionClasses = new HashSet<>(2);
exceptionClasses.add(Repository.lookupClass("java/util/concurrent/CopyOnWriteArrayList"));
exceptionClasses.add(Repository.lookupClass("java/util/concurrent/CopyOnWriteArraySet"));
} catch (ClassNotFoundException cnfe) {
@@ -90,7 +90,7 @@
private static final Map<QMethod, Integer> modifyingMethods;
static {
- Map<QMethod, Integer> mm = new HashMap<QMethod, Integer>();
+ Map<QMethod, Integer> mm = new HashMap<>();
mm.put(new QMethod("add", "(Ljava/lang/Object;)Z"), Values.ONE);
mm.put(new QMethod("addAll", "(Ljava/util/Collection;)Z"), Values.ONE);
mm.put(new QMethod("addAll", "(ILjava/util/Collection;)Z"), Values.TWO);
@@ -136,9 +136,9 @@
try {
stack = new OpcodeStack();
- collectionGroups = new ArrayList<GroupPair>();
- groupToIterator = new HashMap<Integer, Integer>();
- loops = new HashMap<Integer, Loop>(10);
+ collectionGroups = new ArrayList<>();
+ groupToIterator = new HashMap<>();
+ loops = new HashMap<>(10);
super.visitClassContext(classContext);
} finally {
stack = null;
@@ -383,6 +383,8 @@
*
* @param couldSeePop
* if the preceding instruction returns a value, and thus might need to be popped
+ *
+ * @return when a following instruction issues some sort of return
*/
private boolean returnFollows(boolean couldSeePop) {
@@ -491,7 +493,7 @@
}
private void buildVariableEndScopeMap() {
- endOfScopes = new HashMap<Integer, BitSet>();
+ endOfScopes = new HashMap<>();
LocalVariableTable lvt = getMethod().getLocalVariableTable();
if (lvt != null) {
@@ -570,7 +572,7 @@
private final String colClass;
public GroupPair(Comparable<?> member, String cls) {
- groupMembers = new HashSet<Comparable<?>>();
+ groupMembers = new HashSet<>();
groupMembers.add(member);
colClass = cls;
}
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DubiousMapCollection.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DubiousMapCollection.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/DubiousMapCollection.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -30,6 +30,7 @@
import com.mebigfatguy.fbcontrib.utils.BugType;
import com.mebigfatguy.fbcontrib.utils.OpcodeUtils;
+import com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException;
import com.mebigfatguy.fbcontrib.utils.UnmodifiableSet;
import com.mebigfatguy.fbcontrib.utils.Values;
@@ -70,7 +71,6 @@
// @formatter:on
);
-
private BugReporter bugReporter;
private JavaClass mapClass;
private OpcodeStack stack;
@@ -114,15 +114,15 @@
public void visitCode(Code obj) {
isInSpecial = SPECIAL_METHODS.contains(getMethod().getName());
stack.resetForMethodEntry(this);
- super.visitCode(obj);
+ try {
+ super.visitCode(obj);
+ } catch (StopOpcodeParsingException e) {
+ // no more unaccounted for map fields
+ }
}
@Override
public void sawOpcode(int seen) {
- if (mapFields.isEmpty()) {
- return;
- }
-
try {
if ((seen == INVOKEINTERFACE) || (seen == INVOKEVIRTUAL)) {
@@ -136,6 +136,9 @@
XField xf = item.getXField();
if (xf != null) {
mapFields.remove(xf.getName());
+ if (mapFields.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
}
}
} else if ((seen == PUTFIELD) || (seen == PUTSTATIC)) {
@@ -143,6 +146,7 @@
if (xf != null) {
if (!isInSpecial) {
mapFields.remove(xf.getName());
+
} else {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
@@ -151,6 +155,10 @@
}
}
}
+ if (mapFields.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
+
}
}
@@ -180,6 +188,10 @@
String mName = getNameConstantOperand();
if (MAP_METHODS.contains(mName)) {
mapFields.remove(fName);
+ if (mapFields.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
+
return;
}
@@ -190,6 +202,10 @@
if (MODIFYING_METHODS.contains(mName)) {
mapFields.remove(fName);
+ if (mapFields.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
+
return;
}
}
@@ -207,6 +223,10 @@
XField xf = item.getXField();
if (xf != null) {
mapFields.remove(xf.getName());
+ if (mapFields.isEmpty()) {
+ throw new StopOpcodeParsingException();
+ }
+
}
} else {
return;
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -320,6 +320,8 @@
* the list of active catch blocks
* @param pc
* the current pc
+ * @param seen
+ * the currently parsed opcode
*/
private void updateEndPCsOnCatchRegScope(List<CatchInfo> infos, int pc, int seen) {
if (lvt != null) {
@@ -363,9 +365,14 @@
/**
* finds the super class or interface that constrains the types of exceptions that can be thrown from the given method
*
+ * @param cls
+ * the currently parsed class
* @param m
* the method to check
* @return a map containing the class name to a set of exceptions that constrain this method
+ *
+ * @throws ClassNotFoundException
+ * if a super class or super interface can't be loaded from the repository
*/
private Map<String, Set<String>> getConstrainingInfo(JavaClass cls, Method m) throws ClassNotFoundException {
String methodName = m.getName();
@@ -436,6 +443,9 @@
* @param m
* the method to add exceptions from
* @return a map with one entry of a class name to a set of exceptions that constrain what can be thrown.
+ *
+ * @throws ClassNotFoundException
+ * if an exception class can't be loaded from the repository
*/
private Map<String, Set<String>> buildConstrainingInfo(JavaClass cls, Method m) throws ClassNotFoundException {
Map<String, Set<String>> constraintInfo = new HashMap<>();
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FieldCouldBeLocal.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -96,7 +96,7 @@
@Override
public void visitClassContext(ClassContext classContext) {
try {
- localizableFields = new HashMap<String, FieldInfo>();
+ localizableFields = new HashMap<>();
visitedBlocks = new BitSet();
clsContext = classContext;
clsName = clsContext.getJavaClass().getClassName();
@@ -158,7 +158,7 @@
cfg = clsContext.getCFG(obj);
cpg = cfg.getMethodGen().getConstantPool();
BasicBlock bb = cfg.getEntry();
- Set<String> uncheckedFields = new HashSet<String>(localizableFields.keySet());
+ Set<String> uncheckedFields = new HashSet<>(localizableFields.keySet());
visitedBlocks.clear();
checkBlock(bb, uncheckedFields);
} catch (CFGBuilderException cbe) {
@@ -228,7 +228,7 @@
* the list of fields to look for
*/
private void checkBlock(BasicBlock bb, Set<String> uncheckedFields) {
- Deque<BlockState> toBeProcessed = new ArrayDeque<BlockState>();
+ Deque<BlockState> toBeProcessed = new ArrayDeque<>();
toBeProcessed.addLast(new BlockState(bb, uncheckedFields));
visitedBlocks.set(bb.getLabel());
@@ -270,8 +270,11 @@
INVOKESPECIAL is = (INVOKESPECIAL) ins;
ReferenceType rt = is.getReferenceType(cpg);
- if (Values.CONSTRUCTOR.equals(is.getMethodName(cpg))
- && ((rt instanceof ObjectType) && ((ObjectType) rt).getClassName().startsWith(clsContext.getJavaClass().getClassName() + '$'))) {
+ if (Values.CONSTRUCTOR.equals(is.getMethodName(cpg))) {
+ if ((rt instanceof ObjectType) && ((ObjectType) rt).getClassName().startsWith(clsContext.getJavaClass().getClassName() + '$')) {
+ localizableFields.clear();
+ }
+ } else {
localizableFields.clear();
}
} else if (ins instanceof INVOKEVIRTUAL) {
@@ -441,6 +444,9 @@
/**
* return the field from the set of unchecked fields if this occurs make a copy of the set on write to reduce memory usage
*
+ * @param field
+ * the field to be removed
+ *
* @return whether the object was removed.
*/
public boolean removeUncheckedField(String field) {
@@ -455,7 +461,7 @@
}
if (fieldsAreSharedWithParent) {
- uncheckedFields = new HashSet<String>(uncheckedFields);
+ uncheckedFields = new HashSet<>(uncheckedFields);
fieldsAreSharedWithParent = false;
uncheckedFields.remove(field);
} else {
@@ -473,15 +479,15 @@
private static class FieldModifier extends BytecodeScanningDetector {
- private final Map<String, Set<String>> methodCallChain = new HashMap<String, Set<String>>();
- private final Map<String, Set<String>> mfModifiers = new HashMap<String, Set<String>>();
+ private final Map<String, Set<String>> methodCallChain = new HashMap<>();
+ private final Map<String, Set<String>> mfModifiers = new HashMap<>();
private String clsName;
public Map<String, Set<String>> getMethodFieldModifiers() {
- Map<String, Set<String>> modifiers = new HashMap<String, Set<String>>(mfModifiers.size());
+ Map<String, Set<String>> modifiers = new HashMap<>(mfModifiers.size());
modifiers.putAll(mfModifiers);
for (Entry<String, Set<String>> method : modifiers.entrySet()) {
- modifiers.put(method.getKey(), new HashSet<String>(method.getValue()));
+ modifiers.put(method.getKey(), new HashSet<>(method.getValue()));
}
boolean modified = true;
@@ -496,7 +502,7 @@
if (fields != null) {
Set<String> flds = modifiers.get(methodDesc);
if (flds == null) {
- flds = new HashSet<String>();
+ flds = new HashSet<>();
modifiers.put(methodDesc, flds);
}
if (flds.addAll(fields)) {
@@ -523,7 +529,7 @@
String methodDesc = getMethodName() + getMethodSig();
Set<String> fields = mfModifiers.get(methodDesc);
if (fields == null) {
- fields = new HashSet<String>();
+ fields = new HashSet<>();
mfModifiers.put(methodDesc, fields);
}
fields.add(getNameConstantOperand());
@@ -532,7 +538,7 @@
String methodDesc = getMethodName() + getMethodSig();
Set<String> methods = methodCallChain.get(methodDesc);
if (methods == null) {
- methods = new HashSet<String>();
+ methods = new HashSet<>();
methodCallChain.put(methodDesc, methods);
}
methods.add(getNameConstantOperand() + getSigConstantOperand());
Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java
===================================================================
--- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java 2016-07-24 19:20:39 UTC (rev 1793)
+++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/FinalParameters.java 2016-08-17 00:36:37 UTC (rev 1794)
@@ -33,6 +33,7 @@
import org.apache.bcel.generic.Type;
import com.mebigfatguy.fbcontrib.utils.BugType;
+import com.mebigfatguy.fbc...
[truncated message content] |