/** Compiles the compilation unit from sources. */
  public void compile(int throughPhase) throws CompilationFailedException {
    //
    // To support delta compilations, we always restart
    // the compiler.  The individual passes are responsible
    // for not reprocessing old code.
    gotoPhase(Phases.INITIALIZATION);
    throughPhase = Math.min(throughPhase, Phases.ALL);

    while (throughPhase >= phase && phase <= Phases.ALL) {

      if (phase == Phases.SEMANTIC_ANALYSIS) {
        doPhaseOperation(resolve);
        if (dequeued()) continue;
      }

      processPhaseOperations(phase);
      // Grab processing may have brought in new AST transforms into various phases, process them as
      // well
      processNewPhaseOperations(phase);

      if (progressCallback != null) progressCallback.call(this, phase);
      completePhase();
      applyToSourceUnits(mark);

      if (dequeued()) continue;

      gotoPhase(phase + 1);

      if (phase == Phases.CLASS_GENERATION) {
        sortClasses();
      }
    }

    errorCollector.failIfErrors();
  }
 private int getSuperInterfaceCount(ClassNode element) {
   int count = 1;
   ClassNode[] interfaces = element.getInterfaces();
   for (ClassNode anInterface : interfaces) {
     count = Math.max(count, getSuperInterfaceCount(anInterface) + 1);
   }
   return count;
 }
        public void call(SourceUnit source, GeneratorContext context, ClassNode classNode)
            throws CompilationFailedException {

          optimizer.visitClass(
              classNode, source); // GROOVY-4272: repositioned it here from staticImport

          if (!classNode.isSynthetic()) {
            GenericsVisitor genericsVisitor = new GenericsVisitor(source);
            genericsVisitor.visitClass(classNode);
          }
          //
          // Run the Verifier on the outer class
          //
          try {
            verifier.visitClass(classNode);
          } catch (GroovyRuntimeException rpe) {
            ASTNode node = rpe.getNode();
            getErrorCollector()
                .addError(
                    new SyntaxException(
                        rpe.getMessage(),
                        node.getLineNumber(),
                        node.getColumnNumber(),
                        node.getLastLineNumber(),
                        node.getLastColumnNumber()),
                    source);
          }

          LabelVerifier lv = new LabelVerifier(source);
          lv.visitClass(classNode);

          ClassCompletionVerifier completionVerifier = new ClassCompletionVerifier(source);
          completionVerifier.visitClass(classNode);

          ExtendedVerifier xverifier = new ExtendedVerifier(source);
          xverifier.visitClass(classNode);

          // because the class may be generated even if a error was found
          // and that class may have an invalid format we fail here if needed
          getErrorCollector().failIfErrors();

          //
          // Prep the generator machinery
          //
          ClassVisitor visitor = createClassVisitor();

          String sourceName =
              (source == null ? classNode.getModule().getDescription() : source.getName());
          // only show the file name and its extension like javac does in its stacktraces rather
          // than the full path
          // also takes care of both \ and / depending on the host compiling environment
          if (sourceName != null)
            sourceName =
                sourceName.substring(
                    Math.max(sourceName.lastIndexOf('\\'), sourceName.lastIndexOf('/')) + 1);
          AsmClassGenerator generator = new AsmClassGenerator(source, context, visitor, sourceName);

          //
          // Run the generation and create the class (if required)
          //
          // GRECLIPSE: if there are errors, don't generate code.
          // code gen can fail unexpectedly if there was an earlier error.
          if (!source.getErrorCollector().hasErrors()) {
            // end
            generator.visitClass(classNode);

            byte[] bytes = ((ClassWriter) visitor).toByteArray();
            /// GRECLIPSE: start: added classNode, sourceUnit
            /*old{
            generatedClasses.add(new GroovyClass(classNode.getName(), bytes));
            }*/
            // newcode
            generatedClasses.add(new GroovyClass(classNode.getName(), bytes, classNode, source));
            // end

            //
            // Handle any callback that's been set
            //
            if (CompilationUnit.this.classgenCallback != null) {
              classgenCallback.call(visitor, classNode);
            }

            //
            // Recurse for inner classes
            //
            LinkedList innerClasses = generator.getInnerClasses();
            while (!innerClasses.isEmpty()) {
              classgen.call(source, context, (ClassNode) innerClasses.removeFirst());
            }
            // GRECLIPSE: if there are errors, don't generate code
          }
          // end
        }