Different behavior between LanguageInjector and MultiHostInjector Follow
Hi,
I noticed differences between LanguageInjector and MultiHostInjector in terms of highlighting and code insight
In this example, the code inside attributes is injected using <languageInjector>
The other interpolations (which are part of the custom language) are injected using <multiHostInjector>
Notice how window is highlighted as a global function in the attribute but not in the interpolation
The function hello is also correctly highlighted when focused but not inside the interpolations
Code insight
I tried debugging this but it's complicated
Basically, the interpolcation injected Psi doesn't get through to JSSemanticHighlightingUtil#highlight
because it doesn't get cached properly, so when InjectedLanguageUtil#getCachedInjectedDocuments is invoked, it only returns the attribute injections and other injections but again not the interpolations
From the first screenshot, I get only 4 injections and not 7 as you would expect
Btw, I didn't find the exact method which sets INJECTED_DOCS_KEY, if you know, please tell me so I can further debug it
Do you know a plugin which uses MultiHostInjector with JS and gets it right with highlighting and everything?
Could this be a bug? Is it a known limitation? Any hint is much appreciated
Cheers
Please sign in to leave a comment.
MultiHostInjector should behave the same way as LanguageInjector in most cases. Do you use exactly JavascriptLanguage.INSTANCE language for injection? It's hard to say what goes wrong without seeing the code of your injector.
Hi,
Thank you for your response, here's my branch
https://github.com/unlocomqx/svelte-intellij/commit/2f9d496af274a51d4cb1945f29be4340fa2b9257
Here's where JS is injected into the custom language
https://github.com/unlocomqx/svelte-intellij/blob/2f9d496af274a51d4cb1945f29be4340fa2b9257/src/main/java/dev/blachut/svelte/lang/SvelteCodeMultiHostInjector.kt#L221
I moved the attributes injection to the multihost and dropped the LanguageInjection extension but got the same behavior
I tried JavascriptLanguage.INSTANCE as well as JavaScriptSupportLoader.ECMA_SCRIPT_6 but it didn't make a difference
The difference is probably because the interpolations are part of the custom language, how to tell the IDE to treat them like the other injections
I debugged very deep into the API but couldn't pinpoint the cause
Thank you
Thanks for sharing the code!
The attribute injections created in 'injectJsInAttributeValue' look like JS injections are supposed to behave: there is completion and highlighting just like for regular JavaScript.
If I can suggest a change - I would recommend not injecting 'SvelteLanguage.INSTANCE' here: it seems unnecessary, MultiHostRegistrar is not intended to support multiple different languages in a single instance. It's likely only one of the injections will actually be used, and there are no guarantees as to which one. And even if it somehow works, the editor can still show highlighting from only one injection at a particular text range.
The injections outside of attributes, on the other hand, don't seem to be actually working (there is no completion and no highlighting, as you have noticed):
The reason for this is: SvelteLanguage is defined as a template language and injecting into 'base' language elements is currently not supported (injecting into Svelte* elements are in this case). A solution could be to inject into HTML elements of the same file instead, or to replace injections with lazily parseable elements that would contain JavaScript (this will also be more performant. A code sample from Angular plugin).
-- but that is something for the plugin's author. We'll try to reach out to them with this suggestion.
You can probably go ahead with your change (injecting into attributes) regardless of the changes to the other injections.
Thank you very much,
I will remove the double injection (I did that to get braces highlighting) and also take care of injection into attribute names as well to support directives
Thank you for the code sample, that's great