Fix @Language injection when using named parameters

Start using names of arguments if they are available when fetching
the @Language injection information.

Fixes KT-35859
This commit is contained in:
Aurimas Liutikas
2020-08-19 19:03:59 -07:00
committed by Nikolay Krasko
parent a9ddf02556
commit 777b16e0a3
2 changed files with 34 additions and 3 deletions
@@ -347,9 +347,14 @@ class KotlinLanguageInjector(
}
private fun injectionForKotlinCall(argument: KtValueArgument, ktFunction: KtFunction, reference: PsiReference): InjectionInfo? {
val argumentName = argument.getArgumentName()?.asName
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
val ktParameter = ktFunction.valueParameters.getOrNull(argumentIndex) ?: return null
// Prefer using argument name if present
val ktParameter = if (argumentName != null) {
ktFunction.valueParameters.firstOrNull { it.nameAsName == argumentName }
} else {
ktFunction.valueParameters.getOrNull(argumentIndex)
} ?: return null
val patternInjection = findInjection(ktParameter, configuration.getInjections(KOTLIN_SUPPORT_ID))
if (patternInjection != null) {
return patternInjection
@@ -363,7 +368,11 @@ class KotlinLanguageInjector(
ktReference.resolveToDescriptors(bindingContext).singleOrNull() as? FunctionDescriptor
} ?: return null
val parameterDescriptor = functionDescriptor.valueParameters.getOrNull(argumentIndex) ?: return null
val parameterDescriptor = if (argumentName != null) {
functionDescriptor.valueParameters.firstOrNull { it.name == argumentName }
} else {
functionDescriptor.valueParameters.getOrNull(argumentIndex)
} ?: return null
return injectionInfoByAnnotation(parameterDescriptor)
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.psi
import com.intellij.codeInsight.completion.CompletionType
import com.intellij.lang.html.HTMLLanguage
import com.intellij.lang.xml.XMLLanguage
import com.intellij.openapi.fileTypes.PlainTextLanguage
import org.intellij.lang.annotations.Language
import org.intellij.lang.regexp.RegExpLanguage
@@ -780,5 +781,26 @@ class KotlinInjectionTest : AbstractInjectionTest() {
languageId = HTMLLanguage.INSTANCE.id, unInjectShouldBePresent = false
)
fun testInjectionWithUsageInFunctionWithMarkedSecondNamedParameterWithAnnotation() = doInjectionPresentTest(
"""
import org.intellij.lang.annotations.Language
fun foo(@Language("XML") a: String = "", @Language("HTML") b: String = "") {}
fun other() { foo(b = "some<caret>") }
""",
languageId = HTMLLanguage.INSTANCE.id, unInjectShouldBePresent = false
)
fun testInjectionWithUsageInFunctionWithMarkedFirstNamedParameterWithAnnotation() = doInjectionPresentTest(
"""
import org.intellij.lang.annotations.Language
fun foo(@Language("XML") a: String = "", @Language("HTML") b: String = "") {}
fun other() { foo(a = "some<caret>") }
""",
languageId = XMLLanguage.INSTANCE.id, unInjectShouldBePresent = false
)
}