From 9fcf6c5f8980adaabc49581fee85d4ed08ca4a8b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 8 Feb 2024 23:54:59 +0100 Subject: [PATCH] JVM: add tests on some JPMS-related diagnostics Somehow we ended up in the state where we have two diagnostics which are not covered by any tests in the project. This commit adds simple tests for them. #KT-60797 --- .../noDependencyOnNamed/lib/foo/Foo.java | 6 ++++ .../noDependencyOnNamed/lib/module-info.java | 3 ++ .../javaModules/noDependencyOnNamed/main.txt | 13 ++++++++ .../noDependencyOnNamed/main/module-info.java | 3 ++ .../noDependencyOnNamed/main/usage.kt | 7 +++++ .../noDependencyOnUnnamed/lib/foo/Foo.java | 6 ++++ .../noDependencyOnUnnamed/main.txt | 13 ++++++++ .../main/module-info.java | 3 ++ .../noDependencyOnUnnamed/main/usage.kt | 7 +++++ .../AbstractJavaModulesIntegrationTest.kt | 31 +++++++++++++++++-- 10 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/javaModules/noDependencyOnNamed/lib/foo/Foo.java create mode 100644 compiler/testData/javaModules/noDependencyOnNamed/lib/module-info.java create mode 100644 compiler/testData/javaModules/noDependencyOnNamed/main.txt create mode 100644 compiler/testData/javaModules/noDependencyOnNamed/main/module-info.java create mode 100644 compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt create mode 100644 compiler/testData/javaModules/noDependencyOnUnnamed/lib/foo/Foo.java create mode 100644 compiler/testData/javaModules/noDependencyOnUnnamed/main.txt create mode 100644 compiler/testData/javaModules/noDependencyOnUnnamed/main/module-info.java create mode 100644 compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt diff --git a/compiler/testData/javaModules/noDependencyOnNamed/lib/foo/Foo.java b/compiler/testData/javaModules/noDependencyOnNamed/lib/foo/Foo.java new file mode 100644 index 00000000000..26688f00945 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnNamed/lib/foo/Foo.java @@ -0,0 +1,6 @@ +package foo; + +public class Foo { + public int field = 42; + public void method() {} +} diff --git a/compiler/testData/javaModules/noDependencyOnNamed/lib/module-info.java b/compiler/testData/javaModules/noDependencyOnNamed/lib/module-info.java new file mode 100644 index 00000000000..1d982df087c --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnNamed/lib/module-info.java @@ -0,0 +1,3 @@ +module lib { + exports foo; +} diff --git a/compiler/testData/javaModules/noDependencyOnNamed/main.txt b/compiler/testData/javaModules/noDependencyOnNamed/main.txt new file mode 100644 index 00000000000..38772b215d4 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnNamed/main.txt @@ -0,0 +1,13 @@ +compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:3:15: error: symbol is declared in module 'lib' which current module does not depend on +fun test(foo: Foo) { + ^^^ +compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:4:9: error: symbol is declared in module 'lib' which current module does not depend on + foo.field + ^^^^^ +compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:5:9: error: symbol is declared in module 'lib' which current module does not depend on + foo.method() + ^^^^^^ +compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt:6:5: error: symbol is declared in module 'lib' which current module does not depend on + Foo() + ^^^ +COMPILATION_ERROR diff --git a/compiler/testData/javaModules/noDependencyOnNamed/main/module-info.java b/compiler/testData/javaModules/noDependencyOnNamed/main/module-info.java new file mode 100644 index 00000000000..e7e86dd9f44 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnNamed/main/module-info.java @@ -0,0 +1,3 @@ +module main { + requires kotlin.stdlib; +} diff --git a/compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt b/compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt new file mode 100644 index 00000000000..240c80c56b0 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnNamed/main/usage.kt @@ -0,0 +1,7 @@ +import foo.* + +fun test(foo: Foo) { + foo.field + foo.method() + Foo() +} diff --git a/compiler/testData/javaModules/noDependencyOnUnnamed/lib/foo/Foo.java b/compiler/testData/javaModules/noDependencyOnUnnamed/lib/foo/Foo.java new file mode 100644 index 00000000000..26688f00945 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnUnnamed/lib/foo/Foo.java @@ -0,0 +1,6 @@ +package foo; + +public class Foo { + public int field = 42; + public void method() {} +} diff --git a/compiler/testData/javaModules/noDependencyOnUnnamed/main.txt b/compiler/testData/javaModules/noDependencyOnUnnamed/main.txt new file mode 100644 index 00000000000..ebb1f4250b6 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnUnnamed/main.txt @@ -0,0 +1,13 @@ +compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:3:15: error: symbol is declared in unnamed module which is not read by current module +fun test(foo: Foo) { + ^^^ +compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:4:9: error: symbol is declared in unnamed module which is not read by current module + foo.field + ^^^^^ +compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:5:9: error: symbol is declared in unnamed module which is not read by current module + foo.method() + ^^^^^^ +compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt:6:5: error: symbol is declared in unnamed module which is not read by current module + Foo() + ^^^ +COMPILATION_ERROR diff --git a/compiler/testData/javaModules/noDependencyOnUnnamed/main/module-info.java b/compiler/testData/javaModules/noDependencyOnUnnamed/main/module-info.java new file mode 100644 index 00000000000..e7e86dd9f44 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnUnnamed/main/module-info.java @@ -0,0 +1,3 @@ +module main { + requires kotlin.stdlib; +} diff --git a/compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt b/compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt new file mode 100644 index 00000000000..240c80c56b0 --- /dev/null +++ b/compiler/testData/javaModules/noDependencyOnUnnamed/main/usage.kt @@ -0,0 +1,7 @@ +import foo.* + +fun test(foo: Foo) { + foo.field + foo.method() + Foo() +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/modules/AbstractJavaModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/modules/AbstractJavaModulesIntegrationTest.kt index 0c33ea1f49f..cd54e9fb4c9 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/modules/AbstractJavaModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/modules/AbstractJavaModulesIntegrationTest.kt @@ -35,6 +35,7 @@ abstract class AbstractJavaModulesIntegrationTest( addModules: List = emptyList(), additionalKotlinArguments: List = emptyList(), manifest: Manifest? = null, + destination: File? = null, checkKotlinOutput: (String) -> Unit = this.checkKotlinOutput(name), ): File { val paths = (modulePath + ForTestCompileRuntime.runtimeJarForTests()).joinToString(separator = File.pathSeparator) { it.path } @@ -51,7 +52,8 @@ abstract class AbstractJavaModulesIntegrationTest( return compileLibrary( name, - additionalOptions = kotlinOptions, + destination ?: File(tmpdir, "$name.jar"), + kotlinOptions, compileJava = { _, javaFiles, outputDir -> val javaOptions = mutableListOf( "-d", outputDir.path, @@ -63,8 +65,8 @@ abstract class AbstractJavaModulesIntegrationTest( } KotlinTestUtils.compileJavaFilesExternallyWithJava11(javaFiles, javaOptions) }, - checkKotlinOutput = checkKotlinOutput, - manifest = manifest + checkKotlinOutput, + manifest ) } @@ -349,4 +351,27 @@ abstract class AbstractJavaModulesIntegrationTest( assertTrue(it, it.trimEnd().endsWith("COMPILATION_ERROR")) }) } + + // TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE. + fun testNoDependencyOnNamed() = muteForK2 { + // This is a test on the JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE diagnostic. + val lib = module("lib") + module("main", listOf(lib), listOf("lib")) + } + + // TODO (KT-60797): missing JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE. + fun testNoDependencyOnUnnamed() = muteForK2 { + // This is a test on the JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE diagnostic. + // Most of the other tests in this class are compiling modules to jars, however here we need to compile the module to a directory. + // The reason is twofold: + // 1) Currently the compiler adds all classpath entries as module path entries as long as we're compiling a named module (i.e. have + // `module-info.java` in the sources), see `configureSourceRoots` in `KotlinToJVMBytecodeCompiler.kt`. This is most likely + // incorrect. + // 2) All jars found in the module path which are NOT named modules are loaded as automatic modules, see + // `ClasspathRootsResolver.modularBinaryRoot`. Combined with p.1, it means that _any_ jar in the dependencies will be loaded + // as either a named or an automatic module; there's no way to observe a jar that is a part of the unnamed module. + // In this test we're checking the diagnostic about using symbols from unnamed modules, so we need to compile 'lib' to a directory. + val lib = module("lib", destination = File(tmpdir, name)) + module("main", additionalKotlinArguments = listOf("-classpath", lib.path)) + } }