Getting declared variables within Kotlin scope
Answered
I'm able to get Java/Groovy variables within a given scope using PsiScopesUtil.treeWalkUp(). I'm also able to get Python variables within a given scope using ControlFlowCache.getScope().getNamedElements().
What are the equivalent methods for doing this in Kotlin? I get no results when I use PsiScopesUtil.treeWalkUp() inside a Kotlin function. Are there more universal ways of doing this? PsiElement.processDeclarations() looks promising, but I can't get it to return anything either.
Please sign in to leave a comment.
Hi Brandon,
Wow did you use PsiScopesUtil.treeWalkUp() inside Kotlin function?
Apologies for the late reply.
I have a fairly simple action that I would like to print the declared variables up to that point. Here is an example that attempts to do that but the PsiScopeProcessor is never executed:
Hi Brandon,
Notice that PsiScopesUtil is Java-specific class (it's in java-psi-impl module) and that's probably why it's not executed (I didn't verify it, please check).
I would implement KtVisitor which collects the information you are interested in.
Hi Karol,
I tried using PsiTreeUtil.treeWalkUp which belongs to platform-api.jar, but it has the same effect. Looking closer, it seems most (if not all) Kotlin elements do not implement processDeclarations. For example, KtNamedFunction does not extend processDeclarations from PsiElementBase, which simply returns true. Do you know why Kotlin elements do not implement that function?
Also, I understand a KtVisitor could work, but doesn't that mean I would have to implement the logic which limits the visiting based on the scope? I would think that's already implemented since Kotlin already has the ability to recommend local variables during auto-completion.
Hi Brandon,
There are various ways, for example
or you can try to convert an element to a light class (e.g. `org.jetbrains.kotlin.asJava.LightClassUtilsKt#toLightElements`) and pass it to `treeWalkUp`
Thanks Dmitry, the elements.parents(true) solution seems to be the easiest to understand/implement. The only change I made was to filter on KtBlockExpression instead of KtNamedFunction. This allows me to grab more declarations (e.g those inside Ktor get("/") expression).
I'm sure I'm not grabbing all the variables available at a specific location, but this is getting a decent amount of them: