KT-60940 [Analysis API] Properly handle vararg types in KtFirReferenceShortener
^KT-60940 Fixed ^KTIJ-26518 Fixed
This commit is contained in:
+32
-6
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtReferenceShortener
|
||||
import org.jetbrains.kotlin.analysis.api.components.ShortenCommand
|
||||
import org.jetbrains.kotlin.analysis.api.components.ShortenOption
|
||||
@@ -416,12 +417,7 @@ private class ElementsToShortenCollector(
|
||||
}
|
||||
|
||||
private fun processTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
|
||||
val typeElement = when (val realPsi = resolvedTypeRef.realPsi) {
|
||||
is KtTypeReference -> realPsi.typeElement
|
||||
is KtNameReferenceExpression -> realPsi.parent as? KtTypeElement
|
||||
else -> null
|
||||
}?.unwrapNullability() as? KtUserType ?: return
|
||||
|
||||
val typeElement = resolvedTypeRef.correspondingTypePsi ?: return
|
||||
if (typeElement.referenceExpression?.textRange?.intersects(selection) != true) return
|
||||
if (typeElement.qualifier == null) return
|
||||
|
||||
@@ -430,6 +426,36 @@ private class ElementsToShortenCollector(
|
||||
findTypeToShorten(classifierId, typeElement)?.let(::addElementToShorten)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the corresponding [KtUserType] PSI the given [FirResolvedTypeRef].
|
||||
*
|
||||
* This code handles some quirks of FIR sources and PSI:
|
||||
* - in `vararg args: String` declaration, `String` type reference has fake source, but `Array<String>` has real source
|
||||
* (see [KtFakeSourceElementKind.ArrayTypeFromVarargParameter]).
|
||||
* - if FIR reference points to the type with generic parameters (like `Foo<Bar>`), its source is not [KtTypeReference], but
|
||||
* [KtNameReferenceExpression].
|
||||
*/
|
||||
private val FirResolvedTypeRef.correspondingTypePsi: KtUserType?
|
||||
get() {
|
||||
val sourcePsi = when {
|
||||
// array type for vararg parameters is not present in the code, so no need to handle it
|
||||
delegatedTypeRef?.source?.kind == KtFakeSourceElementKind.ArrayTypeFromVarargParameter -> null
|
||||
|
||||
// but the array's underlying type is present with a fake source, and needs to be handled
|
||||
source?.kind == KtFakeSourceElementKind.ArrayTypeFromVarargParameter -> psi
|
||||
|
||||
else -> realPsi
|
||||
}
|
||||
|
||||
val outerTypeElement = when (sourcePsi) {
|
||||
is KtTypeReference -> sourcePsi.typeElement
|
||||
is KtNameReferenceExpression -> sourcePsi.parent as? KtTypeElement
|
||||
else -> null
|
||||
}
|
||||
|
||||
return outerTypeElement?.unwrapNullability() as? KtUserType
|
||||
}
|
||||
|
||||
val ConeKotlinType.candidateClassId: ClassId?
|
||||
get() {
|
||||
return when (this) {
|
||||
|
||||
+6
@@ -418,6 +418,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/typeParams2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/vararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variable.kt")
|
||||
public void testVariable() throws Exception {
|
||||
|
||||
+6
@@ -418,6 +418,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/typeParams2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/vararg.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variable.kt")
|
||||
public void testVariable() throws Exception {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// FILE: main.kt
|
||||
fun test(vararg args: <expr>dependency.Foo</expr>) {}
|
||||
|
||||
// FILE: dependency.kt
|
||||
package dependency
|
||||
|
||||
class Foo
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
Before shortening: dependency.Foo
|
||||
with DO_NOT_SHORTEN:
|
||||
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||
with SHORTEN_AND_IMPORT:
|
||||
[type] dependency.Foo
|
||||
with SHORTEN_AND_STAR_IMPORT:
|
||||
[type] dependency.Foo
|
||||
Reference in New Issue
Block a user