Support -Xmodule-path and -Xadd-modules command line arguments
#KT-18598 In Progress #KT-18599 Fixed
This commit is contained in:
+11
@@ -88,6 +88,17 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
|
||||
// Advanced options
|
||||
|
||||
@Argument(value = "-Xmodule-path", valueDescription = "<path>", description = "Paths where to find Java 9+ modules")
|
||||
public String javaModulePath;
|
||||
|
||||
@Argument(
|
||||
value = "-Xadd-modules",
|
||||
valueDescription = "<module[,]>",
|
||||
description = "Root modules to resolve in addition to the initial modules,\n" +
|
||||
"or all modules on the module path if <module> is ALL-MODULE-PATH"
|
||||
)
|
||||
public String[] additionalJavaModules;
|
||||
|
||||
@Argument(value = "-Xno-call-assertions", description = "Don't generate not-null assertion after each invocation of method returning not-null")
|
||||
public boolean noCallAssertions;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
@@ -106,6 +107,9 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
val classpath = getClasspath(paths, arguments)
|
||||
configuration.addJvmClasspathRoots(classpath)
|
||||
for (modularRoot in arguments.javaModulePath?.split(File.pathSeparatorChar).orEmpty()) {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, JvmModulePathRoot(File(modularRoot)))
|
||||
}
|
||||
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
|
||||
|
||||
@@ -299,6 +303,10 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, components)
|
||||
}
|
||||
}
|
||||
|
||||
arguments.additionalJavaModules?.let { additionalJavaModules ->
|
||||
configuration.addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, additionalJavaModules.toList())
|
||||
}
|
||||
}
|
||||
|
||||
override fun createArguments(): K2JVMCompilerArguments = K2JVMCompilerArguments().apply {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||
import org.jetbrains.kotlin.config.ContentRoot
|
||||
@@ -41,6 +42,7 @@ import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
||||
internal class ClasspathRootsResolver(
|
||||
private val psiManager: PsiManager,
|
||||
private val messageCollector: MessageCollector?,
|
||||
private val additionalModules: List<String>,
|
||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?
|
||||
) {
|
||||
private val javaModuleFinder = CliJavaModuleFinder(VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL))
|
||||
@@ -75,6 +77,15 @@ internal class ClasspathRootsResolver(
|
||||
is JvmClasspathRoot -> {
|
||||
result += JavaRoot(root, JavaRoot.RootType.BINARY)
|
||||
}
|
||||
is JvmModulePathRoot -> {
|
||||
// TODO: sanitize the automatic module name exactly as in javac
|
||||
// TODO: read Automatic-Module-Name manifest entry
|
||||
val module = modularBinaryRoot(root, automaticModuleName = { contentRoot.file.name })
|
||||
if (module != null) {
|
||||
// TODO: report something in case of several modules with the same name?
|
||||
modules += module
|
||||
}
|
||||
}
|
||||
else -> error("Unknown root type: $contentRoot")
|
||||
}
|
||||
}
|
||||
@@ -97,6 +108,17 @@ internal class ClasspathRootsResolver(
|
||||
return JavaModule.Explicit(JavaModuleInfo.create(psiJavaModule), root, moduleInfoFile, isBinary = false)
|
||||
}
|
||||
|
||||
private fun modularBinaryRoot(root: VirtualFile, automaticModuleName: () -> String): JavaModule? {
|
||||
val moduleInfoFile = root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE)
|
||||
return if (moduleInfoFile != null) {
|
||||
val moduleInfo = JavaModuleInfo.read(moduleInfoFile) ?: return null
|
||||
JavaModule.Explicit(moduleInfo, root, moduleInfoFile, isBinary = true)
|
||||
}
|
||||
else {
|
||||
JavaModule.Automatic(automaticModuleName(), root)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addModularRoots(modules: List<JavaModule>, result: MutableList<JavaRoot>) {
|
||||
val sourceModules = modules.filterIsInstance<JavaModule.Explicit>().filterNot(JavaModule::isBinary)
|
||||
if (sourceModules.size > 1) {
|
||||
@@ -113,12 +135,17 @@ internal class ClasspathRootsResolver(
|
||||
|
||||
if (javaModuleFinder.allObservableModules.none()) return
|
||||
|
||||
val rootModules =
|
||||
if (sourceModules.isNotEmpty()) {
|
||||
// TODO: support an option similar to --add-modules
|
||||
listOf(sourceModules.single().name)
|
||||
}
|
||||
else computeDefaultRootModules() // TODO: + everything from module path
|
||||
val addAllModulePathToRoots = "ALL-MODULE-PATH" in additionalModules
|
||||
if (addAllModulePathToRoots && sourceModules.isNotEmpty()) {
|
||||
report(ERROR, "-Xadd-modules=ALL-MODULE-PATH can only be used when compiling the unnamed module")
|
||||
return
|
||||
}
|
||||
|
||||
val rootModules = when {
|
||||
sourceModules.isNotEmpty() -> listOf(sourceModules.single().name) + additionalModules
|
||||
addAllModulePathToRoots -> modules.map(JavaModule::name)
|
||||
else -> computeDefaultRootModules() + modules.map(JavaModule::name)
|
||||
}
|
||||
|
||||
// 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 ->
|
||||
|
||||
@@ -194,7 +194,11 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
classpathRootsResolver = ClasspathRootsResolver(PsiManager.getInstance(project), messageCollector, this::contentRootToVirtualFile)
|
||||
classpathRootsResolver = ClasspathRootsResolver(
|
||||
PsiManager.getInstance(project), messageCollector,
|
||||
configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES),
|
||||
this::contentRootToVirtualFile
|
||||
)
|
||||
|
||||
val (initialRoots, javaModules) =
|
||||
classpathRootsResolver.convertClasspathRoots(configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS))
|
||||
@@ -304,7 +308,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
private fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? {
|
||||
return when (root) {
|
||||
is JvmClasspathRoot -> if (root.file.isFile) findJarRoot(root) else findLocalFile(root)
|
||||
is JvmClasspathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root)
|
||||
is JvmModulePathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root)
|
||||
is JavaSourceRoot -> findLocalFile(root)
|
||||
else -> throw IllegalStateException("Unexpected root: $root")
|
||||
}
|
||||
@@ -320,8 +325,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun findJarRoot(root: JvmClasspathRoot): VirtualFile? =
|
||||
applicationEnvironment.jarFileSystem.findFileByPath("${root.file}${URLUtil.JAR_SEPARATOR}")
|
||||
private fun findJarRoot(file: File): VirtualFile? =
|
||||
applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}")
|
||||
|
||||
private fun getSourceRootsCheckingForDuplicates(): Collection<String> {
|
||||
val uniqueSourceRoots = linkedSetOf<String>()
|
||||
|
||||
@@ -30,6 +30,8 @@ data class JvmClasspathRoot(override val file: File) : JvmContentRoot
|
||||
|
||||
data class JavaSourceRoot(override val file: File, val packagePrefix: String?) : JvmContentRoot
|
||||
|
||||
data class JvmModulePathRoot(override val file: File) : JvmContentRoot
|
||||
|
||||
fun CompilerConfiguration.addJvmClasspathRoot(file: File) {
|
||||
add(JVMConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(file))
|
||||
}
|
||||
|
||||
@@ -117,4 +117,6 @@ public class JVMConfigurationKeys {
|
||||
public static final CompilerConfigurationKey<Boolean> USE_JAVAC =
|
||||
CompilerConfigurationKey.create("use javac");
|
||||
|
||||
public static final CompilerConfigurationKey<List<String>> ADDITIONAL_JAVA_MODULES =
|
||||
CompilerConfigurationKey.create("additional Java modules");
|
||||
}
|
||||
|
||||
+3
@@ -1,5 +1,8 @@
|
||||
Usage: kotlinc-jvm <options> <source files>
|
||||
where advanced options include:
|
||||
-Xmodule-path=<path> Paths where to find Java 9+ modules
|
||||
-Xadd-modules=<module[,]> Root modules to resolve in addition to the initial modules,
|
||||
or all modules on the module path if <module> is ALL-MODULE-PATH
|
||||
-Xno-call-assertions Don't generate not-null assertion after each invocation of method returning not-null
|
||||
-Xno-param-assertions Don't generate not-null assertions on parameters of methods accessible from Java
|
||||
-Xno-optimize Disable optimizations
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
error: -Xadd-modules=ALL-MODULE-PATH can only be used when compiling the unnamed module
|
||||
COMPILATION_ERROR
|
||||
@@ -0,0 +1,3 @@
|
||||
package foo
|
||||
|
||||
class Foo
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
module main {
|
||||
exports foo;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package a;
|
||||
|
||||
public class A {}
|
||||
@@ -0,0 +1,3 @@
|
||||
module moduleA {
|
||||
exports a;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package b;
|
||||
|
||||
public class B {}
|
||||
@@ -0,0 +1,3 @@
|
||||
module moduleB {
|
||||
exports b;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package c;
|
||||
|
||||
public class C {}
|
||||
@@ -0,0 +1,3 @@
|
||||
module moduleC {
|
||||
exports c;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1,5 @@
|
||||
module moduleD {
|
||||
requires moduleA;
|
||||
requires moduleB;
|
||||
requires moduleC;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import a.*
|
||||
import b.B
|
||||
import c.C
|
||||
|
||||
fun usage() {
|
||||
A()
|
||||
B()
|
||||
C()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt:11:24: error: unresolved reference: httpserver
|
||||
val s: com.sun.net.httpserver.HttpServer? = null
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
@@ -0,0 +1,5 @@
|
||||
module main {
|
||||
requires java.naming;
|
||||
requires jdk.net;
|
||||
requires oracle.desktop;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fun main(args: Array<String>) {
|
||||
// Module java.naming
|
||||
val b: javax.naming.Binding? = null
|
||||
println(b)
|
||||
|
||||
// Module jdk.net
|
||||
val j: jdk.net.Sockets? = null
|
||||
println(j)
|
||||
|
||||
// Module jdk.httpserver (this module doesn't depend on it)
|
||||
val s: com.sun.net.httpserver.HttpServer? = null
|
||||
println(s)
|
||||
|
||||
// Module oracle.desktop
|
||||
val a: com.oracle.awt.AWTUtils? = null
|
||||
println(a)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1,17 @@
|
||||
fun main(args: Array<String>) {
|
||||
// Module java.naming
|
||||
val b: javax.naming.Binding? = null
|
||||
println(b)
|
||||
|
||||
// Module jdk.net
|
||||
val j: jdk.net.Sockets? = null
|
||||
println(j)
|
||||
|
||||
// Module jdk.httpserver
|
||||
val s: com.sun.net.httpserver.HttpServer? = null
|
||||
println(s)
|
||||
|
||||
// Module oracle.desktop
|
||||
val a: com.oracle.awt.AWTUtils? = null
|
||||
println(a)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package foo;
|
||||
|
||||
public class Foo {}
|
||||
@@ -0,0 +1,3 @@
|
||||
module moduleA {
|
||||
exports foo;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1,3 @@
|
||||
module moduleB {
|
||||
requires moduleA;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import foo.Foo
|
||||
|
||||
fun usage() {
|
||||
Foo()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package a;
|
||||
|
||||
import a.impl.AImpl;
|
||||
|
||||
public class A {
|
||||
public static AImpl getInstance() {
|
||||
return new AImpl();
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package a.impl;
|
||||
|
||||
import a.A;
|
||||
|
||||
public class AImpl extends A {}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
module moduleA {
|
||||
exports a;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
compiler/testData/javaModules/simpleUseNonExportedPackage/moduleB/usage.kt:8:9: error: symbol is declared in module 'moduleA' which does not export package 'a.impl'
|
||||
val a3: AImpl = A.getInstance()
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
module moduleB {
|
||||
requires moduleA;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
import a.*
|
||||
import a.impl.*
|
||||
|
||||
val a1: A = A()
|
||||
val a2: A = A.getInstance()
|
||||
val a3: AImpl = A.getInstance()
|
||||
@@ -0,0 +1,3 @@
|
||||
package foo;
|
||||
|
||||
public class Foo {}
|
||||
@@ -0,0 +1,3 @@
|
||||
module moduleA {
|
||||
exports foo;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Usage {
|
||||
public static void main(String[] args) {
|
||||
new foo.Foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import foo.Foo
|
||||
|
||||
fun usage() {
|
||||
Foo()
|
||||
}
|
||||
@@ -912,6 +912,27 @@ public class KotlinTestUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean compileJavaFilesExternallyWithJava9(@NotNull Collection<File> files, @NotNull List<String> options) {
|
||||
File jdk9 = getJdk9HomeIfPossible();
|
||||
assert jdk9 != null : "Environment variable JDK_19 is not set";
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add(new File(jdk9, "bin/javac").getPath());
|
||||
command.addAll(options);
|
||||
for (File file : files) {
|
||||
command.add(file.getPath());
|
||||
}
|
||||
|
||||
try {
|
||||
Process process = new ProcessBuilder().command(command).inheritIO().start();
|
||||
process.waitFor();
|
||||
return process.exitValue() == 0;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String errorsToString(@NotNull DiagnosticCollector<JavaFileObject> diagnosticCollector, boolean humanReadable) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
+13
-4
@@ -39,6 +39,8 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() {
|
||||
return File(testDataDirectory, "${getTestName(true)}.$extension")
|
||||
}
|
||||
|
||||
class JavaCompilationError : AssertionError("Java files are not compiled successfully")
|
||||
|
||||
/**
|
||||
* Compiles all sources (.java and .kt) under the directory named [libraryName] to [destination].
|
||||
* [destination] should be either a path to the directory under [tmpdir], or a path to the resulting .jar file (also under [tmpdir]).
|
||||
@@ -50,10 +52,15 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() {
|
||||
libraryName: String,
|
||||
destination: File = File(tmpdir, "$libraryName.jar"),
|
||||
additionalOptions: List<String> = emptyList(),
|
||||
compileJava: (sourceDir: File, javaFiles: List<File>, outputDir: File) -> Boolean = { _, javaFiles, outputDir ->
|
||||
KotlinTestUtils.compileJavaFiles(javaFiles, listOf("-d", outputDir.path))
|
||||
},
|
||||
checkKotlinOutput: (String) -> Unit = { actual -> assertEquals(normalizeOutput("" to ExitCode.OK), actual) },
|
||||
vararg extraClassPath: File
|
||||
): File {
|
||||
val javaFiles = FileUtil.findFilesByMask(JAVA_FILES, File(testDataDirectory, libraryName))
|
||||
val kotlinFiles = FileUtil.findFilesByMask(KOTLIN_FILES, File(testDataDirectory, libraryName))
|
||||
val sourceDir = File(testDataDirectory, libraryName)
|
||||
val javaFiles = FileUtil.findFilesByMask(JAVA_FILES, sourceDir)
|
||||
val kotlinFiles = FileUtil.findFilesByMask(KOTLIN_FILES, sourceDir)
|
||||
assert(javaFiles.isNotEmpty() || kotlinFiles.isNotEmpty()) { "There should be either .kt or .java files in the directory" }
|
||||
|
||||
val isJar = destination.name.endsWith(".jar")
|
||||
@@ -61,12 +68,14 @@ abstract class AbstractKotlinCompilerIntegrationTest : TestCaseWithTmpdir() {
|
||||
val outputDir = if (isJar) File(tmpdir, "output-$libraryName") else destination
|
||||
if (kotlinFiles.isNotEmpty()) {
|
||||
val output = compileKotlin(libraryName, outputDir, extraClassPath.toList(), K2JVMCompiler(), additionalOptions, expectedFileName = null)
|
||||
assertEquals(normalizeOutput("" to ExitCode.OK), normalizeOutput(output))
|
||||
checkKotlinOutput(normalizeOutput(output))
|
||||
}
|
||||
|
||||
if (javaFiles.isNotEmpty()) {
|
||||
outputDir.mkdirs()
|
||||
KotlinTestUtils.compileJavaFiles(javaFiles, listOf("-d", outputDir.path))
|
||||
if (!compileJava(sourceDir, javaFiles, outputDir)) {
|
||||
throw JavaCompilationError()
|
||||
}
|
||||
}
|
||||
|
||||
if (isJar) {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jvm.compiler
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() {
|
||||
override val testDataPath: String
|
||||
get() = "compiler/testData/javaModules/"
|
||||
|
||||
private fun module(
|
||||
name: String,
|
||||
modulePath: List<File> = emptyList(),
|
||||
addModules: List<String> = emptyList()
|
||||
): File {
|
||||
val jdk9Home = KotlinTestUtils.getJdk9HomeIfPossible() ?: return File("<test-skipped>")
|
||||
|
||||
val paths = modulePath.joinToString(separator = File.pathSeparator) { it.path }
|
||||
|
||||
val kotlinOptions = mutableListOf(
|
||||
"-jdk-home", jdk9Home.path,
|
||||
"-Xmodule-path=$paths"
|
||||
)
|
||||
if (addModules.isNotEmpty()) {
|
||||
kotlinOptions += "-Xadd-modules=${addModules.joinToString()}"
|
||||
}
|
||||
|
||||
return compileLibrary(
|
||||
name,
|
||||
additionalOptions = kotlinOptions,
|
||||
compileJava = { _, javaFiles, outputDir ->
|
||||
val javaOptions = mutableListOf(
|
||||
"-d", outputDir.path,
|
||||
"--module-path", paths
|
||||
)
|
||||
if (addModules.isNotEmpty()) {
|
||||
javaOptions += "--add-modules"
|
||||
javaOptions += addModules.joinToString()
|
||||
}
|
||||
KotlinTestUtils.compileJavaFilesExternallyWithJava9(javaFiles, javaOptions)
|
||||
},
|
||||
checkKotlinOutput = { actual ->
|
||||
KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "$name.txt"), actual)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun testSimple() {
|
||||
val a = module("moduleA")
|
||||
module("moduleB", listOf(a))
|
||||
}
|
||||
|
||||
fun testSimpleUseNonExportedPackage() {
|
||||
val a = module("moduleA")
|
||||
module("moduleB", listOf(a))
|
||||
}
|
||||
|
||||
fun testDependOnManyModules() {
|
||||
val a = module("moduleA")
|
||||
val b = module("moduleB")
|
||||
val c = module("moduleC")
|
||||
module("moduleD", listOf(a, b, c))
|
||||
}
|
||||
|
||||
fun testUnnamedDependsOnNamed() {
|
||||
val a = module("moduleA")
|
||||
module("moduleB", listOf(a), listOf("moduleA"))
|
||||
|
||||
// Also check that -Xadd-modules=ALL-MODULE-PATH has the same effect as -Xadd-module=moduleA, i.e. adds moduleA to the roots
|
||||
module("moduleB", listOf(a), listOf("ALL-MODULE-PATH"))
|
||||
}
|
||||
|
||||
fun testAllModulePathAndNamedModule() {
|
||||
try {
|
||||
module("main", addModules = listOf("ALL-MODULE-PATH"))
|
||||
}
|
||||
catch (e: JavaCompilationError) {
|
||||
// Java compilation should fail, it's expected
|
||||
}
|
||||
}
|
||||
|
||||
fun testJdkModulesFromNamed() {
|
||||
module("main")
|
||||
}
|
||||
|
||||
fun testJdkModulesFromUnnamed() {
|
||||
module("main")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user