Fix infinite recursion during indexing types (EA-86494)
This commit is contained in:
@@ -19,7 +19,10 @@ package org.jetbrains.kotlin.idea.stubindex
|
|||||||
import com.intellij.psi.stubs.IndexSink
|
import com.intellij.psi.stubs.IndexSink
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.stubs.*
|
import org.jetbrains.kotlin.psi.stubs.KotlinCallableStubBase
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.KotlinModifierListStub
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.KotlinStubWithFqName
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.KotlinTypeAliasStub
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||||
import org.jetbrains.kotlin.util.aliasImportMap
|
import org.jetbrains.kotlin.util.aliasImportMap
|
||||||
|
|
||||||
@@ -27,10 +30,12 @@ fun <TDeclaration : KtCallableDeclaration> indexTopLevelExtension(stub: KotlinCa
|
|||||||
if (stub.isExtension()) {
|
if (stub.isExtension()) {
|
||||||
val declaration = stub.psi
|
val declaration = stub.psi
|
||||||
val containingTypeReference = declaration.receiverTypeReference!!
|
val containingTypeReference = declaration.receiverTypeReference!!
|
||||||
containingTypeReference.typeElement?.index(declaration, containingTypeReference) { typeName ->
|
index(containingTypeReference.typeElement, declaration, containingTypeReference) { typeName ->
|
||||||
val name = declaration.name ?: return@index
|
val name = declaration.name ?: return@index
|
||||||
sink.occurrence(KotlinTopLevelExtensionsByReceiverTypeIndex.INSTANCE.key,
|
sink.occurrence(
|
||||||
KotlinTopLevelExtensionsByReceiverTypeIndex.buildKey(typeName, name))
|
KotlinTopLevelExtensionsByReceiverTypeIndex.INSTANCE.key,
|
||||||
|
KotlinTopLevelExtensionsByReceiverTypeIndex.buildKey(typeName, name)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,53 +44,68 @@ fun indexTypeAliasExpansion(stub: KotlinTypeAliasStub, sink: IndexSink) {
|
|||||||
val declaration = stub.psi
|
val declaration = stub.psi
|
||||||
val typeReference = declaration.getTypeReference() ?: return
|
val typeReference = declaration.getTypeReference() ?: return
|
||||||
val typeElement = typeReference.typeElement ?: return
|
val typeElement = typeReference.typeElement ?: return
|
||||||
typeElement.index(declaration, typeReference) { typeName ->
|
index(typeElement, declaration, typeReference) { typeName ->
|
||||||
sink.occurrence(KotlinTypeAliasByExpansionShortNameIndex.KEY, typeName)
|
sink.occurrence(KotlinTypeAliasByExpansionShortNameIndex.KEY, typeName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtTypeElement.index(
|
private fun index(
|
||||||
|
typeElement: KtTypeElement?,
|
||||||
|
declaration: KtTypeParameterListOwner,
|
||||||
|
containingTypeReference: KtTypeReference,
|
||||||
|
occurrence: (String) -> Unit
|
||||||
|
) {
|
||||||
|
fun internalIndex(
|
||||||
|
typeElement: KtTypeElement?,
|
||||||
declaration: KtTypeParameterListOwner,
|
declaration: KtTypeParameterListOwner,
|
||||||
containingTypeReference: KtTypeReference,
|
containingTypeReference: KtTypeReference,
|
||||||
|
visited: MutableSet<KtTypeElement>,
|
||||||
occurrence: (String) -> Unit
|
occurrence: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
when (this) {
|
if (typeElement == null) return
|
||||||
is KtUserType -> {
|
if (typeElement in visited) return
|
||||||
val referenceName = referencedName ?: return
|
|
||||||
|
|
||||||
val typeParameter = declaration.typeParameters.firstOrNull { it.name == referenceName }
|
visited.add(typeElement)
|
||||||
if (typeParameter != null) {
|
|
||||||
val bound = typeParameter.extendsBound
|
when (typeElement) {
|
||||||
if (bound != null) {
|
is KtUserType -> {
|
||||||
bound.typeElement?.index(declaration, containingTypeReference, occurrence)
|
val referenceName = typeElement.referencedName ?: return
|
||||||
|
|
||||||
|
val typeParameter = declaration.typeParameters.firstOrNull { it.name == referenceName }
|
||||||
|
if (typeParameter != null) {
|
||||||
|
val bound = typeParameter.extendsBound
|
||||||
|
if (bound != null) {
|
||||||
|
internalIndex(bound.typeElement, declaration, containingTypeReference, visited, occurrence)
|
||||||
|
} else {
|
||||||
|
occurrence("Any")
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
occurrence("Any")
|
occurrence(referenceName)
|
||||||
}
|
|
||||||
return
|
typeElement.aliasImportMap()[referenceName].forEach { occurrence(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
occurrence(referenceName)
|
is KtNullableType -> internalIndex(typeElement.innerType, declaration, containingTypeReference, visited, occurrence)
|
||||||
|
|
||||||
aliasImportMap()[referenceName].forEach { occurrence(it) }
|
is KtFunctionType -> {
|
||||||
}
|
val arity = typeElement.parameters.size + (if (typeElement.receiverTypeReference != null) 1 else 0)
|
||||||
|
val suspendPrefix =
|
||||||
is KtNullableType -> innerType?.index(declaration, containingTypeReference, occurrence)
|
|
||||||
|
|
||||||
is KtFunctionType -> {
|
|
||||||
val arity = parameters.size + (if (receiverTypeReference != null) 1 else 0)
|
|
||||||
val suspendPrefix =
|
|
||||||
if (containingTypeReference.modifierList?.hasModifier(KtTokens.SUSPEND_KEYWORD) == true)
|
if (containingTypeReference.modifierList?.hasModifier(KtTokens.SUSPEND_KEYWORD) == true)
|
||||||
"Suspend"
|
"Suspend"
|
||||||
else
|
else
|
||||||
""
|
""
|
||||||
occurrence("${suspendPrefix}Function$arity")
|
occurrence("${suspendPrefix}Function$arity")
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtDynamicType -> occurrence("Any")
|
||||||
|
|
||||||
|
else -> error("Unsupported type: $typeElement")
|
||||||
}
|
}
|
||||||
|
|
||||||
is KtDynamicType -> occurrence("Any")
|
|
||||||
|
|
||||||
else -> error("Unsupported type: $this")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internalIndex(typeElement, declaration, containingTypeReference, mutableSetOf(), occurrence)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indexInternals(stub: KotlinCallableStubBase<*>, sink: IndexSink) {
|
fun indexInternals(stub: KotlinCallableStubBase<*>, sink: IndexSink) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
//fun <T: T> T.some() {}
|
||||||
Generated
+5
@@ -39,6 +39,11 @@ public class KotlinTypeAliasByExpansionShortNameIndexTestGenerated extends Abstr
|
|||||||
runTest("idea/testData/typealiasExpansionIndex/generics.kt");
|
runTest("idea/testData/typealiasExpansionIndex/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursion.kt")
|
||||||
|
public void testRecursion() throws Exception {
|
||||||
|
runTest("idea/testData/typealiasExpansionIndex/recursion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleType.kt")
|
@TestMetadata("simpleType.kt")
|
||||||
public void testSimpleType() throws Exception {
|
public void testSimpleType() throws Exception {
|
||||||
runTest("idea/testData/typealiasExpansionIndex/simpleType.kt");
|
runTest("idea/testData/typealiasExpansionIndex/simpleType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user