Search in sources :

Example 1 with InstructionIterator

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);
                }
            }
        }
    }
}
Also used : BasicBlock(edu.umd.cs.findbugs.ba.BasicBlock) ToString(com.mebigfatguy.fbcontrib.utils.ToString) Instruction(org.apache.bcel.generic.Instruction) FieldInstruction(org.apache.bcel.generic.FieldInstruction) INVOKESPECIAL(org.apache.bcel.generic.INVOKESPECIAL) ArrayDeque(java.util.ArrayDeque) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ReferenceType(org.apache.bcel.generic.ReferenceType) InstructionIterator(edu.umd.cs.findbugs.ba.BasicBlock.InstructionIterator) GETFIELD(org.apache.bcel.generic.GETFIELD) ObjectType(org.apache.bcel.generic.ObjectType) FieldInstruction(org.apache.bcel.generic.FieldInstruction) Edge(edu.umd.cs.findbugs.ba.Edge) INVOKEVIRTUAL(org.apache.bcel.generic.INVOKEVIRTUAL)

Aggregations

ToString (com.mebigfatguy.fbcontrib.utils.ToString)1 BasicBlock (edu.umd.cs.findbugs.ba.BasicBlock)1 InstructionIterator (edu.umd.cs.findbugs.ba.BasicBlock.InstructionIterator)1 Edge (edu.umd.cs.findbugs.ba.Edge)1 ArrayDeque (java.util.ArrayDeque)1 FieldInstruction (org.apache.bcel.generic.FieldInstruction)1 GETFIELD (org.apache.bcel.generic.GETFIELD)1 INVOKESPECIAL (org.apache.bcel.generic.INVOKESPECIAL)1 INVOKEVIRTUAL (org.apache.bcel.generic.INVOKEVIRTUAL)1 Instruction (org.apache.bcel.generic.Instruction)1 InstructionHandle (org.apache.bcel.generic.InstructionHandle)1 ObjectType (org.apache.bcel.generic.ObjectType)1 ReferenceType (org.apache.bcel.generic.ReferenceType)1