Inspections and "Go To Declaration" require cut/paste before detecting correct structure
The custom language plugin I'm creating doesn't seem to pick up code changes that should refresh which inspections are triggered or find the usage of declarations created.
For example, let's say I have the custom code:
define
a sub entity,
has b,
plays r;
c sub relation,
relates r;
In this example "plays r" is a usage of the declaration "relates r". However, when I type this out IntelliJ never realizes that "plays r" is a usage and so the "Go To Declaration" will not work if I click on the "plays r" and "Find Usages" will not work if I click on "relates r".
You can see that with this gif:

However, the moment I cut and paste this exact snippet of code, that functionality starts to work:

I've checked the PSI that's created before and after the "Go To Declaration"/"Find Usages" works and it's exactly the same. I've also tried running DaemonCodeAnalyzer#restart() and this does not help. This issue also affects inspections so I believe them to be the same issue.
Source code (if necessary): https://github.com/BFergerson/graql/tree/master/plugins/jetbrains-plugin
What possible reasons are there for inspections, declarations, and usages to not pick up when code is written but picked up when code is pasted?
Please sign in to leave a comment.
After a quick debugging, I've found out that when you start typing the relates keyword:
there is ANTLRPsiNode(type_property) created, which is a base type of the PsiRelatesTypeProperty. Your GraqlParserDefinition doesn't create proper type because it is failing the following condition:
} else if (node.getFirstChildNode() != null && node.getFirstChildNode().getText().equals("relates")) {String relatesTo = node.getLastChildNode().getText();
if (!relatesTo.isEmpty()) return new PsiRelatesTypeProperty(node);
}
However, when you finish the relates keyword, it remains a base type instead of being converted into the PsiRelatesTypeProperty type (this is why when you paste full definition at once, it is recognized correctly - it matches the above condition).
I understand what you're saying but I don't understand how to fix the issue based on that understanding. I've tried re-writing the logic you've mentioned but the least amount of code I can get it down to is:
else if (node.getFirstChildNode() != null && node.getFirstChildNode().getText().equals("relates")) {return new PsiRelatesTypeProperty(node);
}
This logic does not work either though and I don't see how I can reduce it considering I need to know that it's using the "relates" keyword before I can assign it to be of type PsiRelatesTypeProperty.
I originally wrote it the way it is to avoid running into PsiErrorElement in the inspections and code further down. I can add checks for this further down instead of in GraqlParserDefinition, but even at reduced logic, I don't see how to transform ANTLRPsiNode(type_property) into PsiRelatesTypeProperty. The earliest I can know it's PsiRelatesTypeProperty is once I see the "relates" keyword and that's not working.
Jakub, could you offer a bit more insight into this? We chatted on Slack some time ago but you said the same thing you said here. I get what you're saying in theory but I don't see how to apply it in practice. I didn't want to seem bothersome so I waited some time to bring up this issue again. If you have any other advice I can try it would be appreciated.