Rework checkWithAttachment/requireWithAttachment

* better naming
* throw corresponding KotlinIllegalStateExceptionWithAttachments/KotlinIllegalArgumentExceptionWithAttachments instead of general KotlinRuntimeExceptionWithAttachments
This commit is contained in:
Ilya Kirillov
2023-06-30 15:56:26 +02:00
committed by Space Team
parent 2d791eb292
commit 4b3bff3344
12 changed files with 40 additions and 34 deletions
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.bas
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtSymbol import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
import org.jetbrains.kotlin.analysis.api.symbols.psiSafe import org.jetbrains.kotlin.analysis.api.symbols.psiSafe
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
@@ -33,7 +33,7 @@ internal class KtFe10MultiplatformInfoProvider(
val expectsForActual = (expectedCompatibilityMap[ExpectActualCompatibility.Compatible] val expectsForActual = (expectedCompatibilityMap[ExpectActualCompatibility.Compatible]
?: expectedCompatibilityMap.values.flatten()) ?: expectedCompatibilityMap.values.flatten())
check(expectsForActual.size <= 1) { "expected as maximum one `expect` for the actual" } check(expectsForActual.size <= 1) { "expected as maximum one `expect` for the actual" }
checkWithAttachmentBuilder(expectsForActual.size <= 1, message = { "expected as maximum one `expect` for the actual" }) { checkWithAttachment(expectsForActual.size <= 1, message = { "expected as maximum one `expect` for the actual" }) {
withEntry("actual", memberDescriptor.toString()) withEntry("actual", memberDescriptor.toString())
withEntry("expectsForActualSize", expectsForActual.size.toString()) withEntry("expectsForActualSize", expectsForActual.size.toString())
for ((index, expectForActual) in expectsForActual.withIndex()) { for ((index, expectForActual) in expectsForActual.withIndex()) {
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationInfo
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.analysis.utils.errors.withClassEntry import org.jetbrains.kotlin.analysis.utils.errors.withClassEntry
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirAnnotationContainer
@@ -47,7 +47,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirExpression> { internal fun mapAnnotationParameters(annotation: FirAnnotation): Map<Name, FirExpression> {
if (annotation is FirAnnotationCall && annotation.arguments.isEmpty()) return emptyMap() if (annotation is FirAnnotationCall && annotation.arguments.isEmpty()) return emptyMap()
checkWithAttachmentBuilder(annotation.resolved, { "By now the annotations argument mapping should have been resolved" }) { checkWithAttachment(annotation.resolved, { "By now the annotations argument mapping should have been resolved" }) {
withFirEntry("annotation", annotation) withFirEntry("annotation", annotation)
withClassEntry("annotationTypeRef", annotation.annotationTypeRef) withClassEntry("annotationTypeRef", annotation.annotationTypeRef)
withClassEntry("typeRef", annotation.typeRef) withClassEntry("typeRef", annotation.typeRef)
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolEntry import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolEntry
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.expectForActual import org.jetbrains.kotlin.fir.declarations.expectForActual
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@@ -29,7 +29,7 @@ internal class KtFirMultiplatformInfoProvider(
if (!isActual(actual)) return null if (!isActual(actual)) return null
val expectsForActual = firSymbol.expectForActual?.get(ExpectActualCompatibility.Compatible) ?: return null val expectsForActual = firSymbol.expectForActual?.get(ExpectActualCompatibility.Compatible) ?: return null
checkWithAttachmentBuilder(expectsForActual.size <= 1, message = { "expected as maximum one `expect` for the actual" }) { checkWithAttachment(expectsForActual.size <= 1, message = { "expected as maximum one `expect` for the actual" }) {
withFirSymbolEntry("actual", firSymbol) withFirSymbolEntry("actual", firSymbol)
withEntry("expectsForActualSize", expectsForActual.size.toString()) withEntry("expectsForActualSize", expectsForActual.size.toString())
for ((index, expectForActual) in expectsForActual.withIndex()) { for ((index, expectForActual) in expectsForActual.withIndex()) {
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.fir.containingClassForLocal import org.jetbrains.kotlin.fir.containingClassForLocal
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isInner
@@ -94,7 +94,7 @@ internal object UsualClassTypeQualifierBuilder {
} }
private fun collectDesignationPathForLocal(declaration: FirClassLikeDeclaration): List<FirDeclaration> { private fun collectDesignationPathForLocal(declaration: FirClassLikeDeclaration): List<FirDeclaration> {
checkWithAttachmentBuilder( checkWithAttachment(
declaration.isLocal, declaration.isLocal,
message = { "${declaration::class} is not local" } message = { "${declaration::class} is not local" }
) { ) {
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.containingClass
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
@@ -151,7 +151,7 @@ private fun collectDesignationPathWithContainingClass(target: FirDeclaration, co
?: findKotlinStdlibClass(classId, target) ?: findKotlinStdlibClass(classId, target)
} }
checkWithAttachmentBuilder( checkWithAttachment(
declaration is FirRegularClass, declaration is FirRegularClass,
message = { "'FirRegularClass' expected as a containing declaration, got '${declaration?.javaClass?.name}'" }, message = { "'FirRegularClass' expected as a containing declaration, got '${declaration?.javaClass?.name}'" },
buildAttachment = { buildAttachment = {
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder
import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.ThreadSafe import org.jetbrains.kotlin.analysis.api.impl.barebone.annotations.ThreadSafe
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
import org.jetbrains.kotlin.fir.builder.PsiRawFirBuilder import org.jetbrains.kotlin.fir.builder.PsiRawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
@@ -25,7 +25,7 @@ internal class LLFirFileBuilder(val moduleComponents: LLFirModuleResolveComponen
val contextualModule = moduleComponents.module val contextualModule = moduleComponents.module
val actualFileModule = projectStructureProvider.getModule(ktFile, contextualModule) val actualFileModule = projectStructureProvider.getModule(ktFile, contextualModule)
checkWithAttachmentBuilder(actualFileModule == contextualModule, { "Modules are inconsistent" }) { checkWithAttachment(actualFileModule == contextualModule, { "Modules are inconsistent" }) {
withEntry("file", ktFile.name) withEntry("file", ktFile.name)
withEntry("file module", actualFileModule) { withEntry("file module", actualFileModule) {
it.toString() it.toString()
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.analysis.utils.classIdIfNonLocal import org.jetbrains.kotlin.analysis.utils.classIdIfNonLocal
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSessionComponent { class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSessionComponent {
fun getFirClass(psiClass: PsiClass): FirRegularClassSymbol? { fun getFirClass(psiClass: PsiClass): FirRegularClassSymbol? {
@@ -32,7 +32,7 @@ class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSe
"${LLFirFirClassByPsiClassProvider::class.simpleName} can create only non-kotlin classes" "${LLFirFirClassByPsiClassProvider::class.simpleName} can create only non-kotlin classes"
} }
checkWithAttachmentBuilder( checkWithAttachment(
psiClass !is ClsElementImpl || !psiClass.hasAnnotation(JvmAnnotationNames.METADATA_FQ_NAME.asString()), { psiClass !is ClsElementImpl || !psiClass.hasAnnotation(JvmAnnotationNames.METADATA_FQ_NAME.asString()), {
"${LLFirFirClassByPsiClassProvider::class.simpleName} can create only non-kotlin classes, but got ${psiClass::class} with ${JvmAnnotationNames.METADATA_FQ_NAME.asString()} annotation" "${LLFirFirClassByPsiClassProvider::class.simpleName} can create only non-kotlin classes, but got ${psiClass::class} with ${JvmAnnotationNames.METADATA_FQ_NAME.asString()} annotation"
} }
@@ -47,7 +47,7 @@ class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSe
val firClassSymbol = createFirClassFromFirProvider(psiClass) val firClassSymbol = createFirClassFromFirProvider(psiClass)
val gotPsi = firClassSymbol.fir.psi val gotPsi = firClassSymbol.fir.psi
checkWithAttachmentBuilder( checkWithAttachment(
gotPsi == psiClass, gotPsi == psiClass,
{ "resulted FirClass.psi != requested PsiClass" } { "resulted FirClass.psi != requested PsiClass" }
) { ) {
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockPro
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkDelegatedConstructorIsResolved import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkDelegatedConstructorIsResolved
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.* import org.jetbrains.kotlin.analysis.low.level.api.fir.util.*
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
@@ -103,7 +103,7 @@ private class LLFirBodyTargetResolver(
} }
private fun calculateControlFlowGraph(target: FirRegularClass) { private fun calculateControlFlowGraph(target: FirRegularClass) {
checkWithAttachmentBuilder( checkWithAttachment(
target.controlFlowGraphReference == null, target.controlFlowGraphReference == null,
{ "'controlFlowGraphReference' should be 'null' if the class phase < $resolverPhase)" }, { "'controlFlowGraphReference' should be 'null' if the class phase < $resolverPhase)" },
) { ) {
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.util package org.jetbrains.kotlin.analysis.low.level.api.fir.util
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.packageFqName import org.jetbrains.kotlin.fir.packageFqName
@@ -70,11 +70,11 @@ internal object FirElementFinder {
expectedDeclarationAcceptor: (FirDeclaration) -> Boolean, expectedDeclarationAcceptor: (FirDeclaration) -> Boolean,
): FirDeclarationDesignation? { ): FirDeclarationDesignation? {
if (containerClassId != null) { if (containerClassId != null) {
requireWithAttachmentBuilder(!containerClassId.isLocal, { "ClassId should not be local" }) { requireWithAttachment(!containerClassId.isLocal, { "ClassId should not be local" }) {
withEntry("classId", containerClassId) { it.asString() } withEntry("classId", containerClassId) { it.asString() }
} }
requireWithAttachmentBuilder( requireWithAttachment(
firFile.packageFqName == containerClassId.packageFqName, firFile.packageFqName == containerClassId.packageFqName,
{ "ClassId should not be local" } { "ClassId should not be local" }
) { ) {
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.util package org.jetbrains.kotlin.analysis.low.level.api.fir.util
import org.jetbrains.kotlin.utils.exceptions.ExceptionAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.ExceptionAttachmentBuilder
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription
@@ -30,7 +30,7 @@ internal inline fun checkTypeRefIsResolved(
acceptImplicitTypeRef: Boolean = false, acceptImplicitTypeRef: Boolean = false,
extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {}, extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {},
) { ) {
checkWithAttachmentBuilder( checkWithAttachment(
condition = typeRef is FirResolvedTypeRef || acceptImplicitTypeRef && typeRef is FirImplicitTypeRef, condition = typeRef is FirResolvedTypeRef || acceptImplicitTypeRef && typeRef is FirImplicitTypeRef,
message = { message = {
buildString { buildString {
@@ -66,7 +66,7 @@ internal fun checkBodyIsResolved(function: FirFunction) {
internal fun checkExpectForActualIsResolved(memberDeclaration: FirMemberDeclaration) { internal fun checkExpectForActualIsResolved(memberDeclaration: FirMemberDeclaration) {
if (!memberDeclaration.isActual) return if (!memberDeclaration.isActual) return
checkWithAttachmentBuilder( checkWithAttachment(
condition = memberDeclaration.expectForActual != null, condition = memberDeclaration.expectForActual != null,
message = { "Expect for actual matching is missing" } message = { "Expect for actual matching is missing" }
) { ) {
@@ -87,7 +87,7 @@ internal fun checkReferenceIsResolved(
owner: FirResolvable, owner: FirResolvable,
extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {}, extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {},
) { ) {
checkWithAttachmentBuilder( checkWithAttachment(
condition = reference is FirResolvedNamedReference || reference is FirErrorNamedReference || reference is FirFromMissingDependenciesNamedReference, condition = reference is FirResolvedNamedReference || reference is FirErrorNamedReference || reference is FirFromMissingDependenciesNamedReference,
message = { message = {
"Expected ${FirNamedReference::class.simpleName}, " + "Expected ${FirNamedReference::class.simpleName}, " +
@@ -116,7 +116,7 @@ internal fun checkDefaultValueIsResolved(parameter: FirValueParameter) {
} }
internal fun checkDeprecationProviderIsResolved(declaration: FirDeclaration, provider: DeprecationsProvider) { internal fun checkDeprecationProviderIsResolved(declaration: FirDeclaration, provider: DeprecationsProvider) {
checkWithAttachmentBuilder( checkWithAttachment(
condition = provider !is UnresolvedDeprecationProvider, condition = provider !is UnresolvedDeprecationProvider,
message = { "Unresolved deprecation provider found for ${declaration::class.simpleName}" } message = { "Unresolved deprecation provider found for ${declaration::class.simpleName}" }
) { ) {
@@ -136,7 +136,7 @@ internal fun checkReceiverTypeRefIsResolved(declaration: FirCallableDeclaration,
internal fun checkContractDescriptionIsResolved(declaration: FirContractDescriptionOwner) { internal fun checkContractDescriptionIsResolved(declaration: FirContractDescriptionOwner) {
val contractDescription = declaration.contractDescription val contractDescription = declaration.contractDescription
checkWithAttachmentBuilder( checkWithAttachment(
condition = contractDescription is FirResolvedContractDescription || condition = contractDescription is FirResolvedContractDescription ||
contractDescription is FirEmptyContractDescription || contractDescription is FirEmptyContractDescription ||
contractDescription is FirLegacyRawContractDescription /* TODO: should be dropped after KT-60310 */, contractDescription is FirLegacyRawContractDescription /* TODO: should be dropped after KT-60310 */,
@@ -148,7 +148,7 @@ internal fun checkContractDescriptionIsResolved(declaration: FirContractDescript
internal fun checkDeclarationStatusIsResolved(declaration: FirMemberDeclaration) { internal fun checkDeclarationStatusIsResolved(declaration: FirMemberDeclaration) {
val status = declaration.status val status = declaration.status
checkWithAttachmentBuilder( checkWithAttachment(
condition = status is FirResolvedDeclarationStatus, condition = status is FirResolvedDeclarationStatus,
message = { "Expected ${FirResolvedDeclarationStatus::class.simpleName} but ${status::class.simpleName} found for ${declaration::class.simpleName}" } message = { "Expected ${FirResolvedDeclarationStatus::class.simpleName} but ${status::class.simpleName} found for ${declaration::class.simpleName}" }
) { ) {
@@ -161,7 +161,7 @@ internal fun <T> checkAnnotationArgumentsMappingIsResolved(
) where T : FirAnnotationContainer, T : FirElementWithResolveState { ) where T : FirAnnotationContainer, T : FirElementWithResolveState {
for (annotation in annotationContainer.annotations) { for (annotation in annotationContainer.annotations) {
if (annotation is FirAnnotationCall) { if (annotation is FirAnnotationCall) {
checkWithAttachmentBuilder( checkWithAttachment(
condition = annotation.argumentList is FirResolvedArgumentList, condition = annotation.argumentList is FirResolvedArgumentList,
message = { message = {
buildString { buildString {
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.util package org.jetbrains.kotlin.analysis.low.level.api.fir.util
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachmentBuilder import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.resolvePhase
internal fun FirElementWithResolveState.checkPhase(requiredResolvePhase: FirResolvePhase) { internal fun FirElementWithResolveState.checkPhase(requiredResolvePhase: FirResolvePhase) {
@OptIn(ResolveStateAccess::class) @OptIn(ResolveStateAccess::class)
val declarationResolveState = resolveState val declarationResolveState = resolveState
checkWithAttachmentBuilder( checkWithAttachment(
declarationResolveState.resolvePhase >= requiredResolvePhase, declarationResolveState.resolvePhase >= requiredResolvePhase,
{ "At least $requiredResolvePhase expected but $declarationResolveState found for ${this::class.simpleName}" }, { "At least $requiredResolvePhase expected but $declarationResolveState found for ${this::class.simpleName}" },
) { ) {
@@ -91,27 +91,33 @@ inline fun rethrowExceptionWithDetails(
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
inline fun checkWithAttachmentBuilder( inline fun checkWithAttachment(
condition: Boolean, condition: Boolean,
message: () -> String, message: () -> String,
attachmentName: String = "info.txt",
buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {}, buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {},
) { ) {
contract { returns() implies (condition) } contract { returns() implies (condition) }
if (!condition) { if (!condition) {
errorWithAttachment(message(), buildAttachment = buildAttachment) val exception = KotlinIllegalStateExceptionWithAttachments(message())
exception.buildAttachment(attachmentName) { buildAttachment() }
throw exception
} }
} }
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
inline fun requireWithAttachmentBuilder( inline fun requireWithAttachment(
condition: Boolean, condition: Boolean,
message: () -> String, message: () -> String,
attachmentName: String = "info.txt",
buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {}, buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {},
) { ) {
contract { returns() implies (condition) } contract { returns() implies (condition) }
if (!condition) { if (!condition) {
errorWithAttachment(message(), buildAttachment = buildAttachment) val exception = KotlinIllegalArgumentExceptionWithAttachments(message())
exception.buildAttachment(attachmentName) { buildAttachment() }
throw exception
} }
} }