VisibleForTesting
763682
boolean shouldExecuteOnProject() {
    File baseDir = fileSystem.baseDir();
    File reportUTs = pathResolver.relativeFile(baseDir, configuration.getReportPath());
    File reportITs = pathResolver.relativeFile(baseDir, configuration.getItReportPath());
    boolean foundOneReport = reportUTs.exists() || reportITs.exists();
    boolean shouldExecute = configuration.shouldExecuteOnProject(foundOneReport);
    if (!foundOneReport && shouldExecute) {
      JaCoCoExtensions.logger().info("JaCoCoOverallSensor: JaCoCo reports not found.");
    }
    return shouldExecute;
  }
1152959
@Override
    public void sawOpcode(int seen) {

        try {
            stack.precomputation(this);

            if ((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) {
                FQMethod key = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand());

                Object posObject = characterMethods.get(key);
                if (posObject instanceof Integer) {
                    if (checkSingleParamMethod(((Integer) posObject).intValue()) && !isInlineAppend(key)) {
                        reportBug();
                    }
                } else if ((posObject instanceof IntPair) && checkDoubleParamMethod((IntPair) posObject)) {
                    reportBug();
                }

            } else if (seen == Const.DUP) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    String duppedSig = itm.getSignature();
                    if (Values.SIG_JAVA_UTIL_STRINGBUILDER.equals(duppedSig) || Values.SIG_JAVA_UTIL_STRINGBUFFER.equals(duppedSig)) {
                        itm.setUserValue(UCPMUserValue.INLINE);
                    }
                }
            } else if ((seen == Const.PUTFIELD) || (((seen == Const.PUTSTATIC) || OpcodeUtils.isAStore(seen)) && (stack.getStackDepth() > 0))) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(null);
            }
        } finally {
            UCPMUserValue uv = callHasInline(seen);

            stack.sawOpcode(this, seen);
            if ((uv == UCPMUserValue.INLINE) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(uv);
            }
        }
    }
863100
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            int pc = getPC();
            CodeException ex = catchHandlerPCs.get(Integer.valueOf(pc));
            if (ex != null) {
                int endPC;
                if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                    endPC = this.getBranchTarget();
                } else {
                    endPC = Integer.MAX_VALUE;
                }
                ConstantPool pool = getConstantPool();
                ConstantClass ccls = (ConstantClass) pool.getConstant(ex.getCatchType());
                String catchSig = ccls.getBytes(pool);
                CatchInfo ci = new CatchInfo(ex.getHandlerPC(), endPC, catchSig);
                catchInfos.add(ci);
            }

            updateEndPCsOnCatchRegScope(catchInfos, pc, seen);
            removeFinishedCatchBlocks(catchInfos, pc);

            if (seen == Const.ATHROW) {
                processThrow();
            } else if ((seen == Const.IRETURN) && isBooleanMethod && !hasValidFalseReturn && (stack.getStackDepth() > 0)) {
                processBooleanReturn();
            }

        } finally {
            stack.sawOpcode(this, seen);
        }
    }
288403
@Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String exceptions[]) {
        // skip static initializers
        if (name.equals("<clinit>")) {
            return null;
        }

        MethodInfoImpl methodInfo = new MethodInfoImpl(name, desc, exceptions, access, classInfo);

        if (name.equals("<init>")) {
            constructorInfos.add(methodInfo);
        } else {
            methodInfos.add(methodInfo);
        }

        if (logParms != null) {
            logParms[1] = name;
            logParms[2] = methodInfo.getHashText();
        }

        methodVisitor.setMethodInfo(methodInfo);
        return methodVisitor;
    }
678983
public void accept(final MethodVisitor mv, boolean visible) {
        Label[] start = new Label[this.start.size()];
        Label[] end = new Label[this.end.size()];
        int[] index = new int[this.index.size()];
        for (int i = 0; i < start.length; ++i) {
            start[i] = this.start.get(i).getLabel();
            end[i] = this.end.get(i).getLabel();
            index[i] = this.index.get(i);
        }
        accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
                index, desc, true));
    }
661088
@Override
    public void sawOpcode(int seen) {
        ImmutabilityType seenImmutable = null;
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.INVOKESTATIC: {
                    String className = getClassConstantOperand();
                    String methodName = getNameConstantOperand();

                    if (IMMUTABLE_PRODUCING_METHODS.contains(className + '.' + methodName)) {
                        seenImmutable = ImmutabilityType.IMMUTABLE;
                        break;
                    }
                }
                //$FALL-THROUGH$
                case Const.INVOKEINTERFACE:
                case Const.INVOKESPECIAL:
                case Const.INVOKEVIRTUAL: {
                    String className = getClassConstantOperand();
                    String methodName = getNameConstantOperand();
                    String signature = getSigConstantOperand();

                    MethodInfo mi = Statistics.getStatistics().getMethodStatistics(className, methodName, signature);
                    seenImmutable = mi.getImmutabilityType();
                    if (seenImmutable == ImmutabilityType.UNKNOWN) {
                        seenImmutable = null;
                    }
                }
                break;

                case Const.ARETURN: {
                    processARreturn();
                    break;
                }
                default:
                break;
            }

        } finally {
            stack.sawOpcode(this, seen);
            if ((seenImmutable != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(seenImmutable);
            }
        }
    }
