use of edu.umd.cs.findbugs.ba.BasicBlock.InstructionIterator in project fb-contrib by mebigfatguy.
the class FieldCouldBeLocal method checkBlock.
/**
* looks in this basic block for the first access to the fields in uncheckedFields. Once found the item is removed from uncheckedFields, and removed from
* localizableFields if the access is a GETFIELD. If any unchecked fields remain, this method is recursively called on all outgoing edges of this basic
* block.
*
* @param startBB
* this basic block
* @param uncheckedFields
* the list of fields to look for
*/
private void checkBlock(BasicBlock startBB, Set<String> uncheckedFields) {
Deque<BlockState> toBeProcessed = new ArrayDeque<>();
toBeProcessed.addLast(new BlockState(startBB, uncheckedFields));
visitedBlocks.set(startBB.getLabel());
while (!toBeProcessed.isEmpty()) {
if (localizableFields.isEmpty()) {
return;
}
BlockState bState = toBeProcessed.removeFirst();
BasicBlock bb = bState.getBasicBlock();
InstructionIterator ii = bb.instructionIterator();
while ((bState.getUncheckedFieldSize() > 0) && ii.hasNext()) {
InstructionHandle ih = ii.next();
Instruction ins = ih.getInstruction();
if (ins instanceof FieldInstruction) {
FieldInstruction fi = (FieldInstruction) ins;
if (fi.getReferenceType(cpg).getSignature().equals(clsSig)) {
String fieldName = fi.getFieldName(cpg);
FieldInfo finfo = localizableFields.get(fieldName);
if ((finfo != null) && localizableFields.get(fieldName).hasAnnotation()) {
localizableFields.remove(fieldName);
} else {
boolean justRemoved = bState.removeUncheckedField(fieldName);
if (ins instanceof GETFIELD) {
if (justRemoved) {
localizableFields.remove(fieldName);
if (localizableFields.isEmpty()) {
return;
}
}
} else if (finfo != null) {
finfo.setSrcLineAnnotation(SourceLineAnnotation.fromVisitedInstruction(clsContext, this, ih.getPosition()));
}
}
}
} else if (ins instanceof INVOKESPECIAL) {
INVOKESPECIAL is = (INVOKESPECIAL) ins;
ReferenceType rt = is.getReferenceType(cpg);
if (Values.CONSTRUCTOR.equals(is.getMethodName(cpg))) {
if ((rt instanceof ObjectType) && ((ObjectType) rt).getClassName().startsWith(clsContext.getJavaClass().getClassName() + Values.INNER_CLASS_SEPARATOR)) {
localizableFields.clear();
}
} else {
localizableFields.clear();
}
} else if (ins instanceof INVOKEVIRTUAL) {
INVOKEVIRTUAL is = (INVOKEVIRTUAL) ins;
ReferenceType rt = is.getReferenceType(cpg);
if ((rt instanceof ObjectType) && ((ObjectType) rt).getClassName().equals(clsName)) {
String methodDesc = is.getName(cpg) + is.getSignature(cpg);
Set<String> fields = methodFieldModifiers.get(methodDesc);
if (fields != null) {
localizableFields.keySet().removeAll(fields);
}
}
}
}
if (bState.getUncheckedFieldSize() > 0) {
Iterator<Edge> oei = cfg.outgoingEdgeIterator(bb);
while (oei.hasNext()) {
Edge e = oei.next();
BasicBlock cb = e.getTarget();
int label = cb.getLabel();
if (!visitedBlocks.get(label)) {
toBeProcessed.addLast(new BlockState(cb, bState));
visitedBlocks.set(label);
}
}
}
}
}
Aggregations