FIR: replace receiver in anon initializer with containing decl

This way the abstraction represents the intended use better and
doesn't stay on the way of using FirAnonymousInitializer in scripts
This commit is contained in:
Ilya Chernikov
2023-11-30 17:49:51 +01:00
committed by Space Team
parent 12da3d2b9f
commit ff4f30ddc1
13 changed files with 59 additions and 46 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.api
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.nullableJavaSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingClassId
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isScriptDependentDeclaration
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
@@ -21,10 +20,11 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.ClassId
@@ -106,8 +106,8 @@ private fun collectDesignationPath(target: FirElementWithResolveState): List<Fir
}
is FirAnonymousInitializer -> {
val containingClassId = target.containingClassId()
if (containingClassId.isLocal) return null
val containingClassId = (target.containingDeclarationSymbol as? FirClassSymbol<*>)?.classId
if (containingClassId == null || containingClassId.isLocal) return null
return collectDesignationPathWithContainingClass(target, containingClassId)
}
@@ -293,8 +293,17 @@ fun FirElementWithResolveState.tryCollectDesignationWithFile(): FirDesignationWi
}
private fun FirDeclaration.scriptDesignation(): FirDesignationWithFile? {
if (this !is FirStatement || !isScriptDependentDeclaration) return null
val firFile = getContainingFile() ?: return null
val firScript = firFile.declarations.singleOrNull() as? FirScript ?: return null
return FirDesignationWithFile(path = emptyList(), firScript, firFile)
return when {
this is FirAnonymousInitializer -> {
val firScriptSymbol = (containingDeclarationSymbol as? FirScriptSymbol) ?: return null
val firFile = firScriptSymbol.fir.getContainingFile() ?: return null
FirDesignationWithFile(path = emptyList(), firScriptSymbol.fir, firFile)
}
isScriptDependentDeclaration -> {
val firFile = getContainingFile() ?: return null
val firScript = firFile.declarations.singleOrNull() as? FirScript ?: return null
FirDesignationWithFile(path = emptyList(), firScript, firFile)
}
else -> null
}
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir
import org.jetbrains.kotlin.analysis.low.level.api.fir.ContextByDesignationCollector
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingClassId
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingClassIdOrNull
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
@@ -64,7 +64,7 @@ internal object PersistenceContextCollector {
is FirClassLikeDeclaration -> declaration.symbol.classId.isLocal
is FirCallableDeclaration -> declaration.symbol.callableId.isLocal
is FirDanglingModifierList -> declaration.containingClass()?.classId?.isLocal == true
is FirAnonymousInitializer -> declaration.containingClassId().isLocal
is FirAnonymousInitializer -> declaration.containingClassIdOrNull()?.isLocal == true
is FirScript, is FirCodeFragment -> false
else -> errorWithAttachment("Unsupported declaration ${declaration::class}") {
withFirEntry("declaration", declaration)
@@ -25,7 +25,7 @@ fun FirElementWithResolveState.getContainingFile(): FirFile? {
is FirBackingField -> propertySymbol.fir.getContainingFile()
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFileIfAny(symbol)
is FirAnonymousInitializer -> provider.getFirClassifierContainerFileIfAny(containingClassId())
is FirAnonymousInitializer -> containingDeclarationSymbol?.fir?.getContainingFile()
is FirDanglingModifierList, is FirCodeFragment -> {
val ktFile = psi?.containingFile as? KtFile
?: error("File for dangling modifier list cannot be null")
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.*
@@ -171,17 +172,8 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider(
return candidate?.takeIf { it.psi == this }
}
fun FirAnonymousInitializer.containingClassId(): ClassId {
val dispatchReceiverType = this.dispatchReceiverType
checkWithAttachment(
condition = dispatchReceiverType != null,
message = { "dispatchReceiverType for ${FirAnonymousInitializer::class.simpleName} modifier cannot be null" },
) {
withFirEntry("initializer", this@containingClassId)
}
return dispatchReceiverType.lookupTag.classId
}
fun FirAnonymousInitializer.containingClassIdOrNull(): ClassId? =
(containingDeclarationSymbol as? FirClassSymbol<*>)?.classId
val ORIGINAL_DECLARATION_KEY = com.intellij.openapi.util.Key<KtDeclaration>("ORIGINAL_DECLARATION_KEY")
var KtDeclaration.originalDeclaration by UserDataProperty(ORIGINAL_DECLARATION_KEY)