@ Override public void sawOpcode ( int seen ) { try { stack . precomputation ( this ) ; if ( OpcodeUtils . isStandardInvoke ( seen ) ) { String clsName = getClassConstantOperand ( ) ; if ( ! safeClasses . contains ( clsName ) ) { try { JavaClass cls = Repository . lookupClass ( clsName ) ; Method [ ] methods = cls . getMethods ( ) ; String methodName = getNameConstantOperand ( ) ; String signature = getSigConstantOperand ( ) ; boolean found = false ; for ( Method m : methods ) { if ( m . getName ( ) . equals ( methodName ) && m . getSignature ( ) . equals ( signature ) ) { if ( isAnonymousInnerCtor ( m , cls ) ) { // The java compiler doesn't properly attached an Exception Table to anonymous // constructors, so just clear if so break ; } ExceptionTable et = m . getExceptionTable ( ) ; if ( et != null ) { String [ ] thrownExceptions = et . getExceptionNames ( ) ; for ( String thrownException : thrownExceptions ) { removeThrownExceptionHierarchy ( thrownException ) ; } } found = true ; break ; } } if ( ! found ) { clearExceptions ( ) ; } } catch ( ClassNotFoundException cnfe ) { bugReporter . reportMissingClass ( cnfe ) ; clearExceptions ( ) ; } } else if ( "wait" . equals ( getNameConstantOperand ( ) ) ) { removeException ( "java.lang.InterruptedException" ) ; } } else if ( seen == Const . ATHROW ) { if ( stack . getStackDepth ( ) > 0 ) { OpcodeStack . Item item = stack . getStackItem ( 0 ) ; String exSig = item . getSignature ( ) ; String thrownException = SignatureUtils . stripSignature ( exSig ) ; removeThrownExceptionHierarchy ( thrownException ) ; } else { clearExceptions ( ) ; } } } finally { stack . sawOpcode ( this , seen ) ; } }
implements the visitor to look for method calls that could throw the exceptions that are listed in the declaration .