Is there any way to have an api member that is pub...
# library-development
s
Is there any way to have an api member that is public but also not discoverable by a client? i.e. if you know it is there, you can use it, otherwise it is invisible? I think the answer is no, but I need to confirm.
j
If your specific case is to preserve binary compatibility for consumers that are already compiled, you could also used
@Deprecated
with level
HIDDEN
. But it won't allow new code to be compiled with the hidden declaration, so that might not work for you. If you want new code to compile, but still provide some friction, I think the best you can do is a
RequiresOptIn
with ERROR level.
1
There is also the specific case of exposing things for the sake of
inline
functions. Your inline function calls some other functions/properties, and those need to be public in the bytecode because they will be inlined in the consumer's code, but you don't want consumers to use these declarations directly. In this case, you can use
internal
+
@PublishedApi
to declare the functions that are used by inline functions and that you don't really want to expose.
If you describe your use case more specifically, we might think of other ways 😉
s
thanks, I have considered all of these options, unfortunately none meet the need of new code compilation, and truly hidden API. The specific use case is a "special" consumer of our library who wants "special" API to access functionality we would rather not vend publicly. If you happen to type the magic member's name, it will compile, but otherwise it isn't discoverable. Seems like the best way to do this is to just ship a special library for them alone.
j
If the API can be written "on top" of existing APIs, then yeah another module would do. But I guess that's not your case here. One alternative way to do this could be to use a subtype that only they know about, but the "official" static type that consumers get is a supertype with less functions. Getting the special API would be done by downcasting the known official supertype to the hidden subtype
b
you could do something like:
Copy code
interface PublicApi {
    fun doSomethingPublic()
}

interface PrivateApi {
    fun doSomethingPrivate()
}

fun PublicApi(): PublicApi {
    return object: PublicApi, PrivateApi {
        override fun doSomethingPublic() {
            println("public")
        }
        
        override fun doSomethingPrivate() {
            println("private")
        }
    }
}


fun main() {
    val publicApi = PublicApi()
    publicApi.doSomethingPublic()

    publicApi as PrivateApi // Only special people know you can actually do this ;)
    publicApi.doSomethingPrivate()
}
yeah I think that's pretty much the same thing as @Joffrey said 🙂
😄 1
j
I was rather thinking about making
PrivateApi
a real subtype of
PublicApi
, but yeah otherwise that would be the idea
s
I am hopeful this strategy works for them. This helps me scope the problem to what is possible so I don't promise something impossible. That is really helpful, thanks.
👍 1