use of edu.umd.cs.findbugs.ba.XMethod in project wcomponents by BorderTech.
the class CheckComponentModelDefinition method visitClassContext.
/**
* {@inheritDoc}
*/
@Override
public void visitClassContext(final ClassContext classContext) {
if (!util.isComponentModel(classContext.getJavaClass())) {
return;
}
// TODO: This is nasty, but classContext.getXClass().isStatic() returns FALSE for static inner classes.
boolean isStatic = false;
if (classContext.getXClass().getImmediateEnclosingClass() != null) {
for (Attribute attribute : classContext.getJavaClass().getAttributes()) {
if (attribute instanceof InnerClasses) {
InnerClass inner = ((InnerClasses) attribute).getInnerClasses()[0];
isStatic = (inner.getInnerAccessFlags() & IClassConstants.ACC_STATIC) != 0;
break;
}
}
}
if (!classContext.getXClass().isPublic() || classContext.getClassDescriptor().isAnonymousClass()) {
reportBug(classContext);
} else if (classContext.getXClass().getImmediateEnclosingClass() != null && !isStatic) {
reportBug(classContext);
} else {
boolean foundPublicNoArgsConstructor = false;
boolean foundConstructor = false;
for (XMethod method : classContext.getXClass().getXMethods()) {
if ("<init>".equals(method.getMethodDescriptor().getName())) {
foundConstructor = true;
if (method.isPublic() && method.getNumParams() == 0) {
foundPublicNoArgsConstructor = true;
break;
}
}
}
if (foundConstructor && !foundPublicNoArgsConstructor) {
reportBug(classContext);
}
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class PresizeCollections method sawOpcode.
/**
* implements the visitor to look for creation of collections that are then populated with a known number of elements usually based on another collection,
* but the new collection is not presized.
*
* @param seen
* the opcode of the currently parsed instruction
*/
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "CLI_CONSTANT_LIST_INDEX", justification = "Constrained by FindBugs API")
@Override
public void sawOpcode(int seen) {
PSCUserValue userValue = null;
boolean sawAlloc = false;
try {
stack.precomputation(this);
switch(seen) {
case Const.INVOKESPECIAL:
String clsName = getClassConstantOperand();
if (PRESIZEABLE_COLLECTIONS.contains(clsName)) {
String methodName = getNameConstantOperand();
if (Values.CONSTRUCTOR.equals(methodName)) {
String signature = getSigConstantOperand();
if (SignatureBuilder.SIG_VOID_TO_VOID.equals(signature)) {
userValue = new PSCUserValue(Integer.valueOf(nextAllocNumber++));
sawAlloc = true;
} else if (guavaOnPath && (stack.getStackDepth() > 0)) {
FQMethod fqMethod = new FQMethod(clsName, methodName, signature);
if (HASHMAP_SIZED_CTOR.equals(fqMethod) || HASHSET_SIZED_CTOR.equals(fqMethod)) {
OpcodeStack.Item itm = stack.getStackItem(0);
XMethod xm = itm.getReturnValueOf();
if ((xm != null) && "size".equals(xm.getMethodDescriptor().getName())) {
bugReporter.reportBug(new BugInstance(this, BugType.PSC_SUBOPTIMAL_COLLECTION_SIZING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
}
}
}
break;
case Const.INVOKEINTERFACE:
String methodName = getNameConstantOperand();
if (ITERATOR_METHOD.equals(new QMethod(methodName, getSigConstantOperand()))) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item itm = stack.getStackItem(0);
userValue = isSizedSource(itm);
}
} else if (ITERATOR_HASNEXT.equals(new FQMethod(getClassConstantOperand(), methodName, getSigConstantOperand()))) {
if (stack.getStackDepth() > 0) {
OpcodeStack.Item itm = stack.getStackItem(0);
userValue = (PSCUserValue) itm.getUserValue();
}
} else if ("add".equals(methodName) || "addAll".equals(methodName)) {
String signature = getSigConstantOperand();
int numArguments = SignatureUtils.getNumParameters(signature);
if ((numArguments == 1) && (stack.getStackDepth() > 1)) {
OpcodeStack.Item item = stack.getStackItem(1);
PSCUserValue uv = (PSCUserValue) item.getUserValue();
if (uv != null) {
Integer allocNum = uv.getAllocationNumber();
if (allocNum != null) {
if ("addAll".equals(methodName)) {
allocToAddPCs.remove(allocNum);
} else {
List<Integer> lines = allocToAddPCs.get(allocNum);
if (lines == null) {
lines = new ArrayList<>();
allocToAddPCs.put(allocNum, lines);
}
lines.add(Integer.valueOf(getPC()));
}
}
}
}
} else if ("put".equals(methodName) || "putAll".equals(methodName)) {
String signature = getSigConstantOperand();
int numArguments = SignatureUtils.getNumParameters(signature);
if ((numArguments == 2) && (stack.getStackDepth() > 2)) {
OpcodeStack.Item item = stack.getStackItem(2);
PSCUserValue uv = (PSCUserValue) item.getUserValue();
if (uv != null) {
Integer allocNum = uv.getAllocationNumber();
if (allocNum != null) {
if ("putAll".equals(methodName)) {
allocToAddPCs.remove(allocNum);
} else {
List<Integer> lines = allocToAddPCs.get(allocNum);
if (lines == null) {
lines = new ArrayList<>();
allocToAddPCs.put(allocNum, lines);
}
lines.add(Integer.valueOf(getPC()));
}
}
}
}
}
break;
case Const.INVOKESTATIC:
FQMethod fqm = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand());
if (STATIC_COLLECTION_FACTORIES.contains(fqm)) {
userValue = new PSCUserValue(Integer.valueOf(nextAllocNumber++));
sawAlloc = true;
}
break;
case Const.LOOKUPSWITCH:
case Const.TABLESWITCH:
int[] offsets = getSwitchOffsets();
if (offsets.length >= 2) {
int pc = getPC();
int thisOffset = pc + offsets[0];
for (int o = 0; o < (offsets.length - 1); o++) {
int nextOffset = offsets[o + 1] + pc;
CodeRange db = new CodeRange(thisOffset, nextOffset, false);
optionalRanges.add(db);
thisOffset = nextOffset;
}
}
break;
case Const.IFEQ:
case Const.IFNE:
case Const.IFLT:
case Const.IFLE:
case Const.IF_ICMPEQ:
case Const.IF_ICMPNE:
case Const.IF_ICMPLT:
case Const.IF_ICMPGE:
case Const.IF_ICMPGT:
case Const.IF_ICMPLE:
case Const.IF_ACMPEQ:
case Const.IF_ACMPNE:
case Const.GOTO:
case Const.GOTO_W:
if (getBranchOffset() < 0) {
if (branchBasedOnUnsizedObject(seen)) {
break;
}
int target = getBranchTarget();
Iterator<Map.Entry<Integer, List<Integer>>> it = allocToAddPCs.entrySet().iterator();
while (it.hasNext()) {
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 (int pc : pcs) {
if (pc > target) {
if (hasSinglePossiblySizedBranch(allocLoc.intValue(), pc)) {
bugReporter.reportBug(new BugInstance(this, BugType.PSC_PRESIZE_COLLECTIONS.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this, pc));
it.remove();
}
break;
}
}
}
}
} else {
CodeRange db = new CodeRange(getPC(), getBranchTarget(), !branchBasedOnUnsizedObject(seen));
optionalRanges.add(db);
}
break;
case Const.IFNULL:
case Const.IFNONNULL:
case Const.IFGE:
case Const.IFGT:
// null check and >, >= branches are hard to presize
if (getBranchOffset() > 0) {
CodeRange db = new CodeRange(getPC(), getBranchTarget(), false);
optionalRanges.add(db);
}
break;
case Const.ASTORE:
case Const.ASTORE_0:
case Const.ASTORE_1:
case Const.ASTORE_2:
case Const.ASTORE_3:
{
if (stack.getStackDepth() > 0) {
PSCUserValue uv = (PSCUserValue) stack.getStackItem(0).getUserValue();
if (uv != null) {
storeToUserValue.put(getRegisterOperand(), uv);
}
}
}
break;
case Const.ALOAD:
case Const.ALOAD_0:
case Const.ALOAD_1:
case Const.ALOAD_2:
case Const.ALOAD_3:
{
userValue = storeToUserValue.get(getRegisterOperand());
}
break;
case Const.PUTFIELD:
{
if (stack.getStackDepth() > 0) {
PSCUserValue uv = (PSCUserValue) stack.getStackItem(0).getUserValue();
if (uv != null) {
storeToUserValue.put(getNameConstantOperand(), uv);
}
}
}
break;
case Const.GETFIELD:
{
userValue = storeToUserValue.get(getNameConstantOperand());
}
}
} finally {
stack.sawOpcode(this, seen);
if ((userValue != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(userValue);
if (sawAlloc) {
allocLocation.put(userValue.getAllocationNumber(), Integer.valueOf(getPC()));
}
}
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class PresizeCollections method branchBasedOnUnsizedObject.
/**
* returns if the conditional is based on a method call from an object that has no sizing to determine what presize should be. it's possible the correct
* implementation should just return true, if <code>if ((seen != IFNE) || (stack.getStackDepth() == 0))</code>
*
* @param seen
* the current visited opcode
* @return whether this conditional is based on a unsized object
*/
private boolean branchBasedOnUnsizedObject(int seen) {
if ((seen == Const.IF_ACMPEQ) || (seen == Const.IF_ACMPNE)) {
return true;
}
if ((seen != Const.IFNE) || (stack.getStackDepth() == 0)) {
return false;
}
OpcodeStack.Item itm = stack.getStackItem(0);
XMethod xm = itm.getReturnValueOf();
if (xm == null) {
return false;
}
FQMethod fqm = new FQMethod(xm.getClassName().replace('.', '/'), xm.getName(), xm.getSignature());
if (ITERATOR_HASNEXT.equals(fqm)) {
PSCUserValue uv = (PSCUserValue) itm.getUserValue();
if (uv == null) {
return true;
}
return !uv.hasSizedSource();
}
return UNSIZED_SOURCES.contains(fqm);
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class UnnecessaryApiConversion method sawOpcode.
@Override
public void sawOpcode(int seen) {
try {
switch(seen) {
case INVOKEVIRTUAL:
FQMethod conversionMethod = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand());
LegacyInfo legacyInfo = conversions.get(conversionMethod);
if ((legacyInfo != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item itm = stack.getStackItem(0);
XMethod xm = itm.getReturnValueOf();
if ((xm != null) && (xm.getName().equals(legacyInfo.methodName) && (xm.getClassName().equals(conversionMethod.getClassName().replace('/', '.'))))) {
bugReporter.reportBug(new BugInstance(this, legacyInfo.bugType.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
break;
default:
break;
}
} finally {
stack.sawOpcode(this, seen);
}
}
use of edu.umd.cs.findbugs.ba.XMethod in project fb-contrib by mebigfatguy.
the class StringifiedTypes method sawOpcode.
@Override
public void sawOpcode(int seen) {
String userValue = null;
int[] checkParms = null;
try {
stack.precomputation(this);
int stackDepth = stack.getStackDepth();
switch(seen) {
case Const.INVOKEVIRTUAL:
{
String clsName = getClassConstantOperand();
String methodName = getNameConstantOperand();
String sig = getSigConstantOperand();
boolean isStringBuilder = SignatureUtils.isPlainStringConvertableClass(clsName);
if (Values.TOSTRING.equals(methodName) && SignatureBuilder.SIG_VOID_TO_STRING.equals(sig)) {
if (isStringBuilder) {
if (stackDepth > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
userValue = (String) item.getUserValue();
}
} else {
userValue = Values.TOSTRING;
}
} else if (isStringBuilder) {
if ("append".equals(methodName)) {
if (stackDepth > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
userValue = (String) item.getUserValue();
if ((userValue == null) && !Values.SIG_JAVA_LANG_STRING.equals(item.getSignature())) {
userValue = Values.TOSTRING;
if (stackDepth > 1) {
item = stack.getStackItem(1);
int reg = item.getRegisterNumber();
if (reg >= 0) {
toStringStringBuilders.set(reg);
}
}
}
}
} else if ((stackDepth > 1) && "setLength".equals(methodName)) {
OpcodeStack.Item item = stack.getStackItem(1);
item.setUserValue(null);
int reg = item.getRegisterNumber();
if (reg >= 0) {
toStringStringBuilders.clear(reg);
}
}
} else if (Values.SLASHED_JAVA_LANG_STRING.equals(clsName)) {
Integer priority = STRING_PARSE_METHODS.get(methodName);
if (priority != null) {
int numParameters = SignatureUtils.getNumParameters(sig);
if (stackDepth > numParameters) {
OpcodeStack.Item item = stack.getStackItem(numParameters);
if ((item.getXField() != null) || FROM_FIELD.equals(item.getUserValue())) {
bugReporter.reportBug(new BugInstance(this, BugType.STT_STRING_PARSING_A_FIELD.name(), priority.intValue()).addClass(this).addMethod(this).addSourceLine(this));
}
}
}
}
}
break;
case Const.INVOKEINTERFACE:
{
String clsName = getClassConstantOperand();
String methodName = getNameConstantOperand();
String sig = getSigConstantOperand();
int numParameters = SignatureUtils.getNumParameters(sig);
if (stackDepth > numParameters) {
FQMethod cm = new FQMethod(clsName, methodName, sig);
checkParms = COLLECTION_PARMS.get(cm);
if (checkParms != null) {
OpcodeStack.Item item = stack.getStackItem(numParameters);
if (item.getXField() == null) {
if (MAP_PUT.equals(cm)) {
OpcodeStack.Item itm = stack.getStackItem(1);
XMethod xm = itm.getReturnValueOf();
if (xm != null) {
if (Values.DOTTED_JAVA_LANG_STRINGBUILDER.equals(xm.getClassName())) {
bugReporter.reportBug(new BugInstance(this, BugType.STT_TOSTRING_MAP_KEYING.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
}
} else {
for (int parm : checkParms) {
if ((parm >= 0) && Values.TOSTRING.equals(stack.getStackItem(parm).getUserValue())) {
bugReporter.reportBug(new BugInstance(this, BugType.STT_TOSTRING_STORED_IN_FIELD.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
break;
}
}
}
}
}
}
break;
case Const.PUTFIELD:
if (stackDepth > 0) {
OpcodeStack.Item item = stack.getStackItem(0);
if (Values.TOSTRING.equals(item.getUserValue())) {
bugReporter.reportBug(new BugInstance(this, BugType.STT_TOSTRING_STORED_IN_FIELD.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
}
}
break;
case Const.ALOAD:
case Const.ALOAD_0:
case Const.ALOAD_1:
case Const.ALOAD_2:
case Const.ALOAD_3:
{
int reg = RegisterUtils.getALoadReg(this, seen);
if (toStringStringBuilders.get(reg)) {
userValue = Values.TOSTRING;
}
}
break;
case Const.ASTORE:
case Const.ASTORE_0:
case Const.ASTORE_1:
case Const.ASTORE_2:
case Const.ASTORE_3:
{
int reg = RegisterUtils.getAStoreReg(this, seen);
toStringStringBuilders.clear(reg);
}
break;
default:
break;
}
} finally {
stack.sawOpcode(this, seen);
if ((userValue != null) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(userValue);
}
if ((checkParms != null) && (checkParms[0] == -1) && (stack.getStackDepth() > 0)) {
OpcodeStack.Item item = stack.getStackItem(0);
item.setUserValue(FROM_FIELD);
}
}
}
Aggregations