Compile a CompilationUnit if dirty.

@param unit CompilationUnit
@return true if the CompilationUnit was dirty
@throws IOException
342453
private boolean compileIfDirty(CompilationUnit unit) throws IOException {
        if (isDirty(unit)) {
            logger.debug("compiling less: {}", unit);
            long start = System.currentTimeMillis();

            try {
                String sourceMapFileName = unit.getSourceMapFile() != null ? unit.getSourceMapFile().getPath() : null;
                CompilationDetails compilationResult = lessCompiler.compileWithDetails(unit.getSourceAsString(), unit.getResourceReader(), unit.getOptions(), unit.getSourceLocation(), unit.getDestination().getPath(), sourceMapFileName);
                if (unit.getDestination() != null) {
                    unit.getDestination().getAbsoluteFile().getParentFile().mkdirs();
                    IOUtils.writeFile(compilationResult.getResult(), unit.getDestination(), unit.getEncoding());
                }
                if (unit.getSourceMapFile() != null && compilationResult.getSourceMap() != null) {
                    unit.getSourceMapFile().getAbsoluteFile().getParentFile().mkdirs();
                    IOUtils.writeFile(compilationResult.getSourceMap(), unit.getSourceMapFile(), unit.getEncoding());
                }
                updateImportsAndCache(unit, compilationResult.getImports());
                logger.info("compilation of less {} finished in {} millis", unit, System.currentTimeMillis() - start);
                return true;
            } catch (LessParseException e) {
                unit.setExceptionTimestamp(System.currentTimeMillis());
                cache(unit);
                throw e;
            }
        }
        return false;
    }
915131
private void compile(ICompilationUnit[] sourceUnits, boolean lastRound) {
        this.stats.startTime = System.currentTimeMillis();
        try {
            // build and record parsed units
            reportProgress(Messages.compilation_beginningToCompile);

            if (this.options.complianceLevel >= ClassFileConstants.JDK9) {
                // in Java 9 the compiler must never ask the oracle for a module that is contained in the input units:
                sortModuleDeclarationsFirst(sourceUnits);
            }
            if (this.annotationProcessorManager == null) {
                beginToCompile(sourceUnits);
            } else {
                ICompilationUnit[] originalUnits = sourceUnits.clone(); // remember source units in case a source type collision occurs
                try {
                    beginToCompile(sourceUnits);
                    if (!lastRound) {
                        processAnnotations();
                    }
                    if (!this.options.generateClassFiles) {
                        // -proc:only was set on the command line
                        return;
                    }
                } catch (SourceTypeCollisionException e) {
                    backupAptProblems();
                    reset();
                    // a generated type was referenced before it was created
                    // the compiler either created a MissingType or found a BinaryType for it
                    // so add the processor's generated files & start over,
                    // but remember to only pass the generated files to the annotation processor
                    int originalLength = originalUnits.length;
                    int newProcessedLength = e.newAnnotationProcessorUnits.length;
                    ICompilationUnit[] combinedUnits = new ICompilationUnit[originalLength + newProcessedLength];
                    System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength);
                    System.arraycopy(e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength);
                    this.annotationProcessorStartIndex  = originalLength;
                    compile(combinedUnits, e.isLastRound);
                    return;
                }
            }
            // Restore the problems before the results are processed and cleaned up.
            restoreAptProblems();
            processCompiledUnits(0, lastRound);
        } catch (AbortCompilation e) {
            this.handleInternalException(e, null);
        }
        if (this.options.verbose) {
            if (this.totalUnits > 1) {
                this.out.println(
                        Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits)));
            } else {
                this.out.println(
                        Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits)));
            }
        }
    }
365778
public Class<?> compile(String className, String code, ClassLoader classLoader, OutputStream os, long lastModify) {
        code = code.trim();
        try {
            return Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException e) {
            if (!code.endsWith("}")) {
                throw new IllegalStateException("The java code not endsWith \"}\", code: \n" + code + "\n");
            }
            try {
                return doCompile(className, code, os);
            } catch (RuntimeException t) {
                throw t;
            } catch (Throwable t) {
                throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: "
                        + className + ", code: \n" + code + "\n, stack: " + ClassUtils.toString(t));
            }
        }
    }