1239414
@Override
    public void sawOpcode(final int seen) {
        try {
            stack.precomputation(this);

            BitSet regs = localScopeEnds.remove(Integer.valueOf(getPC()));
            if (regs != null) {
                int i = regs.nextSetBit(0);
                while (i >= 0) {
                    localCollections.remove(i);
                    localSourceLineAnnotations.remove(i);
                    i = regs.nextSetBit(i + 1);
                }
            }
            if (seen == Const.INVOKEINTERFACE) {
                String className = getClassConstantOperand();
                if (COLLECTION_CLASSES.contains(className)) {
                    String methodName = getNameConstantOperand();
                    String methodSig = getSigConstantOperand();
                    if ("add".equals(methodName) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(methodSig)) {
                        if (stack.getStackDepth() > 1) {
                            OpcodeStack.Item colItm = stack.getStackItem(1);
                            OpcodeStack.Item addItm = stack.getStackItem(0);
                            checkAdd(colItm, addItm);
                        }
                    } else if (("put".equals(methodName) && SignatureBuilder.SIG_TWO_OBJECTS_TO_OBJECT.equals(methodSig)) && (stack.getStackDepth() > 2)) {
                        // For maps, just check the keys
                        OpcodeStack.Item colItm = stack.getStackItem(2);
                        OpcodeStack.Item addItm = stack.getStackItem(1);
                        checkAdd(colItm, addItm);
                    }
                }
            } else if (seen == Const.AASTORE) {
                if (stack.getStackDepth() > 2) {
                    OpcodeStack.Item arrayItm = stack.getStackItem(2);
                    OpcodeStack.Item addItm = stack.getStackItem(0);
                    checkAdd(arrayItm, addItm);
                }
            } else if (OpcodeUtils.isAStore(seen)) {
                Integer reg = Integer.valueOf(RegisterUtils.getAStoreReg(this, seen));
                localCollections.remove(reg);
                localSourceLineAnnotations.remove(reg);
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
997430
@Override
    public void sawOpcode(int seen) {
        stack.precomputation(this);

        switch (seen) {
            case Const.INVOKESTATIC: {
                String className = getClassConstantOperand();
                for (Backports backport : BACKPORTS) {
                    if (className.startsWith(backport.getPathPrefix())) {
                        if (clsVersion >= backport.getMinimumJDK()) {
                            reportBug(backport.getLibrary());
                            break;
                        }
                    }
                }
            }
            break;

            case Const.INVOKESPECIAL: {
                String className = getClassConstantOperand();
                String methodName = getNameConstantOperand();
                for (Backports backport : BACKPORTS) {
                    if (Values.CONSTRUCTOR.equals(methodName) && className.startsWith(backport.getPathPrefix()) && (clsVersion >= backport.getMinimumJDK())) {
                        reportBug(backport.getLibrary());
                        break;
                    }
                }
            }
            break;

            default:
            break;
        }
    }
1001432
@Override
    public void sawOpcode(int seen) {
        int reg = -1;
        Object uValue = null;
        boolean sawAlias = false;
        boolean sawLoad = false;
        boolean sawNewArray = false;

        try {
            stack.precomputation(this);

            if (seen == Const.INVOKEINTERFACE) {
                String methodName = getNameConstantOperand();
                String signature = getSigConstantOperand();
                if ("size".equals(methodName) && SignatureBuilder.SIG_VOID_TO_INT.equals(signature)) {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        reg = isLocalCollection(itm);
                        if (reg >= 0) {
                            sawAlias = true;
                        }
                    }
                } else if ("get".equals(methodName) && SignatureBuilder.SIG_INT_TO_OBJECT.equals(signature)) {
                    if (stack.getStackDepth() > 1) {
                        OpcodeStack.Item itm = stack.getStackItem(1);
                        reg = isLocalCollection(itm);
                        if (reg >= 0) {
                            sawAlias = true;
                        }
                    }
                } else if (("keySet".equals(methodName) || "values".equals(methodName) || "iterator".equals(methodName) || "next".equals(methodName))
                        && (stack.getStackDepth() > 0)) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    reg = isLocalCollection(itm);
                    if (reg >= 0) {
                        sawAlias = true;
                    }
                }
            } else if (OpcodeUtils.isIStore(seen) || OpcodeUtils.isAStore(seen)) {
                if (stack.getStackDepth() > 0) {
                    uValue = stack.getStackItem(0).getUserValue();
                    userValues.put(Integer.valueOf(RegisterUtils.getStoreReg(this, seen)), uValue);
                }
            } else if (OpcodeUtils.isILoad(seen) || OpcodeUtils.isALoad(seen)) {
                sawLoad = true;
            } else if (seen == Const.ANEWARRAY) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    uValue = itm.getUserValue();
                    sawNewArray = true;
                }
            } else if (seen == Const.IF_ICMPGE) {
                if (stack.getStackDepth() > 1) {
                    OpcodeStack.Item itm1 = stack.getStackItem(1);
                    OpcodeStack.Item itm2 = stack.getStackItem(0);
                    reg = itm1.getRegisterNumber();
                    if ((reg >= 0) && (itm1.couldBeZero())) {
                        uValue = itm2.getUserValue();
                        if (uValue != null) {
                            userValues.put(Integer.valueOf(reg), uValue);
                        }
                    }
                }
            } else if ((seen >= Const.IASTORE) && (seen <= Const.SASTORE)) {
                if (stack.getStackDepth() > 2) {
                    OpcodeStack.Item arItem = stack.getStackItem(2);
                    OpcodeStack.Item idxItem = stack.getStackItem(1);
                    OpcodeStack.Item valueItem = stack.getStackItem(0);
                    reg = isLocalCollection(arItem);
                    if ((reg >= 0) && (idxItem.getUserValue() != null) && (valueItem.getUserValue() != null)) {
                        bugReporter.reportBug(
                                new BugInstance(this, BugType.UTA_USE_TO_ARRAY.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                    }
                }
            } else if ((seen == Const.CHECKCAST) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                uValue = itm.getUserValue();
                if (uValue instanceof Integer) {
                    reg = ((Integer) uValue).intValue();
                    sawAlias = true;
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (sawAlias) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    itm.setUserValue(Integer.valueOf(reg));
                }
            } else if (sawLoad) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    reg = itm.getRegisterNumber();
                    if (reg >= 0) {
                        uValue = userValues.get(Integer.valueOf(reg));
                        itm.setUserValue(uValue);
                    }
                }
            } else if (sawNewArray && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(uValue);
            }
        }
    }
