IDEA-141849 Maven integration should not create multiple annotation processors profiles with same settings

This commit is contained in:
Vladislav.Soroka
2016-02-10 12:15:07 +03:00
parent 16ef7e467a
commit fabfaf0f97
4 changed files with 132 additions and 79 deletions
@@ -22,9 +22,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
import org.jetbrains.jps.model.java.impl.compiler.ProcessorConfigProfileImpl;
@@ -42,6 +45,10 @@ public class MavenAnnotationProcessorConfigurer extends MavenModuleConfigurer {
public static final String DEFAULT_ANNOTATION_PATH_OUTPUT = "target/generated-sources/annotations";
public static final String DEFAULT_TEST_ANNOTATION_OUTPUT = "target/generated-test-sources/test-annotations";
public static final String MAVEN_BSC_DEFAULT_ANNOTATION_PROFILE = PROFILE_PREFIX + "maven-processor-plugin default configuration";
public static final String DEFAULT_BSC_ANNOTATION_PATH_OUTPUT = "target/generated-sources/apt";
public static final String DEFAULT_BSC_TEST_ANNOTATION_OUTPUT = "target/generated-sources/apt-test";
@Override
public void configure(@NotNull MavenProject mavenProject, @NotNull Project project, @Nullable Module module) {
if (module == null) return;
@@ -50,29 +57,21 @@ public class MavenAnnotationProcessorConfigurer extends MavenModuleConfigurer {
if (sdk != null) {
String versionString = sdk.getVersionString();
if (versionString != null) {
if (versionString.contains("1.5") || versionString.contains("1.4") || versionString.contains("1.3") || versionString.contains("1.2")) {
if (versionString.contains("1.5") ||
versionString.contains("1.4") ||
versionString.contains("1.3") ||
versionString.contains("1.2")) {
return;
}
}
}
CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
ProcessorConfigProfile currentProfile = compilerConfiguration.getAnnotationProcessingConfiguration(module);
String moduleProfileName = PROFILE_PREFIX + module.getName();
if (currentProfile != compilerConfiguration.getDefaultProcessorProfile()
&& !MAVEN_DEFAULT_ANNOTATION_PROFILE.equals(currentProfile.getName())
&& !moduleProfileName.equals(currentProfile.getName())) {
return;
}
ProcessorConfigProfile moduleProfile = compilerConfiguration.findModuleProcessorProfile(moduleProfileName);
ProcessorConfigProfile defaultMavenProfile = compilerConfiguration.findModuleProcessorProfile(MAVEN_DEFAULT_ANNOTATION_PROFILE);
final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
final MavenProject rootProject =
ObjectUtils.notNull(MavenProjectsManager.getInstance(project).findRootProject(mavenProject), mavenProject);
if (shouldEnableAnnotationProcessors(mavenProject)) {
final String moduleProfileName;
String annotationProcessorDirectory = getRelativeAnnotationProcessorDirectory(mavenProject, false);
if (annotationProcessorDirectory == null) {
annotationProcessorDirectory = DEFAULT_ANNOTATION_PATH_OUTPUT;
@@ -83,80 +82,128 @@ public class MavenAnnotationProcessorConfigurer extends MavenModuleConfigurer {
testAnnotationProcessorDirectory = DEFAULT_TEST_ANNOTATION_OUTPUT;
}
Map<String, String> options = mavenProject.getAnnotationProcessorOptions();
List<String> processors = mavenProject.getDeclaredAnnotationProcessors();
if (processors == null
&& options.isEmpty()
&& DEFAULT_ANNOTATION_PATH_OUTPUT.equals(annotationProcessorDirectory.replace('\\', '/'))
&& DEFAULT_TEST_ANNOTATION_OUTPUT.equals(testAnnotationProcessorDirectory.replace('\\', '/'))) {
if (moduleProfile != null) {
compilerConfiguration.removeModuleProcessorProfile(moduleProfile);
}
if (defaultMavenProfile == null) {
defaultMavenProfile = new ProcessorConfigProfileImpl(MAVEN_DEFAULT_ANNOTATION_PROFILE);
defaultMavenProfile.setEnabled(true);
defaultMavenProfile.setOutputRelativeToContentRoot(true);
defaultMavenProfile.setObtainProcessorsFromClasspath(true);
defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_ANNOTATION_PATH_OUTPUT, false);
defaultMavenProfile.setGeneratedSourcesDirectoryName(DEFAULT_TEST_ANNOTATION_OUTPUT, true);
compilerConfiguration.addModuleProcessorProfile(defaultMavenProfile);
}
defaultMavenProfile.addModuleName(module.getName());
final boolean isDefault;
if (isMavenDefaultAnnotationProcessorConfiguration(annotationProcessorDirectory, testAnnotationProcessorDirectory, mavenProject)) {
moduleProfileName = MAVEN_DEFAULT_ANNOTATION_PROFILE;
isDefault = true;
}
else if (isMavenProcessorPluginDefaultConfiguration(annotationProcessorDirectory, testAnnotationProcessorDirectory, mavenProject)) {
moduleProfileName = MAVEN_BSC_DEFAULT_ANNOTATION_PROFILE;
isDefault = true;
}
else {
if (defaultMavenProfile != null) {
defaultMavenProfile.removeModuleName(module.getName());
moduleProfileName = PROFILE_PREFIX + module.getName();
isDefault = false;
}
ProcessorConfigProfile moduleProfile = compilerConfiguration.findModuleProcessorProfile(moduleProfileName);
if (defaultMavenProfile.getModuleNames().isEmpty()) {
compilerConfiguration.removeModuleProcessorProfile(defaultMavenProfile);
}
}
if (moduleProfile == null) {
moduleProfile = new ProcessorConfigProfileImpl(moduleProfileName);
compilerConfiguration.addModuleProcessorProfile(moduleProfile);
}
if (moduleProfile == null) {
moduleProfile = new ProcessorConfigProfileImpl(moduleProfileName);
moduleProfile.setOutputRelativeToContentRoot(true);
moduleProfile.setEnabled(true);
moduleProfile.setObtainProcessorsFromClasspath(true);
moduleProfile.addModuleName(module.getName());
compilerConfiguration.addModuleProcessorProfile(moduleProfile);
}
moduleProfile.setOutputRelativeToContentRoot(true);
moduleProfile.setEnabled(true);
moduleProfile.setObtainProcessorsFromClasspath(true);
moduleProfile.setGeneratedSourcesDirectoryName(annotationProcessorDirectory, false);
moduleProfile.setGeneratedSourcesDirectoryName(testAnnotationProcessorDirectory, true);
moduleProfile.setGeneratedSourcesDirectoryName(annotationProcessorDirectory, false);
moduleProfile.setGeneratedSourcesDirectoryName(testAnnotationProcessorDirectory, true);
moduleProfile.clearProcessorOptions();
for (Map.Entry<String, String> entry : mavenProject.getAnnotationProcessorOptions().entrySet()) {
moduleProfile.setOption(entry.getKey(), entry.getValue());
}
moduleProfile.clearProcessorOptions();
for (Map.Entry<String, String> entry : options.entrySet()) {
moduleProfile.setOption(entry.getKey(), entry.getValue());
}
moduleProfile.clearProcessors();
if (processors != null) {
for (String processor : processors) {
moduleProfile.addProcessor(processor);
}
moduleProfile.clearProcessors();
final List<String> processors = mavenProject.getDeclaredAnnotationProcessors();
if (processors != null) {
for (String processor : processors) {
moduleProfile.addProcessor(processor);
}
}
moduleProfile.addModuleName(module.getName());
cleanAndMergeModuleProfiles(rootProject, compilerConfiguration, moduleProfile, isDefault, module);
}
else {
if (defaultMavenProfile != null) {
defaultMavenProfile.removeModuleName(module.getName());
cleanAndMergeModuleProfiles(rootProject, compilerConfiguration, null, false, module);
}
}
if (defaultMavenProfile.getModuleNames().isEmpty()) {
compilerConfiguration.removeModuleProcessorProfile(defaultMavenProfile);
private static void cleanAndMergeModuleProfiles(@NotNull MavenProject rootProject,
@NotNull CompilerConfigurationImpl compilerConfiguration,
@Nullable ProcessorConfigProfile moduleProfile,
boolean isDefault,
@NotNull Module module) {
List<ProcessorConfigProfile> profiles = ContainerUtil.newArrayList(compilerConfiguration.getModuleProcessorProfiles());
for (ProcessorConfigProfile p : profiles) {
if (p != moduleProfile) {
p.removeModuleName(module.getName());
if (p.getModuleNames().isEmpty()) {
compilerConfiguration.removeModuleProcessorProfile(p);
}
}
if (moduleProfile != null) {
compilerConfiguration.removeModuleProcessorProfile(moduleProfile);
if (!isDefault && moduleProfile != null && isSimilarProfiles(p, moduleProfile)) {
final String mavenProjectRootProfileName = PROFILE_PREFIX + rootProject.getDisplayName();
ProcessorConfigProfile mergedProfile = compilerConfiguration.findModuleProcessorProfile(mavenProjectRootProfileName);
if (mergedProfile == null) {
mergedProfile = new ProcessorConfigProfileImpl(moduleProfile);
mergedProfile.setName(mavenProjectRootProfileName);
compilerConfiguration.addModuleProcessorProfile(mergedProfile);
mergedProfile.addModuleNames(p.getModuleNames());
p.clearModuleNames();
compilerConfiguration.removeModuleProcessorProfile(p);
moduleProfile.clearModuleNames();
compilerConfiguration.removeModuleProcessorProfile(moduleProfile);
}
else if (p == mergedProfile || isSimilarProfiles(mergedProfile, moduleProfile)) {
mergedProfile.addModuleNames(moduleProfile.getModuleNames());
moduleProfile.clearModuleNames();
compilerConfiguration.removeModuleProcessorProfile(moduleProfile);
if (p != mergedProfile) {
mergedProfile.addModuleNames(p.getModuleNames());
p.clearModuleNames();
compilerConfiguration.removeModuleProcessorProfile(p);
}
}
}
}
}
private static boolean isSimilarProfiles(@Nullable ProcessorConfigProfile profile1, @Nullable ProcessorConfigProfile profile2) {
if (profile1 == null || profile2 == null) return false;
ProcessorConfigProfileImpl p1 = new ProcessorConfigProfileImpl(profile1);
p1.setName("tmp");
p1.clearModuleNames();
ProcessorConfigProfileImpl p2 = new ProcessorConfigProfileImpl(profile2);
p2.setName("tmp");
p2.clearModuleNames();
return p1.equals(p2);
}
private static boolean isMavenDefaultAnnotationProcessorConfiguration(@NotNull String annotationProcessorDirectory,
@NotNull String testAnnotationProcessorDirectory,
@NotNull MavenProject mavenProject) {
Map<String, String> options = mavenProject.getAnnotationProcessorOptions();
List<String> processors = mavenProject.getDeclaredAnnotationProcessors();
return ContainerUtil.isEmpty(processors)
&& options.isEmpty()
&& DEFAULT_ANNOTATION_PATH_OUTPUT.equals(annotationProcessorDirectory.replace('\\', '/'))
&& DEFAULT_TEST_ANNOTATION_OUTPUT.equals(testAnnotationProcessorDirectory.replace('\\', '/'));
}
private static boolean isMavenProcessorPluginDefaultConfiguration(@NotNull String annotationProcessorDirectory,
@NotNull String testAnnotationProcessorDirectory,
@NotNull MavenProject mavenProject) {
Map<String, String> options = mavenProject.getAnnotationProcessorOptions();
List<String> processors = mavenProject.getDeclaredAnnotationProcessors();
return ContainerUtil.isEmpty(processors)
&& options.isEmpty()
&& DEFAULT_BSC_ANNOTATION_PATH_OUTPUT.equals(annotationProcessorDirectory.replace('\\', '/'))
&& DEFAULT_BSC_TEST_ANNOTATION_OUTPUT.equals(testAnnotationProcessorDirectory.replace('\\', '/'));
}
@Nullable
private static String getRelativeAnnotationProcessorDirectory(MavenProject mavenProject, boolean isTest) {
String annotationProcessorDirectory = mavenProject.getAnnotationProcessorDirectory(isTest);
@@ -175,5 +222,4 @@ public class MavenAnnotationProcessorConfigurer extends MavenModuleConfigurer {
return mavenProject.getProcMode() != MavenProject.ProcMode.NONE
|| mavenProject.findPlugin("org.bsc.maven", "maven-processor-plugin") != null;
}
}
@@ -358,14 +358,14 @@ public class MavenProject {
MavenPlugin bscMavenPlugin = findPlugin("org.bsc.maven", "maven-processor-plugin");
Element cfg = getPluginGoalConfiguration(bscMavenPlugin, testSources ? "process-test" : "process");
if (bscMavenPlugin != null && cfg == null) {
return getBuildDirectory() + "/generated-sources/apt";
return getBuildDirectory() + (testSources ? "/generated-sources/apt-test" : "/generated-sources/apt");
}
if (cfg != null) {
String out = MavenJDOMUtil.findChildValueByPath(cfg, "outputDirectory");
if (out == null) {
out = MavenJDOMUtil.findChildValueByPath(cfg, "defaultOutputDirectory");
if (out == null) {
return getBuildDirectory() + "/generated-sources/apt";
return getBuildDirectory() + (testSources ? "/generated-sources/apt-test" : "/generated-sources/apt");
}
}
@@ -730,9 +730,15 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
}
@Nullable
public MavenProject findAggregator(@NotNull MavenProject module) {
public MavenProject findAggregator(@NotNull MavenProject mavenProject) {
if (!isInitialized()) return null;
return myProjectsTree.findAggregator(module);
return myProjectsTree.findAggregator(mavenProject);
}
@Nullable
public MavenProject findRootProject(@NotNull MavenProject mavenProject) {
if (!isInitialized()) return null;
return myProjectsTree.findRootProject(mavenProject);
}
@NotNull
@@ -26,7 +26,7 @@ import org.jetbrains.idea.maven.importing.configurers.MavenAnnotationProcessorCo
@SuppressWarnings("GroovyPointlessBoolean")
class AnnotationProcessorImportingTest extends MavenImportingTestCase {
public void testSettingTargetLevel() throws Exception {
public void testImportAnnotationProcessorProfiles() throws Exception {
createModulePom("module1", """
<groupId>test</groupId>
<artifactId>module1</artifactId>
@@ -126,7 +126,8 @@ class AnnotationProcessorImportingTest extends MavenImportingTestCase {
def compilerConfiguration = ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject))
assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE).getModuleNames() == new HashSet<String>(["module1"])
assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_DEFAULT_ANNOTATION_PROFILE).getModuleNames() == new HashSet<String>(["module1", "module4"])
assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.MAVEN_BSC_DEFAULT_ANNOTATION_PROFILE) == null
assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + 'module2').getProcessors() == new HashSet<String>(["com.test.SourceCodeGeneratingAnnotationProcessor2"])
assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + 'module3') == null
assert compilerConfiguration.findModuleProcessorProfile(MavenAnnotationProcessorConfigurer.PROFILE_PREFIX + 'module3_1') == null