diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 374d25888ca4..da2282d82411 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -2364,21 +2364,23 @@ public class CompileDriver { modulesWithoutOutputPathSpecified.add(module.getName()); } } - if (config.getAnnotationProcessingConfiguration(module).isEnabled()) { - final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module); - if (path == null) { - final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(module.getProject()); - if (extension == null || extension.getCompilerOutputUrl() == null) { - isProjectCompilePathSpecified = false; + if (!useOutOfProcessBuild()) { + if (config.getAnnotationProcessingConfiguration(module).isEnabled()) { + final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module); + if (path == null) { + final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(module.getProject()); + if (extension == null || extension.getCompilerOutputUrl() == null) { + isProjectCompilePathSpecified = false; + } + else { + modulesWithoutOutputPathSpecified.add(module.getName()); + } } else { - modulesWithoutOutputPathSpecified.add(module.getName()); - } - } - else { - final File file = new File(path); - if (!file.exists()) { - nonExistingOutputPaths.add(file); + final File file = new File(path); + if (!file.exists()) { + nonExistingOutputPaths.add(file); + } } } } @@ -2456,12 +2458,10 @@ public class CompileDriver { if (chunkModules.size() <= 1) { continue; // no need to check one-module chunks } - if (!useOutOfProcessBuild()) { - for (Module chunkModule : chunkModules) { - if (config.getAnnotationProcessingConfiguration(chunkModule).isEnabled()) { - showCyclesNotSupportedForAnnotationProcessors(chunkModules.toArray(new Module[chunkModules.size()])); - return false; - } + for (Module chunkModule : chunkModules) { + if (config.getAnnotationProcessingConfiguration(chunkModule).isEnabled()) { + showCyclesNotSupportedForAnnotationProcessors(chunkModules.toArray(new Module[chunkModules.size()])); + return false; } } Sdk jdk = null; diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java b/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java index 867317d8bbc3..dd5dce226359 100644 --- a/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java +++ b/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java @@ -115,7 +115,7 @@ public class ProcessorProfilePanel extends JPanel { final JLabel warning = new JLabel("WARNING!
" + /*"All source files located in the generated sources output directory WILL BE EXCLUDED from annotation processing. " +*/ "If option 'Clear output directory on rebuild' is enabled, " + - "the entire contents of directories specified in the table below WILL BE CLEARED on rebuild."); + "the entire contents of directories where generated sources are stored WILL BE CLEARED on rebuild."); warning.setFont(warning.getFont().deriveFont(Font.BOLD)); add(myCbEnableProcessing, diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index c6121dcbf8ab..91ccb8ac3f85 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -294,19 +294,36 @@ public class IncProjectBuilder { private static void clearOutputs(CompileContext context) throws ProjectBuildException, IOException { final Collection modulesToClean = context.getProject().getModules().values(); - final Map>> rootsToDelete = - new HashMap>>(); // map: outputRoot-> setOfPairs([module, isTest]) + final Map>> rootsToDelete = new HashMap>>(); // map: outputRoot-> setOfPairs([module, isTest]) + final Set annotationOutputs = new HashSet(); // separate collection because no root intersection checks needed for annotation generated sources final Set allSourceRoots = new HashSet(); + final ProjectPaths paths = context.getProjectPaths(); + for (Module module : modulesToClean) { - final File out = context.getProjectPaths().getModuleOutputDir(module, false); + final File out = paths.getModuleOutputDir(module, false); if (out != null) { appendRootInfo(rootsToDelete, out, module, false); } - final File testOut = context.getProjectPaths().getModuleOutputDir(module, true); + final File testOut = paths.getModuleOutputDir(module, true); if (testOut != null) { appendRootInfo(rootsToDelete, testOut, module, true); } + + final AnnotationProcessingProfile profile = context.getAnnotationProcessingProfile(module); + if (profile.isEnabled()) { + File annotationOut = + paths.getAnnotationProcessorGeneratedSourcesOutputDir(module, false, profile.getGeneratedSourcesDirName()); + if (annotationOut != null) { + annotationOutputs.add(annotationOut); + } + annotationOut = + paths.getAnnotationProcessorGeneratedSourcesOutputDir(module, true, profile.getGeneratedSourcesDirName()); + if (annotationOut != null) { + annotationOutputs.add(annotationOut); + } + } + final List moduleRoots = context.getModuleRoots(module); for (RootDescriptor d : moduleRoots) { allSourceRoots.add(d.root); @@ -349,6 +366,14 @@ public class IncProjectBuilder { } } + for (File annotationOutput : annotationOutputs) { + // do not delete output root itself to avoid lots of unnecessary "roots_changed" events in IDEA + final File[] children = annotationOutput.listFiles(); + if (children != null) { + filesToDelete.addAll(Arrays.asList(children)); + } + } + context.processMessage(new ProgressMessage("Cleaning output directories...")); FileUtil.asyncDelete(filesToDelete); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 644987d4c892..ccc51cacea7d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -109,7 +109,7 @@ public class JavaBuilder extends ModuleLevelBuilder { } } out.setTemp(isTemp); - if (!isTemp) { + if (!isTemp && out.getKind() == JavaFileObject.Kind.CLASS) { final Callbacks.Backend callback = DELTA_MAPPINGS_CALLBACK_KEY.get(context); if (callback != null) { final ClassReader reader = new ClassReader(content.getBuffer(), content.getOffset(), content.getLength()); @@ -267,7 +267,6 @@ public class JavaBuilder extends ModuleLevelBuilder { paths.getCompilationClasspath(chunk, context.isCompilingTests(), false/*context.isProjectRebuild()*/); final Collection platformCp = paths.getPlatformCompilationClasspath(chunk, context.isCompilingTests(), false/*context.isProjectRebuild()*/); - final Map> outs = buildOutputDirectoriesMap(context, chunk); // begin compilation round final DiagnosticSink diagnosticSink = new DiagnosticSink(context); @@ -294,7 +293,7 @@ public class JavaBuilder extends ModuleLevelBuilder { boolean compiledOk = true; if (filesCount > 0) { LOG.info("Compiling " + filesCount + " java files; module: " + chunkName); - compiledOk = compileJava(chunk, files, classpath, platformCp, tempRootsSourcePath, outs, context, diagnosticSink, outputSink); + compiledOk = compileJava(context, chunk, files, classpath, platformCp, tempRootsSourcePath, diagnosticSink, outputSink); } context.checkCanceled(); @@ -386,18 +385,35 @@ public class JavaBuilder extends ModuleLevelBuilder { return buf.toString(); } - private boolean compileJava(ModuleChunk chunk, Collection files, - Collection classpath, - Collection platformCp, - Collection sourcePath, - Map> outs, - CompileContext context, - DiagnosticOutputConsumer diagnosticSink, - final OutputFileConsumer outputSink) throws Exception { - final List options = getCompilationOptions(context, chunk); - if (context.errorsDetected()) { - return true; + private boolean compileJava( + CompileContext context, + ModuleChunk chunk, + Collection files, + Collection classpath, + Collection platformCp, + Collection sourcePath, + DiagnosticOutputConsumer diagnosticSink, + final OutputFileConsumer outputSink) throws Exception { + + final Set modules = chunk.getModules(); + AnnotationProcessingProfile profile = null; + if (modules.size() == 1) { + profile = context.getAnnotationProcessingProfile(modules.iterator().next()); } + else { + // check that all chunk modules are excluded from annotation processing + for (Module module : modules) { + final AnnotationProcessingProfile prof = context.getAnnotationProcessingProfile(module); + if (prof.isEnabled()) { + String message = "Annotation processing is not supported for module cycles. Please ensure that all modules from cycle [" + getChunkPresentableName(chunk) + "] are excluded from annotation processing"; + context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message)); + return true; + } + } + } + + final Map> outs = buildOutputDirectoriesMap(context, chunk); + final List options = getCompilationOptions(context, chunk, profile); final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink); try { final boolean rc; @@ -600,7 +616,7 @@ public class JavaBuilder extends ModuleLevelBuilder { return cached; } - private static List getCompilationOptions(CompileContext context, ModuleChunk chunk) { + private static List getCompilationOptions(CompileContext context, ModuleChunk chunk, AnnotationProcessingProfile profile) { List cached = JAVAC_OPTIONS.get(context); if (cached == null) { loadCommonJavacOptions(context); @@ -669,20 +685,6 @@ public class JavaBuilder extends ModuleLevelBuilder { } } - AnnotationProcessingProfile profile = null; - for (Module module : chunk.getModules()) { - if (profile == null) { - profile = context.getAnnotationProcessingProfile(module); - } - else { - final AnnotationProcessingProfile profile2 = context.getAnnotationProcessingProfile(module); - if (profile2 != profile) { - String message = "Modules in cycle [" + getChunkPresentableName(chunk) + "] must use the same annotation processing profile"; - context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message)); - } - } - } - if (profile != null && profile.isEnabled()) { // configuring annotation processing if (!profile.getObtainProcessorsFromClasspath()) { @@ -700,7 +702,9 @@ public class JavaBuilder extends ModuleLevelBuilder { options.add("-A" + optionEntry.getKey() + "=" + optionEntry.getValue()); } - final File srcOutput = getGeneratedSourcesOutputDirectory(context, chunk, profile.getGeneratedSourcesDirName()); + final File srcOutput = context.getProjectPaths() + .getAnnotationProcessorGeneratedSourcesOutputDir(chunk.getModules().iterator().next(), context.isCompilingTests(), + profile.getGeneratedSourcesDirName()); if (srcOutput != null) { srcOutput.mkdirs(); options.add("-s"); @@ -714,12 +718,6 @@ public class JavaBuilder extends ModuleLevelBuilder { return options; } - @Nullable - private static File getGeneratedSourcesOutputDirectory(CompileContext context, ModuleChunk chunk, String name) { - // todo: support multiple outputs for module chunk - return context.getProjectPaths().getAnnotationProcessorGeneratedSourcesOutputDir(chunk.getModules().iterator().next(), context.isCompilingTests(), name); - } - private static boolean isEncodingSet(List options) { for (String option : options) { if ("-encoding".equals(option)) { @@ -826,7 +824,7 @@ public class JavaBuilder extends ModuleLevelBuilder { private static void instrumentNotNull(CompileContext context, OutputFilesSink sink, final InstrumentationClassFinder finder) { for (final OutputFileObject fileObject : sink.getFileObjects()) { final OutputFileObject.Content originalContent = fileObject.getContent(); - if (originalContent == null || !JavaFileObject.Kind.CLASS.equals(fileObject.getKind())) { + if (originalContent == null || fileObject.getKind() != JavaFileObject.Kind.CLASS) { continue; } final ClassReader reader = new ClassReader(originalContent.getBuffer(), originalContent.getOffset(), originalContent.getLength()); @@ -873,7 +871,7 @@ public class JavaBuilder extends ModuleLevelBuilder { final Map compiledClassNames = new HashMap(); for (OutputFileObject fileObject : outputSink.getFileObjects()) { - if (JavaFileObject.Kind.CLASS.equals(fileObject.getKind())) { + if (fileObject.getKind() == JavaFileObject.Kind.CLASS) { compiledClassNames.put(fileObject.getClassName(), fileObject); } }