@ Override public void visitMethod ( final Method obj ) { try { if ( obj . isSynthetic ( ) ) { return ; } Code code = obj . getCode ( ) ; if ( code == null ) { return ; } // There really is no valid relationship between reportLimit and // code // length, but it is good enough. If the method is small, don't // bother if ( code . getCode ( ) . length < ( 2 * reportLimit ) ) { return ; } BitSet exceptionNodeTargets = new BitSet ( ) ; CFG cfg = classContext . getCFG ( obj ) ; int branches = 0 ; Iterator < BasicBlock > bbi = cfg . blockIterator ( ) ; while ( bbi . hasNext ( ) ) { BasicBlock bb = bbi . next ( ) ; Iterator < Edge > iei = cfg . outgoingEdgeIterator ( bb ) ; int lastSwitchTargetBlockLabel = Integer . MIN_VALUE ; while ( iei . hasNext ( ) ) { Edge e = iei . next ( ) ; int edgeType = e . getType ( ) ; if ( ( edgeType != EdgeTypes . FALL_THROUGH_EDGE ) && ( edgeType != EdgeTypes . RETURN_EDGE ) && ( edgeType != EdgeTypes . UNKNOWN_EDGE ) ) { if ( ( edgeType == EdgeTypes . UNHANDLED_EXCEPTION_EDGE ) || ( edgeType == EdgeTypes . HANDLED_EXCEPTION_EDGE ) ) { int nodeTarget = e . getTarget ( ) . getLabel ( ) ; if ( ! exceptionNodeTargets . get ( nodeTarget ) ) { exceptionNodeTargets . set ( nodeTarget ) ; branches ++ ; } } else if ( ( edgeType == EdgeTypes . SWITCH_EDGE ) || ( edgeType == EdgeTypes . SWITCH_DEFAULT_EDGE ) ) { int nodeTarget = e . getTarget ( ) . getLabel ( ) ; if ( nodeTarget != lastSwitchTargetBlockLabel ) { branches ++ ; } lastSwitchTargetBlockLabel = nodeTarget ; } else { branches ++ ; } } } } if ( branches > reportLimit ) { int priority = ( branches > ( reportLimit * 2 ) ? HIGH_PRIORITY : NORMAL_PRIORITY ) ; BugInstance bug = new BugInstance ( this , BugType . CC_CYCLOMATIC_COMPLEXITY . name ( ) , priority ) . addClass ( this ) . addMethod ( this ) . addSourceLine ( classContext , this , 0 ) . addInt ( branches ) ; bugReporter . reportBug ( bug ) ; } } catch ( CFGBuilderException cbe ) { bugReporter . logError ( "Failure examining basic blocks for method " + classContext . getJavaClass ( ) . getClassName ( ) + ' ' + obj . getName ( ) + " in Cyclomatic Complexity detector" , cbe ) ; } }
overrides the visitor to navigate the basic block list to count branches