149108
@Override
    public void sawOpcode(int seen) {
        Comparable<?> regOrField = null;
        Comparable<?> uValue;
        boolean sawAlias = false;
        boolean sawLoad = false;

        try {
            stack.precomputation(this);

            int pc = getPC();
            Iterator<LoopInfo> it = loops.values().iterator();
            while (it.hasNext()) {
                LoopInfo loop = it.next();
                int endPC = loop.getEndPC();
                int loopPC = loop.getAddPC();
                if ((endPC - 3) <= pc) {
                    if (loopPC > 0) {
                        bugReporter.reportBug(new BugInstance(this, BugType.UAA_USE_ADD_ALL.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
                                .addSourceLine(this, loopPC));
                    }
                    it.remove();
                } else if ((endPC > pc) && (loopPC < (pc - 5)) && (loopPC > 0)) {
                    it.remove();
                }
            }

            if (seen == Const.INVOKEINTERFACE) {
                String methodName = getNameConstantOperand();
                String signature = getSigConstantOperand();
                if ("get".equals(methodName) && SignatureBuilder.SIG_INT_TO_OBJECT.equals(signature)) {
                    if (stack.getStackDepth() > 1) {
                        OpcodeStack.Item itm = stack.getStackItem(1);
                        int reg = isLocalCollection(itm);
                        if (reg >= 0) {
                            regOrField = Integer.valueOf(reg);
                            sawAlias = true;
                        } else {
                            String field = isFieldCollection(itm);
                            if (field != null) {
                                regOrField = field;
                                sawAlias = true;
                            }
                        }
                    }
                } else if ("keySet".equals(methodName) || "values".equals(methodName) || "iterator".equals(methodName) || "next".equals(methodName)
                        || "hasNext".equals(methodName)) {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        int reg = isLocalCollection(itm);
                        if (reg >= 0) {
                            regOrField = Integer.valueOf(reg);
                            sawAlias = true;
                        } else {
                            String field = isFieldCollection(itm);
                            if (field != null) {
                                regOrField = field;
                                sawAlias = true;
                            }
                        }
                    }
                } else if ("add".equals(methodName) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(signature) && (stack.getStackDepth() > 1)) {
                    OpcodeStack.Item colItem = stack.getStackItem(1);
                    OpcodeStack.Item valueItem = stack.getStackItem(0);
                    int reg = isLocalCollection(colItem);
                    if (reg >= 0) {
                        regOrField = Integer.valueOf(reg);
                        uValue = (Comparable<?>) valueItem.getUserValue();
                        if (uValue != null) {
                            LoopInfo loop = loops.get(uValue);
                            if ((loop != null) && loop.isInLoop(pc) && (this.getCodeByte(getNextPC()) == Const.POP)) {
                                loop.foundAdd(pc);
                            }
                        }
                    } else {
                        String field = isFieldCollection(colItem);
                        if (field != null) {
                            regOrField = field;
                            uValue = (Comparable<?>) valueItem.getUserValue();
                            if (uValue != null) {
                                LoopInfo loop = loops.get(uValue);
                                if ((loop != null) && loop.isInLoop(pc) && (this.getCodeByte(getNextPC()) == Const.POP)) {
                                    loop.foundAdd(pc);
                                }
                            }
                        }
                    }
                }
            } else if (OpcodeUtils.isIStore(seen) || OpcodeUtils.isAStore(seen)) {
                if (stack.getStackDepth() > 0) {
                    uValue = (Comparable<?>) stack.getStackItem(0).getUserValue();
                    userValues.put(Integer.valueOf(RegisterUtils.getStoreReg(this, seen)), uValue);
                }
            } else if (OpcodeUtils.isILoad(seen) || OpcodeUtils.isALoad(seen)) {
                sawLoad = true;
            } else if (seen == Const.IFEQ) {
                boolean loopFound = false;
                if ((stack.getStackDepth() > 0) && (getBranchOffset() > 0)) {
                    int gotoPos = getBranchTarget() - 3;
                    byte[] code = getCode().getCode();
                    if ((0x00FF & code[gotoPos]) == Const.GOTO) {
                        short brOffset = (short) (0x0FF & code[gotoPos + 1]);
                        brOffset <<= 8;
                        brOffset |= (0x0FF & code[gotoPos + 2]);
                        gotoPos += brOffset;
                        if (gotoPos < pc) {
                            OpcodeStack.Item itm = stack.getStackItem(0);
                            uValue = (Comparable<?>) itm.getUserValue();
                            if (uValue != null) {
                                loops.put(uValue, new LoopInfo(pc, getBranchTarget()));
                            }
                            loopFound = true;
                        }
                    }

                    if (!loopFound) {
                        removeLoop(pc);
                    }
                }
            } else if (isInstanceMethod && (seen == Const.PUTFIELD)) {
                if (stack.getStackDepth() > 1) {
                    OpcodeStack.Item item = stack.getStackItem(1);
                    if (item.getRegisterNumber() == 0) {
                        uValue = (Comparable<?>) stack.getStackItem(0).getUserValue();
                        userValues.put(getNameConstantOperand(), uValue);
                    }
                }
            } else if (isInstanceMethod && (seen == Const.GETFIELD)) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    if (item.getRegisterNumber() == 0) {
                        sawLoad = true;
                    }
                }
            } else if (((seen > Const.IFEQ) && (seen <= Const.GOTO)) || (seen == Const.IFNULL) || (seen == Const.IFNONNULL)) {
                removeLoop(pc);
            } else if ((seen == Const.CHECKCAST) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                uValue = (Comparable<?>) itm.getUserValue();
                if (uValue != null) {
                    regOrField = uValue;
                    sawAlias = true;
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (sawAlias) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    itm.setUserValue(regOrField);
                }
            } else if (sawLoad && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                int reg = itm.getRegisterNumber();
                if (reg >= 0) {
                    uValue = userValues.get(Integer.valueOf(reg));
                    itm.setUserValue(uValue);
                } else {
                    XField xField = itm.getXField();
                    if (xField != null) {
                        uValue = userValues.get(xField.getName());
                        itm.setUserValue(uValue);
                    }
                }
            }
        }
    }
