Use of Kotlin Light Classes on IDEA Plugin


#1

Hi, last week I added support for Kotlin to an existing IDEA plugin but found that it wasn't totally straightforward, so I would like to know if what I'm currently doing is okay (or maybe someone can at least point me up to some good plugin/code that makes use of those kotlin light classes).

What I ended up doing for getting the PSI Classes from a JetFile is (psiFile is the JetFile):

 
psiFile.declarations.asSequence()
        .map({ LightClassUtil.getPsiClass(it as? JetClass) })
        .filterNotNull().toList()

So I was wondering if there is a more efficient (not related to how I'm iterating the declarations) or better way of doing it or if this is just perfectly fine (I mean, maybe there is a class which caches the result for each declaration so that getPsiClass doesn't need to be called each time, or perhaps that is not necessary when calling that method, I don't know).

In any case let’s say that part wasn’t so “tough” to figure out (well, I just had to dive into the code a little bit I guess). What it wasn’t so easy to figure out, though, was when I had to add some code for getting a PsiAnnotation from a JetAnnotationEntry instance. So what I ended up doing was this:

JetAnnotationsIndex.getInstance().get(name, project, scope).asSequence()
        .mapNotNull({ jetAnnotation ->

            val function = jetAnnotation.parent?.parent as? JetFunction
 
            function?.let {
                val psiAnnotation = LightClassUtil.getLightClassMethod(function)?.modifierList?.findAnnotation(qualifiedName.toString())
                psiAnnotation?.let { NavigableKotlinPsiAnnotation(psiAnnotation, jetAnnotation) }
            }
  }).filterNotNull().toList()

So basically I navigate up from the jetAnnotation in order to get an instance of a ClassMethod and then from there I get the PsiAnnotation for the corresponding JetAnnotationEntry. I did it like that because I didn't find a way to directly get a PsiAnnotation from a JetAnnotation. So my question for this is, is this code also okay or did I missed something (maybe something I also missed for the first code)?

Also, I would like to know if there are any plans to add documentation and/or better support for creating IDEA plugins in the future after 1.0 is released (I mean, maybe it’s not immediately totally self-evident for some people—like me—how to add support for Kotlin to a new or existing plugin when diving into Kotlin’s source code)? :slight_smile:

Message was edited by: Rodrigo Quesada


#2

Oh, I forgot to add that NavigableKotlinPsiAnnotation is a custom class that wraps the returned PsiAnnotation in order to add navigation support to it (using jetElement.textOffset), so regarding that, am I missing something or are there plans to add support for that kind of stuff (which I guess the compiler or other classes in your code don't need right now)? :)


#3

On your first question, I'd do something like this:

PsiTreeUtil.getChildrenOfType(psiFile, JetClass::class.java)

#4

Yes, this looks correct. Note that this API changes very often, and we're nowhere near being able to offer this as a supported and documented API.


#5

Oh I see, no problem, I guess I'll just have to keep an eye on the API changes then. :) Thanks for replying!