Fix depth-first search for Java 9 modules
To compute modules to be added to compilation roots in
JavaModuleGraph.getAllDependencies, we should look not only for
transitive requirements of root modules, but for transitive requirements
of _root modules' requirements_. The same logic applies to
JavaModuleGraph.reads. In other words, when looking for a path in the
module graph between two modules, the first edge's transitiveness
doesn't matter, but all other edges after the first must be transitive.
There was also a stupid bug in dfs in
JavaModuleGraph.getAllDependencies: we continued the DFS only if the
module _was not_ added to the "visited" set ("add" returns true if the
element was added successfully)
#KT-18598 In Progress
This commit is contained in:
+29
-4
@@ -32,13 +32,29 @@ class JavaModuleGraph(finder: JavaModuleFinder) {
|
||||
// Automatic modules have no transitive exports, so we only consider explicit modules here
|
||||
val moduleInfo = (module(moduleName) as? JavaModule.Explicit)?.moduleInfo ?: return
|
||||
for ((dependencyModuleName, isTransitive) in moduleInfo.requires) {
|
||||
if (!visited.add(dependencyModuleName) && isTransitive) {
|
||||
if (isTransitive && visited.add(dependencyModuleName)) {
|
||||
dfs(dependencyModuleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moduleNames.forEach(::dfs)
|
||||
for (moduleName in moduleNames) {
|
||||
val module = module(moduleName) ?: continue
|
||||
when (module) {
|
||||
is JavaModule.Automatic -> {
|
||||
// Do nothing; all automatic modules should be added to compilation roots at call site as per java.lang.module javadoc
|
||||
}
|
||||
is JavaModule.Explicit -> {
|
||||
for ((dependencyModuleName) in module.moduleInfo.requires) {
|
||||
if (visited.add(dependencyModuleName)) {
|
||||
dfs(dependencyModuleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> error("Unknown module: $module (${module.javaClass})")
|
||||
}
|
||||
}
|
||||
|
||||
return visited.toList()
|
||||
}
|
||||
|
||||
@@ -50,7 +66,7 @@ class JavaModuleGraph(finder: JavaModuleFinder) {
|
||||
fun dfs(name: String): Boolean {
|
||||
if (!visited.add(name)) return false
|
||||
|
||||
val module = module(name)
|
||||
val module = module(name) ?: return false
|
||||
when (module) {
|
||||
is JavaModule.Automatic -> return true
|
||||
is JavaModule.Explicit -> {
|
||||
@@ -60,11 +76,20 @@ class JavaModuleGraph(finder: JavaModuleFinder) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
null -> return false
|
||||
else -> error("Unsupported module type: $module")
|
||||
}
|
||||
}
|
||||
|
||||
val module = module(moduleName) ?: return false
|
||||
when (module) {
|
||||
is JavaModule.Automatic -> return true
|
||||
is JavaModule.Explicit -> {
|
||||
for ((dependencyModuleName) in module.moduleInfo.requires) {
|
||||
if (dfs(dependencyModuleName)) return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dfs(moduleName)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user