JsonStringLiteral as declaration with rename action
Answered
I'm currently working on a plugin that extends JSON language in some way. I want to have a reference that resolves to JsonStringLiteral that is a value of a JSON property.
For example, consider the following JSON:
{
"name": "field"
}
This file contains "name" property with "field" value. "field" must work as a declaration. In my "framework", each "name" property value can be localized by another JSON file like this:
{
"field": "This is a field localization string!"
}
I want to have a reference from localization file to base file by "field" property.
I have already implemented PsiReferenceContributor with provider and resolve logic. It works fine, but there are some problems.
- I can go to the declaration from the "field" property in l10n file, but I can't find usages for the property in the base file.
- I cannot rename neither localization key (it says: Cannot perform refactoring. Caret should be positioned at symbol to be renamed) nor the base property value (nothing happens when you press the hotkey).
Please sign in to leave a comment.
Let me clarify the question. Here is another interpretation.
It is possible to have a reference that resolves to an element that can't be renamed, but still have rename refactoring enabled?
In my case, JsonStringLiteral (as property value) cannot be renamed, but I want to use it as declaration that some reference may resolve to.
Sorry for delay, yes see https://plugins.jetbrains.com/docs/intellij/rename-refactoring.html#custom-rename-ui-and-workflow
You might need adding a com.intellij.psi.search.UseScopeEnlarger to expand search scope across current file.
Thank you for response.
I've tried to implement renameHandler EP and also useScopeEnlarger. But my former problem remains.
I will try to ask my question differently. I've attached two screenshots. On the first one I have two localization properties. I have a reference on "group" substring to another .json file property value. The referenced element is shown on the second screenshot.
Screenshot 1. Both "group" substrings have a reference that resolves to the JsonStringLiteral element on screenshot 2. It is possible to ctrl-click and go to the referenced element.
Screenshot 2. The "group" declaration as property value. Those references resolve to this element.
The problem: I can navigate to the referenced element, but I can't find usages for this element on the 2nd screenshot (can't ctrl-click it). I also can't rename it. It does not count as a declaration. I've tried to implement FindUsagesProvider and RenameHandler, but I still get the message: "Cannot search for usages from this location".
Is there a way to register a property value as a "declaration"? And can I have multiple declarations in one JsonStringLiteral, like I can have multiple references in it using TextRange? For example, "group.field" will have two declarations: "group" and "field". I want to have Find Usages / Rename / Go to declaration functionalities for them.
I hope everything is clear. Thank you in advance for any help.
Bump
Still looking for solution
Hi,
Could you please try implementing
com.intellij.codeInsight.TargetElementEvaluatorEx2.getNamedElement(PsiElement)
and return the string literal, which is a declaration?It should be registered like:
<targetElementEvaluator language="JSON" implementationClass="MyTargetElementEvaluator"/>
If it doesn’t help, it’s a bit hard to guess what the reason can be without the code. Is there any chance to share it?
Thank you for your answer.
I've never heard about this extension, thank you for pointing it out. Unfortunately, I have actually already came up with the solution by implementing a symbol declaration inside JsonStringLiteral. I found a lot of helpful code in markdown plugin and my code now looks like this.
I find this method of implementing symbol declarations a little bit tricky, because I also needed to write my own usage searchers and some other stuff, which is done automatically if I use psi references.
I will look into TargetElementEvaluator a little bit later to see if it can make the code easier. Thank you again for help.