diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt index 8f8237c2f38..9dca29715ff 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirCallableSymbol.kt @@ -19,22 +19,34 @@ abstract class FirCallableSymbol : FirBasedSymbol val resolvedReturnTypeRef: FirResolvedTypeRef get() { ensureType(fir.returnTypeRef) - return fir.returnTypeRef as FirResolvedTypeRef + val returnTypeRef = fir.returnTypeRef + if (returnTypeRef !is FirResolvedTypeRef) { + errorInLazyResolve("returnTypeRef", returnTypeRef::class, FirResolvedTypeRef::class) + } + + return returnTypeRef } val resolvedReturnType: ConeKotlinType get() = resolvedReturnTypeRef.coneType - val resolvedReceiverTypeRef: FirResolvedTypeRef? - get() { - ensureType(fir.receiverParameter?.typeRef) - return fir.receiverParameter?.typeRef as FirResolvedTypeRef? + get() = calculateReceiverTypeRef() + + private fun calculateReceiverTypeRef(): FirResolvedTypeRef? { + val receiverParameter = fir.receiverParameter ?: return null + ensureType(receiverParameter.typeRef) + val receiverTypeRef = receiverParameter.typeRef + if (receiverTypeRef !is FirResolvedTypeRef) { + errorInLazyResolve("receiverTypeRef", receiverTypeRef::class, FirResolvedTypeRef::class) } + return receiverTypeRef + } + val receiverParameter: FirReceiverParameter? get() { - ensureType(fir.receiverParameter?.typeRef) + calculateReceiverTypeRef() return fir.receiverParameter } @@ -46,19 +58,13 @@ abstract class FirCallableSymbol : FirBasedSymbol } val resolvedStatus: FirResolvedDeclarationStatus - get() { - lazyResolveToPhase(FirResolvePhase.STATUS) - return fir.status as FirResolvedDeclarationStatus - } + get() = fir.resolvedStatus() val rawStatus: FirDeclarationStatus get() = fir.status - val typeParameterSymbols: List - get() { - return fir.typeParameters.map { it.symbol } - } + get() = fir.typeParameters.map { it.symbol } val dispatchReceiverType: ConeSimpleKotlinType? get() = fir.dispatchReceiverType diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt index 9f738186ddb..8d226bf4130 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirClassLikeSymbol.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -20,13 +20,13 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.SpecialNames sealed class FirClassLikeSymbol( - val classId: ClassId + val classId: ClassId, ) : FirClassifierSymbol() { abstract override fun toLookupTag(): ConeClassLikeLookupTag val name get() = classId.shortClassName - fun getDeprecation(apiVersion: ApiVersion): DeprecationsPerUseSite? { + fun getDeprecation(apiVersion: ApiVersion): DeprecationsPerUseSite? { if (annotations.isEmpty()) return null lazyResolveToPhase(FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS) return fir.deprecationsProvider.getDeprecationsInfo(apiVersion) @@ -36,15 +36,10 @@ sealed class FirClassLikeSymbol( get() = fir.status val resolvedStatus: FirResolvedDeclarationStatus - get() { - lazyResolveToPhase(FirResolvePhase.STATUS) - return fir.status as FirResolvedDeclarationStatus - } + get() = fir.resolvedStatus() val typeParameterSymbols: List - get() { - return fir.typeParameters.map { it.symbol } - } + get() = fir.typeParameters.map { it.symbol } override fun toString(): String = "${this::class.simpleName} ${classId.asString()}" } @@ -67,9 +62,7 @@ sealed class FirClassSymbol(classId: ClassId) : FirClassLikeSymbol get() = resolvedSuperTypeRefs.map { it.coneType } val declarationSymbols: List> - get() { - return fir.declarations.map { it.symbol } - } + get() = fir.declarations.map { it.symbol } val classKind: ClassKind get() = fir.classKind diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt index dcd6a0b8926..b112bd20a48 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.name.* sealed class FirFunctionSymbol( - override val callableId: CallableId + override val callableId: CallableId, ) : FirCallableSymbol() { val valueParameterSymbols: List get() = fir.valueParameters.map { it.symbol } @@ -49,11 +49,11 @@ interface FirIntersectionCallableSymbol { class FirIntersectionOverrideFunctionSymbol( callableId: CallableId, - override val intersections: Collection> + override val intersections: Collection>, ) : FirNamedFunctionSymbol(callableId), FirIntersectionCallableSymbol class FirConstructorSymbol( - callableId: CallableId + callableId: CallableId, ) : FirFunctionSymbol(callableId) { constructor(classId: ClassId) : this(classId.callableIdForConstructor()) @@ -71,10 +71,10 @@ class FirConstructorSymbol( } val delegatedConstructorCallIsThis: Boolean - get() = fir.delegatedConstructor?.isThis ?: false + get() = fir.delegatedConstructor?.isThis == true val delegatedConstructorCallIsSuper: Boolean - get() = fir.delegatedConstructor?.isSuper ?: false + get() = fir.delegatedConstructor?.isSuper == true } /** @@ -86,7 +86,7 @@ class FirConstructorSymbol( */ abstract class FirSyntheticPropertySymbol( propertyId: CallableId, - val getterId: CallableId + val getterId: CallableId, ) : FirPropertySymbol(propertyId) { abstract fun copy(): FirSyntheticPropertySymbol } @@ -94,7 +94,7 @@ abstract class FirSyntheticPropertySymbol( // ------------------------ unnamed ------------------------ sealed class FirFunctionWithoutNameSymbol( - stubName: Name + stubName: Name, ) : FirFunctionSymbol(CallableId(FqName("special"), stubName)) class FirAnonymousFunctionSymbol : FirFunctionWithoutNameSymbol(Name.identifier("anonymous")) { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/Utils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/Utils.kt new file mode 100644 index 00000000000..3df7d8ea1ff --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/Utils.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.symbols.impl + +import kotlin.reflect.KClass +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.declarations.FirResolvedDeclarationStatus +import org.jetbrains.kotlin.fir.psi +import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithAttributes +import org.jetbrains.kotlin.fir.renderer.FirFileAnnotationsContainerRenderer +import org.jetbrains.kotlin.fir.renderer.FirRenderer +import org.jetbrains.kotlin.fir.renderer.FirResolvePhaseRenderer +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase +import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments + +internal fun FirBasedSymbol<*>.errorInLazyResolve(name: String, actualClass: KClass<*>, expected: KClass<*>): Nothing { + throw KotlinExceptionWithAttachments("Unexpected $name. Expected is ${expected.simpleName}, but was ${actualClass.simpleName}").apply { + withAttachment( + "FirElement.txt", + FirRenderer( + resolvePhaseRenderer = FirResolvePhaseRenderer(), + declarationRenderer = FirDeclarationRendererWithAttributes(), + fileAnnotationsContainerRenderer = FirFileAnnotationsContainerRenderer(), + ).renderElementAsString(fir), + ) + + withAttachment("FirBasedSymbol.txt", this::class.simpleName) + withAttachment("KtSourceElementKind.txt", fir.source?.kind?.let { it::class.simpleName }) + withPsiAttachment("PsiElement.txt", fir.psi) + } +} + +internal fun FirMemberDeclaration.resolvedStatus(): FirResolvedDeclarationStatus { + lazyResolveToPhase(FirResolvePhase.STATUS) + + val status = status + if (status !is FirResolvedDeclarationStatus) { + symbol.errorInLazyResolve("status", status::class, FirResolvedDeclarationStatus::class) + } + + return status +} \ No newline at end of file