mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java] allows one module-info file in either source or test root - compilation (IDEA-171221)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.compiler.CompilerManager
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.search.FilenameIndex
|
||||
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
||||
@@ -35,37 +36,50 @@ class JavaModuleIndexBuildTask : CompileTask {
|
||||
|
||||
val systemDir = BuildManager.getInstance().getProjectSystemDirectory(project)
|
||||
if (systemDir == null) {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "Internal error: no system directory for project: ${project}", null, 0, 0)
|
||||
context.error("Internal error: no system directory for project: ${project}")
|
||||
return false
|
||||
}
|
||||
|
||||
val map = runReadAction {
|
||||
val compilerManager = CompilerManager.getInstance(project)
|
||||
ModuleManager.getInstance(project).modules.asSequence()
|
||||
.map {
|
||||
val files = FilenameIndex.getVirtualFilesByName(project, PsiJavaModule.MODULE_INFO_FILE, it.getModuleScope(false))
|
||||
it.name to files.filter { !compilerManager.isExcludedFromCompilation(it) }
|
||||
val badModules = mutableListOf<String>()
|
||||
val paths = mutableMapOf<String, String?>()
|
||||
|
||||
val compilerManager = CompilerManager.getInstance(project)
|
||||
runReadAction {
|
||||
ModuleManager.getInstance(project).modules.forEach { module ->
|
||||
val index = ModuleRootManager.getInstance(module).fileIndex
|
||||
val sourceFiles = mutableListOf<String>()
|
||||
val testFiles = mutableListOf<String>()
|
||||
FilenameIndex.getVirtualFilesByName(project, PsiJavaModule.MODULE_INFO_FILE, module.moduleScope).forEach { file ->
|
||||
if (!compilerManager.isExcludedFromCompilation(file)) {
|
||||
(if (index.isInTestSourceContent(file)) testFiles else sourceFiles) += file.path
|
||||
}
|
||||
}
|
||||
.toMap()
|
||||
if (sourceFiles.size + testFiles.size > 1) {
|
||||
badModules += module.name
|
||||
}
|
||||
else {
|
||||
paths += module.name + JavaModuleIndexImpl.SOURCE_SUFFIX to sourceFiles.firstOrNull()
|
||||
paths += module.name + JavaModuleIndexImpl.TEST_SUFFIX to testFiles.firstOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val errors = map.filter { it.value.size > 1 }.map { IdeBundle.message("compiler.multiple.module.descriptors", it.key) }
|
||||
if (errors.isNotEmpty()) {
|
||||
errors.forEach { context.addMessage(CompilerMessageCategory.ERROR, it, null, 0, 0) }
|
||||
if (badModules.isNotEmpty()) {
|
||||
badModules.forEach { context.error(IdeBundle.message("compiler.multiple.module.descriptors", it)) }
|
||||
return false
|
||||
}
|
||||
|
||||
val paths = map.map { it.key to it.value.firstOrNull()?.path }.toMap()
|
||||
|
||||
try {
|
||||
JavaModuleIndexImpl.store(BuildDataPathsImpl(systemDir).dataStorageRoot, paths)
|
||||
}
|
||||
catch(e: Exception) {
|
||||
Logger.getInstance(JavaModuleIndexBuildTask::class.java).error(e)
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "Internal error: can't save module index: ${e.message}", null, 0, 0)
|
||||
context.error("Internal error: can't save module index: ${e.message}")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun CompileContext.error(message: String) = addMessage(CompilerMessageCategory.ERROR, message, null, 0, 0)
|
||||
}
|
||||
@@ -235,12 +235,17 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
});
|
||||
|
||||
boolean hasModules = false;
|
||||
if ((!filesToCompile.isEmpty() || dirtyFilesHolder.hasRemovedFiles()) &&
|
||||
JpsJavaSdkType.parseVersion(getLanguageLevel(ContainerUtil.getFirstItem(chunk.getModules()))) >= 9) {
|
||||
// at the moment, there is no incremental compilation for module-info files, so they should be rebuilt on every change
|
||||
JavaModuleIndex index = getJavaModuleIndex(context);
|
||||
for (JpsModule module : chunk.getModules()) {
|
||||
ContainerUtil.addIfNotNull(filesToCompile, index.getModuleInfoFile(module));
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
File moduleInfoFile = index.getModuleInfoFile(target.getModule(), target.isTests());
|
||||
if (moduleInfoFile != null) {
|
||||
filesToCompile.add(moduleInfoFile);
|
||||
hasModules = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +256,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
return compile(context, chunk, dirtyFilesHolder, filesToCompile, outputConsumer, compilingTool);
|
||||
return compile(context, chunk, dirtyFilesHolder, filesToCompile, outputConsumer, compilingTool, hasModules);
|
||||
}
|
||||
catch (BuildDataCorruptedException | PersistentEnumeratorBase.CorruptedException | ProjectBuildException e) {
|
||||
throw e;
|
||||
@@ -270,7 +275,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
|
||||
Collection<File> files,
|
||||
OutputConsumer outputConsumer,
|
||||
JavaCompilingTool compilingTool) throws Exception {
|
||||
JavaCompilingTool compilingTool,
|
||||
boolean hasModules) throws Exception {
|
||||
ExitCode exitCode = ExitCode.NOTHING_DONE;
|
||||
|
||||
final boolean hasSourcesToCompile = !files.isEmpty();
|
||||
@@ -323,7 +329,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
}
|
||||
try {
|
||||
compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink, compilingTool);
|
||||
compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink, compilingTool, hasModules);
|
||||
}
|
||||
finally {
|
||||
// heuristic: incorrect paths data recovery, so that the next make should not contain non-existing sources in 'recompile' list
|
||||
@@ -370,7 +376,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
Collection<File> sourcePath,
|
||||
DiagnosticOutputConsumer diagnosticSink,
|
||||
OutputFileConsumer outputSink,
|
||||
JavaCompilingTool compilingTool) throws Exception {
|
||||
JavaCompilingTool compilingTool,
|
||||
boolean hasModules) throws Exception {
|
||||
final TasksCounter counter = new TasksCounter();
|
||||
COUNTER_KEY.set(context, counter);
|
||||
|
||||
@@ -395,7 +402,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
try {
|
||||
final int targetLanguageLevel = JpsJavaSdkType.parseVersion(getLanguageLevel(chunk.getModules().iterator().next()));
|
||||
final boolean shouldForkJavac = shouldForkCompilerProcess(context, chunk, targetLanguageLevel);
|
||||
final boolean hasModules = targetLanguageLevel >= 9 && getJavaModuleIndex(context).hasJavaModules(modules);
|
||||
|
||||
// when forking external javac, compilers from SDK 1.6 and higher are supported
|
||||
Pair<String, Integer> forkSdk = null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,17 +20,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class JavaModuleIndex {
|
||||
/**
|
||||
* Returns a path to a module descriptor (module-info.java file) for the given module,
|
||||
* or {@code null} when there is no descriptor.
|
||||
*/
|
||||
public abstract @Nullable File getModuleInfoFile(@NotNull JpsModule module);
|
||||
|
||||
/**
|
||||
* Returns {@code true} when at least one module in the chunk has a module descriptor (module-info.java file).
|
||||
*/
|
||||
public abstract boolean hasJavaModules(@NotNull Set<JpsModule> chunk);
|
||||
public abstract @Nullable File getModuleInfoFile(@NotNull JpsModule module, boolean forTests);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.model.java.JavaModuleIndex;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType;
|
||||
import org.jetbrains.jps.model.java.compiler.JpsCompilerExcludes;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
|
||||
@@ -30,9 +31,11 @@ import java.io.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaModuleIndexImpl extends JavaModuleIndex {
|
||||
public static final String SOURCE_SUFFIX = ":S";
|
||||
public static final String TEST_SUFFIX = ":T";
|
||||
|
||||
private static final String INDEX_PATH = "jigsaw/module-info.map";
|
||||
private static final String NULL_PATH = "-";
|
||||
private static final String MODULE_INFO_FILE = "module-info.java";
|
||||
@@ -50,34 +53,27 @@ public class JavaModuleIndexImpl extends JavaModuleIndex {
|
||||
myExcludes = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public @Nullable File getModuleInfoFile(@NotNull JpsModule module) {
|
||||
String key = module.getName();
|
||||
public File getModuleInfoFile(@NotNull JpsModule module, boolean forTests) {
|
||||
String key = module.getName() + (forTests ? TEST_SUFFIX : SOURCE_SUFFIX);
|
||||
|
||||
if (myExcludes == null || myMapping.containsKey(key)) {
|
||||
return myMapping.get(key);
|
||||
}
|
||||
|
||||
File file = findModuleInfoFile(module);
|
||||
File file = findModuleInfoFile(module, forTests ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE);
|
||||
myMapping.put(key, file);
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasJavaModules(@NotNull Set<JpsModule> chunk) {
|
||||
for (JpsModule module : chunk) {
|
||||
if (getModuleInfoFile(module) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private File findModuleInfoFile(JpsModule module) {
|
||||
private File findModuleInfoFile(JpsModule module, JavaSourceRootType rootType) {
|
||||
for (JpsModuleSourceRoot root : module.getSourceRoots()) {
|
||||
File file = new File(JpsPathUtil.urlToOsPath(root.getUrl()), MODULE_INFO_FILE);
|
||||
if (file.isFile() && !myExcludes.isExcluded(file)) {
|
||||
return file;
|
||||
if (rootType.equals(root.getRootType())) {
|
||||
File file = new File(JpsPathUtil.urlToOsPath(root.getUrl()), MODULE_INFO_FILE);
|
||||
if (file.isFile() && !myExcludes.isExcluded(file)) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user