Avoid calling PsiType::resolve while adding supertype references
Otherwise, e.g. in case of inner classes it may lead to StackOverflowError: - Someone tries to resolve supertypes - We're starting building extends/implements lists - Then calling resolve on the type references leads that some logic in Java resolution again is trying to resolve supertype of the same class (only in case of inner ones) Probably, it could be fixed on the side of Java resolve but at the same time it's clear that calling `resolve` while building extends list it's really somewhat not very cool The exception is following: at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration$_extendsList$2.invoke(KtLightClassForSourceDeclaration.kt:77) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration$_extendsList$2.invoke(KtLightClassForSourceDeclaration.kt:73) at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration.get_extendsList(KtLightClassForSourceDeclaration.kt) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration.getExtendsList(KtLightClassForSourceDeclaration.kt:320) at com.intellij.psi.impl.PsiClassImplUtil.getExtendsListTypes(PsiClassImplUtil.java:1017) at com.intellij.psi.impl.light.AbstractLightClass.getExtendsListTypes(AbstractLightClass.java:137) at com.intellij.psi.impl.ScopedClassHierarchy.getSuperTypes(ScopedClassHierarchy.java:95) at com.intellij.psi.impl.ScopedClassHierarchy.visitType(ScopedClassHierarchy.java:80) at com.intellij.psi.impl.ScopedClassHierarchy.getSuperClassSubstitutor(ScopedClassHierarchy.java:115) at com.intellij.psi.impl.JavaClassSupersImpl.getSuperSubstitutorWithCaching(JavaClassSupersImpl.java:111) at com.intellij.psi.impl.JavaClassSupersImpl.getSuperClassSubstitutor(JavaClassSupersImpl.java:71) at com.intellij.psi.util.TypeConversionUtil.getMaybeSuperClassSubstitutor(TypeConversionUtil.java:1089) at com.intellij.psi.util.TypeConversionUtil.getClassSubstitutor(TypeConversionUtil.java:1055) at com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl.advancedResolveImpl(ClsJavaCodeReferenceElementImpl.java:143) at com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl.access$000(ClsJavaCodeReferenceElementImpl.java:43) at com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl$Resolver.resolve(ClsJavaCodeReferenceElementImpl.java:121) at com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl$Resolver.resolve(ClsJavaCodeReferenceElementImpl.java:115) at com.intellij.psi.impl.source.resolve.ResolveCache.lambda$resolveWithCaching$1(ResolveCache.java:203) at com.intellij.openapi.util.RecursionManager$2.doPreventingRecursion(RecursionManager.java:99) at com.intellij.psi.impl.source.resolve.ResolveCache.resolveWithCaching(ResolveCache.java:202) at com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl.multiResolve(ClsJavaCodeReferenceElementImpl.java:223) at com.intellij.psi.impl.compiled.ClsJavaCodeReferenceElementImpl.advancedResolve(ClsJavaCodeReferenceElementImpl.java:213) at com.intellij.psi.impl.source.PsiClassReferenceType.resolveGenerics(PsiClassReferenceType.java:191) at com.intellij.psi.impl.source.PsiClassReferenceType.resolve(PsiClassReferenceType.java:138) at org.jetbrains.kotlin.asJava.classes.LightReferenceListBuilder.addReference(LightReferenceListBuilder.java:53) at org.jetbrains.kotlin.asJava.classes.KtUltraLightClass.createExtendsList(ultraLightPsi.kt:91) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration$_extendsList$2.invoke(KtLightClassForSourceDeclaration.kt:77) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration$_extendsList$2.invoke(KtLightClassForSourceDeclaration.kt:73) at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration.get_extendsList(KtLightClassForSourceDeclaration.kt) at org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration.getExtendsList(KtLightClassForSourceDeclaration.kt:320) at com.intellij.psi.impl.PsiClassImplUtil.getExtendsListTypes(PsiClassImplUtil.java:1017) at com.intellij.psi.impl.light.AbstractLightClass.getExtendsListTypes(AbstractLightClass.java:137) a
This commit is contained in:
-3
@@ -47,9 +47,6 @@ public class KotlinLightReferenceListBuilder extends LightReferenceListBuilder i
|
||||
|
||||
@Override
|
||||
public void addReference(PsiClassType type) {
|
||||
final PsiClass resolved = type.resolve();
|
||||
if (resolved == null) return;
|
||||
|
||||
final PsiJavaCodeReferenceElement ref = myFactory.createReferenceElementByType(type);
|
||||
myRefs.add(ref);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.asJava.builder.LightClassData
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
|
||||
|
||||
class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: UltraLightSupport) :
|
||||
KtLightClassImpl(classOrObject) {
|
||||
@@ -75,24 +77,35 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult
|
||||
}
|
||||
|
||||
private fun allSuperTypes() =
|
||||
getDescriptor()?.typeConstructor?.supertypes?.mapNotNull {
|
||||
it.asPsiType(classOrObject, support, TypeMappingMode.SUPER_TYPE, this) as? PsiClassType
|
||||
}.orEmpty()
|
||||
getDescriptor()?.typeConstructor?.supertypes.orEmpty().asSequence()
|
||||
|
||||
private fun mapSupertype(supertype: KotlinType) =
|
||||
supertype.asPsiType(classOrObject, support, TypeMappingMode.SUPER_TYPE, this) as? PsiClassType
|
||||
|
||||
override fun createExtendsList(): PsiReferenceList? =
|
||||
if (tooComplex) super.createExtendsList()
|
||||
else LightReferenceListBuilder(manager, language, PsiReferenceList.Role.EXTENDS_LIST).also { list ->
|
||||
else KotlinLightReferenceListBuilder(
|
||||
manager,
|
||||
language,
|
||||
PsiReferenceList.Role.EXTENDS_LIST
|
||||
).also { list ->
|
||||
allSuperTypes()
|
||||
.filter { (isInterface || it.resolve()?.isInterface == false) && !it.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) }
|
||||
.filter { (isInterface || !JvmCodegenUtil.isJvmInterface(it)) && !it.isAnyOrNullableAny() }
|
||||
.map(this::mapSupertype)
|
||||
.forEach(list::addReference)
|
||||
}
|
||||
|
||||
override fun createImplementsList(): PsiReferenceList? =
|
||||
if (tooComplex) super.createImplementsList()
|
||||
else LightReferenceListBuilder(manager, language, PsiReferenceList.Role.IMPLEMENTS_LIST).also { list ->
|
||||
else KotlinLightReferenceListBuilder(
|
||||
manager,
|
||||
language,
|
||||
PsiReferenceList.Role.IMPLEMENTS_LIST
|
||||
).also { list ->
|
||||
if (!isInterface) {
|
||||
allSuperTypes()
|
||||
.filter { it.resolve()?.isInterface == true }
|
||||
.filter { JvmCodegenUtil.isJvmInterface(it) }
|
||||
.map(this::mapSupertype)
|
||||
.forEach(list::addReference)
|
||||
}
|
||||
}
|
||||
@@ -579,7 +592,7 @@ internal class KtUltraLightMethod(
|
||||
}
|
||||
|
||||
private val _throwsList: PsiReferenceList by lazyPub {
|
||||
val list = LightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST)
|
||||
val list = KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST)
|
||||
(kotlinOrigin?.resolve() as? FunctionDescriptor)?.let {
|
||||
for (ex in FunctionCodegen.getThrownExceptions(it)) {
|
||||
list.addReference(ex.fqNameSafe.asString())
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
public abstract class A <T extends A<T>> extends B<java.util.Collection<? extends T>> implements C<T> {
|
||||
public A() { /* compiled code */ }
|
||||
|
||||
public class Inner <D> extends B<java.util.Collection<? extends T>> implements C<D> {
|
||||
public Inner() { /* compiled code */ }
|
||||
}
|
||||
|
||||
public final class Inner2 <X> extends A<T>.Inner<X> implements C<X> {
|
||||
public Inner2() { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// A
|
||||
open class B<F>
|
||||
interface C<E>
|
||||
abstract class A<T : A<T>> : B<Collection<T>>(), C<T> {
|
||||
inner open class Inner<D> : B<Collection<T>>(), C<D> {
|
||||
}
|
||||
|
||||
inner class Inner2<X> : Inner<X>(), C<X>
|
||||
}
|
||||
+5
@@ -134,6 +134,11 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
|
||||
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypePararametersInClass.kt")
|
||||
public void testTypePararametersInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/TypePararametersInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarArgs.kt")
|
||||
public void testVarArgs() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/VarArgs.kt");
|
||||
|
||||
+5
@@ -134,6 +134,11 @@ public class UltraLightClassSanityTestGenerated extends AbstractUltraLightClassS
|
||||
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypePararametersInClass.kt")
|
||||
public void testTypePararametersInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/TypePararametersInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarArgs.kt")
|
||||
public void testVarArgs() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/VarArgs.kt");
|
||||
|
||||
Generated
+5
@@ -134,6 +134,11 @@ public class IdeCompiledLightClassTestGenerated extends AbstractIdeCompiledLight
|
||||
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypePararametersInClass.kt")
|
||||
public void testTypePararametersInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/TypePararametersInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarArgs.kt")
|
||||
public void testVarArgs() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/VarArgs.kt");
|
||||
|
||||
+5
@@ -134,6 +134,11 @@ public class IdeLightClassTestGenerated extends AbstractIdeLightClassTest {
|
||||
runTest("compiler/testData/asJava/lightClasses/StubOrderForOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TypePararametersInClass.kt")
|
||||
public void testTypePararametersInClass() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/TypePararametersInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarArgs.kt")
|
||||
public void testVarArgs() throws Exception {
|
||||
runTest("compiler/testData/asJava/lightClasses/VarArgs.kt");
|
||||
|
||||
Reference in New Issue
Block a user