From 0439abba462a67e10c2fb73f2ae01d2a03892103 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 14 Feb 2018 11:37:28 +0100 Subject: [PATCH] Check that kotlin.stdlib is explicitly required in module-info Writing a Jigsaw-modular Kotlin program which doesn't require kotlin.stdlib doesn't make sense because it most likely will fail at runtime, on access to anything from the standard library. Previously, we checked that kotlin.stdlib was in the module graph, but that's not enough, we should also check that the source module requires it. '-Xallow-kotlin-package' can be used to disable the error. Add a test checking that an indirect (transitive) dependency is also OK --- .../jvm/compiler/ClasspathRootsResolver.kt | 2 +- .../moduleD/module-info.java | 4 ++- ...edWithIndirectDependencyViaOtherModule.txt | 1 + .../module-info.java | 3 ++ .../test.kt | 6 ++++ .../namedWithoutExplicitDependency.txt | 34 +------------------ .../jdkModulesFromNamed/main/module-info.java | 2 ++ .../multiReleaseLibrary/main/module-info.java | 2 ++ .../moduleC/module-info.java | 2 ++ .../moduleD/module-info.java | 2 ++ .../main/module-info.java | 2 ++ .../simple/moduleB/module-info.java | 2 ++ .../moduleB/module-info.java | 2 ++ .../module-info.java | 2 ++ .../compiler/Java9ModulesIntegrationTest.kt | 3 +- .../main/module-info.java | 2 ++ .../Java9MultiModuleHighlightingTest.kt | 4 ++- 17 files changed, 38 insertions(+), 37 deletions(-) create mode 100644 compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule.txt create mode 100644 compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/module-info.java create mode 100644 compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/test.kt 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 95c66a1b292..6652c06ac0b 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 @@ -265,7 +265,7 @@ class ClasspathRootsResolver( } } - if (requireStdlibModule && sourceModule != null && KOTLIN_STDLIB_MODULE_NAME !in allDependencies) { + if (requireStdlibModule && sourceModule != null && !javaModuleGraph.reads(sourceModule.name, KOTLIN_STDLIB_MODULE_NAME)) { report( ERROR, "The Kotlin standard library is not found in the module graph. " + diff --git a/compiler/testData/javaModules/dependOnManyModules/moduleD/module-info.java b/compiler/testData/javaModules/dependOnManyModules/moduleD/module-info.java index 42bc3beeee6..8fec54bdbd6 100644 --- a/compiler/testData/javaModules/dependOnManyModules/moduleD/module-info.java +++ b/compiler/testData/javaModules/dependOnManyModules/moduleD/module-info.java @@ -2,4 +2,6 @@ module moduleD { requires moduleA; requires moduleB; requires moduleC; -} \ No newline at end of file + + requires kotlin.stdlib; +} diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule.txt b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/module-info.java b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/module-info.java new file mode 100644 index 00000000000..f3b37fdbf7d --- /dev/null +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/module-info.java @@ -0,0 +1,3 @@ +module namedWithIndirectDependencyViaOtherModule { + requires namedWithExplicitDependency; +} diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/test.kt b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/test.kt new file mode 100644 index 00000000000..879c4b9d885 --- /dev/null +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithIndirectDependencyViaOtherModule/test.kt @@ -0,0 +1,6 @@ +import kotlin.text.Regex + +fun f1(): List = emptyList() +fun f2(): Array> = arrayOf() +fun f3(map: Map): Collection = + map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values diff --git a/compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency.txt b/compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency.txt index e52f151b592..5cfcb716366 100644 --- a/compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency.txt +++ b/compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency.txt @@ -1,34 +1,2 @@ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:1:20: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on -import kotlin.text.Regex - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:3:27: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on -fun f1(): List = emptyList() - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:4:17: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on -fun f2(): Array> = arrayOf() - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:4:22: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on -fun f2(): Array> = arrayOf() - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:5:22: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on -fun f3(map: Map): Collection = - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:5:42: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on -fun f3(map: Map): Collection = - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:6:13: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on - map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:6:26: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on - map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:6:31: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on - map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:6:48: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on - map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values - ^ -compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/test.kt:6:61: error: symbol is declared in module 'kotlin.stdlib' which current module does not depend on - map.filterNot { (key, entry) -> "$key".equals(entry.toString(), ignoreCase = true) }.values - ^ +compiler/testData/javaModules/dependencyOnStdlib/namedWithoutExplicitDependency/module-info.java: error: the Kotlin standard library is not found in the module graph. Please ensure you have the 'requires kotlin.stdlib' clause in your module definition COMPILATION_ERROR diff --git a/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java b/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java index fe3861e3055..87a88c8de60 100644 --- a/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java +++ b/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java @@ -2,4 +2,6 @@ module main { requires java.naming; requires jdk.net; requires oracle.desktop; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java b/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java index e236e735339..0fb94cf3856 100644 --- a/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java +++ b/compiler/testData/javaModules/multiReleaseLibrary/main/module-info.java @@ -1,3 +1,5 @@ module main { requires library; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/namedReadsTransitive/moduleC/module-info.java b/compiler/testData/javaModules/namedReadsTransitive/moduleC/module-info.java index 401e33a50c7..1187895d16a 100644 --- a/compiler/testData/javaModules/namedReadsTransitive/moduleC/module-info.java +++ b/compiler/testData/javaModules/namedReadsTransitive/moduleC/module-info.java @@ -1,3 +1,5 @@ module moduleC { requires moduleB; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/nonTransitiveDoesNotAffectExplicitDependency/moduleD/module-info.java b/compiler/testData/javaModules/nonTransitiveDoesNotAffectExplicitDependency/moduleD/module-info.java index 2608009a8c3..f89eaa41e0a 100644 --- a/compiler/testData/javaModules/nonTransitiveDoesNotAffectExplicitDependency/moduleD/module-info.java +++ b/compiler/testData/javaModules/nonTransitiveDoesNotAffectExplicitDependency/moduleD/module-info.java @@ -1,4 +1,6 @@ module moduleD { requires moduleC; requires moduleB; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/severalModulesWithTheSameName/main/module-info.java b/compiler/testData/javaModules/severalModulesWithTheSameName/main/module-info.java index d069dfb8d7a..83c84a81f37 100644 --- a/compiler/testData/javaModules/severalModulesWithTheSameName/main/module-info.java +++ b/compiler/testData/javaModules/severalModulesWithTheSameName/main/module-info.java @@ -1,3 +1,5 @@ module main { requires dependency; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/simple/moduleB/module-info.java b/compiler/testData/javaModules/simple/moduleB/module-info.java index b8f934c3a2d..05f3c03282c 100644 --- a/compiler/testData/javaModules/simple/moduleB/module-info.java +++ b/compiler/testData/javaModules/simple/moduleB/module-info.java @@ -1,3 +1,5 @@ module moduleB { requires moduleA; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/module-info.java b/compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/module-info.java index b8f934c3a2d..05f3c03282c 100644 --- a/compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/module-info.java +++ b/compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/module-info.java @@ -1,3 +1,5 @@ module moduleB { requires moduleA; + + requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/specifyPathToModuleInfoInArguments/someOtherDirectoryWithTheActualModuleInfo/module-info.java b/compiler/testData/javaModules/specifyPathToModuleInfoInArguments/someOtherDirectoryWithTheActualModuleInfo/module-info.java index b8f934c3a2d..05f3c03282c 100644 --- a/compiler/testData/javaModules/specifyPathToModuleInfoInArguments/someOtherDirectoryWithTheActualModuleInfo/module-info.java +++ b/compiler/testData/javaModules/specifyPathToModuleInfoInArguments/someOtherDirectoryWithTheActualModuleInfo/module-info.java @@ -1,3 +1,5 @@ module moduleB { requires moduleA; + + requires kotlin.stdlib; } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt index 5fc0ed19a93..02430b541fc 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt @@ -227,8 +227,9 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { fun testDependencyOnStdlib() { module("unnamed") - module("namedWithExplicitDependency") + val namedWithExplicitDependency = module("namedWithExplicitDependency") module("namedWithoutExplicitDependency") + module("namedWithIndirectDependencyViaOtherModule", listOf(namedWithExplicitDependency)) module("namedWithIndirectDependencyViaReflect", listOf(ForTestCompileRuntime.reflectJarForTests())) } diff --git a/idea/testData/multiModuleHighlighting/java9/simpleLibraryExportsPackage/main/module-info.java b/idea/testData/multiModuleHighlighting/java9/simpleLibraryExportsPackage/main/module-info.java index e236e735339..0fb94cf3856 100644 --- a/idea/testData/multiModuleHighlighting/java9/simpleLibraryExportsPackage/main/module-info.java +++ b/idea/testData/multiModuleHighlighting/java9/simpleLibraryExportsPackage/main/module-info.java @@ -1,3 +1,5 @@ module main { requires library; + + requires kotlin.stdlib; } diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/Java9MultiModuleHighlightingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/Java9MultiModuleHighlightingTest.kt index adc4f6d99c5..2eb5385ec81 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/Java9MultiModuleHighlightingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/Java9MultiModuleHighlightingTest.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.caches.resolve import com.intellij.openapi.module.Module +import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.MockLibraryUtil @@ -41,9 +42,10 @@ class Java9MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { fun testSimpleLibraryExportsPackage() = doTest { val jdk9Home = KotlinTestUtils.getJdk9HomeIfPossible() ?: return + // -Xallow-kotlin-package to avoid "require kotlin.stdlib" in module-info.java val library = MockLibraryUtil.compileJvmLibraryToJar( testDataPath + "${getTestName(true)}/library", "library", - extraOptions = listOf("-jdk-home", jdk9Home.path), + extraOptions = listOf("-jdk-home", jdk9Home.path, "-Xallow-kotlin-package"), useJava9 = true )