668265
int writeParameterAttrs(MethodSymbol m) {
        boolean hasVisible = false;
        boolean hasInvisible = false;
        if (m.params != null) {
            for (VarSymbol s : m.params) {
                for (Attribute.Compound a : s.getRawAttributes()) {
                    switch (types.getRetention(a)) {
                    case SOURCE: break;
                    case CLASS: hasInvisible = true; break;
                    case RUNTIME: hasVisible = true; break;
                    default: ;// /* fail soft */ throw new AssertionError(vis);
                    }
                }
            }
        }

        int attrCount = 0;
        if (hasVisible) {
            int attrIndex = writeAttr(names.RuntimeVisibleParameterAnnotations);
            databuf.appendByte(m.params.length());
            for (VarSymbol s : m.params) {
                ListBuffer<Attribute.Compound> buf = new ListBuffer<Attribute.Compound>();
                for (Attribute.Compound a : s.getRawAttributes())
                    if (types.getRetention(a) == RetentionPolicy.RUNTIME)
                        buf.append(a);
                databuf.appendChar(buf.length());
                for (Attribute.Compound a : buf)
                    writeCompoundAttribute(a);
            }
            endAttr(attrIndex);
            attrCount++;
        }
        if (hasInvisible) {
            int attrIndex = writeAttr(names.RuntimeInvisibleParameterAnnotations);
            databuf.appendByte(m.params.length());
            for (VarSymbol s : m.params) {
                ListBuffer<Attribute.Compound> buf = new ListBuffer<Attribute.Compound>();
                for (Attribute.Compound a : s.getRawAttributes())
                    if (types.getRetention(a) == RetentionPolicy.CLASS)
                        buf.append(a);
                databuf.appendChar(buf.length());
                for (Attribute.Compound a : buf)
                    writeCompoundAttribute(a);
            }
            endAttr(attrIndex);
            attrCount++;
        }
        return attrCount;
    }
