JetBrains / java-annotations

Annotations for JVM-based languages.
Apache License 2.0
404 stars 47 forks source link

@HiddenFromAutocomplete or the most useful missing low hanging fruit #64

Closed LifeIsStrange closed 2 years ago

LifeIsStrange commented 2 years ago

Hi @Jetbrains, there are many cases where a method has been superseded by another or simply exists for an implementationDetail reason. E.g in Kotlin multiplatform in order to make lists much more interoperable between pure JS and Kotlin JVM code, I have to make an extension method on MutableLIst.addAllMPP() that only exists as an implementation detail, it is used in our Kotlin JS and JVM wrappers of arraylists but elsewhere we want developpers to only use the regular .addAll(). There is already the @Deprecated annotation which put a strikethrough on the autocomplete result, but here we want to remove all noise and simply hides the method from autocomplete results, a basic filter. Therefore it would be amazing if you could implement an identifier annotation @HiddenFromAutocomplete that the Kotlin plugin (and maybe the Java one) could leverage :) On a more common case, it could be used for accelerating the reduction of use of the most evil deprecated or dangerous functions.

@amaembo friendly ping

amaembo commented 2 years ago

I'm not sure you can add this library as a dependency on a Kotlin multiplatform project, as this library is written in Java.

If it's implementation detail why not declare it as internal?

chashnikov commented 2 years ago

Also note that there is an attribute level in @Deprecated annotation in Kotlin, and specifying DeprecationLevel.HIDDEN will hide the variant from autocompletion as well.

LifeIsStrange commented 2 years ago

@amaembo

I'm not sure you can add this library as a dependency on a Kotlin multiplatform project, as this library is written in Java.

Yeah good question but I wanted at least to signal the use case to JetBrains. Though annotations markers in general are compatible with Kotlin multiplatform, e.g @Deprecrated is allowed.

If it's implementation detail why not declare it as internal?

It's a top level extension method, my BD ArrayList in kotlin js and the one in jvm needs a top level for both of them to have access to it. I can make the extension method internal but it doesn't change anything being top-level, it stills shows on autocomplete.

@chashnikov

specifying DeprecationLevel.HIDDEN will hide the variant from autocompletion as well

Well that would solve my issue unfortunately it does not seem to work. I have put this label and even after restarting the IDE, list._addAllMPP still shows in autocomplete :/ even when I type list.addAll it still shows..

@Deprecated("it is an implementation detail of BFArrayList", level = DeprecationLevel.HIDDEN)
fun <T> MutableList<T>._addAllMPP(elements: Collection<T>): Boolean {
    if (elements.isEmpty()) return false
    for (element in elements) {
        this.add(element)
    }
    return true
}

oh and I didn't realize but DeprecationLevel.HIDDEN makes the code unreachable:

actual open class BFArrayList<E> actual constructor(array: Array<E>) : java.util.ArrayList<E>(BFArrayAsCollection(array, isVarargs = true)) {
    actual override fun addAll(elements: Collection<E>): Boolean {
        return this._addAllMPP(elements) // unreachable, does not compile with HIDDEN
        //return super.addAll(elements)
    }
}
chashnikov commented 2 years ago

Yes, DeprecationLevel.HIDDEN is the most strict deprecation level, so code which use it won't compile. I think if it's ok to use the function from some trusted places, it shouldn't be marked as deprecated (which means that it shouldn't be used at all), it's better to somehow mark it as 'internal'. We already have @ApiStatus.Internal annotation in this library exactly for the cases where it isn't possible to limit visibility using visibility modifiers, and IDEA will show a warning if such items are used from external code. Currently this annotation isn't taken into account by completion, but I think it makes sense to assign lower priority for such items (IDEA-285531).

Anyway, I don't think we should remove any items from the completion list if code which use these items compiles successfully. If some item isn't shown in the completion, but users will be able to type it manually and get code which works, they'll think that it's a bug in the IDE. I think it should be enough to move such items to the bottom of the completion list and highlight them in a special way directly in the completion popup.