mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-26 00:21:32 +00:00
Add support for mixed named arguments to parameter info popup
Don't display parameter info in square brackets if the caller doesn't have to use a named argument. This makes the parameter info popup reflect the new capability introduced with MixedNamedArgumentsInTheirOwnPosition. ^KT-41645 Fixed
This commit is contained in:
committed by
Vladimir Dolzhenko
parent
af6e744b65
commit
91c021c699
@@ -25,14 +25,17 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.ui.Gray
|
||||
import com.intellij.ui.JBColor
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.FrontendInternals
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.completion.canBeUsedWithoutNameInCall
|
||||
import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
|
||||
import org.jetbrains.kotlin.idea.core.resolveCandidates
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||
import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter
|
||||
@@ -213,6 +216,9 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
||||
if (!argumentListClass.java.isInstance(context.parameterOwner)) return false
|
||||
val call = itemToShow.call ?: return false
|
||||
|
||||
val supportsMixedNamedArgumentsInTheirOwnPosition =
|
||||
call.callElement.languageVersionSettings.supportsFeature(LanguageFeature.MixedNamedArgumentsInTheirOwnPosition)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val argumentList = context.parameterOwner as TArgumentList
|
||||
|
||||
@@ -230,6 +236,7 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
||||
val text = buildString {
|
||||
val usedParameterIndices = HashSet<Int>()
|
||||
var namedMode = false
|
||||
var argumentIndex = 0
|
||||
|
||||
if (call.callType == Call.CallType.ARRAY_SET_METHOD) {
|
||||
// for set-operator the last parameter is used for the value assigned
|
||||
@@ -238,7 +245,9 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
||||
|
||||
val includeParameterNames = !substitutedDescriptor.hasSynthesizedParameterNames()
|
||||
|
||||
fun appendParameter(parameter: ValueParameterDescriptor) {
|
||||
fun appendParameter(parameter: ValueParameterDescriptor, named: Boolean = false) {
|
||||
argumentIndex++
|
||||
|
||||
if (length > 0) {
|
||||
append(", ")
|
||||
}
|
||||
@@ -248,7 +257,7 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
||||
boldStartOffset = length
|
||||
}
|
||||
|
||||
append(renderParameter(parameter, includeParameterNames, namedMode, project))
|
||||
append(renderParameter(parameter, includeParameterNames, named || namedMode, project))
|
||||
|
||||
if (highlightParameter) {
|
||||
boldEndOffset = length
|
||||
@@ -260,15 +269,20 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
||||
val parameter = argumentToParameter(argument) ?: continue
|
||||
if (!usedParameterIndices.add(parameter.index)) continue
|
||||
|
||||
if (argument.isNamed()) {
|
||||
if (argument.isNamed() &&
|
||||
!(supportsMixedNamedArgumentsInTheirOwnPosition && argument.canBeUsedWithoutNameInCall(itemToShow))
|
||||
) {
|
||||
namedMode = true
|
||||
}
|
||||
|
||||
appendParameter(parameter)
|
||||
appendParameter(parameter, argument.isNamed())
|
||||
}
|
||||
|
||||
for (parameter in substitutedDescriptor.valueParameters) {
|
||||
if (parameter.index !in usedParameterIndices) {
|
||||
if (argumentIndex != parameter.index) {
|
||||
namedMode = true
|
||||
}
|
||||
appendParameter(parameter)
|
||||
}
|
||||
}
|
||||
@@ -521,6 +535,9 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
||||
private fun ValueArgument.hasError(bindingContext: BindingContext) =
|
||||
getArgumentExpression()?.let { bindingContext.getType(it) }?.isError ?: true
|
||||
|
||||
private fun ValueArgument.canBeUsedWithoutNameInCall(callInfo: CallInfo) =
|
||||
this is KtValueArgument && this.canBeUsedWithoutNameInCall(callInfo.resolvedCall as ResolvedCall<out CallableDescriptor>)
|
||||
|
||||
// we should not compare descriptors directly because partial resolve is involved
|
||||
private fun descriptorsEqual(descriptor1: FunctionDescriptor, descriptor2: FunctionDescriptor): Boolean {
|
||||
if (descriptor1.original == descriptor2.original) return true
|
||||
|
||||
12
idea/testData/parameterInfo/functionCall/MixedNamedArguments.kt
vendored
Normal file
12
idea/testData/parameterInfo/functionCall/MixedNamedArguments.kt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
open class A(x: Int) {
|
||||
fun m(x: Boolean, y: Int) = 1
|
||||
fun m(x: Boolean, y: Int, z: Int) = 2
|
||||
|
||||
fun d(x: Int) {
|
||||
m(false, y = 23<caret>)
|
||||
}
|
||||
}
|
||||
/*
|
||||
Text: (x: Boolean, <highlight>[y: Int]</highlight>), Disabled: false, Strikeout: false, Green: true
|
||||
Text: (x: Boolean, <highlight>[y: Int]</highlight>, z: Int), Disabled: false, Strikeout: false, Green: false
|
||||
*/
|
||||
14
idea/testData/parameterInfo/functionCall/MixedNamedArguments2.kt
vendored
Normal file
14
idea/testData/parameterInfo/functionCall/MixedNamedArguments2.kt
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// COMPILER_ARGUMENTS: -XXLanguage:-MixedNamedArgumentsInTheirOwnPosition
|
||||
|
||||
open class A(x: Int) {
|
||||
fun m(x: Boolean, y: Int) = 1
|
||||
fun m(x: Boolean, y: Int, z: Int) = 2
|
||||
|
||||
fun d(x: Int) {
|
||||
m(false, y = 23<caret>)
|
||||
}
|
||||
}
|
||||
/*
|
||||
Text: (x: Boolean, <highlight>[y: Int]</highlight>), Disabled: false, Strikeout: false, Green: true
|
||||
Text: (x: Boolean, <highlight>[y: Int]</highlight>, [z: Int]), Disabled: false, Strikeout: false, Green: false
|
||||
*/
|
||||
@@ -196,6 +196,16 @@ public class ParameterInfoTestGenerated extends AbstractParameterInfoTest {
|
||||
runTest("idea/testData/parameterInfo/functionCall/LocalFunctionBug.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MixedNamedArguments.kt")
|
||||
public void testMixedNamedArguments() throws Exception {
|
||||
runTest("idea/testData/parameterInfo/functionCall/MixedNamedArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MixedNamedArguments2.kt")
|
||||
public void testMixedNamedArguments2() throws Exception {
|
||||
runTest("idea/testData/parameterInfo/functionCall/MixedNamedArguments2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NamedAndDefaultParameter.kt")
|
||||
public void testNamedAndDefaultParameter() throws Exception {
|
||||
runTest("idea/testData/parameterInfo/functionCall/NamedAndDefaultParameter.kt");
|
||||
|
||||
Reference in New Issue
Block a user