88793
public static void dumpUnit(CompilationUnit unit) {
    String relativeOutputPath = unit.getMainTypeName().replace('.', '/') + ".ast";
    File outputFile = new File(
        unit.getEnv().options().fileUtil().getOutputDirectory(), relativeOutputPath);
    outputFile.getParentFile().mkdirs();

    try (FileOutputStream fout = new FileOutputStream(outputFile);
        OutputStreamWriter out = new OutputStreamWriter(fout, "UTF-8")) {
      out.write(dump(unit));
    } catch (IOException e) {
      ErrorUtil.fatalError(e, outputFile.getPath());
    }
  }
1222547
public void addClassNodeToCompile(ClassNode node, SourceUnit location) {
        String nodeName = node.getName();
        classesToCompile.put(nodeName, node);
        classNameToSource.put(nodeName, location);
    }
354034
protected SourceReader createSourceReader(CompilationUnit unit)
    throws IOException {

        Reader r = new BufferedReader(unit.getReader());
        return new SourceReader(r, "<%", "%>");
    }
945826
@SuppressWarnings( "unchecked" )
    protected List<TypeMetadata> createTypeMetadata( CompilationUnit unit ) {
        List<TypeMetadata> metadata = new ArrayList<TypeMetadata>();
        List<AbstractTypeDeclaration> topLevelType = unit.types();

        for (AbstractTypeDeclaration abstractTypeDeclaration : topLevelType) {
            // process TypeDeclaration (class, interface)
            if (abstractTypeDeclaration instanceof TypeDeclaration) {
                TypeDeclaration typeDeclaration = (TypeDeclaration)abstractTypeDeclaration;
                if (typeDeclaration.isInterface()) {
                    // is an interface top level type
                    TypeMetadata interfaceMetadata = TypeMetadata.interfaceType(JavaMetadataUtil.getName(typeDeclaration.getName()));

                    // detect the interfaces, if any
                    for (Type superInterfaceType : (List<Type>)typeDeclaration.superInterfaceTypes()) {
                        interfaceMetadata.getInterfaceNames().add(getTypeName(superInterfaceType));
                    }

                    metadata.add(interfaceMetadata);
                } else {
                    // is a class top level type
                    TypeMetadata classMetadata = TypeMetadata.classType(JavaMetadataUtil.getName(typeDeclaration.getName()));
                    processModifiersOfTypeDeclaration(typeDeclaration, classMetadata);

                    // set the superclass, if any
                    Type superClassType = typeDeclaration.getSuperclassType();
                    if (superClassType != null) {
                        classMetadata.setSuperTypeName(getTypeName(superClassType));
                    }

                    // detect the interfaces, if any
                    for (Type superInterfaceType : (List<Type>)typeDeclaration.superInterfaceTypes()) {
                        classMetadata.getInterfaceNames().add(getTypeName(superInterfaceType));
                    }

                    // fields of the class top level type
                    FieldDeclaration[] fieldDeclarations = typeDeclaration.getFields();
                    for (FieldDeclaration fieldDeclaration : fieldDeclarations) {
                        FieldMetadata fieldMetadata = getFieldMetadataFrom(fieldDeclaration);
                        classMetadata.getFields().add(fieldMetadata);
                    }
                    // methods of the class top level type
                    MethodDeclaration[] methodDeclarations = typeDeclaration.getMethods();
                    for (MethodDeclaration methodDeclaration : methodDeclarations) {
                        MethodMetadata methodMetadata = getMethodMetadataFrom(methodDeclaration);
                        classMetadata.getMethods().add(methodMetadata);
                    }
                    metadata.add(classMetadata);
                }
            }

            // process EnumDeclaration
            if (abstractTypeDeclaration instanceof EnumDeclaration) {
                EnumDeclaration enumDeclaration = (EnumDeclaration)abstractTypeDeclaration;

                // is a class top level type
                EnumMetadata enumMetadata = TypeMetadata.enumType(JavaMetadataUtil.getName(enumDeclaration.getName()));
                processModifiersOfTypeDeclaration(enumDeclaration, enumMetadata);

                // Store the enum values
                List<EnumConstantDeclaration> enumValues = enumDeclaration.enumConstants();
                for (EnumConstantDeclaration enumValue : enumValues) {
                    enumMetadata.getValues().add(enumValue.getName().getIdentifier());
                }

                // Enums don't have superclasses

                // detect the interfaces, if any
                for (Type superInterfaceType : (List<Type>)enumDeclaration.superInterfaceTypes()) {
                    enumMetadata.getInterfaceNames().add(getTypeName(superInterfaceType));
                }

                /*
                 * It would be nice to be able to reuse the convenience methods from AbstractTypeDeclaration,
                 * but they don't exist in EnumDeclaration.  So we improvise!
                 */

                List<BodyDeclaration> bodyDecls = enumDeclaration.bodyDeclarations();
                for (BodyDeclaration bodyDecl : bodyDecls) {
                    if (bodyDecl instanceof FieldDeclaration) {
                        // fields of the class top level type
                        FieldMetadata fieldMetadata = getFieldMetadataFrom((FieldDeclaration)bodyDecl);
                        enumMetadata.getFields().add(fieldMetadata);
                    } else if (bodyDecl instanceof MethodDeclaration) {
                        // methods of the class top level type
                        MethodMetadata methodMetadata = getMethodMetadataFrom((MethodDeclaration)bodyDecl);
                        enumMetadata.getMethods().add(methodMetadata);
                    }
                }

                metadata.add(enumMetadata);
            }

            // process annotationTypeDeclaration
            if (abstractTypeDeclaration instanceof AnnotationTypeDeclaration) {
                // AnnotationTypeDeclaration annotationTypeDeclaration = (AnnotationTypeDeclaration)abstractTypeDeclaration;
                // TODO get infos from annotation type declaration and create a annotation meta data object.
            }
        }
        return metadata;
    }
