[Analysis API FIR] add more info to some exceptions
This commit is contained in:
+10
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
@@ -67,6 +69,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||
|
||||
internal class KtFirCallResolver(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -1162,4 +1165,11 @@ internal class KtFirCallResolver(
|
||||
else -> realPsi as? KtExpression
|
||||
}
|
||||
}
|
||||
|
||||
override fun unresolvedKtCallError(psi: KtElement): Nothing {
|
||||
errorWithAttachment("${psi::class.simpleName}(${psi::class.simpleName}) should always resolve to a KtCallInfo") {
|
||||
withPsiAttachment("psi", psi)
|
||||
psi.getOrBuildFir(firResolveSession)?.let { withFirAttachment("fir", it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbolOfType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolAttachment
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirAttachment
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||
|
||||
|
||||
+12
-10
@@ -8,16 +8,23 @@ package org.jetbrains.kotlin.analysis.api.components
|
||||
import org.jetbrains.kotlin.analysis.api.calls.KtCallCandidateInfo
|
||||
import org.jetbrains.kotlin.analysis.api.calls.KtCallInfo
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallElement
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtUnaryExpression
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||
|
||||
public abstract class KtCallResolver : KtAnalysisSessionComponent() {
|
||||
public abstract fun resolveCall(psi: KtElement): KtCallInfo?
|
||||
|
||||
public abstract fun collectCallCandidates(psi: KtElement): List<KtCallCandidateInfo>
|
||||
|
||||
public open fun unresolvedKtCallError(psi: KtElement): Nothing {
|
||||
errorWithAttachment("${psi::class.simpleName}(${psi::class.simpleName}) should always resolve to a KtCallInfo") {
|
||||
withPsiAttachment("psi", psi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
|
||||
@@ -27,18 +34,18 @@ public interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
|
||||
|
||||
public fun KtCallElement.resolveCall(): KtCallInfo = withValidityAssertion {
|
||||
analysisSession.callResolver.resolveCall(this)
|
||||
?: unresolvedKtCallError(this)
|
||||
?: analysisSession.callResolver.unresolvedKtCallError(this)
|
||||
}
|
||||
|
||||
public fun KtUnaryExpression.resolveCall(): KtCallInfo = withValidityAssertion {
|
||||
analysisSession.callResolver.resolveCall(this)
|
||||
?: unresolvedKtCallError(this)
|
||||
?: analysisSession.callResolver.unresolvedKtCallError(this)
|
||||
}
|
||||
|
||||
|
||||
public fun KtArrayAccessExpression.resolveCall(): KtCallInfo = withValidityAssertion {
|
||||
analysisSession.callResolver.resolveCall(this)
|
||||
?: unresolvedKtCallError(this)
|
||||
?: analysisSession.callResolver.unresolvedKtCallError(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,8 +58,3 @@ public interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
|
||||
public fun KtElement.collectCallCandidates(): List<KtCallCandidateInfo> =
|
||||
withValidityAssertion { analysisSession.callResolver.collectCallCandidates(this) }
|
||||
}
|
||||
|
||||
private inline fun <reified PSI : KtElement> unresolvedKtCallError(element: PSI): Nothing {
|
||||
throw KotlinExceptionWithAttachments("${PSI::class.simpleName}(${element::class.simpleName}) should always resolve to a KtCallInfo")
|
||||
.withAttachment("elementText", element.getElementTextInContext())
|
||||
}
|
||||
|
||||
+15
@@ -5,7 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.utils.errors
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||
|
||||
public fun unexpectedElementError(elementName: String, element: Any?): Nothing {
|
||||
errorWithAttachment("Unexpected $elementName ${element?.let { it::class.simpleName }}") {
|
||||
@@ -15,4 +20,14 @@ public fun unexpectedElementError(elementName: String, element: Any?): Nothing {
|
||||
|
||||
public inline fun <reified ELEMENT> unexpectedElementError(element: Any?): Nothing {
|
||||
unexpectedElementError(ELEMENT::class.simpleName ?: ELEMENT::class.java.name, element)
|
||||
}
|
||||
|
||||
public fun KotlinExceptionWithAttachments.withPsiAttachment(name: String, psi: PsiElement?): KotlinExceptionWithAttachments {
|
||||
withAttachmentDetailed(name, psi) { psiElement ->
|
||||
when (psiElement) {
|
||||
is KtElement -> psiElement.getElementTextInContext()
|
||||
else -> psiElement.text
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
+1
-1
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableS
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
|
||||
+1
-1
@@ -18,10 +18,10 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProv
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
|
||||
+31
-13
@@ -6,17 +6,21 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.KtDeclarationAndFirDeclarationEqualityChecker
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredConstructors
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredFunctionSymbols
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.withAttachmentBuilder
|
||||
|
||||
/**
|
||||
* Allows to search for FIR declarations by compiled [KtDeclaration]s.
|
||||
@@ -37,10 +41,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
||||
private fun findNonLocalEnumEntry(declaration: KtEnumEntry): FirEnumEntry {
|
||||
require(!declaration.isLocal)
|
||||
val classId = declaration.containingClassOrObject?.getClassId()
|
||||
?: firErrorWithAttachment(
|
||||
"Non-local class should have classId. The class is ${declaration.getElementTextInContext()}",
|
||||
psi = declaration
|
||||
)
|
||||
?: firErrorWithAttachment("Non-local class should have classId", psi = declaration)
|
||||
|
||||
val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId)
|
||||
?: firErrorWithAttachment("We should be able to find a symbol for $classId", psi = declaration)
|
||||
@@ -56,10 +57,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
||||
|
||||
val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId)
|
||||
?: firErrorWithAttachment("We should be able to find a symbol for $classId", psi = declaration) {
|
||||
withAttachment(
|
||||
"classId",
|
||||
classId.asString()
|
||||
)
|
||||
withAttachment("classId", classId.asString())
|
||||
}
|
||||
|
||||
return classCandidate.fir
|
||||
@@ -84,21 +82,27 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
||||
private fun findNonLocalFunction(declaration: KtNamedFunction): FirFunction {
|
||||
require(!declaration.isLocal)
|
||||
|
||||
val candidates = symbolProvider.findFunctionCandidates(declaration)
|
||||
val functionCandidate =
|
||||
symbolProvider.findFunctionCandidates(declaration)
|
||||
candidates
|
||||
.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
||||
?: firErrorWithAttachment("We should be able to find a symbol for function", psi = declaration)
|
||||
?: firErrorWithAttachment("We should be able to find a symbol for function", psi = declaration) {
|
||||
withCandidates(candidates)
|
||||
}
|
||||
|
||||
return functionCandidate.fir
|
||||
}
|
||||
|
||||
|
||||
private fun findNonLocalProperty(declaration: KtProperty): FirProperty {
|
||||
require(!declaration.isLocal)
|
||||
|
||||
val candidates = symbolProvider.findPropertyCandidates(declaration)
|
||||
val propertyCandidate =
|
||||
symbolProvider.findPropertyCandidates(declaration)
|
||||
.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
||||
?: firErrorWithAttachment("We should be able to find a symbol for property", psi = declaration)
|
||||
candidates.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
||||
?: firErrorWithAttachment("We should be able to find a symbol for property", psi = declaration) {
|
||||
withCandidates(candidates)
|
||||
}
|
||||
|
||||
return propertyCandidate.fir
|
||||
}
|
||||
@@ -133,3 +137,17 @@ private fun representSameConstructor(psiConstructor: KtConstructor<*>, firConstr
|
||||
|
||||
return KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(psiConstructor, firConstructor)
|
||||
}
|
||||
|
||||
private fun KotlinExceptionWithAttachments.withCandidates(candidates: List<FirBasedSymbol<*>>) {
|
||||
withAttachmentBuilder("candidates") {
|
||||
appendLine("Candidates count ${candidates.size}")
|
||||
for ((index, candidate) in candidates.withIndex()) {
|
||||
appendLine("Candidate $index, ${candidate::class.java}")
|
||||
val ktModule = candidate.llFirModuleData.ktModule
|
||||
appendLine("From ${ktModule::class.java} ${ktModule.moduleDescription}")
|
||||
appendLine("Origin ${candidate.origin}")
|
||||
appendLine(debugFirRenderer.renderElementAsString(candidate.fir))
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-10
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
@@ -40,15 +41,7 @@ fun KotlinExceptionWithAttachments.withConeTypeAttachment(name: String, coneType
|
||||
return this
|
||||
}
|
||||
|
||||
fun KotlinExceptionWithAttachments.withPsiAttachment(name: String, psi: PsiElement?): KotlinExceptionWithAttachments {
|
||||
withAttachmentDetailed(name, psi) { psiElement ->
|
||||
when (psiElement) {
|
||||
is KtElement -> psiElement.getElementTextInContext()
|
||||
else -> psiElement.text
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun firErrorWithAttachment(
|
||||
@@ -76,5 +69,5 @@ fun firErrorWithAttachment(
|
||||
}
|
||||
|
||||
|
||||
private val debugFirRenderer =
|
||||
val debugFirRenderer =
|
||||
FirRenderer(resolvePhaseRenderer = FirResolvePhaseRenderer(), declarationRenderer = FirDeclarationRendererWithAttributes())
|
||||
|
||||
@@ -38,6 +38,11 @@ open class KotlinExceptionWithAttachments : RuntimeException, ExceptionWithAttac
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun KotlinExceptionWithAttachments.withAttachmentBuilder(name: String, buildContent: StringBuilder.() -> Unit): KotlinExceptionWithAttachments {
|
||||
return withAttachment(name, buildString { buildContent() })
|
||||
}
|
||||
|
||||
fun <T> KotlinExceptionWithAttachments.withAttachmentDetailed(
|
||||
name: String,
|
||||
content: T?,
|
||||
|
||||
Reference in New Issue
Block a user