diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt index a03da2c01ad..a0755c72d36 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/ClasspathRootsResolver.kt @@ -172,11 +172,21 @@ internal class ClasspathRootsResolver( else -> computeDefaultRootModules() + additionalModules } - // TODO: if at least one automatic module is added, add all automatic modules as per java.lang.module javadoc - val allDependencies = javaModuleGraph.getAllDependencies(rootModules).also { loadedModules -> - report(LOGGING, "Loading modules: $loadedModules") + val allDependencies = javaModuleGraph.getAllDependencies(rootModules).toMutableList() + + if (allDependencies.any { moduleName -> javaModuleFinder.findModule(moduleName) is JavaModule.Automatic }) { + // According to java.lang.module javadoc, if at least one automatic module is added to the module graph, + // all observable automatic modules should be added. + // There are no automatic modules in the JDK, so we select all automatic modules out of user modules + for (module in modules) { + if (module is JavaModule.Automatic) { + allDependencies += module.name + } + } } + report(LOGGING, "Loading modules: $allDependencies") + for (moduleName in allDependencies) { val module = javaModuleFinder.findModule(moduleName) if (module == null) { diff --git a/compiler/testData/javaModules/namedAgainstSeveralAutomatic/autoA/foo/Foo.java b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/autoA/foo/Foo.java new file mode 100644 index 00000000000..7f566bafd45 --- /dev/null +++ b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/autoA/foo/Foo.java @@ -0,0 +1,3 @@ +package foo; + +public class Foo {} diff --git a/compiler/testData/javaModules/namedAgainstSeveralAutomatic/autoB/bar/Bar.java b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/autoB/bar/Bar.java new file mode 100644 index 00000000000..e94fe68bd76 --- /dev/null +++ b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/autoB/bar/Bar.java @@ -0,0 +1,3 @@ +package bar; + +public class Bar {} diff --git a/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main.txt b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main/module-info.java b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main/module-info.java new file mode 100644 index 00000000000..fd2e43f14d6 --- /dev/null +++ b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main/module-info.java @@ -0,0 +1,3 @@ +module main { + requires autoB; +} diff --git a/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main/usage.kt b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main/usage.kt new file mode 100644 index 00000000000..5488e0a7d2c --- /dev/null +++ b/compiler/testData/javaModules/namedAgainstSeveralAutomatic/main/usage.kt @@ -0,0 +1,6 @@ +import foo.Foo +import bar.Bar + +fun usage(): String { + return "${Foo()}${Bar()}" +} diff --git a/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/autoA/foo/Foo.java b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/autoA/foo/Foo.java new file mode 100644 index 00000000000..7f566bafd45 --- /dev/null +++ b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/autoA/foo/Foo.java @@ -0,0 +1,3 @@ +package foo; + +public class Foo {} diff --git a/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/autoB/bar/Bar.java b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/autoB/bar/Bar.java new file mode 100644 index 00000000000..e94fe68bd76 --- /dev/null +++ b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/autoB/bar/Bar.java @@ -0,0 +1,3 @@ +package bar; + +public class Bar {} diff --git a/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/main.txt b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/main.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/main.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/main/usage.kt b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/main/usage.kt new file mode 100644 index 00000000000..5488e0a7d2c --- /dev/null +++ b/compiler/testData/javaModules/unnamedAgainstSeveralAutomatic/main/usage.kt @@ -0,0 +1,6 @@ +import foo.Foo +import bar.Bar + +fun usage(): String { + return "${Foo()}${Bar()}" +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt index e40585b2e77..b61ec2493fd 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt @@ -198,4 +198,19 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { module("main", listOf(m1, m2)) } + + fun testUnnamedAgainstSeveralAutomatic() { + val a = module("autoA") + val b = module("autoB") + // Even though we only add autoA to the module graph, autoB should be added as well because autoA, being automatic, + // transitively requires every other automatic module, and in particular, autoB. + // Furthermore, because autoB is automatic, main should read autoB + module("main", listOf(a, b), addModules = listOf("autoA")) + } + + fun testNamedAgainstSeveralAutomatic() { + val a = module("autoA") + val b = module("autoB") + module("main", listOf(a, b)) + } }