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.