[LL FIR] do not crash on attempt to resolve class initializer in case of class clash
^KT-61788 Fixed
This commit is contained in:
committed by
Space Team
parent
e3ad946d23
commit
c9df6aff5f
+6
-6
@@ -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)
|
||||
}
|
||||
|
||||
+2
-3
@@ -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)
|
||||
|
||||
+1
-1
@@ -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")
|
||||
|
||||
+4
-16
@@ -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")
|
||||
|
||||
+11
@@ -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>
|
||||
}
|
||||
+30
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user