y

    Youssef Shoaib [MOD]

    6 months ago
    Is it possible to allow
    @HidesMembers
    in the future to work for more functions? And specifically, because I prototyped this in Kotlin 1.4 I think, can the resolution order for
    @HidesMembers
    be fixed to work for member extension functions (I think when I tried to get it to work
    HidesMembers
    only works for plain extension funs)? My use case is changing the behavior of functions like
    toString
    . Consider the fp-style Show:
    interface Show<T> {
        @HidesMembers
        fun T.toString(): String
    }
    
    object IntShow: Show<Int> {
        @HidesMembers
        override fun Int.toString() = "$this is an Integer"
    }
    // usage
    with(IntShow){
        println(5.toString())
    }
    but this can work for overriding any member function to explicitly change its behavior whenever a receiver is in context. I would wager that this isn't surprising to the user of a library because they explicitly opt-in by bringing a receiver in scope. Could this ever be a kotlin feature or am I dreaming too much lol?
    dmitriy.novozhilov

    dmitriy.novozhilov

    6 months ago
    Hi
    @HidesMembers
    won't be a user-accessible annotation neever. It was introduces in language to cover one specific corner case in kotlin/java stdlib parity (to hide
    java.util.Collection.forEach
    and resolve to kotlin extension insted) The main problem with
    @HidesMembers
    is performance: when compiler tries to resolve some function call, it looks for such function in several scopes and stops when it find good function in one of them. Member functions have high priority, and compiler looks here at the first place (and usually it stops here, because users quite frequently call members). But if
    @HidesMembers
    exists than compiler need to look in every scope for each call, because there might be some extension with this annotation, which will incredibly decrease resolution time. Resolution is the most performance heavy part and even with current lazy algorithm (stop of first found function) it takes ~60% of all frontend time
    BTW currently we have a hack for @HidesMembers: don't stop resolution on found function only if function is called
    forEach
    (to cover exact one existing legal usage of
    @HidesMembers
    )https://github.com/JetBrains/kotlin/blob/master/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt#L303