Consider module output as part of the same Java module

This fixes incremental compilation for explicit Java 9 modules

 #KT-20064 Fixed
 #KT-20082 Fixed
This commit is contained in:
Alexander Udalov
2017-09-21 19:30:29 +03:00
parent 0a9c21dbc8
commit 5348d2e43a
2 changed files with 26 additions and 6 deletions
@@ -50,7 +50,8 @@ class ClasspathRootsResolver(
private val additionalModules: List<String>,
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
private val javaModuleFinder: CliJavaModuleFinder,
private val requireStdlibModule: Boolean
private val requireStdlibModule: Boolean,
private val outputDirectory: VirtualFile?
) {
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
@@ -85,8 +86,10 @@ class ClasspathRootsResolver(
val result = mutableListOf<JavaRoot>()
val modules = mutableListOf<JavaModule>()
val hasOutputDirectoryInClasspath = outputDirectory in jvmClasspathRoots || outputDirectory in jvmModulePathRoots
for ((root, packagePrefix) in javaSourceRoots) {
val modularRoot = modularSourceRoot(root)
val modularRoot = modularSourceRoot(root, hasOutputDirectoryInClasspath)
if (modularRoot != null) {
modules += modularRoot
}
@@ -104,7 +107,13 @@ class ClasspathRootsResolver(
result += JavaRoot(root, JavaRoot.RootType.BINARY)
}
val outputDirectoryAddedAsPartOfModule = modules.any { module -> module.moduleRoots.any { it.file == outputDirectory } }
for (root in jvmModulePathRoots) {
// Do not add output directory as a separate module if we're compiling an explicit named module.
// It's going to be included as a root of our module in modularSourceRoot.
if (outputDirectoryAddedAsPartOfModule && root == outputDirectory) continue
val module = modularBinaryRoot(root)
if (module != null) {
modules += module
@@ -130,9 +139,13 @@ class ClasspathRootsResolver(
return moduleInfoFile to psiJavaModule
}
private fun modularSourceRoot(root: VirtualFile): JavaModule.Explicit? {
private fun modularSourceRoot(root: VirtualFile, hasOutputDirectoryInClasspath: Boolean): JavaModule.Explicit? {
val (moduleInfoFile, psiJavaModule) = findSourceModuleInfo(root) ?: return null
val roots = listOf(JavaModule.Root(root, isBinary = false))
val sourceRoot = JavaModule.Root(root, isBinary = false)
val roots =
if (hasOutputDirectoryInClasspath)
listOf(sourceRoot, JavaModule.Root(outputDirectory!!, isBinary = true))
else listOf(sourceRoot)
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), roots, moduleInfoFile)
}
@@ -204,13 +204,19 @@ class KotlinCoreEnvironment private constructor(
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
})
val outputDirectory =
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath
classpathRootsResolver = ClasspathRootsResolver(
PsiManager.getInstance(project),
messageCollector,
configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES),
this::contentRootToVirtualFile,
javaModuleFinder,
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE)
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
outputDirectory?.let(this::findLocalFile)
)
val (initialRoots, javaModules) =
@@ -331,7 +337,8 @@ class KotlinCoreEnvironment private constructor(
}
}
internal fun findLocalFile(path: String) = applicationEnvironment.localFileSystem.findFileByPath(path)
internal fun findLocalFile(path: String): VirtualFile? =
applicationEnvironment.localFileSystem.findFileByPath(path)
private fun findLocalFile(root: JvmContentRoot): VirtualFile? {
return findLocalFile(root.file.absolutePath).also {