@Override
    public void sawOpcode(final int seen) {
        Object hashCodedStringRef = null;
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.INVOKEVIRTUAL:
                    if (Values.SLASHED_JAVA_LANG_STRING.equals(getClassConstantOperand())) {
                        String calledMethodName = getNameConstantOperand();
                        String calledMethodSig = getSigConstantOperand();

                        if (("equals".equals(calledMethodName) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(calledMethodSig))
                                || ("compareTo".equals(calledMethodName) && SignatureBuilder.SIG_STRING_TO_INT.equals(calledMethodSig))
                                || ("equalsIgnoreCase".equals(calledMethodName) && SignatureBuilder.SIG_STRING_TO_BOOLEAN.equals(calledMethodSig))) {

                            if (stack.getStackDepth() > 0) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                Object constant = itm.getConstant();
                                if ((constant != null) && constant.getClass().equals(String.class) && !lookupSwitchOnString()) {
                                    bugReporter.reportBug(new BugInstance(this, "LSC_LITERAL_STRING_COMPARISON", HIGH_PRIORITY) // very
                                                                                                                                // confident
                                            .addClass(this).addMethod(this).addSourceLine(this));
                                }
                            }
                        } else if (Values.HASHCODE.equals(calledMethodName) && (stack.getStackDepth() > 0)) {
                            OpcodeStack.Item item = stack.getStackItem(0);
                            int reg = item.getRegisterNumber();
                            if (reg >= 0) {
                                hashCodedStringRef = String.valueOf(reg);
                            } else {
                                XField xf = item.getXField();
                                if (xf != null) {
                                    hashCodedStringRef = xf.getName();
                                } else {
                                    XMethod xm = item.getReturnValueOf();
                                    if (xm != null) {
                                        hashCodedStringRef = xm.toString();
                                    }
                                }

                            }
                        }
                    }
                break;

                case Const.TABLESWITCH:
                case Const.LOOKUPSWITCH:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        String stringRef = (String) item.getUserValue();
                        if (stringRef != null) {
                            int[] offsets = getSwitchOffsets();
                            BitSet bs = new BitSet();
                            int pc = getPC();
                            for (int offset : offsets) {
                                bs.set(pc + offset);
                            }
                            bs.set(pc + getDefaultSwitchOffset());
                            lookupSwitches.add(new LookupDetails(stringRef, bs));
                        }
                    }
                break;
                default:
                break;
            }

        } finally {
            stack.sawOpcode(this, seen);
            if ((hashCodedStringRef != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(hashCodedStringRef);
            }

            if (!lookupSwitches.isEmpty()) {
                int innerMostSwitch = lookupSwitches.size() - 1;
                LookupDetails details = lookupSwitches.get(innerMostSwitch);
                if (details.getSwitchTargets().get(getPC()) && (stack.getStackDepth() > 0)) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    item.setUserValue(details.getStringReference());
                }

                // previousSetBit is a jdk1.7 api - gonna cheat cause findbugs
                // runs on 1.7
                if (getPC() >= details.getSwitchTargets().previousSetBit(Integer.MAX_VALUE)) {
                    lookupSwitches.remove(innerMostSwitch);
                }
            }
        }
    }
@ Override public void sawOpcode ( final int seen ) { Object hashCodedStringRef = null ; try { stack . precomputation ( this ) ; switch ( seen ) { case Const . INVOKEVIRTUAL : if ( Values . SLASHED_JAVA_LANG_STRING . equals ( getClassConstantOperand ( ) ) ) { String calledMethodName = getNameConstantOperand ( ) ; String calledMethodSig = getSigConstantOperand ( ) ; if ( ( "equals" . equals ( calledMethodName ) && SignatureBuilder . SIG_OBJECT_TO_BOOLEAN . equals ( calledMethodSig ) ) || ( "compareTo" . equals ( calledMethodName ) && SignatureBuilder . SIG_STRING_TO_INT . equals ( calledMethodSig ) ) || ( "equalsIgnoreCase" . equals ( calledMethodName ) && SignatureBuilder . SIG_STRING_TO_BOOLEAN . equals ( calledMethodSig ) ) ) { if ( stack . getStackDepth ( ) > 0 ) { OpcodeStack . Item itm = stack . getStackItem ( 0 ) ; Object constant = itm . getConstant ( ) ; if ( ( constant != null ) && constant . getClass ( ) . equals ( String . class ) && ! lookupSwitchOnString ( ) ) { bugReporter . reportBug ( new BugInstance ( this , "LSC_LITERAL_STRING_COMPARISON" , HIGH_PRIORITY ) . addClass ( this ) . addMethod ( this ) . addSourceLine ( this ) ) ; } } } else if ( Values . HASHCODE . equals ( calledMethodName ) && ( stack . getStackDepth ( ) > 0 ) ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; int reg = item . getRegisterNumber ( ) ; if ( reg >= 0 ) { hashCodedStringRef = String . valueOf ( reg ) ; } else { XField xf = item . getXField ( ) ; if ( xf != null ) { hashCodedStringRef = xf . getName ( ) ; } else { XMethod xm = item . getReturnValueOf ( ) ; if ( xm != null ) { hashCodedStringRef = xm . toString ( ) ; } } } } } break ; case Const . TABLESWITCH : case Const . LOOKUPSWITCH : if ( stack . getStackDepth ( ) > 0 ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; String stringRef = ( String ) item . getUserValue ( ) ; if ( stringRef != null ) { int [ ] offsets = getSwitchOffsets ( ) ; BitSet bs = new BitSet ( ) ; int pc = getPC ( ) ; for ( int offset : offsets ) { bs . set ( pc + offset ) ; } bs . set ( pc + getDefaultSwitchOffset ( ) ) ; lookupSwitches . add ( new LookupDetails ( stringRef , bs ) ) ; } } break ; default : break ; } } finally { stack . sawOpcode ( this , seen ) ; if ( ( hashCodedStringRef != null ) && ( stack . getStackDepth ( ) > 0 ) ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; item . setUserValue ( hashCodedStringRef ) ; } if ( ! lookupSwitches . isEmpty ( ) ) { int innerMostSwitch = lookupSwitches . size ( ) - 1 ; LookupDetails details = lookupSwitches . get ( innerMostSwitch ) ; if ( details . getSwitchTargets ( ) . get ( getPC ( ) ) && ( stack . getStackDepth ( ) > 0 ) ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; item . setUserValue ( details . getStringReference ( ) ) ; } if ( getPC ( ) >= details . getSwitchTargets ( ) . previousSetBit ( Integer . MAX_VALUE ) ) { lookupSwitches . remove ( innerMostSwitch ) ; } } } }
looks for strings comparisons where the stack object is a literal

@param seen
the currently parsed opcode