I have two Kotlin classes in the same package:
Foo.kt
:
data class Foo(
val map: Map<String, String>? = null
)
Bar.kt
:
class Bar {
init {
val foo = Foo()
if (filter.map != null) {
val value = filter.map["some_key"] // IDE shows successful smart cast here
}
}
}
Then trying to compile only one class Bar.kt
:
kotlinc Bar.kt -d output
Class Foo.kt
resides in the same package, but nevertheless I’m getting the following compiler error:
error: smart cast to 'Map<String, String>' is impossible, because '...' is a public API property declared in different module
However compiling both classes completes successfully:
kotlinc Bar.kt Foo.kt -d output // OK
So, my question: is it possible to compile only one Bar.kt
class without smart cast error?
broot
March 12, 2022, 12:09am
2
As the error says, if you don’t specify both files, the compiler doesn’t consider them a part of the same module. And files from the same module have some special “privileges” that are not available otherwise, for example smart casting of properties in some cases.
You can use ?.let()
instead of smart casting:
filter.map?.let { val value = it["some_key"] }
2 Likes
Looks like this advanced compiler option can help me in my question:
-Xsingle-module // Combine modules for source files and binary dependencies into a single module
Unfortunately it causes a crash in the latest version of kotlinc
.
Already reported: https://youtrack.jetbrains.com/issue/KT-51622
2 Likes
When compiling only partial files, you can use -Xfriend-paths to point to the output directory to avoid this problem.
May be like this:
kotlinc Bar.kt -d output -Xfriend-paths=out
I had this problem for a few weeks , and I finally found this key argument while looking at the source code in the JetBrains/kotlin repository.
kotlin/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt at master · JetBrains/kotlin (github.com)