diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt index f82b5a6cf50..461d0a9e8bf 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCallResolver.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.api.fir.components +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals import org.jetbrains.kotlin.analysis.api.calls.* import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic @@ -29,6 +30,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver 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.utils.errors.ExceptionAttachmentBuilder import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry import org.jetbrains.kotlin.analysis.utils.errors.rethrowExceptionWithDetails @@ -1275,11 +1277,9 @@ internal class KtFirCallResolver( } } - override fun unresolvedKtCallError(psi: KtElement): Nothing { - buildErrorWithAttachment("${psi::class.simpleName}(${psi::class.simpleName}) should always resolve to a KtCallInfo") { - withPsiEntry("psi", psi) - psi.getOrBuildFir(firResolveSession)?.let { withFirEntry("fir", it) } - } + @KtAnalysisApiInternals + override fun provideAdditionalAttachmentToUnresolvedCall(psi: KtElement, builder: ExceptionAttachmentBuilder) { + psi.getOrBuildFir(firResolveSession)?.let { builder.withFirEntry("fir", it) } } private inline fun wrapError(element: KtElement, action: () -> R): R { diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtCallResolver.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtCallResolver.kt index ba8d1d0be4d..2a74b525715 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtCallResolver.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtCallResolver.kt @@ -5,10 +5,15 @@ package org.jetbrains.kotlin.analysis.api.components +import com.intellij.openapi.diagnostic.Logger +import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals import org.jetbrains.kotlin.analysis.api.calls.KtCallCandidateInfo import org.jetbrains.kotlin.analysis.api.calls.KtCallInfo +import org.jetbrains.kotlin.analysis.api.calls.KtErrorCallInfo +import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion -import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment +import org.jetbrains.kotlin.analysis.utils.errors.ExceptionAttachmentBuilder +import org.jetbrains.kotlin.analysis.utils.errors.logErrorWithAttachment import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtCallElement @@ -20,13 +25,30 @@ public abstract class KtCallResolver : KtAnalysisSessionComponent() { public abstract fun collectCallCandidates(psi: KtElement): List - public open fun unresolvedKtCallError(psi: KtElement): Nothing { - buildErrorWithAttachment("${psi::class.simpleName}(${psi::class.simpleName}) should always resolve to a KtCallInfo") { + @KtAnalysisApiInternals + public fun unresolvedKtCallError(psi: KtElement): KtErrorCallInfo { + LOG.logErrorWithAttachment("${psi::class.simpleName} should always resolve to a KtCallInfo") { withPsiEntry("psi", psi) + provideAdditionalAttachmentToUnresolvedCall(psi, this) } + return KtErrorCallInfo( + _candidateCalls = emptyList(), + KtNonBoundToPsiErrorDiagnostic(factoryName = null, "Unresolved call", token), + token + ) + } + + @KtAnalysisApiInternals + protected open fun provideAdditionalAttachmentToUnresolvedCall(psi: KtElement, builder: ExceptionAttachmentBuilder) { + } + + public companion object { + @KtAnalysisApiInternals + public val LOG: Logger = Logger.getInstance(KtCallResolver::class.java) } } +@OptIn(KtAnalysisApiInternals::class) public interface KtCallResolverMixIn : KtAnalysisSessionMixIn { public fun KtElement.resolveCall(): KtCallInfo? = diff --git a/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/ExceptionAttachmentBuilder.kt b/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/ExceptionAttachmentBuilder.kt index 262975bc4dc..7406db8db1e 100644 --- a/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/ExceptionAttachmentBuilder.kt +++ b/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/ExceptionAttachmentBuilder.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.analysis.utils.errors +import com.intellij.openapi.diagnostic.Attachment +import com.intellij.openapi.diagnostic.Logger import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint import org.jetbrains.kotlin.util.SourceCodeAnalysisException @@ -70,6 +72,16 @@ public inline fun buildErrorWithAttachment( throw exception } +public inline fun Logger.logErrorWithAttachment( + message: String, + cause: Exception? = null, + attachmentName: String = "info.txt", + buildAttachment: ExceptionAttachmentBuilder.() -> Unit = {} +) { + val attachment = Attachment(attachmentName, ExceptionAttachmentBuilder().apply(buildAttachment).buildString()) + this.error(message, cause, attachment) +} + public inline fun rethrowExceptionWithDetails( message: String, exception: Exception,