@ Override public void sawOpcode ( int seen ) { String methodInfo = null ; try { stack . precomputation ( this ) ; switch ( seen ) { case Const . INVOKEVIRTUAL : case Const . INVOKEINTERFACE : case Const . INVOKESTATIC : String sig = getSigConstantOperand ( ) ; if ( ! sig . endsWith ( Values . SIG_VOID ) ) { methodInfo = getClassConstantOperand ( ) + ' ' + getNameConstantOperand ( ) + getSigConstantOperand ( ) ; } break ; case Const . POP : case Const . POP2 : if ( stack . getStackDepth ( ) > 0 ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; String mInfo = ( String ) item . getUserValue ( ) ; if ( mInfo != null ) { for ( Pattern p : IMMUTABLE_METHODS ) { Matcher m = p . matcher ( mInfo ) ; if ( m . matches ( ) ) { bugReporter . reportBug ( new BugInstance ( this , BugType . NPMC_NON_PRODUCTIVE_METHOD_CALL . name ( ) , NORMAL_PRIORITY ) . addClass ( this ) . addMethod ( this ) . addSourceLine ( this ) . addString ( mInfo ) ) ; break ; } } } } break ; } } finally { stack . sawOpcode ( this , seen ) ; if ( ( methodInfo != null ) && ( stack . getStackDepth ( ) > 0 ) ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; item . setUserValue ( methodInfo ) ; } } }
implements the visitor to look for return values of common immutable method calls that are thrown away .