[LL FIR] treat changes inside contract description as OOBM

Because contracts affects resolution

^KT-59687
^KTIJ-26085 Fixed
^KTIJ-26066
This commit is contained in:
Dmitrii Gridin
2023-06-30 15:31:45 +02:00
parent 99e2a14b9c
commit a50efd7aa2
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
internal object FileElementFactory {
fun createFileStructureElement(
@@ -111,11 +112,11 @@ internal object FileElementFactory {
fun PsiElement.getNonLocalReanalyzableContainingDeclaration(): KtDeclaration? {
return when (val declaration = getNonLocalContainingOrThisDeclaration()) {
is KtNamedFunction -> declaration.takeIf { function ->
function.isReanalyzableContainer() && function.bodyExpression?.isAncestor(this) == true
function.isReanalyzableContainer() && isElementInsideBody(declaration = function, child = this)
}
is KtPropertyAccessor -> declaration.takeIf { accessor ->
accessor.isReanalyzableContainer() && accessor.bodyExpression?.isAncestor(this) == true
accessor.isReanalyzableContainer() && isElementInsideBody(declaration = accessor, child = this)
}
is KtProperty -> declaration.takeIf { property ->
@@ -126,6 +127,20 @@ fun PsiElement.getNonLocalReanalyzableContainingDeclaration(): KtDeclaration? {
}
}
private fun isElementInsideBody(declaration: KtDeclarationWithBody, child: PsiElement): Boolean {
val body = declaration.bodyExpression ?: return false
if (!body.isAncestor(child)) return false
return !isInsideContract(body = body, child = child)
}
private fun isInsideContract(body: KtExpression, child: PsiElement): Boolean {
if (body !is KtBlockExpression) return false
val firstStatement = body.firstStatement ?: return false
if (!firstStatement.isContractDescriptionCallPsiCheck()) return false
return firstStatement.isAncestor(child)
}
private fun KtNamedFunction.isReanalyzableContainer(): Boolean = name != null && (hasBlockBody() || typeReference != null)
private fun KtPropertyAccessor.isReanalyzableContainer(): Boolean {