Is MultiHostInjector the right approach for a Kotlin-based template engine plugin?

Answered

I'm currently writing a template engine that generates classes and compiles those to class files. The engine works fine, but I'm currently stuck with the IntelliJ plugin.

Initially I started with Java as language and used MultiHostInjector to generate the missing pieces for IntelliJ like this:

https://github.com/casid/jte-intellij/blob/master/src/main/java/org/jusecase/jte/intellij/language/JteJavaLanguageInjector.java

For Java, this kind of works (References are available, Code completions are shown, Refactoring seems to work most of the time):

In-place refactoring:

This weekend I changed the engine's language from Java to Kotlin on a branch, since Kotlin offers a lot of language features that would make templating a lot less cumbersome than with plain old Java. This is the MultiHostInjecor for Kotlin:

https://github.com/casid/jte-intellij/blob/kotlin-experiment/src/main/java/org/jusecase/kte/intellij/language/KteKotlinLanguageInjector.java 

However, here the injection doesn't seem to work that good. References are not recognized and cannot be followed by clicking them. Also, only very broad completions are available:

From the PSI it seems the generated Kotlin is valid, but the References are displayed in red. Maybe that is causing the problem?

Currently I'm a bit stuck and lost and any help would be appreciated.

Also, I'm not at all sure if MultiHostInjector is intended to be used the way I did and if there is a better approach to this problem.

In this post someone suggested to use lazy parseable elements. I looked into the Angular2 plugin that does it (with javascript), but I can't seem to get my head around it.

It would be awesome if someone could help pointing me at the right direction here.

2
5 comments
Avatar
Permanently deleted user

Anyone at JetBrains willing to shed some light on this?

After some more digging this weekend, we noticed that the kotlin injection works with built in types (e.g. String), but not with classes defined in the project. Any hint how to tell the Kotlin MultiHostInjector to pick up the project classes?

0
Avatar
Permanently deleted user

If anyone else is running into this problem, we found a workaround that fixes half of the problem. References are now resolved, but only one way. Refactoring / find usages is still not working.

I've created a new post with the workaround and the question how to fix back references here.

0

I don't get this problem BTW.  Do you never get suggestions or just sometimes?

0
Avatar
Permanently deleted user

Thank you for the follow up!

Suggestions work, but back references are not properly resolved. For instance, a Kotlin property is refactored, this change would not be reflected in the templates. Also, find usages doesn't include the template usages.

However, this works when Java is used as injected language in the templates.

Suggestions did not work out of the box with Kotlin, though. After some reverse engineering, we got them working with this  hack.

Would be very happy about any hint on how to improve this :-)

Thanks!

3

Unfortunately I'm not able to help - have never written an Intellij plugin.  I was just seeing if it's the plugin or project setup perhaps.  Good luck :)

0

Please sign in to leave a comment.