1

I'm autogenerating code with KotlinPoet and Auto Service. I didn't find any way to know if an annotated class has "internal" modifier so I can create another class with same modifier. For example:

@MyAnnotation
internal class Car

So I thought using Kotlin Reflection I would be able to get this information but no luck.

With the annotator processor I'm able to get the KClass but the visibility said "public": enter image description here

Any clues on how to do it?

Juan Saravia
  • 7,661
  • 6
  • 29
  • 41

3 Answers3

2

Kotlin's KClass has the visibility property, which can be KVisibility.INTERNAL.

Kiskae
  • 24,655
  • 2
  • 77
  • 74
  • I'm doing that but I see "public" instead of "internal". Code used: `(classElement as Symbol).type::class.visibility` – Juan Saravia Oct 28 '18 at 18:42
  • `x.type::class` would return the KClass of `Symbol.type` aka `KClass`, which is a public class. If the processed class is on the classpath, loading the class and then reflecting into the KClass would give you the required information. Otherwise you'd need to somehow parse the `@Metadata` annotation kotlin embeds in all its classes. – Kiskae Oct 28 '18 at 19:46
  • I did that (as you can see in the image preview in the question) but still not able to get that value. I tried parsing metadata but I didn't find it there neither. Am I missing something? – Juan Saravia Oct 28 '18 at 21:30
  • 1
    In the image I see you accessing `.type::class`, this does not do what you think it does. `::class` returns the `KClass` of the type it is called on, so since `.type` returns a `com.sun.tools.javac.code.Type` that is the KClass you're accessing. – Kiskae Oct 28 '18 at 21:57
  • oh man you are totally right. I don't really know how to get the KClass from annotation processing in order to get this info – Juan Saravia Oct 29 '18 at 01:03
  • Most annotaiton processors allow access to annotations within the code. But I dont think Jetbrains have published an official way to access the embedded metadata yet. – Kiskae Oct 29 '18 at 11:26
2

Kotlin reflection is not applicable during annotation processing. Kotlin reflection is for inspecting your code at runtime. However there is a way to parse the metadata out of Kotlin class files, it's called kotlinx-metadata-jvm.

To use this in your annotation processor, you'll have to obtain the AnnotationMirror of the kotlin.Metadata annotation. From that mirror, obtain the annotation values and use them to construct the KotlinClassHeader as you can see in the examples for kotlinx-metadata-jvm. Once you are there you can use kotlinx-metadata-jvm to extract the flags for your class.

diesieben07
  • 1,487
  • 1
  • 14
  • 25
0

Since internal is a visibility modifier, you should look for something related in the KClass API. The following will help you:

 /**
 * Visibility of this class, or `null` if its visibility cannot be represented in Kotlin.
 */
@SinceKotlin("1.1")
public val visibility: KVisibility?

Used like this: Car::class.visibility //INTERNAL

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
  • Same as the other answer, I'm doing that but I'm receiving "public": `(classElement as Symbol).type::class.visibility` -> public :S . Screenshot: https://drive.google.com/file/d/1fxxQeiXO1fnWCuZx9C0BdvDYEaqHXTZ4/view?usp=sharing – Juan Saravia Oct 28 '18 at 18:44
  • what is `(classElement as Symbol).type::class` giving you exactly? – s1m0nw1 Oct 28 '18 at 18:45
  • A KClass from the annotation processor. Please see the screenshot: Screenshot: https://drive.google.com/file/d/1fxxQeiXO1fnWCuZx9C0BdvDYEaqHXTZ4/view?usp=sharing – Juan Saravia Oct 28 '18 at 18:47
  • I added the screenshot in the question. `(classElement as Symbol).type::class` is giving me a KClass – Juan Saravia Oct 28 '18 at 18:50