853121
public boolean compile(Job job) throws IOException {
        boolean result;

        currentJob = job;
        result = compileCurrent();
        currentJob = null;
        return result;
    }
314487
@Override
   public boolean compileFiles(String[] files)
   {
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
      if (compiler == null) {
         throw new IllegalStateException(
                 "No compiler detected, make sure you are running on top of a JDK instead of a JRE.");
      }
      StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
      Iterable<? extends JavaFileObject> fileList = fileManager.getJavaFileObjectsFromStrings(Arrays
              .asList(files));

      return internalCompile(compiler, wrapJavaFileManager(fileManager), setupDiagnosticListener(),
              fileList);
   }
40421
public <T> ListT<W,T> unit(final T unit) {
        return of(run.unit(ListX.of(unit)));
    }
1322285
public void compile(String name, String code) throws CompilationFailedException {
        CompilationUnit unit = new CompilationUnit(configuration);
        unit.addSource(new SourceUnit(name, code, configuration, unit.getClassLoader(), unit.getErrorCollector()));
        unit.compile();
    }
986177
public Output compileFile(URI inputPath, URI outputPath, Options options)
      throws CompilationException {
    FileContext context = new FileContext(inputPath, outputPath, options);
    return compile(context);
  }
698514
@Override
    public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
        // Switch the current policy and compilation result for this unit to the requested one.
        CompilationResult unitResult =
            new CompilationResult(sourceUnit, this.totalUnits, this.totalUnits, this.options.maxProblemsPerUnit);
        unitResult.checkSecondaryTypes = true;
        try {
            if (this.options.verbose) {
                String count = String.valueOf(this.totalUnits + 1);
                this.out.println(
                    Messages.bind(Messages.compilation_request,
                        new String[] {
                            count,
                            count,
                            new String(sourceUnit.getFileName())
                        }));
            }
            // diet parsing for large collection of unit
            CompilationUnitDeclaration parsedUnit;
            if (this.totalUnits < this.parseThreshold) {
                parsedUnit = this.parser.parse(sourceUnit, unitResult);
            } else {
                parsedUnit = this.parser.dietParse(sourceUnit, unitResult);
            }
            // initial type binding creation
            this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
            addCompilationUnit(sourceUnit, parsedUnit);

            // binding resolution
            this.lookupEnvironment.completeTypeBindings(parsedUnit);
        } catch (AbortCompilationUnit e) {
            // at this point, currentCompilationUnitResult may not be sourceUnit, but some other
            // one requested further along to resolve sourceUnit.
            if (unitResult.compilationUnit == sourceUnit) { // only report once
                this.requestor.acceptResult(unitResult.tagAsAccepted());
            } else {
                throw e; // want to abort enclosing request to compile
            }
        }
    }
