use of edu.umd.cs.findbugs.ba.XMethod in project wcomponents by BorderTech.
the class CheckExpectedWarningsCustom method visitClass.
/**
* {@inheritDoc}
*/
@Override
public void visitClass(final ClassDescriptor classDescriptor) throws CheckedAnalysisException {
if (reporter == null) {
if (!warned) {
System.err.println("*** NOTE ***: CheckExpectedWarnings disabled because bug reporter doesn't use a BugCollection");
warned = true;
}
return;
}
if (warningsByMethod == null) {
//
// Build index of all warnings reported so far, by method.
// Because this detector runs in a later pass than any
// reporting detector, all warnings should have been
// produced by this point.
//
warningsByMethod = new HashMap<>();
warningsByField = new HashMap<>();
warningsByClass = new HashMap<>();
BugCollection bugCollection = reporter.getBugCollection();
for (Iterator<BugInstance> i = bugCollection.iterator(); i.hasNext(); ) {
BugInstance warning = i.next();
MethodAnnotation method = warning.getPrimaryMethod();
FieldAnnotation field = warning.getPrimaryField();
ClassAnnotation clazz = warning.getPrimaryClass();
if (method != null) {
MethodDescriptor methodDesc = method.toXMethod().getMethodDescriptor();
Collection<BugInstance> warnings = warningsByMethod.get(methodDesc);
if (warnings == null) {
warnings = new LinkedList<>();
warningsByMethod.put(methodDesc, warnings);
}
warnings.add(warning);
} else if (field != null) {
FieldDescriptor fieldDesc = XFactory.createXField(field).getFieldDescriptor();
Collection<BugInstance> warnings = warningsByField.get(fieldDesc);
if (warnings == null) {
warnings = new LinkedList<>();
warningsByField.put(fieldDesc, warnings);
}
warnings.add(warning);
} else if (clazz != null) {
ClassDescriptor classDesc = DescriptorFactory.createClassDescriptorFromDottedClassName(clazz.getClassName());
Collection<BugInstance> warnings = warningsByClass.get(classDesc);
if (warnings == null) {
warnings = new LinkedList<>();
warningsByClass.put(classDesc, warnings);
}
warnings.add(warning);
}
}
//
// Based on enabled detectors, figure out which bug codes
// could possibly be reported. Don't complain about
// expected warnings that would be produced by detectors
// that aren't enabled.
//
possibleBugCodes = new HashSet<>();
ExecutionPlan executionPlan = Global.getAnalysisCache().getDatabase(ExecutionPlan.class);
for (Iterator<AnalysisPass> i = executionPlan.passIterator(); i.hasNext(); ) {
AnalysisPass pass = i.next();
for (Iterator<DetectorFactory> j = pass.iterator(); j.hasNext(); ) {
DetectorFactory factory = j.next();
Collection<BugPattern> reportedPatterns = factory.getReportedBugPatterns();
for (BugPattern pattern : reportedPatterns) {
possibleBugCodes.add(pattern.getAbbrev());
}
}
}
if (DEBUG) {
log("CEW: possible warnings are " + possibleBugCodes);
}
}
XClass xclass = Global.getAnalysisCache().getClassAnalysis(XClass.class, classDescriptor);
for (XMethod xmethod : xclass.getXMethods()) {
if (DEBUG) {
log("CEW: checking " + xmethod.toString());
}
check(xmethod, expectWarning, true);
check(xmethod, noWarning, false);
}
for (XField xfield : xclass.getXFields()) {
if (DEBUG) {
log("CEW: checking " + xfield.toString());
}
check(xfield, expectWarning, true);
check(xfield, noWarning, false);
}
check(xclass, expectWarning, true);
check(xclass, noWarning, false);
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class SillynessPotPourri method getTrimUserValue.
@Nullable
private SPPUserValue getTrimUserValue() {
if (stack.getStackDepth() == 0) {
return null;
}
OpcodeStack.Item item = stack.getStackItem(0);
int reg = item.getRegisterNumber();
if (reg >= 0) {
return new SPPUserValue(SPPMethod.TRIM, String.valueOf(reg));
}
XField field = item.getXField();
if (field != null) {
return new SPPUserValue(SPPMethod.TRIM, field.getName());
}
XMethod method = item.getReturnValueOf();
if (method != null) {
return new SPPUserValue(SPPMethod.TRIM, method.getName());
}
return new SPPUserValue(SPPMethod.TRIM);
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class StackedTryBlocks method sawOpcode.
/**
* overrides the visitor to document what catch blocks do with regard to rethrowing the exceptions, and if the message is a static message
*
* @param seen
* the currently parsed opcode
*/
@Override
public void sawOpcode(int seen) {
String message = null;
try {
stack.precomputation(this);
if ((seen == Const.TABLESWITCH) || (seen == Const.LOOKUPSWITCH)) {
int pc = getPC();
for (int offset : getSwitchOffsets()) {
transitionPoints.set(pc + offset);
}
transitionPoints.set(pc + getDefaultSwitchOffset());
} else if (isBranch(seen) && (getBranchOffset() < 0)) {
// throw out try blocks in loops, this could cause false
// negatives
// with two try/catches in one loop, but more unlikely
Iterator<TryBlock> it = blocks.iterator();
int target = getBranchTarget();
while (it.hasNext()) {
TryBlock block = it.next();
if (block.getStartPC() >= target) {
it.remove();
}
}
}
int pc = getPC();
TryBlock block = findBlockWithStart(pc);
if (block != null) {
inBlocks.add(block);
block.setState(TryBlock.State.IN_TRY);
}
if (inBlocks.isEmpty()) {
return;
}
TryBlock innerBlock = inBlocks.get(inBlocks.size() - 1);
int nextPC = getNextPC();
if (innerBlock.atHandlerPC(nextPC)) {
if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
innerBlock.setEndHandlerPC(getBranchTarget());
} else {
inBlocks.remove(innerBlock);
blocks.remove(innerBlock);
}
} else if (innerBlock.atHandlerPC(pc)) {
innerBlock.setState(TryBlock.State.IN_CATCH);
} else if (innerBlock.atEndHandlerPC(pc)) {
inBlocks.remove(inBlocks.size() - 1);
innerBlock.setState(TryBlock.State.AFTER);
}
if (transitionPoints.get(nextPC)) {
if (innerBlock.inCatch() && (innerBlock.getEndHandlerPC() > nextPC)) {
innerBlock.setEndHandlerPC(nextPC);
}
}
if (innerBlock.inCatch()) {
if (((seen >= Const.IFEQ) && ((seen <= Const.RET))) || (seen == Const.GOTO_W) || OpcodeUtils.isReturn(seen)) {
blocks.remove(innerBlock);
inBlocks.remove(inBlocks.size() - 1);
} else if (seen == Const.ATHROW) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
XMethod xm = item.getReturnValueOf();
if (xm != null) {
innerBlock.setThrowSignature(xm.getSignature());
}
innerBlock.setExceptionSignature(item.getSignature());
innerBlock.setMessage((String) item.getUserValue());
} else {
inBlocks.remove(inBlocks.size() - 1);
innerBlock.setState(TryBlock.State.AFTER);
}
} else if ((seen == Const.INVOKESPECIAL) && Values.CONSTRUCTOR.equals(getNameConstantOperand())) {
String cls = getClassConstantOperand();
JavaClass exCls = Repository.lookupClass(cls);
if (exCls.instanceOf(THROWABLE_CLASS)) {
String signature = getSigConstantOperand();
List<String> types = SignatureUtils.getParameterSignatures(signature);
if (!types.isEmpty()) {
if (Values.SIG_JAVA_LANG_STRING.equals(types.get(0)) && (stack.getStackDepth() >= types.size())) {
OpcodeStack.Item item = stack.getStackItem(types.size() - 1);
message = (String) item.getConstant();
if (message == null) {
message = "____UNKNOWN____" + System.identityHashCode(item);
}
}
} else {
message = "";
}
}
}
}
} catch (ClassNotFoundException cnfe) {
bugReporter.reportMissingClass(cnfe);
} finally {
stack.sawOpcode(this, seen);
if ((message != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(message);
}
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class StackedTryBlocks method visitCode.
/**
* overrides the visitor to look for 'idea' try catch blocks to find issues specifically, method needs two or more try catch blocks that only catch one
* exception type.
*
* @param obj
* the currently parsed code object
*/
@Override
public void visitCode(Code obj) {
try {
XMethod xMethod = getXMethod();
if (xMethod != null) {
String[] tes = xMethod.getThrownExceptions();
Set<String> thrownExceptions = new HashSet<>(Arrays.<String>asList((tes == null) ? new String[0] : tes));
blocks = new ArrayList<>();
inBlocks = new ArrayList<>();
transitionPoints = new BitSet();
CodeException[] ces = obj.getExceptionTable();
for (CodeException ce : ces) {
TryBlock tb = new TryBlock(ce);
int existingBlock = blocks.indexOf(tb);
if (existingBlock >= 0) {
tb = blocks.get(existingBlock);
tb.addCatchType(ce);
} else {
blocks.add(tb);
}
}
Iterator<TryBlock> it = blocks.iterator();
while (it.hasNext()) {
TryBlock block = it.next();
if (block.hasMultipleHandlers() || block.isFinally() || block.catchIsThrown(getConstantPool(), thrownExceptions)) {
it.remove();
}
}
if (blocks.size() > 1) {
stack.resetForMethodEntry(this);
super.visitCode(obj);
if (blocks.size() > 1) {
TryBlock firstBlock = blocks.get(0);
for (int i = 1; i < blocks.size(); i++) {
TryBlock secondBlock = blocks.get(i);
if (!blocksSplitAcrossTransitions(firstBlock, secondBlock) && (firstBlock.getCatchType() == secondBlock.getCatchType()) && firstBlock.getThrowSignature().equals(secondBlock.getThrowSignature()) && firstBlock.getMessage().equals(secondBlock.getMessage()) && firstBlock.getExceptionSignature().equals(secondBlock.getExceptionSignature())) {
bugReporter.reportBug(new BugInstance(this, BugType.STB_STACKED_TRY_BLOCKS.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLineRange(this, firstBlock.getStartPC(), firstBlock.getEndHandlerPC()).addSourceLineRange(this, secondBlock.getStartPC(), secondBlock.getEndHandlerPC()));
}
firstBlock = secondBlock;
}
}
}
}
} finally {
blocks = null;
inBlocks = null;
transitionPoints = null;
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class PossiblyRedundantMethodCalls method sawOpcode.
/**
* 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
public void sawOpcode(int seen) {
String userValue = null;
try {
stack.precomputation(this);
int pc = getPC();
if (branchTargets.get(pc)) {
localMethodCalls.clear();
fieldMethodCalls.clear();
branchTargets.clear(pc);
}
if (((seen >= Const.IFEQ) && (seen <= Const.GOTO)) || ((seen >= Const.IFNULL) && (seen <= Const.GOTO_W))) {
branchTargets.set(getBranchTarget());
} else if ((seen == Const.TABLESWITCH) || (seen == Const.LOOKUPSWITCH)) {
int[] offsets = getSwitchOffsets();
for (int offset : offsets) {
branchTargets.set(offset + pc);
}
branchTargets.set(getDefaultSwitchOffset() + pc);
} else if (OpcodeUtils.isAStore(seen)) {
localMethodCalls.remove(Integer.valueOf(RegisterUtils.getAStoreReg(this, seen)));
} else if (seen == Const.PUTFIELD) {
String fieldSource = "";
if (stack.getStackDepth() > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
fieldSource = (String) item.getUserValue();
if (fieldSource == null) {
fieldSource = "";
}
}
fieldMethodCalls.remove(new FieldInfo(fieldSource, getNameConstantOperand()));
} else if (seen == Const.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 == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKESTATIC)) {
String className = getClassConstantOperand();
String methodName = getNameConstantOperand();
String signature = getSigConstantOperand();
int parmCount = SignatureUtils.getNumParameters(signature);
int reg = -1;
XField field = null;
MethodCall mc = null;
String fieldSource = null;
if (seen == Const.INVOKESTATIC) {
XMethod xm = XFactory.createXMethod(getDottedClassConstantOperand(), methodName, signature, true);
String genericSignature = xm.getSourceSignature();
if ((genericSignature != null) && genericSignature.endsWith(">;")) {
return;
}
} else if (stack.getStackDepth() > parmCount) {
OpcodeStack.Item obj = stack.getStackItem(parmCount);
reg = obj.getRegisterNumber();
field = obj.getXField();
if (reg >= 0) {
mc = localMethodCalls.get(Integer.valueOf(reg));
MethodInfo mi = Statistics.getStatistics().getMethodStatistics(className, getNameConstantOperand(), signature);
if ((mi != null) && mi.getModifiesState()) {
clearFieldMethods(String.valueOf(reg));
return;
}
} else if (field != null) {
fieldSource = (String) obj.getUserValue();
if (fieldSource == null) {
fieldSource = "";
}
mc = fieldMethodCalls.get(new FieldInfo(fieldSource, field.getName()));
MethodInfo mi = Statistics.getStatistics().getMethodStatistics(className, getNameConstantOperand(), signature);
if ((mi != null) && mi.getModifiesState()) {
clearFieldMethods(fieldSource);
return;
}
}
}
int neededStackSize = parmCount + ((seen == Const.INVOKESTATIC) ? 0 : 1);
if (stack.getStackDepth() >= neededStackSize) {
Object[] parmConstants = new Object[parmCount];
for (int i = 0; i < parmCount; i++) {
OpcodeStack.Item parm = stack.getStackItem(i);
parmConstants[i] = parm.getConstant();
if (parm.getSignature().startsWith(Values.SIG_ARRAY_PREFIX)) {
if (!Values.ZERO.equals(parm.getConstant())) {
return;
}
XField f = parm.getXField();
if (f != null) {
// Two different fields holding a 0 length array should be considered different
parmConstants[i] = f.getName() + ':' + parmConstants[i];
}
}
if (parmConstants[i] == null) {
return;
}
}
if (seen == Const.INVOKESTATIC) {
mc = staticMethodCalls.get(className);
} else if ((reg < 0) && (field == null)) {
return;
}
if (mc != null) {
if (!signature.endsWith(Values.SIG_VOID) && methodName.equals(mc.getName()) && signature.equals(mc.getSignature()) && !isRiskyName(className, methodName) && !commonMethods.contains(new FQMethod(getClassConstantOperand(), methodName, signature))) {
Object[] parms = mc.getParms();
if (Arrays.equals(parms, parmConstants)) {
int ln = getLineNumber(pc);
if ((ln != mc.getLineNumber()) || (Math.abs(pc - mc.getPC()) < 10)) {
Statistics statistics = Statistics.getStatistics();
MethodInfo mi = statistics.getMethodStatistics(getClassConstantOperand(), methodName, signature);
bugReporter.reportBug(new BugInstance(this, BugType.PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS.name(), getBugPriority(methodName, mi)).addClass(this).addMethod(this).addSourceLine(this).addString(methodName + signature));
}
}
}
if (seen == Const.INVOKESTATIC) {
staticMethodCalls.remove(className);
} else {
if (reg >= 0) {
localMethodCalls.remove(Integer.valueOf(reg));
} else if (fieldSource != null) {
fieldMethodCalls.remove(new FieldInfo(fieldSource, field.getName()));
}
}
} else {
int ln = getLineNumber(pc);
if (seen == Const.INVOKESTATIC) {
staticMethodCalls.put(className, new MethodCall(methodName, signature, parmConstants, pc, ln));
} else {
if (reg >= 0) {
localMethodCalls.put(Integer.valueOf(reg), new MethodCall(methodName, signature, parmConstants, pc, ln));
} else if (field != null) {
OpcodeStack.Item obj = stack.getStackItem(parmCount);
fieldSource = (String) obj.getUserValue();
if (fieldSource == null) {
fieldSource = "";
}
fieldMethodCalls.put(new FieldInfo(fieldSource, field.getName()), new MethodCall(methodName, signature, parmConstants, pc, ln));
}
}
}
}
} else if (OpcodeUtils.isReturn(seen)) {
localMethodCalls.clear();
fieldMethodCalls.clear();
branchTargets.clear(pc);
}
} finally {
stack.sawOpcode(this, seen);
if ((userValue != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(userValue);
}
}
}
Aggregations