Is it okay to use `@kotlin.internal.InlineOnly`? (...
# announcements
m
Is it okay to use
@kotlin.internal.InlineOnly
? (esp. in a Kotlin-only library) 🙂
f
It's internal in Kotlin, how do you want to use it?
m
That’s easy:
Copy code
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.InlineOnly
inline fun …
f
That's pretty evil stuff in a library that you want to release to the public because you are basically opting in to experimental stuff that might change at any point in time but your users don't know that.
That said, you could also just annotate it with
@JvmSynthetic
and achieve the same goal. 😉
m
I don’t find it evil at all. Worst that could happen is that a) a later release of the binary suddenly includes a non-inlined function which isn’t used by Kotlin code anway b) compiling the code with a later Kotlin version may not work it if the annotation changes Existing releases shouldn’t be affected by any changes to the annotation or the compiler.
b
I don’t think it’s that big of a problem.
InlineOnly
is probably never going to change and the consequences of adding it are quite easy to predict. Also it is used a lot in the standard library so it’s unlikely to break code.
m
@JvmSynthetic
is for JVM only. I’m multiplatform. Also it doesn’t make sense. I don’t want the useless method to be there and not just hide it.
f
Does
@InlineOnly
actually remove it from the binary?
🚫 1
b
Also there is a somewhat nicer way to use the annotation. I use it by creating a small library with just the InlineOnly annotation (copy paste from the kotlin source) in the kotlin.internal package. To compile this you can either use java or just use
Copy code
-Xallow-kotlin-package
as a compiler argument.
f
Wouldn't it make more sense to press JetBrains a little to make it public?
They wanted to do that anyways.
m
I’m looking for a solution now, not several Kotlin iterations down the road 🙂 But I agree that asking them to make it public should also happen.
f
Well, you can just go for it. I would have loved to have it several times already too. 😉 If the resulting method is really excluded from the binary (which I will verify shortly, because the doc says it's just made private) then it's really awesome.
m
Where do the docs say it’s made private?
f
If it's only about using
inline
on something where IntelliJ says that the benfit is low of inlining then it's easier to just suppress that intention. It will be inlined in any event.
m
yup
Given all this I don't see a pressing issue to have it. 😛
b
Just checked. The resulting function is still in the class file. And it also dosen’t change the visibility.
m
Specifies that this function should not be called directly without inlining
Nothing about privacy
Yeah it still seems to be there 😮 Very misleading name then.
f
InlineOnly means that the Java method corresponding to this Kotlin function is marked private so that Java code can not access it (which is the only way to call an inline function without actually inlining it).
For this you can just use
@JvmSynthetic
, as I said.
m
Where did you find that info? 🤔 It’s not in the source code
f
The link I shared above with you, here it comes again: https://discuss.kotlinlang.org/t/how-does-synchronized-work/1528/2
m
But yeah if it doesn’t remove the non-inline function then it’s pointless anyway. I don’t care about Java.
Ah, there were two links!
f
😉
m
So not documentation but just a comment 😛
f
Yeah, remembered it incorrectly but was able to find it. 😎
m
Anyway, useless annotation indeed. Probably the multiplatform variant of
@JvmSynthetic
?
b
I guess you could write a tool that removes all functions with
@InlineOnly
from the binary, but I’m not sure if that would break the library. 😜
f
Don't know but there is no real way to hide stuff in a multiplatform manner, that's why I created https://youtrack.jetbrains.com/issue/KT-36439
m
@Burkhard may work. Basically just like ProGuard 😄
f
Having an inline function stay in the binary is not too bad because it allows you to reflect on it (in languages that support reflection), debug it (e.g. set breakpoints), and change from normal to inline and back without breaking clients.
private const val
should imho be removed from the binary, but reflection is probably the reason why even these guys stay.
Or
private typealias
that lead to class redeclaration compiler failures if there is a class of the same name in the package. 😛
m
- I’m not interested in reflection support (library actively tries to avoid full reflection - not multiplatform anyway) - I don’t think that the non-inlined function is necessary for debugging?! - The functions are inlined from the beginning, so no need for forward compatibility here.
b
It might lead to problems if someone compiles against your library with a different kotlin version though.
f
You need to look at this from a language designer point of view and not yours. 😉
m
That would mean full reflection on all platforms and everything dynamic for maximum compatibility, wouldn’t it? ^^
f
Erm, we are looking at a single feature here: removal of inlined code from the binary. There are good reasons why it is why it is as it is (outlined above). Hopefully Kotlin will get a macro system at some point because macros are what you are essentially asking for.
🤩 1
s
Macros would be spectacular. Rust does this particularly well.
f
❤️
Yes!