/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.codehaus.groovy.control;

import groovy.lang.GroovyClassLoader;
import groovy.transform.CompilationUnitAware;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.CompileUnit;
import org.codehaus.groovy.ast.GroovyClassVisitor;
import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.classgen.AsmClassGenerator;
import org.codehaus.groovy.classgen.ClassCompletionVerifier;
import org.codehaus.groovy.classgen.EnumCompletionVisitor;
import org.codehaus.groovy.classgen.EnumVisitor;
import org.codehaus.groovy.classgen.ExtendedVerifier;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.classgen.InnerClassCompletionVisitor;
import org.codehaus.groovy.classgen.InnerClassVisitor;
import org.codehaus.groovy.classgen.VariableScopeVisitor;
import org.codehaus.groovy.classgen.Verifier;
import org.codehaus.groovy.control.customizers.CompilationCustomizer;
import org.codehaus.groovy.control.io.InputStreamReaderSource;
import org.codehaus.groovy.control.io.ReaderSource;
import org.codehaus.groovy.control.messages.ExceptionMessage;
import org.codehaus.groovy.control.messages.Message;
import org.codehaus.groovy.control.messages.SimpleMessage;
import org.codehaus.groovy.syntax.RuntimeParserException;
import org.codehaus.groovy.syntax.SyntaxException;
import org.codehaus.groovy.tools.GroovyClass;
import org.codehaus.groovy.transform.ASTTransformationVisitor;
import org.codehaus.groovy.transform.AnnotationCollectorTransform;
import org.codehaus.groovy.transform.trait.TraitComposer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;

import static java.util.stream.Collectors.toList;
import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.SWITCH_CONDITION_EXPRESSION_TYPE;

/**
 * The CompilationUnit collects all compilation data as it is generated by the compiler system.
 * You can use this object to add additional source units to the compilation, or force the
 * compilation to be run again (to affect only the deltas).
 * <p>
 * You can also add PhaseOperations to this compilation using the addPhaseOperation method.
 * This is commonly used when you want to wire a new AST Transformation into the compilation.
 */
public class CompilationUnit extends ProcessingUnit {

    /** The overall AST for this CompilationUnit. */
    protected CompileUnit ast; // TODO: Switch to private and access through getAST().

    /** The source units from which this unit is built. */
    protected Map<String, SourceUnit> sources = new LinkedHashMap<>();
    protected Queue<SourceUnit> queuedSources = new LinkedList<>();

    /** The classes generated during classgen. */
    private List<GroovyClass> generatedClasses = new ArrayList<>();

    private Deque<PhaseOperation>[] phaseOperations;
    private Deque<PhaseOperation>[] newPhaseOperations;
    {
        final int n = Phases.ALL + 1;
        phaseOperations = new Deque[n];
        newPhaseOperations = new Deque[n];
        for (int i = 0; i < n; i += 1) {
            phaseOperations[i] = new LinkedList<>();
            newPhaseOperations[i] = new LinkedList<>();
        }
    }

    /** Controls behavior of {@link #classgen()} and other routines. */
    protected boolean debug;
    /** True after the first {@link #configure(CompilerConfiguration)} operation. */
    protected boolean configured;

    /** A callback for use during {@link #classgen()} */
    protected ClassgenCallback classgenCallback;
    /** A callback for use during {@link #compile()} */
    protected ProgressCallback progressCallback;

    protected ClassNodeResolver classNodeResolver = new ClassNodeResolver();
    protected ResolveVisitor resolveVisitor = new ResolveVisitor(this);

    /** The AST transformations state data. */
    protected ASTTransformationsContext astTransformationsContext;

    private Set<javax.tools.JavaFileObject> javaCompilationUnitSet = new HashSet<>();

    /**
     * Initializes the CompilationUnit with defaults.
     */
    public CompilationUnit() {
        this(null, null, null);
    }

    /**
     * Initializes the CompilationUnit with defaults except for class loader.
     */
    public CompilationUnit(final GroovyClassLoader loader) {
        this(null, null, loader);
    }

    /**
     * Initializes the CompilationUnit with no security considerations.
     */
    public CompilationUnit(final CompilerConfiguration configuration) {
        this(configuration, null, null);
    }

