private void addPrivateFieldAndMethodAccessors(ClassNode node) {
   addPrivateBridgeMethods(node);
   addPrivateFieldsAccessors(node);
   Iterator<InnerClassNode> it = node.getInnerClasses();
   while (it.hasNext()) {
     addPrivateFieldAndMethodAccessors(it.next());
   }
 }
  /**
   * 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.
   */
  public void applyToPrimaryClassNodes(PrimaryClassNodeOperation body)
      throws CompilationFailedException {
    // GRECLIPSE: start
    /*old{
    Iterator classNodes = getPrimaryClassNodes(body.needSortedInput()).iterator();
    }*/
    // newcode
    List primaryClassNodes = getPrimaryClassNodes(body.needSortedInput());
    Iterator classNodes = primaryClassNodes.iterator();
    // end
    while (classNodes.hasNext()) {
      SourceUnit context = null;
      try {
        ClassNode classNode = (ClassNode) classNodes.next();
        context = classNode.getModule().getContext();
        // GRECLIPSE get to the bottom of this - why are operations running multiple times that
        // should only run once?
        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) {
        throw npe;
      } catch (GroovyBugError e) {
        changeBugText(e, context);
        throw e;
      } catch (Exception e) {
        // check the exception for a nested compilation exception
        ErrorCollector nestedCollector = null;
        for (Throwable next = e.getCause(); next != e && next != null; next = next.getCause()) {
          if (!(next instanceof MultipleCompilationErrorsException)) continue;
          MultipleCompilationErrorsException mcee = (MultipleCompilationErrorsException) next;
          nestedCollector = mcee.collector;
          break;
        }

        if (nestedCollector != null) {
          getErrorCollector().addCollectorContents(nestedCollector);
        } else {
          getErrorCollector().addError(new ExceptionMessage(e, configuration.getDebug(), this));
        }
      }
    }

    getErrorCollector().failIfErrors();
  }
 @Override
 public void visitClass(final ClassNode node) {
   boolean skip = shouldSkipClassNode(node);
   if (!skip && !anyMethodSkip(node)) {
     node.putNodeMetaData(MopWriter.Factory.class, StaticCompilationMopWriter.FACTORY);
   }
   ClassNode oldCN = classNode;
   classNode = node;
   Iterator<InnerClassNode> innerClasses = classNode.getInnerClasses();
   while (innerClasses.hasNext()) {
     InnerClassNode innerClassNode = innerClasses.next();
     boolean innerStaticCompile = !(skip || isSkippedInnerClass(innerClassNode));
     innerClassNode.putNodeMetaData(STATIC_COMPILE_NODE, innerStaticCompile);
     innerClassNode.putNodeMetaData(
         WriterControllerFactory.class, node.getNodeMetaData(WriterControllerFactory.class));
     if (innerStaticCompile && !anyMethodSkip(innerClassNode)) {
       innerClassNode.putNodeMetaData(MopWriter.Factory.class, StaticCompilationMopWriter.FACTORY);
     }
   }
   super.visitClass(node);
   addPrivateFieldAndMethodAccessors(node);
   classNode = oldCN;
 }
  private void printClassContents(PrintWriter out, ClassNode classNode)
      throws FileNotFoundException {
    if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
      // if it is an anonymous inner class, don't generate the stub code for it.
      return;
    }
    try {
      Verifier verifier =
          new Verifier() {
            public void addCovariantMethods(ClassNode cn) {}

            protected void addTimeStamp(ClassNode node) {}

            protected void addInitialization(ClassNode node) {}

            protected void addPropertyMethod(MethodNode method) {
              doAddMethod(method);
            }

            protected void addReturnIfNeeded(MethodNode node) {}

            protected void addMethod(
                ClassNode node,
                boolean shouldBeSynthetic,
                String name,
                int modifiers,
                ClassNode returnType,
                Parameter[] parameters,
                ClassNode[] exceptions,
                Statement code) {
              doAddMethod(
                  new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
            }

            protected void addConstructor(
                Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
              if (code instanceof ExpressionStatement) { // GROOVY-4508
                Statement temp = code;
                code = new BlockStatement();
                ((BlockStatement) code).addStatement(temp);
              }
              ConstructorNode ctrNode =
                  new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
              ctrNode.setDeclaringClass(node);
              constructors.add(ctrNode);
            }

            protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
              final Parameter[] parameters = method.getParameters();
              final Expression[] saved = new Expression[parameters.length];
              for (int i = 0; i < parameters.length; i++) {
                if (parameters[i].hasInitialExpression())
                  saved[i] = parameters[i].getInitialExpression();
              }
              super.addDefaultParameters(action, method);
              for (int i = 0; i < parameters.length; i++) {
                if (saved[i] != null) parameters[i].setInitialExpression(saved[i]);
              }
            }

            private void doAddMethod(MethodNode method) {
              String sig = method.getTypeDescriptor();

              if (propertyMethodsWithSigs.containsKey(sig)) return;

              propertyMethods.add(method);
              propertyMethodsWithSigs.put(sig, method);
            }

            @Override
            protected void addDefaultConstructor(ClassNode node) {
              // not required for stub generation
            }
          };
      verifier.visitClass(classNode);
      currentModule = classNode.getModule();

      boolean isInterface = classNode.isInterface();
      boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0;
      boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
      printAnnotations(out, classNode);
      printModifiers(
          out,
          classNode.getModifiers()
              & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0)
              & ~(isEnum ? Opcodes.ACC_FINAL : 0));

      if (isInterface) {
        if (isAnnotationDefinition) {
          out.print("@");
        }
        out.print("interface ");
      } else if (isEnum) {
        out.print("enum ");
      } else {
        out.print("class ");
      }

      String className = classNode.getNameWithoutPackage();
      if (classNode instanceof InnerClassNode)
        className = className.substring(className.lastIndexOf("$") + 1);
      out.println(className);
      printGenericsBounds(out, classNode, true);

      ClassNode superClass = classNode.getUnresolvedSuperClass(false);

      if (!isInterface && !isEnum) {
        out.print("  extends ");
        printType(out, superClass);
      }

      ClassNode[] interfaces = classNode.getInterfaces();
      if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
        if (isInterface) {
          out.println("  extends");
        } else {
          out.println("  implements");
        }
        for (int i = 0; i < interfaces.length - 1; ++i) {
          out.print("    ");
          printType(out, interfaces[i]);
          out.print(",");
        }
        out.print("    ");
        printType(out, interfaces[interfaces.length - 1]);
      }
      out.println(" {");

      printFields(out, classNode);
      printMethods(out, classNode, isEnum);

      for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) {
        // GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in
        // inner ones
        propertyMethods.clear();
        propertyMethodsWithSigs.clear();
        constructors.clear();
        printClassContents(out, inner.next());
      }

      out.println("}");
    } finally {
      propertyMethods.clear();
      propertyMethodsWithSigs.clear();
      constructors.clear();
      currentModule = null;
    }
  }