private void connectToPossibleExceptionHandler ( Node cfgNode , Node target ) { if ( mayThrowException ( target ) && ! exceptionHandler . isEmpty ( ) ) { Node lastJump = cfgNode ; for ( Node handler : exceptionHandler ) { if ( handler . isFunction ( ) ) { return ; } checkState ( handler . isTry ( ) ) ; Node catchBlock = NodeUtil . getCatchBlock ( handler ) ; boolean lastJumpInCatchBlock = false ; for ( Node ancestor : lastJump . getAncestors ( ) ) { if ( ancestor == handler ) { break ; } else if ( ancestor == catchBlock ) { lastJumpInCatchBlock = true ; break ; } } // No catch but a FINALLY, or lastJump is inside the catch block. if ( ! NodeUtil . hasCatchHandler ( catchBlock ) || lastJumpInCatchBlock ) { if ( lastJump == cfgNode ) { createEdge ( cfgNode , Branch . ON_EX , handler . getLastChild ( ) ) ; } else { finallyMap . put ( lastJump , handler . getLastChild ( ) ) ; } } else { // Has a catch. if ( lastJump == cfgNode ) { createEdge ( cfgNode , Branch . ON_EX , catchBlock ) ; return ; } else { finallyMap . put ( lastJump , catchBlock ) ; } } lastJump = handler ; } } }
Connects cfgNode to the proper CATCH block if target subtree might throw an exception . If there are FINALLY blocks reached before a CATCH it will make the corresponding entry in finallyMap .