AA: handle PsiType conversion for recursive type parameter case (again)
^KT-64595 fixed
This commit is contained in:
committed by
Space Team
parent
93f1555322
commit
f1ce57f08f
+10
-4
@@ -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
|
||||
}
|
||||
|
||||
+9
-3
@@ -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
|
||||
|
||||
+9
-3
@@ -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
|
||||
|
||||
+9
-3
@@ -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
|
||||
|
||||
+15
@@ -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>) {
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
KtType: kotlin.collections.List<Wrapper>
|
||||
PsiType: PsiType:List<? extends Comparable<? super Wrapper<T>>>
|
||||
Reference in New Issue
Block a user