[Analysis API FIR] add more info to some exceptions

This commit is contained in:
Ilya Kirillov
2022-07-23 19:50:08 +02:00
parent 5a5e6ad8cd
commit 76f1744868
11 changed files with 81 additions and 38 deletions
@@ -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
@@ -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
@@ -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
@@ -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()
}
}
}
@@ -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())