Kapt: Cannot get function with backtick name as annotated element

I have an annotation processor and use RoundEnvironment.getElementsAnnotatedWith to collect the annotated elements to process on.
Also I use backticked function names in tests, like @MyAnnotation fun `perform some test`().
Now, when I run the processor via kapt, those backticked functions do never appear in the list of annotated elements. Others work quite well… Is this a general java annotation processing problem with such names?


Run into the exact same problem. Is there a bug to track this?

JVM identifier names only allow for [a-z][A-Z]_$ signs. If I remember correctly $ is used for internal compiler generated functions. I’m not sure how exactly backtick functions are translated into jvm bytecode but their name is somehow modified. There is also a good chance that those functions are marked with @JvmSynthetic to hide them from java (as they can’t be called from java code anyways). Either (or a combination of both) could prevent the RoundEnvironment from returning them to you.
If this is something you really need you should open a ticket at https://kotl.in/issue. I’m not sure how likely this is to change though. This might be just a consequence of how those functions have to be compiled, after all they have to be renamed somehow to turn them into valid function names.

If you want to see how they are compiled exactly you can use Tools>Kotlin>Show Kotlin Bytecode. There should be a button to decompile it into java if you are not familiar enough with JVM bytecode.

The example above actually gets decompiled to:-

public final void test getAdCachePool perform some test() { … }

So it looks like spaces are valid identifiers on the JVM but that’s a good point about @JvmSynthetic

Turns out I’m wrong. I also can’t find any restriction on JVM function names (maybe I missed something). Testing this myself I also get bytecode with spaces in the function name and it doesn’t have the synthetic modifier so that is probably also not the issue. Not sure why kapt doesn’t pick up this function then.

Maybe try looking in the generated java stubs (they should be somewhere in your build directory). Kapt generates them to interface with the normal java annotation processor…

Ah, that’s very interesting. I just learned today there is actually a flag to enable Java AP to process classfiles so perhaps this is how kapt is implemented. I can imagine that the generated stubs exclude methods uncallable from Java for performance reasons.

Thanks for looking into this we’ll take a closer look and report back :slight_smile:

From my understanding kapt just generates java stubs for each kotlin method in your project and then calls the java annotation processor on that. That is the reason that kapt only works for kotlin jvm and not js or native.