From c46dc50e377fe03b71cbe6f564c09013ac2da602 Mon Sep 17 00:00:00 2001
From: Makhnev Petr <51853996+i582@users.noreply.github.com>
Date: Wed, 13 Jul 2022 18:42:52 +0300
Subject: [PATCH] Fix code samples in "Language Injection" article (#804)
- `SimpleInjection` now takes `Language` as first parameter, not `String`
- `.doneInjecting()` should be called at the end of injecting
- Added information about the `elementsToInjectIn()` method, which also needs to be implemented.
- added `plugin.xml` example in `MultiHostInjector` for consistency
---
.../language_injection.md | 33 +++++++++++++++----
1 file changed, 26 insertions(+), 7 deletions(-)
diff --git a/topics/reference_guide/custom_language_support/language_injection.md b/topics/reference_guide/custom_language_support/language_injection.md
index e0f41f5b6..454db022c 100644
--- a/topics/reference_guide/custom_language_support/language_injection.md
+++ b/topics/reference_guide/custom_language_support/language_injection.md
@@ -168,14 +168,17 @@ For instance, if you want to inject a YAML or JSON to a literal language dependi
```java
public final class MyInjector implements LanguageInjectionContributor {
- public Injection getInjection(@NotNull PsiElement context) {
+ @Override
+ public @Nullable Injection getInjection(@NotNull PsiElement context) {
if (!isConfigPlace(context)) return null;
if (shouldInjectYaml(context)) {
return new SimpleInjection(
- YAMLLanguage.INSTANCE.getID(), "", "", null);
+ YAMLLanguage.INSTANCE, "", "", null
+ );
} else if (shouldInjectJSON(context)) {
return new SimpleInjection(
- JsonLanguage.INSTANCE.getID(), "", "", null);
+ JsonLanguage.INSTANCE, "", "", null
+ );
}
return null;
}
@@ -210,23 +213,38 @@ The method `performInjection()` does the actual injection into the context PSI e
[`MultiHostInjector`](upsource:///platform/core-api/src/com/intellij/lang/injection/MultiHostInjector.java) registered in `com.intellij.multiHostInjector` EP is a very low-level API, but it gives plugin authors the most freedom.
It performs language injection inside other PSI elements, e.g. inject SQL inside an XML tag text or inject regular expressions into Java string literals.
-Plugin authors need to implement `getLanguagesToInject()` to provide a list of places to inject a language to.
-For example, to inject regular expressions into Java string literal, you can override this method with something similar to this:
+Plugin authors need to implement `getLanguagesToInject()` to provide a list of places to inject a language, and `elementsToInjectIn()` to return a list of elements to inject.
+
+For example, inject regular expressions into Java string literal:
```java
public class MyRegExpToJavaInjector implements MultiHostInjector {
+ @Override
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar,
@NotNull PsiElement context) {
if (context instanceof PsiLiteralExpression && shouldInject(context)) {
registrar
- .startInjecting(REGEXP_LANG)
- .addPlace(null, null, context, innerRangeStrippingQuotes(context));
+ .startInjecting(RegExpLanguage.INSTANCE)
+ .addPlace(null, null, context, innerRangeStrippingQuotes(context))
+ .doneInjecting();
}
}
+
+ @Override
+ public @NotNull List extends Class extends PsiElement>> elementsToInjectIn() {
+ return List.of(PsiLiteralExpression.class);
+ }
}
```
+Register the implementation in your plugin.xml:
+
+```xml
+
+```
+
A more complex example is when you need to inject into several fragments at once.
For example, if we have an XML-based DSL:
@@ -250,6 +268,7 @@ Here, we need to inject Java into several places at once, i.e. method name and i
```java
public class MyBizarreDSLInjector implements MultiHostInjector {
+ @Override
public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar,
@NotNull PsiElement context) {
if (isMethodTag(context)) {