diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaInjectionPerformer.kt b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaInjectionPerformer.kt new file mode 100644 index 000000000000..445c16620520 --- /dev/null +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaInjectionPerformer.kt @@ -0,0 +1,60 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.intellij.plugins.intelliLang.inject.java + +import com.intellij.lang.injection.MultiHostRegistrar +import com.intellij.lang.injection.general.Injection +import com.intellij.lang.injection.general.LanguageInjectionPerformer +import com.intellij.openapi.util.TextRange +import com.intellij.openapi.util.Trinity +import com.intellij.openapi.util.component1 +import com.intellij.openapi.util.component2 +import com.intellij.psi.ElementManipulators +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiLanguageInjectionHost +import com.intellij.psi.impl.source.tree.injected.JavaConcatenationToInjectorAdapter +import com.intellij.util.SmartList +import org.intellij.plugins.intelliLang.inject.InjectedLanguage +import org.intellij.plugins.intelliLang.inject.InjectorUtils + +class JavaInjectionPerformer : LanguageInjectionPerformer { + override fun isPrimary(): Boolean = true + + override fun performInjection(registrar: MultiHostRegistrar, injection: Injection, context: PsiElement): Boolean { + val injectorAdapter = JavaConcatenationToInjectorAdapter(context.project) + val (_, operands) = injectorAdapter.computeAnchorAndOperands(context) + + if (operands.isEmpty()) return false + val containingFile = context.containingFile + + val injectedLanguage = InjectedLanguage.create(injection.injectedLanguageId, + injection.prefix, + injection.suffix, false) ?: return false + + val language = injectedLanguage.language ?: return false + + val trinities = SmartList>() + var pendingPrefix = injectedLanguage.prefix + for (operand in operands.slice(0 until operands.size - 1)) { + if (operand !is PsiLanguageInjectionHost) continue + val injectionPart = InjectedLanguage.create(injection.injectedLanguageId, + pendingPrefix, + null, false) ?: continue + pendingPrefix = "" + trinities.add(Trinity.create(operand, injectionPart, ElementManipulators.getValueTextRange(operand))) + } + + InjectedLanguage.create(injection.injectedLanguageId, + pendingPrefix, + injectedLanguage.suffix, false)?.let { injectionPart -> + val operand = operands.last() as? PsiLanguageInjectionHost ?: return@let + trinities.add(Trinity.create(operand, injectionPart, ElementManipulators.getValueTextRange(operand))) + } + + InjectorUtils.registerInjection(language, trinities, containingFile, registrar) + + injection.supportId?.let { InjectorUtils.findInjectionSupport(it) }?.let { + InjectorUtils.registerSupport(it, false, context, language) + } + return true + } +} \ No newline at end of file diff --git a/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml b/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml index eb0683c18e77..486c9157c09f 100644 --- a/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml +++ b/plugins/IntelliLang/src/META-INF/intellilang-java-support.xml @@ -29,6 +29,8 @@ +