    /**
     * Initializes the CompilationUnit with a CodeSource for controlling
     * security stuff and a class loader for loading classes.
     */
    public CompilationUnit(final CompilerConfiguration configuration, final CodeSource codeSource, final GroovyClassLoader loader) {
        this(configuration, codeSource, loader, null);
    }

    /**
     * Initializes the CompilationUnit with a CodeSource for controlling
     * security stuff, a class loader for loading classes, and a class
     * loader for loading AST transformations.
     * <p>
     * <b>Note</b>: The transform loader must be able to load compiler classes.
     * That means {@link #classLoader} must be at last a parent to {@code transformLoader}.
     * The other loader has no such constraint.
     *
     * @param transformLoader - the loader for transforms
     * @param loader          - loader used to resolve classes against during compilation
     * @param codeSource      - security setting for the compilation
     * @param configuration   - compilation configuration
     */
    public CompilationUnit(final CompilerConfiguration configuration, final CodeSource codeSource,
                           final GroovyClassLoader loader, final GroovyClassLoader transformLoader) {
        super(configuration, loader, null);

        this.astTransformationsContext = new ASTTransformationsContext(this, transformLoader);
        this.ast = new CompileUnit(getClassLoader(), codeSource, getConfiguration());

        addPhaseOperations();
        applyCompilationCustomizers();
    }

