Add compiler argument -Xfriend-paths for kotlinc-jvm
#KT-21910 Fixed
This commit is contained in:
+5
-1
@@ -244,7 +244,11 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-Xdisable-standard-script", description = "Disable standard kotlin script support")
|
||||
var disableStandardScript: Boolean by FreezableVar(false)
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
@Argument(
|
||||
value = "-Xfriend-paths",
|
||||
valueDescription = "<path>",
|
||||
description = "Paths to output directories for friend modules (whose internals should be visible)"
|
||||
)
|
||||
var friendPaths: Array<String>? by FreezableVar(null)
|
||||
|
||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ where advanced options include:
|
||||
-Xdisable-default-scripting-plugin
|
||||
Do not enable scripting plugin by default
|
||||
-Xdisable-standard-script Disable standard kotlin script support
|
||||
-Xfriend-paths=<path> Paths to output directories for friend modules (whose internals should be visible)
|
||||
-Xmultifile-parts-inherit Compile multifile classes as a hierarchy of parts and facade
|
||||
-Xmodule-path=<path> Paths where to find Java 9+ modules
|
||||
-Xjavac-arguments=<option[,]> Java compiler arguments
|
||||
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
package a
|
||||
|
||||
internal interface InternalInterface
|
||||
|
||||
public class PublicClass {
|
||||
internal fun internalMemberFun() {}
|
||||
|
||||
internal companion object {}
|
||||
}
|
||||
|
||||
internal val internalVal = ""
|
||||
|
||||
internal fun internalFun(s: String): String = s
|
||||
|
||||
internal typealias InternalTypealias = InternalInterface
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:3:21: error: cannot access 'InternalInterface': it is internal in 'a'
|
||||
private fun test(i: InternalInterface): InternalTypealias {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:3:41: error: cannot access 'InternalTypealias': it is internal in 'a'
|
||||
private fun test(i: InternalInterface): InternalTypealias {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:4:19: error: cannot access 'internalMemberFun': it is internal in 'PublicClass'
|
||||
PublicClass().internalMemberFun()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:5:17: error: cannot access 'Companion': it is internal in 'PublicClass'
|
||||
PublicClass.Companion
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:7:5: error: cannot access 'internalFun': it is internal in 'a'
|
||||
internalFun(internalVal)
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/internalFromForeignModule/source.kt:7:17: error: cannot access 'internalVal': it is internal in 'a'
|
||||
internalFun(internalVal)
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import a.*
|
||||
|
||||
private fun test(i: InternalInterface): InternalTypealias {
|
||||
PublicClass().internalMemberFun()
|
||||
PublicClass.Companion
|
||||
|
||||
internalFun(internalVal)
|
||||
|
||||
return i
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package a
|
||||
|
||||
internal interface InternalInterface
|
||||
|
||||
public class PublicClass {
|
||||
internal fun internalMemberFun() {}
|
||||
|
||||
internal companion object {}
|
||||
}
|
||||
|
||||
internal val internalVal = ""
|
||||
|
||||
internal fun internalFun(s: String): String = s
|
||||
|
||||
internal typealias InternalTypealias = InternalInterface
|
||||
+1
@@ -0,0 +1 @@
|
||||
OK
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import a.*
|
||||
|
||||
private fun test(i: InternalInterface): InternalTypealias {
|
||||
PublicClass().internalMemberFun()
|
||||
PublicClass.Companion
|
||||
|
||||
internalFun(internalVal)
|
||||
|
||||
return i
|
||||
}
|
||||
@@ -16,22 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.test.CompilerTestUtil
|
||||
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* This test checks that [org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments.friendPaths] works by invoking the compiler's
|
||||
* "exec" method directly. Once there's a CLI argument for friend paths, it can be simplified to use that CLI argument instead.
|
||||
*/
|
||||
class FriendPathsTest : TestCaseWithTmpdir() {
|
||||
private fun getTestDataDirectory(): File = File("compiler/testData/friendPaths/")
|
||||
|
||||
@@ -40,7 +29,13 @@ class FriendPathsTest : TestCaseWithTmpdir() {
|
||||
val libDest = File(tmpdir, "lib.jar")
|
||||
CompilerTestUtil.executeCompilerAssertSuccessful(K2JVMCompiler(), listOf("-d", libDest.path, libSrc.path))
|
||||
|
||||
Assert.assertEquals(ExitCode.OK, invokeCompiler(libDest.path))
|
||||
CompilerTestUtil.executeCompilerAssertSuccessful(
|
||||
K2JVMCompiler(),
|
||||
listOf(
|
||||
"-d", tmpdir.path, "-cp", libDest.path, File(getTestDataDirectory(), "usage.kt").path,
|
||||
"-Xfriend-paths=${libDest.path}"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testDirectory() {
|
||||
@@ -48,28 +43,12 @@ class FriendPathsTest : TestCaseWithTmpdir() {
|
||||
val libDest = File(tmpdir, "lib")
|
||||
CompilerTestUtil.executeCompilerAssertSuccessful(K2JVMCompiler(), listOf("-d", libDest.path, libSrc.path))
|
||||
|
||||
Assert.assertEquals(ExitCode.OK, invokeCompiler(libDest.path))
|
||||
}
|
||||
|
||||
private fun invokeCompiler(libraryPath: String): ExitCode {
|
||||
return K2JVMCompiler().exec(ThrowingMessageCollector(), Services.EMPTY, K2JVMCompilerArguments().apply {
|
||||
destination = tmpdir.path
|
||||
classpath = libraryPath
|
||||
freeArgs = arrayListOf(File(getTestDataDirectory(), "usage.kt").path)
|
||||
|
||||
friendPaths = arrayOf(libraryPath)
|
||||
})
|
||||
}
|
||||
|
||||
private class ThrowingMessageCollector : MessageCollector {
|
||||
override fun clear() {}
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
|
||||
if (severity.isError) {
|
||||
Assert.fail("${severity.presentableName}: $message at $location")
|
||||
}
|
||||
}
|
||||
|
||||
override fun hasErrors(): Boolean = false
|
||||
CompilerTestUtil.executeCompilerAssertSuccessful(
|
||||
K2JVMCompiler(),
|
||||
listOf(
|
||||
"-d", tmpdir.path, "-cp", libDest.path, File(getTestDataDirectory(), "usage.kt").path,
|
||||
"-Xfriend-paths=${libDest.path}"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -471,6 +471,15 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
||||
)
|
||||
}
|
||||
|
||||
fun testInternalFromForeignModule() {
|
||||
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
|
||||
}
|
||||
|
||||
fun testInternalFromFriendModule() {
|
||||
val library = compileLibrary("library")
|
||||
compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}"))
|
||||
}
|
||||
|
||||
companion object {
|
||||
// compiler before 1.1.4 version did not include suspension marks into bytecode.
|
||||
private fun stripSuspensionMarksToImitateLegacyCompiler(bytes: ByteArray): Pair<ByteArray, Int> {
|
||||
|
||||
Reference in New Issue
Block a user