How to embed external resource file into PsiElement-tree?
Hi,
I'd like to make the reference resolver of my custom language plugin (https://github.com/holgerbrandl/r4intellij) aware of sourced in script files. E.g. consider the example:

At the moment the plugin is not able to resolve fun_in_core_commons, but I'd like to change this by taking the external resource into account when resolving references.
I've figured already how to adopt com.intellij.codeInsight.daemon.impl.quickfix.FetchExtResourceAction to fetch the external resource file into a dedicated project-library. However, it's not clear how to make my reference-resolver/parser aware of this. I would imagine something like a parser-postprocessor to replace the function-call-psi-node of `source_url` in the document above with the psi-reference to the resource file.
Is this possible at all? If yes, is there a recommended pattern/API to implement such a functionality?
Thanks,
Holger
Please sign in to leave a comment.
Your resolver can do whatever it needs with the text and PSI. It can take the URL, find the corresponding project library, take the needed files from it, and use them for resolve. It's not a parser-postprocessor, but it's a more flexible approach. It's for you to decide on the details, you have total freedom. Your users might benefit from having a reference on that URL text that points to the downloaded file (and you could reuse this inside other resolvers), but that's just one of the possible ideas.
Thanks Peter, for your sound advice. I'll change my resolver accordingly.
Concerning the reference on that URL: By default IJ opens the browser if I click on URL in a string. How could I intercept this and open a cached copy of the resource-URL sitting in my library instead?
Thanks,
Holger
You can provide your own PsiReference in this string which should override the default behavior.
Thanks for the pointer, I did as suggested, see
https://github.com/holgerbrandl/r4intellij/blob/master/src/com/r4intellij/psi/references/externalres/ResourceScriptReferenceContributor.java
and
https://github.com/holgerbrandl/r4intellij/blob/master/src/com/r4intellij/psi/references/externalres/ResourceScriptReferenceProvider.java
Doing the structural psi matching with `PsiElementPattern` was fun, and the reference provider works for random strings:
However, in case of URLs (which are my actual use-case since I want to intercept resource URLs) the built in ref-provider still seems to have precedence:
What am I doing wrong?
Thanks,
Holger
Which reference is that? (you can see it in View PSI Structure of Current File). What's the stack trace where this reference is created? (can be determined by setting a breakpoint in its constructor)
I did not know that the psiviewer allow to inspect references as well. It's a nice feature, and helped me to trace down the problem (which was another reference-contributor accidentally registered for string-literals by my plugin). Now it's working as you were suggesting earlier, and I can specifically intercept the click on the url and resolve it as desired.
Thanks a lot for your help,
best,
Holger