提交 0c0c53cc 编写于 作者: D Dmitriy Novozhilov

[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
上级 903defdf
......@@ -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 {
......@@ -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()
......
......@@ -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>()
......
// 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
}
}
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
}
......@@ -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 }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册