Access methods of PsiVariable object representation

Answered

Hi folks,

I made a plugin that works with groovy language. Let's say this code (from a test, failing at this point)

List<GenericValue> rings = from('Mordor')//...
rings.forEach{GenericValue it ->
it.<caret>
}

The plugin now manages to see that the it element is of a type GenericValue.

But i know that the GenericValue class has a method which is getEntityName.

What i'd like to know is this :

Is there a way to access the getEntityName method ( and result ) from the PsiVariable element representing the it element ?

Something like :

PsiVariable myVar.computeInnerMethodWithName('getEntityName')
0
6 comments

Hi Gaëtan,

If you see the "it" type, then check what is the class of type and what it contains. If it is PsiClassType, you can get PsiClass and get methods from it.

0

Hi Karol, thanks a lot for your answer.

I don't think i understand it, how would a PsiMethod from the class would give the result from the it instance

it.getEntityName()

that i'm trying to emulate ?
Maybe my problem isn't clear ?

0

Hi Gaëtan,

I think I understand your problem and maybe I was unclear with my answer.

My understanding:

  • you have a variable "it" and your plugin at <caret> position knows its type is GenericValue - so you know the type (PsiType) of "it" variable, correct?
  • if you know the type of "it" variable, then check what is the exact type (PsiClassType, other XxxType?)
  • once you have actual PsiType implementation, then check if you can resolve its definition
  • if you can resolve its definition, then check its members (for PsiClassType just call allMethods and check if it contains method with name getEntityName

If I'm wrong at any point, please provide more information that will fill the gap.

1
  • you have a variable "it" and your plugin at <caret> position knows its type is GenericValue - so you know the type (PsiType) of "it" variable, correct?

=> Yes, that's done in a pattern (from an other topic : https://intellij-support.jetbrains.com/hc/en-us/community/posts/4417764322578-How-to-get-the-type-of-a-variable-in-a-pattern?page=1#community_comment_4418809943570 )

  • if you know the type of "it" variable, then check what is the exact type (PsiClassType, other XxxType?)
  • once you have actual PsiType implementation, then check if you can resolve its definition

=> I have the definition :

@Override
protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) {
ProjectServiceInterface structureService = parameters.getPosition().getProject().getService(ProjectServiceInterface.class)

PsiElement element = parameters.getPosition()
try {
PsiElement genericValueRef = element.getParent().getFirstChild()
assert genericValueRef instanceof GrReferenceExpression

PsiElement initialVariable = genericValueRef.resolve()
assert initialVariable instanceof GrVariable

String entityName = retrieveEntityOrViewName(initialVariable.getInitializerGroovy().getText())
//...
}

Currently, i use a regexp to extract (from the definition text) the information i'm looking for, which is the entity name. This one works.

But now i have the case of a loop inside a list, like in the intro of the thread.

  • if you can resolve its definition, then check its members (for PsiClassType just call allMethods and check if it contains method with name getEntityName

=> yes, i have that now, but is there a way to compute and get the result of such a method for the it object?

Again, thanks a lot for your answers

0

Hi Gaëtan,

Sorry, I misunderstood you then.

I'm not sure it is a good idea to evaluate scripts in the completion, which should be fast, but you can take a look at:
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360000149284-Running-a-script-in-a-plugin

 

1

Thanks. I'll look into this. I started to figure that there would be no easy way to do this.

I'll come back and post my solution if i manage one :)

0

Please sign in to leave a comment.