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:
Alexander Udalov
2017-06-28 16:13:14 +03:00
parent 72f37a278c
commit 5192f946c5
22 changed files with 135 additions and 4 deletions
@@ -107,4 +107,27 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() {
// because we did not provide -Xadd-modules=moduleA
module("moduleB", listOf(module("moduleA")), addModules = emptyList())
}
fun testNamedReadsTransitive() {
val a = module("moduleA")
val b = module("moduleB", listOf(a))
module("moduleC", listOf(a, b))
}
fun testUnnamedReadsTransitive() {
val a = module("moduleA")
val b = module("moduleB", listOf(a))
module("moduleC", listOf(a, b), addModules = listOf("moduleB"))
}
fun testNonTransitiveDoesNotAffectExplicitDependency() {
// In this test, D depends on C (which requires B non-transitively) and on B; also B transitively requires A.
// We check that if we depend on both C and B, we still transitively depend on A (via B).
// This is a check against an incorrectly implemented DFS which, upon entering C, would write off B as "visited"
// and not enter it later even though we explicitly depend on it in D's module-info
val a = module("moduleA")
val b = module("moduleB", listOf(a))
val c = module("moduleC", listOf(a, b))
module("moduleD", listOf(c, b, a))
}
}