public void applyToPrimaryClassNodes ( PrimaryClassNodeOperation body ) throws CompilationFailedException { Iterator classNodes = getPrimaryClassNodes ( body . needSortedInput ( ) ) . iterator ( ) ; while ( classNodes . hasNext ( ) ) { SourceUnit context = null ; try { ClassNode classNode = ( ClassNode ) classNodes . next ( ) ; context = classNode . getModule ( ) . getContext ( ) ; if ( context == null || context . phase < phase || ( context . phase == phase && ! context . phaseComplete ) ) { int offset = 1 ; Iterator < InnerClassNode > iterator = classNode . getInnerClasses ( ) ; while ( iterator . hasNext ( ) ) { iterator . next ( ) ; offset ++ ; } body . call ( context , new GeneratorContext ( this . ast , offset ) , classNode ) ; } } catch ( CompilationFailedException e ) { // fall through, getErrorReporter().failIfErrors() will trigger } catch ( NullPointerException npe ) { GroovyBugError gbe = new GroovyBugError ( "unexpected NullpointerException" , npe ) ; changeBugText ( gbe , context ) ; throw gbe ; } catch ( GroovyBugError e ) { changeBugText ( e , context ) ; throw e ; } catch ( NoClassDefFoundError e ) { // effort to get more logging in case a dependency of a class is loaded // although it shouldn't have convertUncaughtExceptionToCompilationError ( e ) ; } catch ( Exception e ) { convertUncaughtExceptionToCompilationError ( e ) ; } } getErrorCollector ( ) . failIfErrors ( ) ; }
A loop driver for applying operations to all primary ClassNodes in our AST . Automatically skips units that have already been processed through the current phase .