[LL FIR] do not crash on attempt to resolve class initializer in case of class clash

^KT-61788 Fixed
This commit is contained in:
Dmitrii Gridin
2023-09-18 16:15:11 +02:00
committed by Space Team
parent e3ad946d23
commit c9df6aff5f
8 changed files with 66 additions and 26 deletions
@@ -8,11 +8,9 @@ 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.containingClass
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.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isScriptDependentDeclaration
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
import org.jetbrains.kotlin.builtins.StandardNames
@@ -26,9 +24,11 @@ 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.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isScriptDependentDeclaration
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
class FirDesignationWithFile(
path: List<FirRegularClass>,
@@ -105,7 +105,7 @@ private fun collectDesignationPath(target: FirElementWithResolveState): List<Fir
}
is FirAnonymousInitializer -> {
val containingClassId = target.containingClass().symbol.classId
val containingClassId = target.containingClassId()
if (containingClassId.isLocal) return null
return collectDesignationPathWithContainingClass(target, containingClassId)
}
@@ -8,14 +8,13 @@ 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.containingClass
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingClassId
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContextForProvider
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.resolve.SessionHolder
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
@@ -65,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.containingClass().classId.isLocal
is FirAnonymousInitializer -> declaration.containingClassId().isLocal
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 -> containingClass().getContainingFile()
is FirAnonymousInitializer -> provider.getFirClassifierContainerFileIfAny(containingClassId())
is FirDanglingModifierList, is FirCodeFragment -> {
val ktFile = psi?.containingFile as? KtFile
?: error("File for dangling modifier list cannot be null")
@@ -15,15 +15,13 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.containin
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirFileBuilder
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirStatement
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.resolve.toSymbol
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.fir.utils.exceptions.withFirLookupTagEntry
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
@@ -174,26 +172,16 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider(
return candidate?.takeIf { it.psi == this }
}
fun FirAnonymousInitializer.containingClass(): FirRegularClass {
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@containingClass)
withFirEntry("initializer", this@containingClassId)
}
val lookupTag = dispatchReceiverType.lookupTag
val dispatchReceiverSymbol = lookupTag.toSymbol(llFirSession)
checkWithAttachment(
condition = dispatchReceiverSymbol != null,
message = { "symbol for ${FirAnonymousInitializer::class.simpleName} cannot be null" },
) {
withFirEntry("initializer", this@containingClass)
withFirLookupTagEntry("tag", lookupTag)
}
return dispatchReceiverSymbol.fir as FirRegularClass
return dispatchReceiverType.lookupTag.classId
}
val ORIGINAL_DECLARATION_KEY = com.intellij.openapi.util.Key<KtDeclaration>("ORIGINAL_DECLARATION_KEY")
@@ -0,0 +1,11 @@
// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtClassInitializer
package one.two
class A
typealias Foo = A
class Foo {
<expr>init {
val i = 1
}</expr>
}
@@ -0,0 +1,30 @@
KT element: KtClassInitializer
FIR element: FirAnonymousInitializerImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
init {
[ResolvedTo(RAW_FIR)] lval i: R|kotlin/Int| = Int(1)
}
FIR FILE:
FILE: [ResolvedTo(IMPORTS)] initializerConflict.kt
package one.two
public final [ResolvedTo(STATUS)] class A : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=A] constructor(): R|one/two/A| {
LAZY_super<R|kotlin/Any|>
}
}
public? final [ResolvedTo(SUPER_TYPES)] typealias Foo = R|one/two/A|
public final [ResolvedTo(STATUS)] class Foo : R|kotlin/Any| {
public [ResolvedTo(STATUS)] [ContainingClassKey=Foo] constructor(): R|one/two/Foo| {
LAZY_super<R|kotlin/Any|>
}
init {
[ResolvedTo(RAW_FIR)] lval i: R|kotlin/Int| = Int(1)
}
}
@@ -513,6 +513,12 @@ public class OutOfContentRootGetOrBuildFirTestGenerated extends AbstractOutOfCon
runTest("analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringEntry.kt");
}
@Test
@TestMetadata("initializerConflict.kt")
public void testInitializerConflict() throws Exception {
runTest("analysis/low-level-api-fir/testData/getOrBuildFir/declarations/initializerConflict.kt");
}
@Test
@TestMetadata("kt60387.kt")
public void testKt60387() throws Exception {
@@ -513,6 +513,12 @@ public class SourceGetOrBuildFirTestGenerated extends AbstractSourceGetOrBuildFi
runTest("analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringEntry.kt");
}
@Test
@TestMetadata("initializerConflict.kt")
public void testInitializerConflict() throws Exception {
runTest("analysis/low-level-api-fir/testData/getOrBuildFir/declarations/initializerConflict.kt");
}
@Test
@TestMetadata("kt60387.kt")
public void testKt60387() throws Exception {