private static Map<File, Set<File>> buildOutputDirectoriesMap( CompileContext context, ModuleChunk chunk) { final Map<File, Set<File>> map = new THashMap<File, Set<File>>(FileUtil.FILE_HASHING_STRATEGY); for (ModuleBuildTarget target : chunk.getTargets()) { final File outputDir = target.getOutputDir(); if (outputDir == null) { continue; } final Set<File> roots = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY); for (JavaSourceRootDescriptor descriptor : context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context)) { roots.add(descriptor.root); } map.put(outputDir, roots); } return map; }
private ExitCode compile( final CompileContext context, ModuleChunk chunk, DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder, Collection<File> files, OutputConsumer outputConsumer) throws Exception { ExitCode exitCode = ExitCode.NOTHING_DONE; final boolean hasSourcesToCompile = !files.isEmpty(); if (!hasSourcesToCompile && !dirtyFilesHolder.hasRemovedFiles()) { return exitCode; } final ProjectDescriptor pd = context.getProjectDescriptor(); JavaBuilderUtil.ensureModuleHasJdk( chunk.representativeTarget().getModule(), context, BUILDER_NAME); final Collection<File> classpath = ProjectPaths.getCompilationClasspath(chunk, false /*context.isProjectRebuild()*/); final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false /*context.isProjectRebuild()*/); // begin compilation round final DiagnosticSink diagnosticSink = new DiagnosticSink(context); final Mappings delta = pd.dataManager.getMappings().createDelta(); final Callbacks.Backend mappingsCallback = delta.getCallback(); final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getName()); try { if (hasSourcesToCompile) { final AtomicReference<String> ref = COMPILER_VERSION_INFO.get(context); final String versionInfo = ref.getAndSet(null); // display compiler version info only once per compile session if (versionInfo != null) { LOG.info(versionInfo); context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, versionInfo)); } exitCode = ExitCode.OK; final Set<File> srcPath = new HashSet<File>(); final BuildRootIndex index = pd.getBuildRootIndex(); for (ModuleBuildTarget target : chunk.getTargets()) { for (JavaSourceRootDescriptor rd : index.getTempTargetRoots(target, context)) { srcPath.add(rd.root); } } final String chunkName = chunk.getName(); context.processMessage(new ProgressMessage("Parsing java... [" + chunkName + "]")); final int filesCount = files.size(); boolean compiledOk = true; if (filesCount > 0) { LOG.info( "Compiling " + filesCount + " java files; module: " + chunkName + (chunk.containsTests() ? " (tests)" : "")); if (LOG.isDebugEnabled()) { for (File file : files) { LOG.debug("Compiling " + file.getPath()); } LOG.debug(" classpath for " + chunkName + ":"); for (File file : classpath) { LOG.debug(" " + file.getAbsolutePath()); } LOG.debug(" platform classpath for " + chunkName + ":"); for (File file : platformCp) { LOG.debug(" " + file.getAbsolutePath()); } } compiledOk = compileJava( context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink); } context.checkCanceled(); if (!compiledOk && diagnosticSink.getErrorCount() == 0) { diagnosticSink.report( new PlainMessageDiagnostic( Diagnostic.Kind.ERROR, "Compilation failed: internal java compiler error")); } if (!Utils.PROCEED_ON_ERROR_KEY.get(context, Boolean.FALSE) && diagnosticSink.getErrorCount() > 0) { if (!compiledOk) { diagnosticSink.report( new PlainMessageDiagnostic( Diagnostic.Kind.OTHER, "Errors occurred while compiling module '" + chunkName + "'")); } throw new ProjectBuildException( "Compilation failed: errors: " + diagnosticSink.getErrorCount() + "; warnings: " + diagnosticSink.getWarningCount()); } } } finally { if (JavaBuilderUtil.updateMappings( context, delta, dirtyFilesHolder, chunk, files, outputSink.getSuccessfullyCompiled())) { exitCode = ExitCode.ADDITIONAL_PASS_REQUIRED; } } return exitCode; }