1285212
@Override
    public void sawOpcode(int seen) {
        if (seen != Const.INVOKESPECIAL) {
            return;
        }

        String calledClassName = getClassConstantOperand();
        String calledMethodName = getNameConstantOperand();
        String calledMethodSig = getSigConstantOperand();
        if (calledClassName.equals(getSuperclassName()) && calledMethodName.equals(getMethodName())
                && calledMethodSig.equals(getMethodSig())) {
            sawCallToSuper = true;
        }

    }
484232
@Override
    public void sawOpcode(int seen) {
        boolean markAsValid = false;

        try {
            stack.precomputation(this);

            int pc = getPC();
            for (CodeException ex : exceptions) {
                if (pc == ex.getEndPC()) {
                    if (OpcodeUtils.isReturn(seen)) {
                        addCatchBlock(ex.getHandlerPC(), Integer.MAX_VALUE);
                    } else if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                        addCatchBlock(ex.getHandlerPC(), this.getBranchTarget());
                    } else {
                        addCatchBlock(ex.getHandlerPC(), Integer.MAX_VALUE);
                    }
                } else if (pc == ex.getHandlerPC()) {
                    removePreviousHandlers(pc);
                }
            }

            Iterator<CatchInfo> it = catchInfos.iterator();
            while (it.hasNext()) {
                try {
                    CatchInfo catchInfo = it.next();
                    if (pc == catchInfo.getStart()) {
                        if (!updateExceptionRegister(catchInfo, seen, pc)) {
                            it.remove();
                        }
                        break;
                    } else if (pc > catchInfo.getFinish()) {
                        it.remove();
                        break;
                    } else if ((pc > catchInfo.getStart()) && (pc <= catchInfo.getFinish())) {
                        if (seen == Const.INVOKESPECIAL) {
                            if (Values.CONSTRUCTOR.equals(getNameConstantOperand())) {
                                String className = getClassConstantOperand();
                                JavaClass exClass = Repository.lookupClass(className);
                                if (exClass.instanceOf(throwableClass)) {
                                    String sig = getSigConstantOperand();
                                    if ((sig.indexOf("Exception") >= 0) || (sig.indexOf("Throwable") >= 0) || (sig.indexOf("Error") >= 0)) {
                                        markAsValid = true;
                                        break;
                                    }
                                    if (exClass.instanceOf(assertionClass)) {
                                        // just ignore LEST for AssertionErrors
                                        markAsValid = true;
                                        break;
                                    }
                                }
                            } else if (isPossibleExBuilder(catchInfo.getRegister())) {
                                markAsValid = true;
                            }
                        } else if (seen == Const.INVOKEVIRTUAL) {
                            String methodName = getNameConstantOperand();
                            if ("initCause".equals(methodName) || "addSuppressed".equals(methodName)) {
                                if (stack.getStackDepth() > 1) {
                                    String className = getClassConstantOperand();
                                    JavaClass exClass = Repository.lookupClass(className);
                                    if (exClass.instanceOf(throwableClass)) {
                                        OpcodeStack.Item itm = stack.getStackItem(1);
                                        int reg = itm.getRegisterNumber();
                                        if (reg >= 0) {
                                            exReg.put(Integer.valueOf(reg), Boolean.TRUE);
                                        }
                                        markAsValid = true; // Fixes javac generated code
                                    }
                                }
                            } else if ((("getTargetException".equals(methodName) || "getCause".equals(methodName))
                                    && "java/lang/reflect/InvocationTargetException".equals(getClassConstantOperand()))
                                    || "java/io/UncheckedIOException".equals(getClassConstantOperand())) {
                                markAsValid = true;
                            } else if (isPossibleExBuilder(catchInfo.getRegister())) {
                                markAsValid = true;
                            }
                        } else if ((seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKESTATIC)) {
                            if (isPossibleExBuilder(catchInfo.getRegister())) {
                                markAsValid = true;
                            }
                        } else if (seen == Const.ATHROW) {
                            if (stack.getStackDepth() > 0) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                if ((itm.getRegisterNumber() != catchInfo.getRegister()) && (itm.getUserValue() == null)) {
                                    if (!isPre14Class(itm.getJavaClass())) {
                                        int priority = getPrevOpcode(1) == Const.MONITOREXIT ? LOW_PRIORITY : NORMAL_PRIORITY;
                                        bugReporter.reportBug(new BugInstance(this, BugType.LEST_LOST_EXCEPTION_STACK_TRACE.name(), priority).addClass(this)
                                                .addMethod(this).addSourceLine(this));
                                    }
                                    it.remove();
                                    break;
                                }
                            }
                            if (catchInfo.getFinish() == Integer.MAX_VALUE) {
                                catchInfo.setFinish(pc);
                            }

                        } else if (OpcodeUtils.isAStore(seen)) {
                            if (lastWasExitPoint) {
                                // crazy jdk6 finally block injection -- shut
                                // off detection
                                catchInfos.clear();
                                break;
                            }

                            if (stack.getStackDepth() > 0) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                int reg = RegisterUtils.getAStoreReg(this, seen);
                                exReg.put(Integer.valueOf(reg), (Boolean) itm.getUserValue());
                                if ((reg == catchInfo.getRegister()) && (catchInfo.getFinish() == Integer.MAX_VALUE)) {
                                    it.remove();
                                }
                            }
                        } else if (OpcodeUtils.isALoad(seen)) {
                            Boolean valid = exReg.get(Integer.valueOf(RegisterUtils.getALoadReg(this, seen)));
                            if (valid != null) {
                                markAsValid = valid.booleanValue();
                            }
                        } else if (OpcodeUtils.isReturn(seen)) {
                            removeIndeterminateHandlers(pc);
                            break;
                        }
                    }
                } catch (ClassNotFoundException cnfe) {
                    bugReporter.reportMissingClass(cnfe);
                    it.remove();
                }
            }

            lastWasExitPoint = (seen == Const.GOTO) || (seen == Const.GOTO_W) || (seen == Const.ATHROW) || OpcodeUtils.isReturn(seen);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (markAsValid && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(Boolean.TRUE);
            }
        }
    }
