[FE] Don't analyze members with CLASSIFIERS kind filter in AbstractLazyMemberScope
This commit introduces partial support of descriptorKindFilter in
`AbstractPsiBasedDeclarationProvider`. Without it there may be an error
in following case:
```
sealed class Base
class Derived : Base()
class Test<out V>(val x: Base) {
private val y = when (x) {
is Derived -> null
}
}
```
Here we start to resolve type of `y`, then go to computation of inheritors
of sealed class Base, which also may be inside Test, so we need get all
nested classifiers in Test. But without this filtration we will start
computing descriptor for `y` again, which leads to ReenteringLazyComputationException
#KT-44316 Fixed
This commit is contained in:
+6
@@ -24391,6 +24391,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/sealed/inheritorInDifferentModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44316.kt")
|
||||
public void testKt44316() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/sealed/kt44316.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
|
||||
+7
-2
@@ -88,8 +88,13 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage
|
||||
|
||||
internal fun toInfoString() = toString() + ": " + index().toString()
|
||||
|
||||
override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<KtDeclaration> =
|
||||
index().allDeclarations
|
||||
override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<KtDeclaration> {
|
||||
val allDeclarations = index().allDeclarations
|
||||
if (kindFilter == DescriptorKindFilter.CLASSIFIERS) {
|
||||
return allDeclarations.filter { it is KtClassOrObject || it is KtTypeAlias }
|
||||
}
|
||||
return allDeclarations
|
||||
}
|
||||
|
||||
override fun getFunctionDeclarations(name: Name): List<KtNamedFunction> = index().functions[name.safeNameForLazyResolve()].toList()
|
||||
|
||||
|
||||
+17
-1
@@ -70,10 +70,26 @@ open class LazyClassMemberScope(
|
||||
result.toList()
|
||||
}
|
||||
|
||||
private val allClassifierDescriptors = storageManager.createLazyValue {
|
||||
val result = LinkedHashSet(
|
||||
computeDescriptorsFromDeclaredElements(
|
||||
DescriptorKindFilter.CLASSIFIERS,
|
||||
MemberScope.ALL_NAME_FILTER,
|
||||
NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS
|
||||
)
|
||||
)
|
||||
addSyntheticCompanionObject(result, NoLookupLocation.FOR_ALREADY_TRACKED)
|
||||
addSyntheticNestedClasses(result, NoLookupLocation.FOR_ALREADY_TRACKED)
|
||||
result.toList()
|
||||
}
|
||||
|
||||
override fun getContributedDescriptors(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean
|
||||
): Collection<DeclarationDescriptor> = allDescriptors()
|
||||
): Collection<DeclarationDescriptor> = when (kindFilter) {
|
||||
DescriptorKindFilter.CLASSIFIERS -> allClassifierDescriptors()
|
||||
else -> allDescriptors()
|
||||
}
|
||||
|
||||
protected open fun computeExtraDescriptors(location: LookupLocation): Collection<DeclarationDescriptor> {
|
||||
val result = ArrayList<DeclarationDescriptor>()
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-44316
|
||||
|
||||
sealed class Base
|
||||
class Derived : Base()
|
||||
|
||||
class Test<out V>(val x: Base) {
|
||||
private val y = when (x) {
|
||||
is Derived -> null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package
|
||||
|
||||
public sealed class Base {
|
||||
internal constructor Base()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Derived : Base {
|
||||
public constructor Derived()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Test</*0*/ out V> {
|
||||
public constructor Test</*0*/ out V>(/*0*/ x: Base)
|
||||
public final val x: Base
|
||||
private final val y: kotlin.Nothing?
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Generated
+6
@@ -24481,6 +24481,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/sealed/inheritorInDifferentModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44316.kt")
|
||||
public void testKt44316() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/sealed/kt44316.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("Local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
|
||||
@@ -138,6 +138,24 @@ class DescriptorKindFilter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as DescriptorKindFilter
|
||||
|
||||
if (excludes != other.excludes) return false
|
||||
if (kindMask != other.kindMask) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = excludes.hashCode()
|
||||
result = 31 * result + kindMask
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var nextMaskValue: Int = 0x01
|
||||
private fun nextMask() = nextMaskValue.apply { nextMaskValue = nextMaskValue shl 1 }
|
||||
|
||||
Reference in New Issue
Block a user