100978
@Override
    public synchronized Class<?> doCompile(String name, String sourceCode, OutputStream os) throws Throwable {

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Begin to compile source code: class is '{}'", name);
        }

        int i = name.lastIndexOf('.');
        String packageName = i < 0 ? "" : name.substring(0, i);
        String className = i < 0 ? name : name.substring(i + 1);
        JavaFileObjectImpl javaFileObject = new JavaFileObjectImpl(className, sourceCode);
        javaFileManager.putFileForInput(StandardLocation.SOURCE_PATH, packageName,
                className + ClassUtils.JAVA_EXTENSION, javaFileObject);

        DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<JavaFileObject>();
        Boolean result = compiler.getTask(null, javaFileManager, diagnosticCollector, options, null,
                Arrays.asList(new JavaFileObject[] { javaFileObject })).call();
        if (result == null || !result.booleanValue()) {
            throw new IllegalStateException(
                    "Compilation failed. class: " + name + ", diagnostics: " + diagnosticCollector.getDiagnostics());
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("compile source code done: class is '{}'", name);
            LOGGER.debug("loading class '{}'", name);
        }

        Class<?> retClass = classLoader.loadClass(name);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("loading class done  '{}'", name);
        }

        if (os != null) {
            byte[] bytes = classLoader.loadClassBytes(name);
            if (bytes != null) {
                os.write(bytes);
                os.flush();
            }
        }
        return retClass;
    }
1021253
protected synchronized boolean needsCompile(List<File> sources, File outputDir) throws IOException {
        if (!outputDir.isDirectory())
            return true;

        newestClassFile = null;
        Files.walkFileTree(Paths.get(outputDir.getPath()),
            EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
                public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
                    if (path.toString().endsWith(".class")) {
                        File classFile = path.toFile();
                        if (newestClassFile == null || classFile.lastModified() > newestClassFile.lastModified())
                            newestClassFile = classFile;
                    }
                    return FileVisitResult.CONTINUE;
                }
            }
        );
        if (newestClassFile == null)
            return true;  // nothing compiled

        File newestSourceFile = null;
        for (File source : sources) {
            if (newestSourceFile == null || source.lastModified() > newestSourceFile.lastModified())
                newestSourceFile = source;
        }
        for (Asset jar : AssetCache.getJarAssets()) {
            if (newestSourceFile == null || jar.file().lastModified() > newestSourceFile.lastModified())
                newestSourceFile = jar.file();
        }

        boolean needsCompile = newestSourceFile.lastModified() >= newestClassFile.lastModified();
        if (logger.isDebugEnabled()) {
            if (needsCompile)
                logger.debug("Kt needs compile due to " + newestSourceFile + " >= " + newestClassFile);
            else
                logger.debug("Kt no compile due to " + newestSourceFile + " < " + newestClassFile);
        }
        return needsCompile;
    }
763344
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();
    }
427575
public static String getQualifiedMainTypeName(CompilationUnit unit) {
    PackageDeclaration pkg = unit.getPackage();
    if (pkg.isDefaultPackage()) {
      return unit.getMainTypeName();
    } else {
      return pkg.getName().getFullyQualifiedName() + '.' + unit.getMainTypeName();
    }
  }