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
This commit is contained in:
Makhnev Petr 2022-07-13 18:42:52 +03:00 committed by GitHub
parent 635bf94659
commit c46dc50e37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 <path>plugin.xml</path>:
```xml
<multiHostInjector
implementation="MyRegExpToJavaInjector"/>
```
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)) {