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.

  1. 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. 
  2. 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).
0
6 comments

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.

0

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.

0

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.

0

Bump
Still looking for solution

0

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?

0

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.

0

Please sign in to leave a comment.