985112
@Override
    public void sawOpcode(int seen) {
        Integer arraySize = null;
        String[] loadedTypes = null;

        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.ANEWARRAY: {
                    if (Values.SLASHED_JAVA_LANG_CLASS.equals(getClassConstantOperand()) && (stack.getStackDepth() >= 1)) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        arraySize = (Integer) item.getConstant();
                    }
                }
                break;

                case Const.AASTORE: {
                    if (stack.getStackDepth() >= 3) {
                        OpcodeStack.Item arrayItem = stack.getStackItem(2);
                        String[] arrayTypes = (String[]) arrayItem.getUserValue();
                        if (arrayTypes != null) {
                            OpcodeStack.Item valueItem = stack.getStackItem(0);
                            String type = (String) valueItem.getConstant();
                            if (type != null) {
                                OpcodeStack.Item indexItem = stack.getStackItem(1);
                                Integer index = (Integer) indexItem.getConstant();
                                if (index != null) {
                                    arrayTypes[index.intValue()] = type;
                                }
                            }
                        }
                    }
                }
                break;

                case Const.PUTFIELD:
                case Const.PUTSTATIC: {
                    String name = getNameConstantOperand();
                    if (stack.getStackDepth() >= 1) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        String[] arrayTypes = (String[]) item.getUserValue();
                        if (arrayTypes != null) {
                            fieldClassTypes.put(name, arrayTypes);
                            return;
                        }
                    }
                    fieldClassTypes.remove(name);
                }
                break;

                case Const.GETFIELD:
                case Const.GETSTATIC: {
                    String name = getNameConstantOperand();
                    loadedTypes = fieldClassTypes.get(name);
                }
                break;

                case Const.ASTORE_0:
                case Const.ASTORE_1:
                case Const.ASTORE_2:
                case Const.ASTORE_3:
                case Const.ASTORE: {
                    Integer reg = Integer.valueOf(RegisterUtils.getAStoreReg(this, seen));
                    if (stack.getStackDepth() >= 1) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        String[] arrayTypes = (String[]) item.getUserValue();
                        if (arrayTypes != null) {
                            localClassTypes.put(reg, arrayTypes);
                            return;
                        }
                    }
                    localClassTypes.remove(reg);
                }
                break;

                case Const.ALOAD_0:
                case Const.ALOAD_1:
                case Const.ALOAD_2:
                case Const.ALOAD_3:
                case Const.ALOAD: {
                    int reg = RegisterUtils.getAStoreReg(this, seen);
                    loadedTypes = localClassTypes.get(Integer.valueOf(reg));
                }
                break;

                case Const.INVOKEVIRTUAL: {
                    String cls = getClassConstantOperand();
                    if (Values.SLASHED_JAVA_LANG_CLASS.equals(cls)) {
                        String method = getNameConstantOperand();
                        if ("getMethod".equals(method)) {
                            String sig = getSigConstantOperand();
                            if (SIG_STRING_AND_CLASS_ARRAY_TO_METHOD.equals(sig) && (stack.getStackDepth() >= 2)) {
                                OpcodeStack.Item clsArgs = stack.getStackItem(0);
                                String[] arrayTypes = (String[]) clsArgs.getUserValue();
                                if ((arrayTypes != null) || clsArgs.isNull()) {
                                    OpcodeStack.Item methodItem = stack.getStackItem(1);
                                    String methodName = (String) methodItem.getConstant();
                                    if (methodName != null) {
                                        String reflectionSig = sigWithoutReturn.withMethodName(methodName).withParamTypes(arrayTypes).build();
                                        if (objectSigs.contains(reflectionSig)) {
                                            loadedTypes = (arrayTypes == null) ? new String[0] : arrayTypes;
                                        }
                                    }
                                }
                            }
                        }
                    } else if ("java/lang/reflect/Method".equals(cls)) {
                        String method = getNameConstantOperand();
                        if ("invoke".equals(method) && (stack.getStackDepth() >= 3)) {
                            OpcodeStack.Item methodItem = stack.getStackItem(2);
                            String[] arrayTypes = (String[]) methodItem.getUserValue();
                            if (arrayTypes != null) {
                                bugReporter.reportBug(new BugInstance(this, BugType.ROOM_REFLECTION_ON_OBJECT_METHODS.name(), NORMAL_PRIORITY).addClass(this)
                                        .addMethod(this).addSourceLine(this));
                            }
                        }
                    }
                }
                break;

                default:
                break;
            }
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);

            if (stack.getStackDepth() >= 1) {
                if (arraySize != null) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    item.setUserValue(new String[arraySize.intValue()]);
                } else if (loadedTypes != null) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    item.setUserValue(loadedTypes);
                }
            }
        }
    }
