AA: handle PsiType conversion for recursive type parameter case (again)

^KT-64595 fixed
This commit is contained in:
Jinseong Jeon
2023-12-27 20:22:24 -08:00
committed by Space Team
parent 93f1555322
commit f1ce57f08f
8 changed files with 54 additions and 13 deletions
@@ -120,7 +120,6 @@ internal class KtFirPsiTypeProvider(
type = javaType
}
val javaTypeParameterStack = MutableJavaTypeParameterStack()
var psiClass = PsiTreeUtil.getContextOfType(useSitePosition, PsiClass::class.java, false)
@@ -169,7 +168,11 @@ internal class KtFirPsiTypeProvider(
private fun ConeKotlinType.simplifyType(
session: FirSession,
useSitePosition: PsiElement,
visited: MutableSet<ConeKotlinType> = mutableSetOf()
): ConeKotlinType {
// E.g., Wrapper<T> : Comparable<Wrapper<T>>
if (!visited.add(this)) return this
val substitutor = AnonymousTypesSubstitutor(session)
val visibilityForApproximation = useSitePosition.visibilityForApproximation
// TODO: See if the given [useSitePosition] is an `inline` method
@@ -192,7 +195,11 @@ private fun ConeKotlinType.simplifyType(
} while (oldType !== currentType)
if (typeArguments.isNotEmpty()) {
currentType = currentType.withArguments { it.replaceType(it.type?.simplifyType(session, useSitePosition)) }
currentType = currentType.withArguments { typeProjection ->
typeProjection.replaceType(
typeProjection.type?.simplifyType(session, useSitePosition, visited)
)
}
}
return currentType
}
@@ -342,13 +349,12 @@ private class AnonymousTypesSubstitutor(
visited: MutableSet<ConeKotlinType> = mutableSetOf()
): Boolean {
if (typeArguments.isEmpty()) return false
visited.add(this)
if (!visited.add(this)) return true
for (projection in typeArguments) {
// E.g., Test : Comparable<Test>
val type = (projection as? ConeKotlinTypeProjection)?.type ?: continue
// E.g., Comparable<Test>
val newType = substituteOrNull(type) ?: continue
if (newType in visited) return true
// Visit new type: e.g., Test, as a type argument, is substituted with Comparable<Test>, again.
if (newType.hasRecursiveTypeArgument(visited)) return true
}
@@ -77,9 +77,15 @@ public class FirIdeDependentAnalysisSourceModuleAnalysisApiExpressionPsiTypeProv
}
@Test
@TestMetadata("recursiveTypeParameter.kt")
public void testRecursiveTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter.kt");
@TestMetadata("recursiveTypeParameter_localSimple.kt")
public void testRecursiveTypeParameter_localSimple() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter_localSimple.kt");
}
@Test
@TestMetadata("recursiveTypeParameter_localWithTypeParameter.kt")
public void testRecursiveTypeParameter_localWithTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter_localWithTypeParameter.kt");
}
@Test
@@ -77,9 +77,15 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiExpressionPsiTypeProvide
}
@Test
@TestMetadata("recursiveTypeParameter.kt")
public void testRecursiveTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter.kt");
@TestMetadata("recursiveTypeParameter_localSimple.kt")
public void testRecursiveTypeParameter_localSimple() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter_localSimple.kt");
}
@Test
@TestMetadata("recursiveTypeParameter_localWithTypeParameter.kt")
public void testRecursiveTypeParameter_localWithTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter_localWithTypeParameter.kt");
}
@Test
@@ -77,9 +77,15 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiExpressionPsiType
}
@Test
@TestMetadata("recursiveTypeParameter.kt")
public void testRecursiveTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter.kt");
@TestMetadata("recursiveTypeParameter_localSimple.kt")
public void testRecursiveTypeParameter_localSimple() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter_localSimple.kt");
}
@Test
@TestMetadata("recursiveTypeParameter_localWithTypeParameter.kt")
public void testRecursiveTypeParameter_localWithTypeParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter_localWithTypeParameter.kt");
}
@Test
@@ -0,0 +1,15 @@
// WITH_STDLIB
fun <T> checkTransitiveComparator(list: List<T>, comparator: Comparator<T>) {
class Wrapper(val item: T) : Comparable<Wrapper> {
override fun toString(): String = item.toString()
override fun compareTo(other: Wrapper): Int {
return comparator.compare(this.item, other.item)
}
}
checkTransitiveComparator(<expr>list.map { Wrapper(it) }</expr>)
}
fun <T : Comparable<T>> checkTransitiveComparator(list: List<T>) {
}
@@ -0,0 +1,2 @@
KtType: kotlin.collections.List<Wrapper>
PsiType: PsiType:List<? extends Comparable<? super Wrapper<T>>>