Inject predefined places through usages

This commit is contained in:
Nikolay Krasko
2016-04-20 19:00:26 +03:00
parent 62ff67c2b0
commit 505c6624a7
2 changed files with 38 additions and 5 deletions
@@ -20,6 +20,8 @@ import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.PsiTreeUtil
import org.intellij.plugins.intelliLang.Configuration
import org.intellij.plugins.intelliLang.inject.InjectorUtils
@@ -37,16 +39,19 @@ class KotlinLanguageInjector : LanguageInjector {
if (!host.isValidHost) return
val ktHost: KtElement = host as? KtElement ?: return
val injectionInfo =
injectWithExplicitCodeInstruction(ktHost)
?: injectWithCall(ktHost)
?: injectWithReceiver(ktHost)
?: return
val injectionInfo = findInjectionInfo(host) ?: return
val language = InjectorUtils.getLanguageByString(injectionInfo.languageId) ?: return
injectionPlacesRegistrar.addPlace(language, TextRange.from(0, ktHost.textLength), injectionInfo.prefix, injectionInfo.suffix)
}
private fun findInjectionInfo(place: KtElement): InjectionInfo? {
return injectWithExplicitCodeInstruction(place)
?: injectWithCall(place)
?: injectWithReceiver(place)
?: injectWithVariableUsage(place)
}
private fun injectWithExplicitCodeInstruction(host: KtElement): InjectionInfo? {
val support = kotlinSupport ?: return null
val languageId = support.findAnnotationInjectionLanguageId(host) ?: return null
@@ -77,6 +82,20 @@ class KotlinLanguageInjector : LanguageInjector {
return null
}
private fun injectWithVariableUsage(host: KtElement): InjectionInfo? {
val ktHost: KtElement = host
val ktProperty = host.parent as? KtProperty?: return null
if (ktProperty.initializer != host) return null
if (isAnalyzeOff(ktHost.project)) return null
val searchScope = LocalSearchScope(arrayOf(ktProperty.containingFile), "", true)
return ReferencesSearch.search(ktProperty, searchScope).asSequence().mapNotNull { psiReference ->
val element = psiReference.element as? KtElement ?: return@mapNotNull null
findInjectionInfo(element)
}.firstOrNull()
}
private fun injectWithCall(host: KtElement): InjectionInfo? {
val ktHost: KtElement = host
val argument = ktHost.parent as? KtValueArgument ?: return null
@@ -82,6 +82,20 @@ class KotlinInjectionTest : AbstractInjectionTest() {
|val test = "<caret>simple"
""")
fun testInjectionWithUsageOnReceiverWithRuntime() = testInjectionPresent(
"""
|val test = "<caret>some"
|fun foo() = test.toRegex()
""",
languageId = RegExpLanguage.INSTANCE.id, unInjectShouldBePresent = false)
fun testInjectionWithUsageInParameterWithRuntime() = testInjectionPresent(
"""
|val test = "<caret>some"
|fun foo() = Regex(test)
""",
languageId = RegExpLanguage.INSTANCE.id, unInjectShouldBePresent = false)
fun testInjectionWithMultipleCommentsOnFun() = testInjectionPresent(
"""
|// Some comment