Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package dev.khbd.interp4j.intellij.language;
import com.intellij.lang.injection.MultiHostInjector;
import com.intellij.lang.injection.MultiHostRegistrar;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.PsiLiteralExpression;
import java.util.List;
import java.util.Objects;
/**
* @author Sergei_Khadanovich
*/
public class InterpolatedStringLanguageInjector implements MultiHostInjector {
@Override
public void getLanguagesToInject(MultiHostRegistrar registrar, PsiElement context) {
PsiLiteralExpression literalExpr = (PsiLiteralExpression) context;
Object value = literalExpr.getValue();
if (Objects.nonNull(value) && value instanceof String) {
tryInjectLanguage(registrar, literalExpr, (String) value);
}
}
private void tryInjectLanguage(MultiHostRegistrar registrar, PsiLiteralExpression context, String value) {
int openIndex = value.indexOf("${");
if (openIndex == -1) {
return;
}
int closeIndex = value.indexOf("}", openIndex);
if (closeIndex == -1) {
return;
}
InjectionStrategy injector = new ClassInjectionStrategy();
TextRange range = new TextRange(openIndex + 2, closeIndex);
registrar.startInjecting(JavaLanguage.INSTANCE);
registrar.addPlace(injector.prefix(), injector.suffix(), (PsiLanguageInjectionHost) context, range.shiftRight(1));
registrar.doneInjecting();
System.out.println("Was injected: " + injector.build(value.substring(openIndex + 2, closeIndex)));
}
interface InjectionStrategy {
String prefix();
String suffix();
default String build(String value) {
return prefix() + value + suffix();
}
}
/**
public class Main {
public static Object __target__ = `expression here`;
}
*/
static class ClassInjectionStrategy implements InjectionStrategy {
public String prefix() {
return "public class Main { public static Object __target__ = ";
}
@Override
public String suffix() {
return "; }";
}
}
@Override
public List<? extends Class<? extends PsiElement>> elementsToInjectIn() {
return List.of(PsiLiteralExpression.class);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment