Question
Given a PsiElement
, how to determine if it is (or is contained within) a function or method, and if so, determine the first and last PsiElement that defines this function or method?
Generic solution?
For example, when I invoke my plugin while the caret is on the keyword fun
in Kotlin, I would like to select the entire method that has been declared (I understand some times this would fail, and in such cases I’ll have a fallback of a hard-coded amount of lines to expand).
It seems like this could be useful (from PsiTreeUtil
):
public static @Nullable <T extends PsiElement> T getParentOfType(@Nullable PsiElement element, boolean strict,
@NotNull Class<? extends T> @NotNull ... classes)
but it requires listing out all types of method PsiElements. I’d rather have something more generic that would find all methods and functions.
Psi stuff is based on languages, so I’m a bit lost in terms of abstractions. I understand not all languages have methods and functions (e.g. HTML, XML, etc.).
There is PsiMethod
that, at first, seems very generic, but the documentation mentions that is actually only for Java methods.
Example
To better illustrate my need:
kotlin
package com.foo.bar
import inc.bar.foo
class Wow {
val x = "hmm"
fun bing() { // START
println("shh")
} // END
}
If the caret is anywhere in between the start of the line marked with “START” and the end of the line marked with “END”, then I would like to select to entire method bing()
.
Alternative
Maybe there is a way to simply get the parent PsiElement ?
The main problem I see with that is that it’s hard to determine how far up the psi tree we need to go to get a relevant parent element.
For example, in the example above, if the caret is on "shh"
, isn’t the parent element println
? That would not be good enough.
Potentially something hacky like checking the class name of the PsiElement and selecting anything that contains “Method
” and “Function
” in it?