SLC: distinguish last v.s. non-last vararg during binary resolution
^KT-64795 fixed
This commit is contained in:
+6
@@ -82,6 +82,12 @@ public class FirStandaloneNormalAnalysisSourceModulePsiDeclarationProviderSingle
|
||||
runTest("analysis/analysis-api/testData/standalone/singleModule/multipleFiles.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("setOf_last_vararg.kt")
|
||||
public void testSetOf_last_vararg() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/standalone/singleModule/setOf_last_vararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("singleFile.kt")
|
||||
public void testSingleFile() throws Exception {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
|
||||
fun test() {
|
||||
set<caret>Of("4", "2")
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Resolved to:
|
||||
PsiMethod:setOf(vararg elements: PsiType:T...): PsiType:Set<T>
|
||||
+28
-7
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.providers
|
||||
|
||||
import com.intellij.psi.PsiArrayType
|
||||
import com.intellij.psi.PsiEllipsisType
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
@@ -33,7 +35,6 @@ internal object PsiDeclarationAndKtSymbolEqualityChecker {
|
||||
it,
|
||||
symbol.returnType,
|
||||
KtTypeMappingMode.RETURN_TYPE,
|
||||
isVararg = false
|
||||
)
|
||||
} ?: false
|
||||
}
|
||||
@@ -52,18 +53,28 @@ internal object PsiDeclarationAndKtSymbolEqualityChecker {
|
||||
if (psi.parameterList.parametersCount != valueParameterCount) return false
|
||||
if (symbol.isExtension) {
|
||||
val psiParameter = psi.parameterList.parameters[0]
|
||||
if (symbol.receiverType?.let { isTheSameTypes(psi, psiParameter.type, it, isVararg = false) } != true) return false
|
||||
if (symbol.receiverType?.let { isTheSameTypes(psi, psiParameter.type, it) } != true) return false
|
||||
}
|
||||
val offset = if (symbol.isExtension) 1 else 0
|
||||
symbol.valueParameters.forEachIndexed { index, valueParameterSymbol ->
|
||||
val psiParameter = psi.parameterList.parameters[index + offset]
|
||||
if (valueParameterSymbol.isVararg != psiParameter.isVarArgs) return false
|
||||
// The type of `vararg` value param at last v.s. non-last is mapped differently:
|
||||
// * last -> ellipsis type
|
||||
// * non-last -> array type
|
||||
// In [PsiParameter], we only know whether it `isVarArgs`.
|
||||
// If that's set to `true`, obviously symbol's `isVararg` should be `true`.
|
||||
// But, `isVarArgs` being `false` doesn't mean it is not `vararg`.
|
||||
// It may be the case that it's just not the last value parameter.
|
||||
if (psiParameter.isVarArgs && !valueParameterSymbol.isVararg) {
|
||||
return false
|
||||
}
|
||||
if (!isTheSameTypes(
|
||||
psi,
|
||||
psiParameter.type,
|
||||
valueParameterSymbol.returnType,
|
||||
KtTypeMappingMode.VALUE_PARAMETER,
|
||||
valueParameterSymbol.isVararg
|
||||
valueParameterSymbol.isVararg,
|
||||
psiParameter.isVarArgs,
|
||||
)
|
||||
) return false
|
||||
}
|
||||
@@ -75,12 +86,22 @@ internal object PsiDeclarationAndKtSymbolEqualityChecker {
|
||||
psi: PsiType,
|
||||
ktType: KtType,
|
||||
mode: KtTypeMappingMode = KtTypeMappingMode.DEFAULT,
|
||||
isVararg: Boolean = false
|
||||
isVararg: Boolean = false,
|
||||
isVarargs: Boolean = false, // isVarargs == isVararg && last param
|
||||
): Boolean {
|
||||
// Shortcut: primitive void == Unit as a function return type
|
||||
if (psi == PsiType.VOID && ktType.isUnit) return true
|
||||
val ktTypeRendered = ktType.asPsiType(context, allowErrorTypes = true, mode) ?: return false
|
||||
val rendered = if (isVararg) ktTypeRendered.createArrayType() else ktTypeRendered
|
||||
return rendered == psi
|
||||
return if (isVararg) {
|
||||
if (isVarargs) {
|
||||
// last vararg
|
||||
PsiEllipsisType(ktTypeRendered) == psi
|
||||
} else {
|
||||
// non-last vararg
|
||||
PsiArrayType(ktTypeRendered) == psi
|
||||
}
|
||||
} else {
|
||||
ktTypeRendered == psi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user