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
|
type = javaType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val javaTypeParameterStack = MutableJavaTypeParameterStack()
|
val javaTypeParameterStack = MutableJavaTypeParameterStack()
|
||||||
|
|
||||||
var psiClass = PsiTreeUtil.getContextOfType(useSitePosition, PsiClass::class.java, false)
|
var psiClass = PsiTreeUtil.getContextOfType(useSitePosition, PsiClass::class.java, false)
|
||||||
@@ -169,7 +168,11 @@ internal class KtFirPsiTypeProvider(
|
|||||||
private fun ConeKotlinType.simplifyType(
|
private fun ConeKotlinType.simplifyType(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
useSitePosition: PsiElement,
|
useSitePosition: PsiElement,
|
||||||
|
visited: MutableSet<ConeKotlinType> = mutableSetOf()
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
|
// E.g., Wrapper<T> : Comparable<Wrapper<T>>
|
||||||
|
if (!visited.add(this)) return this
|
||||||
|
|
||||||
val substitutor = AnonymousTypesSubstitutor(session)
|
val substitutor = AnonymousTypesSubstitutor(session)
|
||||||
val visibilityForApproximation = useSitePosition.visibilityForApproximation
|
val visibilityForApproximation = useSitePosition.visibilityForApproximation
|
||||||
// TODO: See if the given [useSitePosition] is an `inline` method
|
// TODO: See if the given [useSitePosition] is an `inline` method
|
||||||
@@ -192,7 +195,11 @@ private fun ConeKotlinType.simplifyType(
|
|||||||
|
|
||||||
} while (oldType !== currentType)
|
} while (oldType !== currentType)
|
||||||
if (typeArguments.isNotEmpty()) {
|
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
|
return currentType
|
||||||
}
|
}
|
||||||
@@ -342,13 +349,12 @@ private class AnonymousTypesSubstitutor(
|
|||||||
visited: MutableSet<ConeKotlinType> = mutableSetOf()
|
visited: MutableSet<ConeKotlinType> = mutableSetOf()
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (typeArguments.isEmpty()) return false
|
if (typeArguments.isEmpty()) return false
|
||||||
visited.add(this)
|
if (!visited.add(this)) return true
|
||||||
for (projection in typeArguments) {
|
for (projection in typeArguments) {
|
||||||
// E.g., Test : Comparable<Test>
|
// E.g., Test : Comparable<Test>
|
||||||
val type = (projection as? ConeKotlinTypeProjection)?.type ?: continue
|
val type = (projection as? ConeKotlinTypeProjection)?.type ?: continue
|
||||||
// E.g., Comparable<Test>
|
// E.g., Comparable<Test>
|
||||||
val newType = substituteOrNull(type) ?: continue
|
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.
|
// Visit new type: e.g., Test, as a type argument, is substituted with Comparable<Test>, again.
|
||||||
if (newType.hasRecursiveTypeArgument(visited)) return true
|
if (newType.hasRecursiveTypeArgument(visited)) return true
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -77,9 +77,15 @@ public class FirIdeDependentAnalysisSourceModuleAnalysisApiExpressionPsiTypeProv
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("recursiveTypeParameter.kt")
|
@TestMetadata("recursiveTypeParameter_localSimple.kt")
|
||||||
public void testRecursiveTypeParameter() throws Exception {
|
public void testRecursiveTypeParameter_localSimple() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter.kt");
|
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
|
@Test
|
||||||
|
|||||||
+9
-3
@@ -77,9 +77,15 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiExpressionPsiTypeProvide
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("recursiveTypeParameter.kt")
|
@TestMetadata("recursiveTypeParameter_localSimple.kt")
|
||||||
public void testRecursiveTypeParameter() throws Exception {
|
public void testRecursiveTypeParameter_localSimple() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter.kt");
|
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
|
@Test
|
||||||
|
|||||||
+9
-3
@@ -77,9 +77,15 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiExpressionPsiType
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("recursiveTypeParameter.kt")
|
@TestMetadata("recursiveTypeParameter_localSimple.kt")
|
||||||
public void testRecursiveTypeParameter() throws Exception {
|
public void testRecursiveTypeParameter_localSimple() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/components/psiTypeProvider/psiType/forExpression/recursiveTypeParameter.kt");
|
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
|
@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