Jeff Lockhart
01/17/2024, 5:49 PMfun foo(context: CoroutineContext? = null, factory: (String) -> T?)
to:
fun foo(context: CoroutineContext?, factory: (String) -> T?)
fun foo(factory: (String) -> T?)
Can I somehow keep the default argument function for binary compatibility with released library versions?Jeff Lockhart
01/17/2024, 5:51 PMfoo(::bar)
doesn't work for the default argument function signature, while it does with the regular function overloads.Jeff Lockhart
01/17/2024, 5:59 PM@Suppress("CONFLICTING_OVERLOADS", "CONFLICTING_JVM_DECLARATIONS")
fun foo(context: CoroutineContext?, factory: (String) -> T?)
@Suppress("CONFLICTING_OVERLOADS", "CONFLICTING_JVM_DECLARATIONS")
@Deprecated("Present for binary compatibility", level = DeprecationLevel.HIDDEN)
fun foo(context: CoroutineContext? = null, factory: (String) -> T?)
mbonnin
01/17/2024, 6:00 PMDeprecationLevel.HIDDEN
but looks like you've thought this through alreadymbonnin
01/17/2024, 6:01 PM@JvmName
?
@Suppress("CONFLICTING_OVERLOADS", "CONFLICTING_JVM_DECLARATIONS")
@JvmName("newFoo")
fun foo(context: CoroutineContext?, factory: (String) -> T?)
mbonnin
01/17/2024, 6:01 PM"CONFLICTING_JVM_DECLARATIONS
, not sure about "CONFLICTING_OVERLOADS"
Jeff Lockhart
01/17/2024, 6:01 PMCONFLICTING_OVERLOADS
error in the IDE. At compile time it gets the CONFLICTING_JVM_DECLARATIONS
error, which I can also suppress.Jeff Lockhart
01/17/2024, 6:03 PMmbonnin
01/17/2024, 6:08 PMfun foo(factory: (String) -> T?)
, that should work? It duplicates a bit the other one but it's not that badmbonnin
01/17/2024, 6:10 PM@JvmName
on the "old" one?
@JvmName("foo")
@Deprecated("old stuff", level = DeprecationLevel.HIDDEN)
fun foo2(context: Int? = null, factory: (String) -> Double?) {}
fun foo(context: Int, factory: (String) -> Double?) {}
fun foo(factory: (String) -> Double?){}
mbonnin
01/17/2024, 6:10 PMmbonnin
01/17/2024, 6:11 PMJeff Lockhart
01/17/2024, 6:11 PMmbonnin
01/17/2024, 6:12 PMmbonnin
01/17/2024, 6:14 PMmbonnin
01/17/2024, 6:16 PMJeff Lockhart
01/17/2024, 6:17 PMmbonnin
01/17/2024, 6:17 PMmbonnin
01/17/2024, 6:18 PMmbonnin
01/17/2024, 6:18 PMmbonnin
01/17/2024, 6:20 PM@JsName
I guess what we're looking for here is a way to control the name mangling in a KMP way.Jeff Lockhart
01/17/2024, 6:24 PM@ObjCName
, but then I also target Linux and Mingw as well.Jeff Lockhart
01/17/2024, 6:26 PMmbonnin
01/17/2024, 6:30 PMJeff Lockhart
01/17/2024, 6:30 PMmbonnin
01/17/2024, 6:31 PM.copy()
case from that article except you can't use the HIDDEN
trick because you're not adding an argumentJeff Lockhart
01/17/2024, 6:47 PMWorst case, you can just addThis might be the best, most straightforward option, keeping the default argument version and only adding the single argument one., that should work? It duplicates a bit the other one but it's not that badfun foo(factory: (String) -> T?)
fun foo(context: CoroutineContext? = null, factory: (String) -> T?)
fun foo(factory: (String) -> T?)
Jeff Lockhart
01/17/2024, 6:48 PMephemient
01/17/2024, 7:12 PMfun foo(context: CoroutineContext? = null, factory: (String) -> T?)
this previously created 2 functions:
fun foo(context: CoroutineContext?, factory: (String) -> T?)
@JvmSynthetic
fun foo(CoroutineContext?, (String) -> T?, Int)
where the latter is a wrapper invoking the first with arguments depending on flagsephemient
01/17/2024, 7:12 PM@Deprecated(HIDDEN)
since you don't want it to be called in source)Jeff Lockhart
01/17/2024, 7:27 PMpublic static synthetic fun foo$default (Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
which looks similar to what you have above, just with an Object
Int
parameter. mbonnin
01/17/2024, 7:29 PMJeff Lockhart
01/17/2024, 7:33 PMJeff Lockhart
01/17/2024, 7:45 PMmbonnin
01/17/2024, 8:27 PMmbonnin
01/17/2024, 8:27 PM$default
to maintain JVM symbol name
@JvmSynthetic
@JvmName("foo\$default")
fun foo(a: Int, b: Int) {}
Jeff Lockhart
01/17/2024, 8:35 PMJeff Lockhart
01/17/2024, 9:34 PM@Deprecated("For binary compatibility", level = DeprecationLevel.HIDDEN)
@JvmSynthetic
@JvmName("foo\$default")
fun <T : Any> foo(
context: CoroutineContext?,
factory: (String) -> T?,
flags: Int,
obj: Any?
) = foo(if (flags and 1 != 0) null else context, factory)
The flags implementation is based on this description.
The only difference in the output from binary compatibility validator is that the function is now final
, which shouldn't matter.
So the only question is, does this work for Kotlin/Native targets as well?Jeff Lockhart
01/17/2024, 10:27 PMephemient
01/18/2024, 12:17 AMephemient
01/18/2024, 12:18 AMephemient
01/18/2024, 12:22 AM@Suppress("CONFLICTING_OVERLOADS")
@JvmName("foo2")
fun foo(context: CoroutineContext?, factory: (String) -> T?)
@Suppress("CONFLICTING_OVERLOADS")
@Deprecated("Present for binary compatibility", level = DeprecationLevel.HIDDEN)
fun foo(context: CoroutineContext? = null, factory: (String) -> T?)
might maintain binary compatibility (possibly with @CName
etc. too?). not if it's `interface`/`open` though..Jeff Lockhart
01/18/2024, 3:29 AMinterface
or open
.