    private void addPhaseOperations() {
        addPhaseOperation(SourceUnit::parse, Phases.PARSING);

        addPhaseOperation(source -> {
            source.convert();
            // add module to compile unit
            getAST().addModule(source.getAST());
            Optional.ofNullable(getProgressCallback())
                .ifPresent(callback -> callback.call(source, getPhase()));
        }, Phases.CONVERSION);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            GroovyClassVisitor visitor = new EnumVisitor(this, source);
            visitor.visitClass(classNode);
        }, Phases.CONVERSION);

        addPhaseOperation(resolve, Phases.SEMANTIC_ANALYSIS);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            GroovyClassVisitor visitor = new StaticImportVisitor(classNode, source);
            visitor.visitClass(classNode);
        }, Phases.SEMANTIC_ANALYSIS);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            GroovyClassVisitor visitor = new InnerClassVisitor(this, source);
            visitor.visitClass(classNode);
        }, Phases.SEMANTIC_ANALYSIS);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            if (!classNode.isSynthetic()) {
                GroovyClassVisitor visitor = new GenericsVisitor(source);
                visitor.visitClass(classNode);
            }
        }, Phases.SEMANTIC_ANALYSIS);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            TraitComposer.doExtendTraits(classNode, source, this);
        }, Phases.CANONICALIZATION);

        addPhaseOperation(source -> {
            List<ClassNode> classes = source.getAST().getClasses();
            for (ClassNode node : classes) {
                CompileUnit cu = node.getCompileUnit();
                for (Iterator<String> it = cu.iterateClassNodeToCompile(); it.hasNext(); ) {
                    String name = it.next();
                    StringBuilder message = new StringBuilder();
                    message
                            .append("Compilation incomplete: expected to find the class ")
                            .append(name)
                            .append(" in ")
                            .append(source.getName());
                    if (classes.isEmpty()) {
                        message.append(", but the file seems not to contain any classes");
                    } else {
                        message.append(", but the file contains the classes: ");
                        boolean first = true;
                        for (ClassNode cn : classes) {
                            if (first) {
                                first = false;
                            } else {
                                message.append(", ");
                            }
                            message.append(cn.getName());
                        }
                    }

                    getErrorCollector().addErrorAndContinue(
                            new SimpleMessage(message.toString(), this)
                    );
                    it.remove();
                }
            }
        }, Phases.CANONICALIZATION);

        addPhaseOperation(classgen, Phases.CLASS_GENERATION);

        addPhaseOperation(groovyClass -> {
            String name = groovyClass.getName().replace('.', File.separatorChar) + ".class";
            File path = new File(getConfiguration().getTargetDirectory(), name);

            // ensure the path is ready for the file
            File directory = path.getParentFile();
            if (directory != null && !directory.exists()) {
                directory.mkdirs();
            }

            // create the file and write out the data
            try (FileOutputStream stream = new FileOutputStream(path)) {
                byte[] bytes = groovyClass.getBytes();
                stream.write(bytes, 0, bytes.length);
            } catch (IOException e) {
                getErrorCollector().addError(Message.create(e.getMessage(), this));
            }
        });

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            AnnotationCollectorTransform.ClassChanger xformer = new AnnotationCollectorTransform.ClassChanger();
            xformer.transformClass(classNode);
        }, Phases.SEMANTIC_ANALYSIS);
        ASTTransformationVisitor.addPhaseOperations(this);

        // post-transform operations:

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            StaticVerifier verifier = new StaticVerifier();
            verifier.visitClass(classNode, source);
        }, Phases.SEMANTIC_ANALYSIS);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            GroovyClassVisitor visitor = new InnerClassCompletionVisitor(this, source);
            visitor.visitClass(classNode);

            visitor = new EnumCompletionVisitor(this, source);
            visitor.visitClass(classNode);
        }, Phases.CANONICALIZATION);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            Object callback = classNode.getNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK);
            if (callback instanceof IPrimaryClassNodeOperation) {
                ((IPrimaryClassNodeOperation) callback).call(source, context, classNode);
                classNode.removeNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK);
            }
        }, Phases.INSTRUCTION_SELECTION);

        addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
            // TODO: Can this be moved into org.codehaus.groovy.transform.sc.transformers.VariableExpressionTransformer?
            GroovyClassVisitor visitor = new ClassCodeExpressionTransformer() {
                @Override
                protected SourceUnit getSourceUnit() {
                    return source;
                }

                @Override
                public Expression transform(final Expression expression) {
                    if (expression instanceof VariableExpression) {
                        // check for "switch(enumType) { case CONST: ... }"
                        ClassNode enumType = expression.getNodeMetaData(SWITCH_CONDITION_EXPRESSION_TYPE);
                        if (enumType != null) {
                            // replace "CONST" variable expression with "EnumType.CONST" property expression
                            Expression propertyExpression = propX(classX(enumType), expression.getText());
                            setSourcePosition(propertyExpression, expression);
                            return propertyExpression;
                        }
                    }
                    return expression;
                }
            };
            visitor.visitClass(classNode);
        }, Phases.INSTRUCTION_SELECTION);
    }

    private void applyCompilationCustomizers() {
        for (CompilationCustomizer customizer : getConfiguration().getCompilationCustomizers()) {
            if (customizer instanceof CompilationUnitAware) {
                ((CompilationUnitAware) customizer).setCompilationUnit(this);
            }
            addPhaseOperation(customizer, customizer.getPhase().getPhaseNumber());
        }
    }

    public void addPhaseOperation(final IGroovyClassOperation op) {
        phaseOperations[Phases.OUTPUT].addFirst(op);
    }

    public void addPhaseOperation(final ISourceUnitOperation op, final int phase) {
        validatePhase(phase);
        phaseOperations[phase].add(op);
    }

    public void addPhaseOperation(final IPrimaryClassNodeOperation op, final int phase) {
        validatePhase(phase);
        phaseOperations[phase].add(op);
    }

    public void addFirstPhaseOperation(final IPrimaryClassNodeOperation op, final int phase) {
        validatePhase(phase);
        phaseOperations[phase].addFirst(op);
    }

    public void addNewPhaseOperation(final ISourceUnitOperation op, final int phase) {
        validatePhase(phase);
        newPhaseOperations[phase].add(op);
    }

    private static void validatePhase(final int phase) {
        if (phase < 1 || phase > Phases.ALL) {
            throw new IllegalArgumentException("phase " + phase + " is unknown");
        }
    }

    /**
     * Configures its debugging mode and classloader classpath from a given compiler configuration.
     * This cannot be done more than once due to limitations in {@link java.net.URLClassLoader URLClassLoader}.
     */
    @Override
    public void configure(final CompilerConfiguration configuration) {
        super.configure(configuration);
        this.debug = getConfiguration().getDebug();
        this.configured = true;
    }

    /**
     * Returns the CompileUnit that roots our AST.
     */
    public CompileUnit getAST() {
        return this.ast;
    }

    /**
     * Get the GroovyClasses generated by compile().
     */
    public List<GroovyClass> getClasses() {
        return generatedClasses;
    }

    /**
     * Convenience routine to get the first ClassNode, for
     * when you are sure there is only one.
     */
    public ClassNode getFirstClassNode() {
        return getAST().getModules().get(0).getClasses().get(0);
    }

    /**
     * Convenience routine to get the named ClassNode.
     */
    public ClassNode getClassNode(final String name) {
        ClassNode[] result = new ClassNode[1];
        IPrimaryClassNodeOperation handler = (source, context, classNode) -> {
            if (classNode.getName().equals(name)) {
                result[0] = classNode;
            }
        };
        try {
            handler.doPhaseOperation(this);
        } catch (CompilationFailedException e) {
            if (debug) e.printStackTrace();
        }
        return result[0];
    }

    /**
     * @return the AST transformations current context
     */
    public ASTTransformationsContext getASTTransformationsContext() {
        return astTransformationsContext;
    }

    public ClassNodeResolver getClassNodeResolver() {
        return classNodeResolver;
    }

    public void setClassNodeResolver(final ClassNodeResolver classNodeResolver) {
        this.classNodeResolver = classNodeResolver;
    }

    public Set<javax.tools.JavaFileObject> getJavaCompilationUnitSet() {
        return javaCompilationUnitSet;
    }

    public void addJavaCompilationUnits(final Set<javax.tools.JavaFileObject> javaCompilationUnitSet) {
        this.javaCompilationUnitSet.addAll(javaCompilationUnitSet);
    }

    /**
     * @return the class loader for loading AST transformations
     */
    public GroovyClassLoader getTransformLoader() {
        return Optional.ofNullable(getASTTransformationsContext().getTransformLoader()).orElseGet(this::getClassLoader);
    }

    //---------------------------------------------------------------------------
    // SOURCE CREATION

    /**
     * Adds a set of file paths to the unit.
     */
    public void addSources(final String[] paths) {
        for (String path : paths) {
            addSource(new File(path));
        }
    }

    /**
     * Adds a set of source files to the unit.
     */
    public void addSources(final File[] files) {
        for (File file : files) {
            addSource(file);
        }
    }

    /**
     * Adds a source file to the unit.
     */
    public SourceUnit addSource(final File file) {
        return addSource(new SourceUnit(file, getConfiguration(), getClassLoader(), getErrorCollector()));
    }

    /**
     * Adds a source file to the unit.
     */
    public SourceUnit addSource(final URL url) {
        return addSource(new SourceUnit(url, getConfiguration(), getClassLoader(), getErrorCollector()));
    }

    /**
     * Adds a InputStream source to the unit.
     */
    public SourceUnit addSource(final String name, final InputStream stream) {
        ReaderSource source = new InputStreamReaderSource(stream, getConfiguration());
        return addSource(new SourceUnit(name, source, getConfiguration(), getClassLoader(), getErrorCollector()));
    }

    public SourceUnit addSource(final String name, final String scriptText) {
        return addSource(new SourceUnit(name, scriptText, getConfiguration(), getClassLoader(), getErrorCollector()));
    }

    /**
     * Adds a SourceUnit to the unit.
     */
    public SourceUnit addSource(final SourceUnit source) {
        String name = source.getName();
        source.setClassLoader(getClassLoader());
        for (SourceUnit su : queuedSources) {
            if (name.equals(su.getName())) return su;
        }
        queuedSources.add(source);
        return source;
    }

    /**
     * Returns an iterator on the unit's SourceUnits.
     */
    public Iterator<SourceUnit> iterator() {
        return new Iterator<SourceUnit>() {
            private Iterator<String> nameIterator = sources.keySet().iterator();
            @Override
            public boolean hasNext() {
                return nameIterator.hasNext();
            }
            @Override
            public SourceUnit next() {
                String name = nameIterator.next();
                return sources.get(name);
            }
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    /**
     * Adds a ClassNode directly to the unit (ie. without source).
     * WARNING: the source is needed for error reporting, using
     * this method without setting a SourceUnit will cause
     * NullPinterExceptions
     */
    public void addClassNode(final ClassNode node) {
        ModuleNode module = new ModuleNode(getAST());
        getAST().addModule(module);
        module.addClass(node);
    }

    //---------------------------------------------------------------------------
    // EXTERNAL CALLBACKS

    /**
     * A callback interface you can use to "accompany" the classgen()
     * code as it traverses the ClassNode tree.  You will be called-back
     * for each primary and inner class.  Use setClassgenCallback() before
     * running compile() to set your callback.
     */
    @FunctionalInterface
    public interface ClassgenCallback {
        void call(ClassVisitor writer, ClassNode node) throws CompilationFailedException;
    }

    public ClassgenCallback getClassgenCallback() {
        return classgenCallback;
    }

    /**
     * Sets a ClassgenCallback.  You can have only one, and setting
     * it to {@code null} removes any existing setting.
     */
    public void setClassgenCallback(final ClassgenCallback visitor) {
        this.classgenCallback = visitor;
    }

    /**
     * A callback interface you can use to get a callback after every
     * unit of the compile process.  You will be called-back with a
     * ProcessingUnit and a phase indicator.  Use setProgressCallback()
     * before running compile() to set your callback.
     */
    @FunctionalInterface
    public interface ProgressCallback {
        void call(ProcessingUnit context, int phase) throws CompilationFailedException;
    }

    public ProgressCallback getProgressCallback() {
        return progressCallback;
    }

    /**
     * Sets a ProgressCallback.  You can have only one, and setting
     * it to {@code null} removes any existing setting.
     */
    public void setProgressCallback(final ProgressCallback callback) {
        this.progressCallback = callback;
    }

    //---------------------------------------------------------------------------
    // ACTIONS

    /**
     * Synonym for {@code compile(Phases.ALL)}.
     */
    public void compile() throws CompilationFailedException {
        compile(Phases.ALL);
    }

    /**
     * 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) {
                resolve.doPhaseOperation(this);
                if (dequeued()) continue;
            }

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

            Optional.ofNullable(getProgressCallback())
                .ifPresent(callback -> callback.call(this, phase));
            completePhase();
            mark();

            if (dequeued()) continue;

            gotoPhase(phase + 1);

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

        getErrorCollector().failIfErrors();
    }

    private void processPhaseOperations(final int phase) {
        for (PhaseOperation op : phaseOperations[phase]) {
            op.doPhaseOperation(this);
        }
    }

    private void processNewPhaseOperations(final int phase) {
        recordPhaseOpsInAllOtherPhases(phase);
        Deque<PhaseOperation> currentPhaseNewOps = newPhaseOperations[phase];
        while (!currentPhaseNewOps.isEmpty()) {
            PhaseOperation operation = currentPhaseNewOps.removeFirst();
            // push this operation to master list and then process it
            phaseOperations[phase].add(operation);
            operation.doPhaseOperation(this);
            // if this operation has brought in more phase ops for ast transforms, keep recording them
            // in master list of other phases and keep processing them for this phase
            recordPhaseOpsInAllOtherPhases(phase);
            currentPhaseNewOps = newPhaseOperations[phase];
        }
    }

    private void recordPhaseOpsInAllOtherPhases(final int phase) {
        // apart from current phase, push new operations for every other phase in the master phase ops list
        for (int ph = Phases.INITIALIZATION; ph <= Phases.ALL; ph += 1) {
            if (ph != phase && !newPhaseOperations[ph].isEmpty()) {
                phaseOperations[ph].addAll(newPhaseOperations[ph]);
                newPhaseOperations[ph].clear();
            }
        }
    }

    private void sortClasses() {
        for (ModuleNode module : getAST().getModules()) {
            module.sortClasses();
        }
    }

    /**
     * Dequeues any source units add through addSource and resets the compiler phase
     * to initialization.
     * <p>
     * Note: this does not mean a file is recompiled. If a SourceUnit has already passed
     * a phase it is skipped until a higher phase is reached.
     *
     * @return true if there was a queued source
     * @throws CompilationFailedException
     */
    protected boolean dequeued() throws CompilationFailedException {
        boolean dequeue = !queuedSources.isEmpty();
        while (!queuedSources.isEmpty()) {
            SourceUnit unit = queuedSources.remove();
            String name = unit.getName();
            sources.put(name, unit);
        }
        if (dequeue) {
            gotoPhase(Phases.INITIALIZATION);
        }
        return dequeue;
    }

    /**
     * Resolves all types.
     */
    private final ISourceUnitOperation resolve = (final SourceUnit source) -> {
        for (ClassNode classNode : source.getAST().getClasses()) {
            GroovyClassVisitor visitor = new VariableScopeVisitor(source);
            visitor.visitClass(classNode);

            resolveVisitor.setClassNodeResolver(classNodeResolver);
            resolveVisitor.startResolving(classNode, source);
        }
    };

    /**
     * Runs {@link #classgen()} on a single {@code ClassNode}.
     */
    private final IPrimaryClassNodeOperation classgen = new IPrimaryClassNodeOperation() {
        @Override
        public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
            new OptimizerVisitor(CompilationUnit.this).visitClass(classNode, source); // GROOVY-4272: repositioned from static import visitor

            //
            // Run the Verifier on the outer class
            //
            GroovyClassVisitor visitor = new Verifier();
            try {
                visitor.visitClass(classNode);
            } catch (RuntimeParserException rpe) {
                getErrorCollector().addError(new SyntaxException(rpe.getMessage(), rpe.getNode()), source);
            }

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

            visitor = new InstanceOfVerifier() {
                @Override
                protected SourceUnit getSourceUnit() {
                    return source;
                }
            };
            visitor.visitClass(classNode);

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

            visitor = new ExtendedVerifier(source);
            visitor.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 classVisitor = 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);
            }

            //
            // Run the generation and create the class (if required)
            //
            visitor = new AsmClassGenerator(source, context, classVisitor, sourceName);
            visitor.visitClass(classNode);

            byte[] bytes = ((ClassWriter) classVisitor).toByteArray();
            getClasses().add(new GroovyClass(classNode.getName(), bytes));

            //
            // Handle any callback that's been set
            //
            Optional.ofNullable(getClassgenCallback())
                .ifPresent(callback -> callback.call(classVisitor, classNode));

            //
            // Recurse for inner classes
            //
            LinkedList<ClassNode> innerClasses = ((AsmClassGenerator) visitor).getInnerClasses();
            while (!innerClasses.isEmpty()) {
                classgen.call(source, context, innerClasses.removeFirst());
            }
        }

        @Override
        public boolean needSortedInput() {
            return true;
        }
    };

    protected ClassVisitor createClassVisitor() {
        CompilerConfiguration config = getConfiguration();
        int computeMaxStackAndFrames = ClassWriter.COMPUTE_MAXS;
        if (CompilerConfiguration.isPostJDK7(config.getTargetBytecode()) || config.isIndyEnabled()) {
            computeMaxStackAndFrames += ClassWriter.COMPUTE_FRAMES;
        }
        return new ClassWriter(computeMaxStackAndFrames) {
            private ClassNode getClassNode(String name) {
                // try classes under compilation
                CompileUnit cu = getAST();
                ClassNode cn = cu.getClass(name);
                if (cn != null) return cn;
                // try inner classes
                cn = cu.getGeneratedInnerClass(name);
                if (cn != null) return cn;
                ClassNodeResolver.LookupResult lookupResult = getClassNodeResolver().resolveName(name, CompilationUnit.this);
                return lookupResult == null ? null : lookupResult.getClassNode();
            }
            private ClassNode getCommonSuperClassNode(ClassNode c, ClassNode d) {
                // adapted from ClassWriter code
                if (c.isDerivedFrom(d)) return d;
                if (d.isDerivedFrom(c)) return c;
                if (c.isInterface() || d.isInterface()) return ClassHelper.OBJECT_TYPE;
                do {
                    c = c.getSuperClass();
                } while (c != null && !d.isDerivedFrom(c));
                if (c == null) return ClassHelper.OBJECT_TYPE;
                return c;
            }
            @Override
            protected String getCommonSuperClass(String arg1, String arg2) {
                ClassNode a = getClassNode(arg1.replace('/', '.'));
                ClassNode b = getClassNode(arg2.replace('/', '.'));
                return getCommonSuperClassNode(a,b).getName().replace('.','/');
            }
        };
    }

    //---------------------------------------------------------------------------
    // PHASE HANDLING

    /**
     * Updates the phase marker on all sources.
     */
    protected void mark() throws CompilationFailedException {
        ISourceUnitOperation mark = (final SourceUnit source) -> {
            if (source.phase < phase) {
                source.gotoPhase(phase);
            }
            if (source.phase == phase && phaseComplete && !source.phaseComplete) {
                source.completePhase();
            }
        };
        mark.doPhaseOperation(this);
    }

    //---------------------------------------------------------------------------
    // LOOP SIMPLIFICATION FOR SourceUnit OPERATIONS

    private interface PhaseOperation {
        void doPhaseOperation(CompilationUnit unit);
    }

    @FunctionalInterface
    public interface ISourceUnitOperation extends PhaseOperation {
        void call(SourceUnit source) throws CompilationFailedException;

        /**
         * A loop driver for applying operations to all SourceUnits.
         * Automatically skips units that have already been processed
         * through the current phase.
         */
        @Override
        default void doPhaseOperation(final CompilationUnit unit) throws CompilationFailedException {
            for (String name : unit.sources.keySet()) {
                SourceUnit source = unit.sources.get(name);
                if (source.phase < unit.phase || (source.phase == unit.phase && !source.phaseComplete)) {
                    try {
                        this.call(source);
                    } catch (CompilationFailedException e) {
                        throw e;
                    } catch (Exception e) {
                        GroovyBugError gbe = new GroovyBugError(e);
                        unit.changeBugText(gbe, source);
                        throw gbe;
                    } catch (GroovyBugError e) {
                        unit.changeBugText(e, source);
                        throw e;
                    }
                }
            }
            unit.getErrorCollector().failIfErrors();
        }
    }

    //---------------------------------------------------------------------------
    // LOOP SIMPLIFICATION FOR PRIMARY ClassNode OPERATIONS

    @FunctionalInterface
    public interface IPrimaryClassNodeOperation extends PhaseOperation {
        void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException;

        /**
         * 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.
         */
        @Override
        default void doPhaseOperation(final CompilationUnit unit) throws CompilationFailedException {
            for (ClassNode classNode : unit.getPrimaryClassNodes(this.needSortedInput())) {
                SourceUnit context = null;
                try {
                    context = classNode.getModule().getContext();
                    if (context == null || context.phase < unit.phase || (context.phase == unit.phase && !context.phaseComplete)) {
                        int offset = 1;
                        for (Iterator<InnerClassNode> it = classNode.getInnerClasses(); it.hasNext(); ) {
                            it.next();
                            offset += 1;
                        }
                        this.call(context, new GeneratorContext(unit.getAST(), offset), classNode);
                    }
                } catch (CompilationFailedException e) {
                    // fall through
                } catch (NullPointerException npe) {
                    GroovyBugError gbe = new GroovyBugError("unexpected NullPointerException", npe);
                    unit.changeBugText(gbe, context);
                    throw gbe;
                } catch (GroovyBugError e) {
                    unit.changeBugText(e, context);
                    throw e;
                } catch (Exception | LinkageError e) {
                    ErrorCollector errorCollector = null;
                    // check for a nested compilation exception
                    for (Throwable t = e.getCause(); t != e && t != null; t = t.getCause()) {
                        if (t instanceof MultipleCompilationErrorsException) {
                            errorCollector = ((MultipleCompilationErrorsException) t).getErrorCollector();
                            break;
                        }
                    }

                    if (errorCollector != null) {
                        unit.getErrorCollector().addCollectorContents(errorCollector);
                    } else if (context != null) {
                        unit.getErrorCollector().addException(e instanceof Exception ? (Exception) e : new RuntimeException(e), context);
                    } else {
                        unit.getErrorCollector().addError(new ExceptionMessage(e instanceof Exception ? (Exception) e : new RuntimeException(e), unit.debug, unit));
                    }
                }
            }
            unit.getErrorCollector().failIfErrors();
        }

        default boolean needSortedInput() {
            return false;
        }
    }

    @FunctionalInterface
    public interface IGroovyClassOperation extends PhaseOperation {
        void call(GroovyClass groovyClass) throws CompilationFailedException;

        @Override
        default void doPhaseOperation(final CompilationUnit unit) throws CompilationFailedException {
            if (unit.phase != Phases.OUTPUT && !(unit.phase == Phases.CLASS_GENERATION && unit.phaseComplete)) {
                throw new GroovyBugError("CompilationUnit not ready for output(). Current phase=" + unit.getPhaseDescription());
            }

            for (GroovyClass groovyClass : unit.getClasses()) {
                try {
                    this.call(groovyClass);
                } catch (CompilationFailedException e) {
                    // fall through
                } catch (NullPointerException npe) {
                    throw npe;
                } catch (GroovyBugError e) {
                    unit.changeBugText(e, null);
                    throw e;
                } catch (Exception e) {
                    throw new GroovyBugError(e);
                }
            }
            unit.getErrorCollector().failIfErrors();
        }
    }

    private static int getSuperClassCount(ClassNode classNode) {
        int count = 0;
        while (classNode != null) {
            count += 1;
            classNode = classNode.getSuperClass();
        }
        return count;
    }

    private static int getSuperInterfaceCount(final ClassNode classNode) {
        int count = 1;
        for (ClassNode face : classNode.getInterfaces()) {
            count = Math.max(count, getSuperInterfaceCount(face) + 1);
        }
        return count;
    }

    private List<ClassNode> getPrimaryClassNodes(final boolean sort) {
        List<ClassNode> unsorted = getAST().getModules().stream()
            .flatMap(module -> module.getClasses().stream()).collect(toList());

        if (!sort) return unsorted;

        int n = unsorted.size();
        int[] indexClass = new int[n];
        int[] indexInterface = new int[n];
        {
            int i = 0;
            for (ClassNode element : unsorted) {
                if (element.isInterface()) {
                    indexInterface[i] = getSuperInterfaceCount(element);
                    indexClass[i] = -1;
                } else {
                    indexClass[i] = getSuperClassCount(element);
                    indexInterface[i] = -1;
                }
                i += 1;
            }
        }

        List<ClassNode> sorted = getSorted(indexInterface, unsorted);
        sorted.addAll(getSorted(indexClass, unsorted));
        return sorted;
    }

    private static List<ClassNode> getSorted(final int[] index, final List<ClassNode> unsorted) {
        int unsortedSize = unsorted.size();
        List<ClassNode> sorted = new ArrayList<>(unsortedSize);
        for (int i = 0; i < unsortedSize; i += 1) {
            int min = -1;
            for (int j = 0; j < unsortedSize; j += 1) {
                if (index[j] == -1) continue;
                if (min == -1 || index[j] < index[min]) {
                    min = j;
                }
            }
            if (min == -1) break;
            sorted.add(unsorted.get(min));
            index[min] = -1;
        }
        return sorted;
    }

    private void changeBugText(final GroovyBugError e, final SourceUnit context) {
        e.setBugText("exception in phase '" + getPhaseDescription() + "' in source unit '" + (context != null ? context.getName() : "?") + "' " + e.getBugText());
    }

    //--------------------------------------------------------------------------

    @Deprecated
    public void addPhaseOperation(final GroovyClassOperation op) {
        addPhaseOperation((IGroovyClassOperation) op);
    }

    @Deprecated
    public void addPhaseOperation(final SourceUnitOperation op, final int phase) {
        addPhaseOperation((ISourceUnitOperation) op, phase);
    }

    @Deprecated
    public void addPhaseOperation(final PrimaryClassNodeOperation op, final int phase) {
        addPhaseOperation((IPrimaryClassNodeOperation) op, phase);
    }

    @Deprecated
    public void addFirstPhaseOperation(final PrimaryClassNodeOperation op, final int phase) {
        addFirstPhaseOperation((IPrimaryClassNodeOperation) op, phase);
    }

    @Deprecated
    public void addNewPhaseOperation(final SourceUnitOperation op, final int phase) {
        addNewPhaseOperation((ISourceUnitOperation) op, phase);
    }

    @Deprecated // IntelliJ IDEA depends on the API
    public void applyToPrimaryClassNodes(final PrimaryClassNodeOperation op) throws CompilationFailedException {
        op.doPhaseOperation(this);
    }

    @Deprecated
    public void applyToSourceUnits(final SourceUnitOperation op) throws CompilationFailedException {
        op.doPhaseOperation(this);
    }

    @Deprecated
    public abstract static class SourceUnitOperation implements ISourceUnitOperation {
    }

    @Deprecated
    public abstract static class GroovyClassOperation implements IGroovyClassOperation {
    }

    @Deprecated
    public abstract static class PrimaryClassNodeOperation implements IPrimaryClassNodeOperation {
    }
}
