[LL FIR] avoid resolve to find property accessor declaration

^KT-57850 Fixed
This commit is contained in:
Dmitrii Gridin
2023-04-13 16:17:21 +02:00
committed by Space Team
parent aea7f4b6d2
commit bca8be6c39
4 changed files with 35 additions and 8 deletions
@@ -95,6 +95,11 @@ internal class FirElementBuilder(
}
}
private fun KtDeclaration.isPartOf(callableDeclaration: KtCallableDeclaration): Boolean = when (this) {
is KtPropertyAccessor -> this.property == callableDeclaration
else -> false
}
internal fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: (KtDeclaration) -> Boolean = { true }): KtDeclaration? {
var candidate: KtDeclaration? = null
@@ -105,8 +110,8 @@ internal fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: (KtDec
}
for (parent in parentsWithSelf) {
if (candidate != null) {
if (parent is KtEnumEntry || parent is KtCallableDeclaration || parent is KtClassInitializer) {
candidate?.let { notNullCandidate ->
if (parent is KtEnumEntry || parent is KtCallableDeclaration && !notNullCandidate.isPartOf(parent) || parent is KtClassInitializer) {
// Candidate turned out to be local. Let's find another one.
candidate = null
}
@@ -138,6 +143,11 @@ internal fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate: (KtDec
propose(parent)
}
}
is KtPropertyAccessor -> {
if (predicate(parent)) {
propose(parent)
}
}
}
}
}
@@ -67,13 +67,16 @@ internal class FileStructure private constructor(
private fun getStructureKtElement(element: KtElement): KtDeclaration? {
val container = element.getNonLocalContainingOrThisDeclaration()
when {
val resultedContainer = when {
container is KtClassOrObject && container.isInsideSuperClassCall(element) -> {
container.primaryConstructor?.let { return it }
container.primaryConstructor
}
container is KtPropertyAccessor -> container.property
else -> null
}
return container
return resultedContainer ?: container
}
private fun KtClassOrObject.isInsideSuperClassCall(element: KtElement): Boolean {
@@ -124,15 +124,16 @@ internal abstract class LLFirResolvableResolveSession(
require(getModuleKind(module) == ModuleKind.RESOLVABLE_MODULE) {
"Declaration should be resolvable module, instead it had ${module::class}"
}
val nonLocalNamedDeclaration = ktDeclaration.getNonLocalContainingOrThisDeclaration()
val nonLocalDeclaration = ktDeclaration.getNonLocalContainingOrThisDeclaration()
?: buildErrorWithAttachment("Declaration should have non-local container") {
withPsiEntry("ktDeclaration", ktDeclaration)
withEntry("module", module) { it.moduleDescription }
}
if (ktDeclaration == nonLocalNamedDeclaration) {
if (ktDeclaration == nonLocalDeclaration) {
val session = getResolvableSessionFor(module)
return nonLocalNamedDeclaration.findSourceNonLocalFirDeclaration(
return nonLocalDeclaration.findSourceNonLocalFirDeclaration(
firFileBuilder = session.moduleComponents.firFileBuilder,
provider = session.firProvider,
).symbol
@@ -110,6 +110,19 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider(
firFile.declarations.firstOrNull { it.psi == this }
}
this is KtScript -> containerFirFile?.declarations?.singleOrNull { it is FirScript }
this is KtPropertyAccessor -> {
val firPropertyDeclaration = property.findSourceNonLocalFirDeclaration(
firFileBuilder,
provider,
containerFirFile,
) as FirVariable
if (isGetter) {
firPropertyDeclaration.getter
} else {
firPropertyDeclaration.setter
}
}
else -> errorWithFirSpecificEntries("Invalid container", psi = this)
}
return candidate?.takeIf { it.realPsi == this }