Different behavior between LanguageInjector and MultiHostInjector

Answered

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

4 comments
Comment actions Permalink

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.

0
Comment actions Permalink

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

0
Comment actions Permalink

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):

<ul>
{alert("hello")}
</ul>

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.

1
Comment actions Permalink

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

0

Please sign in to leave a comment.