869163
@Override
    public void sawOpcode(int seen) {
        switch (state) {
            case COLLECT:
                if ((seen == Const.INVOKESTATIC) || (seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKESPECIAL)) {
                    refClasses.add(getClassConstantOperand());
                    String signature = getSigConstantOperand();
                    Type[] argTypes = Type.getArgumentTypes(signature);
                    for (Type t : argTypes) {
                        addType(t);
                    }
                    Type resultType = Type.getReturnType(signature);
                    addType(resultType);
                }
            break;

            case SEEN_NOTHING:
                if ((seen == Const.LDC) || (seen == Const.LDC_W)) {
                    Constant c = getConstantRefOperand();
                    if (c instanceof ConstantString) {
                        clsName = ((ConstantString) c).getBytes(getConstantPool());
                        state = State.SEEN_LDC;
                    }
                }
            break;

            case SEEN_LDC:
                if ((seen == Const.INVOKESTATIC) && "forName".equals(getNameConstantOperand()) && "java/lang/Class".equals(getClassConstantOperand())
                        && refClasses.contains(clsName)) {
                    bugReporter.reportBug(new BugInstance(this, BugType.SCR_SLOPPY_CLASS_REFLECTION.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
                            .addSourceLine(this));
                }
                state = State.SEEN_NOTHING;
            break;
        }
    }
176450
@Override
    public void sawOpcode(int seen) {
        String methodPackage = null;
        try {
            stack.precomputation(this);

            if (seen == Const.INVOKEVIRTUAL) {
                methodPackage = processInvokeVirtual();

            } else if (OpcodeUtils.isAStore(seen)) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    Integer reg = Integer.valueOf(RegisterUtils.getAStoreReg(this, seen));
                    if (item.getUserValue() != null) {
                        XMethod xm = item.getReturnValueOf();
                        if (xm != null) {
                            toStringRegisters.put(reg, xm.getPackageName());
                        } else {
                            toStringRegisters.remove(reg);
                        }
                    } else {
                        toStringRegisters.remove(reg);
                    }
                }
            } else if (OpcodeUtils.isALoad(seen)) {
                Integer reg = Integer.valueOf(RegisterUtils.getAStoreReg(this, seen));
                methodPackage = toStringRegisters.get(reg);
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if ((methodPackage != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(methodPackage);
            }
        }
    }
1108202
@Override
    public void sawOpcode(int seen) {
        Integer userValue = null;

        if ((conditionalTarget != -1) && (getPC() >= conditionalTarget)) {
            conditionalTarget = -1;
            sawMethodWeight = 0;
        }

        try {
            switch (seen) {
                case Const.INVOKESPECIAL:
                case Const.INVOKESTATIC:
                case Const.INVOKEINTERFACE:
                case Const.INVOKEVIRTUAL:
                    String signature = getSigConstantOperand();
                    if (Values.SIG_VOID.equals(SignatureUtils.getReturnSignature(signature))) {
                        sawMethodWeight = 0;
                        return;
                    }

                    String clsName = getClassConstantOperand();
                    MethodInfo mi = Statistics.getStatistics().getMethodStatistics(clsName, getNameConstantOperand(), signature);
                    if ((mi == null) || (mi.getNumBytes() == 0)) {
                        userValue = Values.ONE;
                    } else {
                        userValue = Integer.valueOf(mi.getNumBytes());
                    }
                break;

                case Const.LCMP:
                case Const.FCMPL:
                case Const.FCMPG:
                case Const.DCMPL:
                case Const.DCMPG:
                case Const.IAND:
                case Const.IOR:
                case Const.IXOR:
                    if (stack.getStackDepth() >= 2) {
                        for (int i = 0; i <= 1; i++) {
                            OpcodeStack.Item itm = stack.getStackItem(i);
                            userValue = (Integer) itm.getUserValue();
                            if (userValue != null) {
                                break;
                            }
                        }
                    } else {
                        sawMethodWeight = 0;
                    }
                break;

                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:
                    if (conditionalTarget < 0) {
                        conditionalTarget = getBranchTarget();
                    } else if (conditionalTarget != getBranchTarget()) {
                        conditionalTarget = -1;
                        sawMethodWeight = 0;
                        return;
                    }

                    if (stack.getStackDepth() >= 2) {
                        int expWeight = 0;
                        for (int i = 0; i <= 1; i++) {
                            OpcodeStack.Item itm = stack.getStackItem(i);

                            Integer uv = (Integer) itm.getUserValue();
                            if (uv != null) {
                                expWeight = Math.max(uv.intValue(), expWeight);
                            }
                        }

                        if ((expWeight == 0) && (sawMethodWeight > 0)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.SEO_SUBOPTIMAL_EXPRESSION_ORDER.name(),
                                    sawMethodWeight >= NORMAL_WEIGHT_LIMIT ? NORMAL_PRIORITY : LOW_PRIORITY).addClass(this).addMethod(this)
                                            .addSourceLine(this));
                            sawMethodWeight = 0;
                            conditionalTarget = Integer.MAX_VALUE;
                        } else {
                            sawMethodWeight = Math.max(sawMethodWeight, expWeight);
                        }
                    }
                break;

                case Const.IFEQ:
                case Const.IFNE:
                case Const.IFLT:
                case Const.IFGE:
                case Const.IFGT:
                case Const.IFLE:
                case Const.IFNULL:
                case Const.IFNONNULL:
                    if (conditionalTarget < 0) {
                        conditionalTarget = getBranchTarget();
                    } else if (conditionalTarget != getBranchTarget()) {
                        conditionalTarget = -1;
                        sawMethodWeight = 0;
                        return;
                    }

                    if (stack.getStackDepth() >= 1) {
                        OpcodeStack.Item itm = stack.getStackItem(0);

                        Integer uv = (Integer) itm.getUserValue();
                        if (uv == null) {
                            if (sawMethodWeight > 0) {
                                bugReporter.reportBug(new BugInstance(this, BugType.SEO_SUBOPTIMAL_EXPRESSION_ORDER.name(),
                                        sawMethodWeight >= NORMAL_WEIGHT_LIMIT ? NORMAL_PRIORITY : LOW_PRIORITY).addClass(this).addMethod(this)
                                                .addSourceLine(this));
                                sawMethodWeight = 0;
                                conditionalTarget = Integer.MAX_VALUE;
                            }
                        } else {
                            sawMethodWeight = Math.max(sawMethodWeight, uv.intValue());
                        }
                    }
                break;

                case Const.ISTORE:
                case Const.LSTORE:
                case Const.FSTORE:
                case Const.DSTORE:
                case Const.ASTORE:
                case Const.ISTORE_0:
                case Const.ISTORE_1:
                case Const.ISTORE_2:
                case Const.ISTORE_3:
                case Const.LSTORE_0:
                case Const.LSTORE_1:
                case Const.LSTORE_2:
                case Const.LSTORE_3:
                case Const.FSTORE_0:
                case Const.FSTORE_1:
                case Const.FSTORE_2:
                case Const.FSTORE_3:
                case Const.DSTORE_0:
                case Const.DSTORE_1:
                case Const.DSTORE_2:
                case Const.DSTORE_3:
                case Const.ASTORE_0:
                case Const.ASTORE_1:
                case Const.ASTORE_2:
                case Const.ASTORE_3:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        itm.setUserValue(null);
                    }
                    sawMethodWeight = 0;
                    conditionalTarget = -1;
                break;

                case Const.ATHROW:
                case Const.POP:
                case Const.POP2:
                case Const.GOTO:
                case Const.GOTO_W:
                case Const.PUTFIELD:
                case Const.PUTSTATIC:
                case Const.IINC:
                case Const.INSTANCEOF:
                case Const.RETURN:
                case Const.ARETURN:
                case Const.IRETURN:
                case Const.LRETURN:
                case Const.FRETURN:
                case Const.DRETURN:
                    sawMethodWeight = 0;
                    conditionalTarget = -1;
                break;

                case Const.ARRAYLENGTH:
                case Const.CHECKCAST:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        userValue = (Integer) itm.getUserValue();
                    }
                break;

                case Const.GETFIELD:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        if (itm.getReturnValueOf() != null) {
                            sawMethodWeight = 0;
                            conditionalTarget = -1;
                        }
                    }
                break;
            }
        } finally {
            stack.sawOpcode(this, seen);
            if ((userValue != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(userValue);
            }
        }
    }