Do not compute stubs when building DefaultImpls light classes
Do not build stubs when computing inner classes of a light class This should implicitly fix a deadlock reported in KT-9907 and KT-9811
This commit is contained in:
@@ -34,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
||||||
|
import org.jetbrains.kotlin.psi.KtClass;
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||||
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
||||||
import org.jetbrains.kotlin.psi.KtFile;
|
import org.jetbrains.kotlin.psi.KtFile;
|
||||||
@@ -146,7 +147,8 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
|||||||
if (!qualifiedName.shortName().asString().equals(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) return;
|
if (!qualifiedName.shortName().asString().equals(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) return;
|
||||||
|
|
||||||
for (KtClassOrObject classOrObject : lightClassGenerationSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
|
for (KtClassOrObject classOrObject : lightClassGenerationSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
|
||||||
if (LightClassUtilsKt.getHasInterfaceDefaultImpls(classOrObject)) {
|
//NOTE: can't filter out more interfaces right away because decompiled declarations do not have member bodies
|
||||||
|
if (classOrObject instanceof KtClass && ((KtClass) classOrObject).isInterface()) {
|
||||||
PsiClass interfaceClass = LightClassUtil.INSTANCE$.getPsiClass(classOrObject);
|
PsiClass interfaceClass = LightClassUtil.INSTANCE$.getPsiClass(classOrObject);
|
||||||
if (interfaceClass != null) {
|
if (interfaceClass != null) {
|
||||||
PsiClass implsClass = interfaceClass.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false);
|
PsiClass implsClass = interfaceClass.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false);
|
||||||
|
|||||||
+9
-18
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|||||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
|
import java.util.*
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
public open class KtLightClassForExplicitDeclaration(
|
public open class KtLightClassForExplicitDeclaration(
|
||||||
@@ -364,12 +365,13 @@ public open class KtLightClassForExplicitDeclaration(
|
|||||||
override fun toString() = "${KtLightClass::class.java.simpleName}:$classFqName"
|
override fun toString() = "${KtLightClass::class.java.simpleName}:$classFqName"
|
||||||
|
|
||||||
override fun getOwnInnerClasses(): List<PsiClass> {
|
override fun getOwnInnerClasses(): List<PsiClass> {
|
||||||
return getDelegate().innerClasses
|
val result = ArrayList<PsiClass?>()
|
||||||
.map {
|
classOrObject.declarations.filterIsInstance<KtClassOrObject>().mapTo(result) { create(it) }
|
||||||
val declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(it) as KtClassOrObject?
|
|
||||||
if (declaration != null) create(declaration, it) else null
|
if (classOrObject.hasInterfaceDefaultImpls) {
|
||||||
}
|
result.add(KtLightClassForInterfaceDefaultImpls(classFqName.defaultImplsChild(), classOrObject))
|
||||||
.filterNotNull()
|
}
|
||||||
|
return result.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUseScope(): SearchScope = getOrigin().useScope
|
override fun getUseScope(): SearchScope = getOrigin().useScope
|
||||||
@@ -387,11 +389,7 @@ public open class KtLightClassForExplicitDeclaration(
|
|||||||
FINAL_KEYWORD to PsiModifier.FINAL)
|
FINAL_KEYWORD to PsiModifier.FINAL)
|
||||||
|
|
||||||
|
|
||||||
@JvmOverloads
|
public fun create(classOrObject: KtClassOrObject): KtLightClassForExplicitDeclaration? {
|
||||||
public fun create(
|
|
||||||
classOrObject: KtClassOrObject,
|
|
||||||
psiClass: PsiClass? = null
|
|
||||||
): KtLightClassForExplicitDeclaration? {
|
|
||||||
if (LightClassUtil.belongsToKotlinBuiltIns(classOrObject.getContainingKtFile())) {
|
if (LightClassUtil.belongsToKotlinBuiltIns(classOrObject.getContainingKtFile())) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -402,13 +400,6 @@ public open class KtLightClassForExplicitDeclaration(
|
|||||||
return KtLightClassForAnonymousDeclaration(fqName, classOrObject)
|
return KtLightClassForAnonymousDeclaration(fqName, classOrObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classOrObject.hasInterfaceDefaultImpls) {
|
|
||||||
val implsFqName = fqName.defaultImplsChild()
|
|
||||||
if (implsFqName.asString() == psiClass?.qualifiedName) {
|
|
||||||
return KtLightClassForInterfaceDefaultImpls(implsFqName, classOrObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return KtLightClassForExplicitDeclaration(fqName, classOrObject)
|
return KtLightClassForExplicitDeclaration(fqName, classOrObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -48,4 +48,6 @@ public open class KtLightClassForInterfaceDefaultImpls(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getContainingClass() = KtLightClassForExplicitDeclaration.create(classOrObject)
|
override fun getContainingClass() = KtLightClassForExplicitDeclaration.create(classOrObject)
|
||||||
|
|
||||||
|
override fun getOwnInnerClasses() = emptyList<PsiClass>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
public class Testing {
|
||||||
|
public static void test() {
|
||||||
|
DefaultImpl<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { lookupString: "DefaultImpls", tailText: " (defaultImpls.NonAbstractFun)" }
|
||||||
|
// EXIST: { lookupString: "DefaultImpls", tailText: " (defaultImpls.NonAbstractFunWithExpressionBody)" }
|
||||||
|
// EXIST: { lookupString: "DefaultImpls", tailText: " (defaultImpls.NonAbstractProperty)" }
|
||||||
|
// EXIST: { lookupString: "DefaultImpls", tailText: " (defaultImpls.NonAbstractPropertyWithBody)" }
|
||||||
|
// ABSENT: { lookupString: "DefaultImpls", tailText: " (defaultImpls.AllAbstract)" }
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package defaultImpls;
|
||||||
|
|
||||||
|
interface AllAbstract {
|
||||||
|
val c: Int
|
||||||
|
fun <T> f(t: T): T
|
||||||
|
|
||||||
|
val g: Int
|
||||||
|
|
||||||
|
var g2: String
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NonAbstractFun {
|
||||||
|
fun f() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NonAbstractFunWithExpressionBody {
|
||||||
|
fun f() = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NonAbstractProperty {
|
||||||
|
val c: Int get() = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NonAbstractPropertyWithBody {
|
||||||
|
val c: Int get() {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -101,6 +101,12 @@ public class CompiledKotlinInJavaCompletionTestGenerated extends AbstractCompile
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InterfaceDefaultImplsNonImported.java")
|
||||||
|
public void testInterfaceDefaultImplsNonImported() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/InterfaceDefaultImplsNonImported.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("MultiFileFacade.java")
|
@TestMetadata("MultiFileFacade.java")
|
||||||
public void testMultiFileFacade() throws Exception {
|
public void testMultiFileFacade() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/MultiFileFacade.java");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/MultiFileFacade.java");
|
||||||
|
|||||||
+6
@@ -101,6 +101,12 @@ public class KotlinSourceInJavaCompletionTestGenerated extends AbstractKotlinSou
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InterfaceDefaultImplsNonImported.java")
|
||||||
|
public void testInterfaceDefaultImplsNonImported() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/InterfaceDefaultImplsNonImported.java");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("MultiFileFacade.java")
|
@TestMetadata("MultiFileFacade.java")
|
||||||
public void testMultiFileFacade() throws Exception {
|
public void testMultiFileFacade() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/MultiFileFacade.java");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/MultiFileFacade.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user