Is there a Rider equivalent of JavaPsiFacade, JavaClass, etc?
I'm developing a plugin for a language (XQuery) in Kotlin that can support C#/CLI imports in the Saxon processor via "clitype:..." (https://saxonica.com/documentation/index.html#!extensibility/dotnetextensions). I would like to implement things like resolving references to these types if the user has the source for those configured (e.g. from mono or .NET core).
Failing the ability to navigate to the source, I would like to be able to interrogate the type information of the modules, classes, methods, and static fields so I can implement features like autocomplete, class and function validation, type signature tooltips, etc..
Kind regards,
Reece
Please sign in to leave a comment.
Unfortunately, the Rider architecture can make certain plugins more complex. All of Rider's .NET indexing and analysis is handled by ReSharper, running as an out of process service. This is fine if the file type is a completely .NET based file, such as C# - you write a ReSharper plugin, wrap it into a simple IntelliJ based plugin (jar file containing .NET assembly add plugin.xml). If the file is completely handled by existing IntelliJ code/plugin, then an IntelliJ plugin can extend it.
However, if you have an IntelliJ based file type that you wish to extend with information from the .NET world, you need to have some kind of hybrid system. The IntelliJ "frontend" can handle e.g. syntax highlighting and code folding, and the .NET "backend" can contribute completion items, or references for Ctrl+Click navigation, etc.
To implement this kind of hybrid file type support, you need to add support to that file type as a ReSharper plugin. If the file type is completely custom, this is a lot of work, and you'll need to create a PSI in ReSharper for the whole file format. If you're trying to extend an existing file, e.g. XML based, this is more straightforward. You'll need to teach ReSharper how to recognise the file as XML, by mapping the extension to the file type, then create the completion or reference providers as normal for a ReSharper extension.
Once this is done, you need to tell the IntelliJ side that there is information coming from the backend. This is all done through the plugin.xml, and can usually reuse existing classes and providers from Rider itself.
Overall, though, this isn't exactly straightforward. You can see it in action in the Unity plugin for Rider, which has several custom file types. E.g. `.asmdef` support is a custom JSON format that has a lot of support handled in the ReSharper backend (completion, inspections, etc.) while reusing the JSON frontend features. You can see the registration in the plugin.xml file.
Thanks for the response.
The functionality I am intending to implement is supported by several plugin-specific extension points and interfaces defined in Kotlin/Java. These are used by the Kotlin code in my plugin to do things like resove the `PsiElement` for an import declaration, so for example in XSLT `xmlns:Environment="clitype:System.Environment"` would support ctrl+click navigation of the `"clitype:System.Environment"` string [1] to the `Environment.cs` file (and associated class) if present (e.g. if the .NET core source was configured), and provide the appropriate `getQuickNavigateInfo` tooltip text -- as if it was a C# `import System.Environment` statement.
The intention is to extend this API so functions, variables, etc. implemented in XQuery, XSLT, Java, and .NET will be visible from the XQuery and XPath environments for things like validation, code completion, and inlay parameter hints (e.g. `version="{OS:Version($os)}"` [1] in XSLT/XPath will have those features, but in this case will be using the bound .NET System.OperatingSystem class to resolve the functions via the plugin API). I have this API in place for XQuery, but I'm in the process of extending it to XSLT/XPath, imported Java modules, and imported .NET modules.
So I need to implement the extension points and appropriate interfaces as a .NET DLL with them mapped in a rider-specific plugin.xml?
Q: Can this be in the same plugin (e.g. as an optional dependency pointing to the rider/resharper specific plugin xml file)?
Q: Does IntelliJ handle the Java <=> .NET interop between registered interfaces, or do I need to write my own glue code?
Q: If IntelliJ handles it, is there a defined mapping between .NET and Java types?
[1] http://www.saxonica.com/documentation/index.html#!extensibility/dotnetextensions