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:
Pavel V. Talanov
2015-11-09 20:56:27 +03:00
parent bff7ff0c5d
commit de4ea45f20
7 changed files with 67 additions and 19 deletions
@@ -34,6 +34,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNamesUtilKt;
import org.jetbrains.kotlin.psi.KtClass;
import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.KtEnumEntry;
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;
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);
if (interfaceClass != null) {
PsiClass implsClass = interfaceClass.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false);
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.util.*
import javax.swing.Icon
public open class KtLightClassForExplicitDeclaration(
@@ -364,12 +365,13 @@ public open class KtLightClassForExplicitDeclaration(
override fun toString() = "${KtLightClass::class.java.simpleName}:$classFqName"
override fun getOwnInnerClasses(): List<PsiClass> {
return getDelegate().innerClasses
.map {
val declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(it) as KtClassOrObject?
if (declaration != null) create(declaration, it) else null
}
.filterNotNull()
val result = ArrayList<PsiClass?>()
classOrObject.declarations.filterIsInstance<KtClassOrObject>().mapTo(result) { create(it) }
if (classOrObject.hasInterfaceDefaultImpls) {
result.add(KtLightClassForInterfaceDefaultImpls(classFqName.defaultImplsChild(), classOrObject))
}
return result.filterNotNull()
}
override fun getUseScope(): SearchScope = getOrigin().useScope
@@ -387,11 +389,7 @@ public open class KtLightClassForExplicitDeclaration(
FINAL_KEYWORD to PsiModifier.FINAL)
@JvmOverloads
public fun create(
classOrObject: KtClassOrObject,
psiClass: PsiClass? = null
): KtLightClassForExplicitDeclaration? {
public fun create(classOrObject: KtClassOrObject): KtLightClassForExplicitDeclaration? {
if (LightClassUtil.belongsToKotlinBuiltIns(classOrObject.getContainingKtFile())) {
return null
}
@@ -402,13 +400,6 @@ public open class KtLightClassForExplicitDeclaration(
return KtLightClassForAnonymousDeclaration(fqName, classOrObject)
}
if (classOrObject.hasInterfaceDefaultImpls) {
val implsFqName = fqName.defaultImplsChild()
if (implsFqName.asString() == psiClass?.qualifiedName) {
return KtLightClassForInterfaceDefaultImpls(implsFqName, classOrObject)
}
}
return KtLightClassForExplicitDeclaration(fqName, classOrObject)
}
@@ -48,4 +48,6 @@ public open class KtLightClassForInterfaceDefaultImpls(
}
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
}
}
@@ -101,6 +101,12 @@ public class CompiledKotlinInJavaCompletionTestGenerated extends AbstractCompile
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")
public void testMultiFileFacade() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/MultiFileFacade.java");
@@ -101,6 +101,12 @@ public class KotlinSourceInJavaCompletionTestGenerated extends AbstractKotlinSou
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")
public void testMultiFileFacade() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/injava/MultiFileFacade.java");