[Analysis API FIR, LL FIR] use exceptionWithAttachment to not leak user data
This commit is contained in:
+6
-1
@@ -9,13 +9,16 @@ import com.intellij.openapi.project.Project
|
|||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.utils.withSymbolAttachment
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.CachingKtAnalysisSessionProvider
|
import org.jetbrains.kotlin.analysis.api.impl.base.CachingKtAnalysisSessionProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
@OptIn(KtAnalysisApiInternals::class)
|
@OptIn(KtAnalysisApiInternals::class)
|
||||||
class KtFirAnalysisSessionProvider(project: Project) : CachingKtAnalysisSessionProvider<LLFirResolveSession>(project) {
|
class KtFirAnalysisSessionProvider(project: Project) : CachingKtAnalysisSessionProvider<LLFirResolveSession>(project) {
|
||||||
@@ -26,7 +29,9 @@ class KtFirAnalysisSessionProvider(project: Project) : CachingKtAnalysisSessionP
|
|||||||
override fun getFirResolveSession(contextSymbol: KtSymbol): LLFirResolveSession {
|
override fun getFirResolveSession(contextSymbol: KtSymbol): LLFirResolveSession {
|
||||||
return when (contextSymbol) {
|
return when (contextSymbol) {
|
||||||
is KtFirSymbol<*> -> contextSymbol.firResolveSession
|
is KtFirSymbol<*> -> contextSymbol.firResolveSession
|
||||||
else -> error("Invalid symbol ${contextSymbol::class}")
|
else -> errorWithAttachment("Invalid symbol") {
|
||||||
|
withSymbolAttachment("symbol", contextSymbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-3
@@ -20,6 +20,10 @@ import org.jetbrains.kotlin.analysis.api.symbols.*
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
|
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withConeTypeAttachment
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirAttachment
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolAttachment
|
||||||
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
@@ -49,6 +53,7 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
@@ -203,7 +208,10 @@ internal class KtSymbolByFirBuilder constructor(
|
|||||||
return buildFunctionSymbol(it.symbol)
|
return buildFunctionSymbol(it.symbol)
|
||||||
}
|
}
|
||||||
if (firSymbol.dispatchReceiverType?.contains { it is ConeStubType } == true) {
|
if (firSymbol.dispatchReceiverType?.contains { it is ConeStubType } == true) {
|
||||||
return buildFunctionSymbol(firSymbol.originalIfFakeOverride() ?: error("Stub type in real declaration"))
|
return buildFunctionSymbol(
|
||||||
|
firSymbol.originalIfFakeOverride()
|
||||||
|
?: firErrorWithAttachment("Stub type in real declaration", fir = firSymbol.fir)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
check(firSymbol.origin != FirDeclarationOrigin.SamConstructor)
|
check(firSymbol.origin != FirDeclarationOrigin.SamConstructor)
|
||||||
@@ -579,8 +587,22 @@ internal class KtSymbolByFirBuilder constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun throwUnexpectedElementError(element: Any): Nothing {
|
private fun throwUnexpectedElementError(element: FirBasedSymbol<*>): Nothing {
|
||||||
error("Unexpected ${element::class.simpleName}")
|
errorWithAttachment("Unexpected ${element::class.simpleName}") {
|
||||||
|
withFirSymbolAttachment("firSymbol", element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun throwUnexpectedElementError(element: FirElement): Nothing {
|
||||||
|
errorWithAttachment("Unexpected ${element::class.simpleName}") {
|
||||||
|
withFirAttachment("firElement", element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun throwUnexpectedElementError(element: ConeKotlinType): Nothing {
|
||||||
|
errorWithAttachment("Unexpected ${element::class.simpleName}") {
|
||||||
|
withConeTypeAttachment("coneType", element)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+2
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
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.api.getOrBuildFir
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver
|
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.utils.printer.parentOfType
|
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
@@ -151,7 +152,7 @@ internal class KtFirCallResolver(
|
|||||||
when (val calleeReference = calleeReference) {
|
when (val calleeReference = calleeReference) {
|
||||||
is FirResolvedNamedReference -> {
|
is FirResolvedNamedReference -> {
|
||||||
val call = createKtCall(psi, this, null, resolveFragmentOfCall)
|
val call = createKtCall(psi, this, null, resolveFragmentOfCall)
|
||||||
?: error("expect `createKtCall` to succeed for resolvable case")
|
?: firErrorWithAttachment("expect `createKtCall` to succeed for resolvable case", fir = this, psi = psi)
|
||||||
KtSuccessCallInfo(call)
|
KtSuccessCallInfo(call)
|
||||||
}
|
}
|
||||||
is FirErrorNamedReference -> {
|
is FirErrorNamedReference -> {
|
||||||
|
|||||||
+33
-9
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirReceiverParameterSymbo
|
|||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirTypeParameterSymbol
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.utils.getContainingKtModule
|
import org.jetbrains.kotlin.analysis.api.fir.utils.getContainingKtModule
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.utils.withSymbolAttachment
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
|
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
|
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
|
||||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
|||||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||||
import org.jetbrains.kotlin.psi
|
import org.jetbrains.kotlin.psi
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
internal class KtFirSymbolContainingDeclarationProvider(
|
internal class KtFirSymbolContainingDeclarationProvider(
|
||||||
override val analysisSession: KtFirAnalysisSession,
|
override val analysisSession: KtFirAnalysisSession,
|
||||||
@@ -85,21 +87,33 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
private fun getContainingPsi(symbol: KtFirSymbol<*>): KtDeclaration {
|
private fun getContainingPsi(symbol: KtFirSymbol<*>): KtDeclaration {
|
||||||
val source = symbol.firSymbol.source
|
val source = symbol.firSymbol.source
|
||||||
val thisSource = when (source?.kind) {
|
val thisSource = when (source?.kind) {
|
||||||
null -> error("PSI should present for declaration built by Kotlin code")
|
null -> errorWithAttachment("PSI should present for declaration built by Kotlin code") {
|
||||||
|
withSymbolAttachment("symbolForContainingPsi", symbol)
|
||||||
|
}
|
||||||
|
|
||||||
KtFakeSourceElementKind.ImplicitConstructor ->
|
KtFakeSourceElementKind.ImplicitConstructor ->
|
||||||
return source.psi as KtDeclaration
|
return source.psi as KtDeclaration
|
||||||
|
|
||||||
KtFakeSourceElementKind.PropertyFromParameter -> return source.psi?.parentOfType<KtPrimaryConstructor>()!!
|
KtFakeSourceElementKind.PropertyFromParameter -> return source.psi?.parentOfType<KtPrimaryConstructor>()!!
|
||||||
KtFakeSourceElementKind.DefaultAccessor -> return source.psi as KtProperty
|
KtFakeSourceElementKind.DefaultAccessor -> return source.psi as KtProperty
|
||||||
KtFakeSourceElementKind.ItLambdaParameter -> return source.psi as KtFunctionLiteral
|
KtFakeSourceElementKind.ItLambdaParameter -> return source.psi as KtFunctionLiteral
|
||||||
KtRealSourceElementKind -> source.psi!!
|
KtRealSourceElementKind -> source.psi!!
|
||||||
else -> error("Unexpected FirSourceElement: kind=${source.kind} element=${source.psi!!::class.simpleName}")
|
else ->
|
||||||
|
errorWithAttachment("errorWithAttachment FirSourceElement: kind=${source.kind} element=${source.psi!!::class.simpleName}") {
|
||||||
|
withSymbolAttachment("symbolForContainingPsi", symbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (symbol.origin) {
|
return when (symbol.origin) {
|
||||||
KtSymbolOrigin.SOURCE -> thisSource.getContainingKtDeclaration()
|
KtSymbolOrigin.SOURCE -> thisSource.getContainingKtDeclaration()
|
||||||
?: error("Containing declaration should present for non-toplevel declaration")
|
?: errorWithAttachment("Containing declaration should present for non-toplevel declaration") {
|
||||||
|
withSymbolAttachment("symbolForContainingPsi", symbol)
|
||||||
|
}
|
||||||
|
|
||||||
KtSymbolOrigin.SOURCE_MEMBER_GENERATED -> thisSource as KtDeclaration
|
KtSymbolOrigin.SOURCE_MEMBER_GENERATED -> thisSource as KtDeclaration
|
||||||
else -> error("Unsupported declaration origin ${symbol.origin}")
|
else -> errorWithAttachment("Unsupported declaration origin ${symbol.origin}") {
|
||||||
|
withSymbolAttachment("symbolForContainingPsi", symbol)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,21 +127,31 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
require(symbol.origin == KtSymbolOrigin.LIBRARY || symbol.origin == KtSymbolOrigin.JAVA)
|
require(symbol.origin == KtSymbolOrigin.LIBRARY || symbol.origin == KtSymbolOrigin.JAVA)
|
||||||
check(symbol.symbolKind == KtSymbolKind.CLASS_MEMBER)
|
check(symbol.symbolKind == KtSymbolKind.CLASS_MEMBER)
|
||||||
|
|
||||||
|
fun error(message: String): Nothing {
|
||||||
|
errorWithAttachment(message) {
|
||||||
|
withSymbolAttachment("symbolToGetContaining", symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val containingClassId = when (symbol) {
|
val containingClassId = when (symbol) {
|
||||||
is KtClassLikeSymbol -> {
|
is KtClassLikeSymbol -> {
|
||||||
val classId = symbol.classIdIfNonLocal ?: error("classId should not be null for non-local declaration")
|
val classId = symbol.classIdIfNonLocal
|
||||||
|
?: error("classId should not be null for non-local declaration")
|
||||||
classId.outerClassId
|
classId.outerClassId
|
||||||
}
|
}
|
||||||
is KtFunctionSymbol -> {
|
is KtFunctionSymbol -> {
|
||||||
val fqName = symbol.callableIdIfNonLocal ?: error("callableIdIfNonLocal should not be null for non-local declaration")
|
val fqName = symbol.callableIdIfNonLocal
|
||||||
|
?: error("callableIdIfNonLocal should not be null for non-local declaration")
|
||||||
fqName.classId
|
fqName.classId
|
||||||
}
|
}
|
||||||
is KtEnumEntrySymbol -> {
|
is KtEnumEntrySymbol -> {
|
||||||
val classId = symbol.containingEnumClassIdIfNonLocal ?: error("fqName should not be null for non-local declaration")
|
val classId = symbol.containingEnumClassIdIfNonLocal
|
||||||
|
?: error("fqName should not be null for non-local declaration")
|
||||||
classId.outerClassId
|
classId.outerClassId
|
||||||
}
|
}
|
||||||
is KtPropertySymbol -> {
|
is KtPropertySymbol -> {
|
||||||
val fqName = symbol.callableIdIfNonLocal ?: error("fqName should not be null for non-local declaration")
|
val fqName = symbol.callableIdIfNonLocal
|
||||||
|
?: error("fqName should not be null for non-local declaration")
|
||||||
fqName.classId
|
fqName.classId
|
||||||
}
|
}
|
||||||
is KtConstructorSymbol -> {
|
is KtConstructorSymbol -> {
|
||||||
@@ -137,6 +161,6 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
|||||||
else -> error("We should not have a ${symbol::class} from a library")
|
else -> error("We should not have a ${symbol::class} from a library")
|
||||||
} ?: error("outerClassId should not be null for member declaration")
|
} ?: error("outerClassId should not be null for member declaration")
|
||||||
val containingClass = containingClassId.getCorrespondingToplevelClassOrObjectSymbol()
|
val containingClass = containingClassId.getCorrespondingToplevelClassOrObjectSymbol()
|
||||||
return containingClass ?: error("Class with id $containingClassId should exists")
|
return containingClass ?: error("Class by class id should exists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-9
@@ -11,17 +11,18 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
|
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.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.originalIfFakeOverride
|
|
||||||
import org.jetbrains.kotlin.fir.render
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
|
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
internal interface KtFirSymbol<out S : FirBasedSymbol<*>> : KtSymbol, KtLifetimeOwner {
|
internal interface KtFirSymbol<out S : FirBasedSymbol<*>> : KtSymbol, KtLifetimeOwner {
|
||||||
val firSymbol: S
|
val firSymbol: S
|
||||||
@@ -49,6 +50,7 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
|
|||||||
else -> KtSymbolOrigin.SOURCE
|
else -> KtSymbolOrigin.SOURCE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FirDeclarationOrigin.Precompiled -> KtSymbolOrigin.SOURCE
|
FirDeclarationOrigin.Precompiled -> KtSymbolOrigin.SOURCE
|
||||||
FirDeclarationOrigin.Library, FirDeclarationOrigin.BuiltIns -> KtSymbolOrigin.LIBRARY
|
FirDeclarationOrigin.Library, FirDeclarationOrigin.BuiltIns -> KtSymbolOrigin.LIBRARY
|
||||||
is FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA
|
is FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA
|
||||||
@@ -60,26 +62,36 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
|
|||||||
when (this) {
|
when (this) {
|
||||||
is FirSyntheticProperty,
|
is FirSyntheticProperty,
|
||||||
is FirSyntheticPropertyAccessor -> KtSymbolOrigin.JAVA_SYNTHETIC_PROPERTY
|
is FirSyntheticPropertyAccessor -> KtSymbolOrigin.JAVA_SYNTHETIC_PROPERTY
|
||||||
else -> throw InvalidFirDeclarationOriginForSymbol(this)
|
|
||||||
|
else -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") {
|
||||||
|
withFirAttachment("firToGetOrigin", this@ktSymbolOrigin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FirDeclarationOrigin.ImportedFromObject -> {
|
FirDeclarationOrigin.ImportedFromObject -> {
|
||||||
val importedFromObjectData = (this as FirCallableDeclaration).importedFromObjectData
|
val importedFromObjectData = (this as FirCallableDeclaration).importedFromObjectData
|
||||||
?: error("Declaration has ImportedFromObject origin, but no importedFromObjectData present")
|
?: errorWithAttachment("Declaration has ImportedFromObject origin, but no importedFromObjectData present") {
|
||||||
|
withFirAttachment("firToGetOrigin", this@ktSymbolOrigin)
|
||||||
|
}
|
||||||
|
|
||||||
importedFromObjectData.original.ktSymbolOrigin()
|
importedFromObjectData.original.ktSymbolOrigin()
|
||||||
}
|
}
|
||||||
|
|
||||||
FirDeclarationOrigin.WrappedIntegerOperator -> {
|
FirDeclarationOrigin.WrappedIntegerOperator -> {
|
||||||
val original = (this as FirSimpleFunction).originalForWrappedIntegerOperator?.fir
|
val original = (this as FirSimpleFunction).originalForWrappedIntegerOperator?.fir
|
||||||
?: error("Declaration has WrappedIntegerOperator origin, but no originalForWrappedIntegerOperator present")
|
?: firErrorWithAttachment(
|
||||||
|
"Declaration has WrappedIntegerOperator origin, but no originalForWrappedIntegerOperator present",
|
||||||
|
fir = this
|
||||||
|
)
|
||||||
|
|
||||||
original.ktSymbolOrigin()
|
original.ktSymbolOrigin()
|
||||||
}
|
}
|
||||||
|
|
||||||
is FirDeclarationOrigin.Plugin -> KtSymbolOrigin.PLUGIN
|
is FirDeclarationOrigin.Plugin -> KtSymbolOrigin.PLUGIN
|
||||||
FirDeclarationOrigin.RenamedForOverride -> KtSymbolOrigin.JAVA
|
FirDeclarationOrigin.RenamedForOverride -> KtSymbolOrigin.JAVA
|
||||||
FirDeclarationOrigin.SubstitutionOverride -> KtSymbolOrigin.SUBSTITUTION_OVERRIDE
|
FirDeclarationOrigin.SubstitutionOverride -> KtSymbolOrigin.SUBSTITUTION_OVERRIDE
|
||||||
FirDeclarationOrigin.DynamicScope -> throw InvalidFirDeclarationOriginForSymbol(this)
|
FirDeclarationOrigin.DynamicScope -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") {
|
||||||
|
withFirAttachment("firToGetOrigin", this@ktSymbolOrigin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvalidFirDeclarationOriginForSymbol(declaration: FirDeclaration) :
|
|
||||||
IllegalStateException("Invalid FirDeclarationOrigin ${declaration.origin::class.simpleName} for ${declaration.render()}")
|
|
||||||
|
|||||||
+15
-4
@@ -10,6 +10,9 @@ import org.jetbrains.kotlin.analysis.api.fir.components.KtFirAnalysisSessionComp
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
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.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.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
@@ -20,6 +23,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
internal class KtFirSymbolProvider(
|
internal class KtFirSymbolProvider(
|
||||||
override val analysisSession: KtFirAnalysisSession,
|
override val analysisSession: KtFirAnalysisSession,
|
||||||
@@ -28,8 +32,9 @@ internal class KtFirSymbolProvider(
|
|||||||
|
|
||||||
override fun getParameterSymbol(psi: KtParameter): KtVariableLikeSymbol {
|
override fun getParameterSymbol(psi: KtParameter): KtVariableLikeSymbol {
|
||||||
return when {
|
return when {
|
||||||
psi.isFunctionTypeParameter -> error(
|
psi.isFunctionTypeParameter -> firErrorWithAttachment(
|
||||||
"Creating KtValueParameterSymbol for function type parameter is not possible. Please see the KDoc of getParameterSymbol"
|
"Creating KtValueParameterSymbol for function type parameter is not possible. Please see the KDoc of getParameterSymbol",
|
||||||
|
psi = psi,
|
||||||
)
|
)
|
||||||
|
|
||||||
psi.isLoopParameter -> {
|
psi.isLoopParameter -> {
|
||||||
@@ -63,7 +68,10 @@ internal class KtFirSymbolProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is FirAnonymousFunctionSymbol -> firSymbolBuilder.functionLikeBuilder.buildAnonymousFunctionSymbol(firSymbol)
|
is FirAnonymousFunctionSymbol -> firSymbolBuilder.functionLikeBuilder.buildAnonymousFunctionSymbol(firSymbol)
|
||||||
else -> error("Unexpected ${firSymbol.fir.renderWithType()}")
|
else -> errorWithAttachment("Unexpected ${firSymbol::class}") {
|
||||||
|
withFirSymbolAttachment("firSymbol", firSymbol)
|
||||||
|
withPsiAttachment("function", psi)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +125,10 @@ internal class KtFirSymbolProvider(
|
|||||||
val firClass =
|
val firClass =
|
||||||
when (val firClassLike = psi.resolveToFirSymbolOfType<FirClassLikeSymbol<*>>(firResolveSession)) {
|
when (val firClassLike = psi.resolveToFirSymbolOfType<FirClassLikeSymbol<*>>(firResolveSession)) {
|
||||||
is FirTypeAliasSymbol -> firClassLike.fullyExpandedClass(firResolveSession.useSiteFirSession)
|
is FirTypeAliasSymbol -> firClassLike.fullyExpandedClass(firResolveSession.useSiteFirSession)
|
||||||
?: error("${firClassLike.fir.render()} should be expanded to the expected type alias")
|
?: errorWithAttachment("${firClassLike.fir::class} should be expanded to the expected type alias") {
|
||||||
|
withFirSymbolAttachment("firClassLikeSymbol", firClassLike)
|
||||||
|
withPsiAttachment("ktClassOrObject", psi)
|
||||||
|
}
|
||||||
is FirAnonymousObjectSymbol -> firClassLike
|
is FirAnonymousObjectSymbol -> firClassLike
|
||||||
is FirRegularClassSymbol -> firClassLike
|
is FirRegularClassSymbol -> firClassLike
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
|
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
||||||
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
||||||
@@ -32,7 +33,7 @@ internal class KtFirFunctionalType(
|
|||||||
override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId }
|
override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId }
|
||||||
override val classSymbol: KtClassLikeSymbol by cached {
|
override val classSymbol: KtClassLikeSymbol by cached {
|
||||||
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
|
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
|
||||||
?: error("Class ${coneType.lookupTag} was not found")
|
?: firErrorWithAttachment("Class was not found", coneType = coneType)
|
||||||
}
|
}
|
||||||
override val typeArguments: List<KtTypeArgument> by cached {
|
override val typeArguments: List<KtTypeArgument> by cached {
|
||||||
coneType.typeArguments.map { typeArgument ->
|
coneType.typeArguments.map { typeArgument ->
|
||||||
|
|||||||
+2
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
||||||
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -26,7 +27,7 @@ internal class KtFirTypeParameterType(
|
|||||||
override val name: Name get() = withValidityAssertion { coneType.lookupTag.name }
|
override val name: Name get() = withValidityAssertion { coneType.lookupTag.name }
|
||||||
override val symbol: KtTypeParameterSymbol by cached {
|
override val symbol: KtTypeParameterSymbol by cached {
|
||||||
builder.classifierBuilder.buildTypeParameterSymbolByLookupTag(coneType.lookupTag)
|
builder.classifierBuilder.buildTypeParameterSymbolByLookupTag(coneType.lookupTag)
|
||||||
?: error("Type parameter ${coneType.lookupTag} was not found")
|
?: firErrorWithAttachment("Type parameter was not found", coneType = coneType)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val annotationsList: KtAnnotationsList by cached {
|
override val annotationsList: KtAnnotationsList by cached {
|
||||||
|
|||||||
+2
-1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
|||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType
|
import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -27,7 +28,7 @@ internal class KtFirUsualClassType(
|
|||||||
override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId }
|
override val classId: ClassId get() = withValidityAssertion { coneType.lookupTag.classId }
|
||||||
override val classSymbol: KtClassLikeSymbol by cached {
|
override val classSymbol: KtClassLikeSymbol by cached {
|
||||||
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
|
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
|
||||||
?: error("Class ${coneType.lookupTag} was not found")
|
?: firErrorWithAttachment("Class was not found", coneType = coneType)
|
||||||
}
|
}
|
||||||
override val typeArguments: List<KtTypeArgument> by cached {
|
override val typeArguments: List<KtTypeArgument> by cached {
|
||||||
coneType.typeArguments.map { typeArgument ->
|
coneType.typeArguments.map { typeArgument ->
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.analysis.api.fir.utils
|
||||||
|
|
||||||
|
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.utils.KotlinExceptionWithAttachments
|
||||||
|
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||||
|
|
||||||
|
|
||||||
|
fun KotlinExceptionWithAttachments.withSymbolAttachment(name: String, symbol: KtSymbol): KotlinExceptionWithAttachments {
|
||||||
|
withAttachmentDetailed(name, symbol, DebugSymbolRenderer::render)
|
||||||
|
withPsiAttachment("${name}Psi", symbol.psi)
|
||||||
|
|
||||||
|
if (symbol is KtFirSymbol<*>) {
|
||||||
|
val symbolFir = symbol.firSymbol.fir
|
||||||
|
withFirAttachment("${name}Fir", symbolFir)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
+5
-1
@@ -5,8 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.utils.errors
|
package org.jetbrains.kotlin.analysis.utils.errors
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
public fun unexpectedElementError(elementName: String, element: Any?): Nothing {
|
public fun unexpectedElementError(elementName: String, element: Any?): Nothing {
|
||||||
error("Unexpected $elementName ${element?.let { it::class.simpleName }}")
|
errorWithAttachment("Unexpected $elementName ${element?.let { it::class.simpleName }}") {
|
||||||
|
withAttachment("element", element)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <reified ELEMENT> unexpectedElementError(element: Any?): Nothing {
|
public inline fun <reified ELEMENT> unexpectedElementError(element: Any?): Nothing {
|
||||||
|
|||||||
+2
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignation
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignation
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
|
|
||||||
abstract class ContextByDesignationCollector<C : Any>(private val designation: FirDeclarationDesignation) {
|
abstract class ContextByDesignationCollector<C : Any>(private val designation: FirDeclarationDesignation) {
|
||||||
private var context: C? = null
|
private var context: C? = null
|
||||||
@@ -56,7 +57,7 @@ private class FirDesignationState(val designation: FirDeclarationDesignation) {
|
|||||||
|
|
||||||
val currentDeclaration: FirDeclaration
|
val currentDeclaration: FirDeclaration
|
||||||
get() = currentDeclarationIfPresent
|
get() = currentDeclarationIfPresent
|
||||||
?: error("Went inside target declaration")
|
?: firErrorWithAttachment("Went inside target declaration")
|
||||||
|
|
||||||
fun goNext() {
|
fun goNext() {
|
||||||
if (canGoNext()) {
|
if (canGoNext()) {
|
||||||
|
|||||||
+4
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirLibraryOrLibra
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirNotUnderContentRootResolvableResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirNotUnderContentRootResolvableResolveSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||||
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
|
||||||
import org.jetbrains.kotlin.analysis.utils.caches.strongCachedValue
|
import org.jetbrains.kotlin.analysis.utils.caches.strongCachedValue
|
||||||
@@ -86,7 +87,9 @@ internal class LLFirResolveSessionService(project: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
error("Unexpected $useSiteKtModule")
|
firErrorWithAttachment("Unexpected ${useSiteKtModule::class.java}") {
|
||||||
|
withAttachment("module", useSiteKtModule.moduleDescription)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-6
@@ -5,17 +5,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
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.withFirAttachment
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.containingClass
|
import org.jetbrains.kotlin.fir.containingClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
import org.jetbrains.kotlin.fir.render
|
|
||||||
import org.jetbrains.kotlin.fir.renderWithType
|
import org.jetbrains.kotlin.fir.renderWithType
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals
|
import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals
|
||||||
|
import org.jetbrains.kotlin.utils.checkWithAttachment
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
class FirDeclarationDesignationWithFile(
|
class FirDeclarationDesignationWithFile(
|
||||||
path: List<FirDeclaration>,
|
path: List<FirDeclaration>,
|
||||||
@@ -77,21 +80,28 @@ private fun collectDesignationPath(declaration: FirDeclaration): List<FirDeclara
|
|||||||
else -> return null
|
else -> return null
|
||||||
} ?: return emptyList()
|
} ?: return emptyList()
|
||||||
|
|
||||||
require(containingClass is FirRegularClass) {
|
checkWithAttachment(containingClass is FirRegularClass, { "FirRegularClass as containing declaration expected" }) {
|
||||||
"FirRegularClass as containing declaration expected but found ${containingClass.renderWithType()}"
|
it.withFirAttachment("containingClassFir", containingClass)
|
||||||
}
|
}
|
||||||
return if (!containingClass.isLocal) containingClass.collectForNonLocal().asReversed() else null
|
return if (!containingClass.isLocal) containingClass.collectForNonLocal().asReversed() else null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirDeclaration.collectDesignation(firFile: FirFile): FirDeclarationDesignationWithFile =
|
fun FirDeclaration.collectDesignation(firFile: FirFile): FirDeclarationDesignationWithFile =
|
||||||
tryCollectDesignation(firFile) ?: error("No designation of local declaration ${this.render()}")
|
tryCollectDesignation(firFile) ?: errorWithAttachment("No designation of local declaration") {
|
||||||
|
withFirAttachment("firFile", firFile)
|
||||||
|
}
|
||||||
|
|
||||||
fun FirDeclaration.collectDesignation(): FirDeclarationDesignation =
|
fun FirDeclaration.collectDesignation(): FirDeclarationDesignation =
|
||||||
tryCollectDesignation() ?: error("No designation of local declaration ${this.render()}")
|
tryCollectDesignation()
|
||||||
|
?: errorWithAttachment("No designation of local declaration") {
|
||||||
|
withFirAttachment("FirDeclaration", this@collectDesignation)
|
||||||
|
}
|
||||||
|
|
||||||
fun FirDeclaration.collectDesignationWithFile(): FirDeclarationDesignationWithFile =
|
fun FirDeclaration.collectDesignationWithFile(): FirDeclarationDesignationWithFile =
|
||||||
tryCollectDesignationWithFile()
|
tryCollectDesignationWithFile()
|
||||||
?: error("No designation of local declaration ${this.render()}")
|
?: errorWithAttachment("No designation of local declaration") {
|
||||||
|
withFirAttachment("FirDeclaration", this@collectDesignationWithFile)
|
||||||
|
}
|
||||||
|
|
||||||
fun FirDeclaration.tryCollectDesignation(firFile: FirFile): FirDeclarationDesignationWithFile? =
|
fun FirDeclaration.tryCollectDesignation(firFile: FirFile): FirDeclarationDesignationWithFile? =
|
||||||
collectDesignationPath(this)?.let {
|
collectDesignationPath(this)?.let {
|
||||||
|
|||||||
+22
-5
@@ -5,16 +5,33 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withConeTypeAttachment
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirAttachment
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolAttachment
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||||
|
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class InvalidFirElementTypeException(
|
class InvalidFirElementTypeException(
|
||||||
actualFirClass: KClass<*>?,
|
actualFirElement: Any?,
|
||||||
ktElement: KtElement?,
|
ktElement: KtElement?,
|
||||||
expectedFirClasses: List<KClass<*>>,
|
expectedFirClasses: List<KClass<*>>,
|
||||||
) : IllegalStateException() {
|
) : KotlinExceptionWithAttachments("") {
|
||||||
|
init {
|
||||||
|
when (actualFirElement) {
|
||||||
|
is FirElement -> withFirAttachment("firElement", actualFirElement)
|
||||||
|
is FirBasedSymbol<*> -> withFirSymbolAttachment("firSymbol", actualFirElement)
|
||||||
|
is ConeKotlinType -> withConeTypeAttachment("coneType", actualFirElement)
|
||||||
|
null -> {}
|
||||||
|
else -> withAttachmentDetailed("element", actualFirElement) { it.toString() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val message: String = buildString {
|
override val message: String = buildString {
|
||||||
if (ktElement != null) {
|
if (ktElement != null) {
|
||||||
append("For $ktElement with text `${ktElement.text}`, ")
|
append("For $ktElement with text `${ktElement.text}`, ")
|
||||||
@@ -25,8 +42,8 @@ class InvalidFirElementTypeException(
|
|||||||
else -> "One of [${expectedFirClasses.joinToString()}] element types expected, but"
|
else -> "One of [${expectedFirClasses.joinToString()}] element types expected, but"
|
||||||
}
|
}
|
||||||
append(if (ktElement == null) message else message.replaceFirstChar { it.lowercase(Locale.getDefault()) })
|
append(if (ktElement == null) message else message.replaceFirstChar { it.lowercase(Locale.getDefault()) })
|
||||||
if (actualFirClass != null) {
|
if (actualFirElement != null) {
|
||||||
append(" ${actualFirClass.simpleName} found")
|
append(" ${actualFirElement::class.simpleName} found")
|
||||||
} else {
|
} else {
|
||||||
append(" no element found")
|
append(" no element found")
|
||||||
}
|
}
|
||||||
@@ -39,5 +56,5 @@ fun throwUnexpectedFirElementError(
|
|||||||
ktElement: KtElement? = null,
|
ktElement: KtElement? = null,
|
||||||
vararg expectedFirClasses: KClass<*>
|
vararg expectedFirClasses: KClass<*>
|
||||||
): Nothing {
|
): Nothing {
|
||||||
throw InvalidFirElementTypeException(firElement?.let { it::class }, ktElement, expectedFirClasses.toList())
|
throw InvalidFirElementTypeException(firElement, ktElement, expectedFirClasses.toList())
|
||||||
}
|
}
|
||||||
+4
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
|||||||
|
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.createEmptySession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.createEmptySession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.firErrorWithAttachment
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
|
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
|
||||||
@@ -132,7 +133,7 @@ object KtDeclarationAndFirDeclarationEqualityChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> error("Invalid type reference $this")
|
else -> firErrorWithAttachment("Invalid type reference", fir = this)
|
||||||
}
|
}
|
||||||
return if (isVararg) {
|
return if (isVararg) {
|
||||||
rendered.asArrayType()
|
rendered.asArrayType()
|
||||||
@@ -165,7 +166,7 @@ object KtDeclarationAndFirDeclarationEqualityChecker {
|
|||||||
}
|
}
|
||||||
append(typeRef.renderTypeAsKotlinType())
|
append(typeRef.renderTypeAsKotlinType())
|
||||||
}
|
}
|
||||||
else -> error("Invalid type projection $this")
|
else -> firErrorWithAttachment("Invalid type reference", fir = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isTheSameTypes(
|
private fun isTheSameTypes(
|
||||||
@@ -200,7 +201,7 @@ object KtDeclarationAndFirDeclarationEqualityChecker {
|
|||||||
// Can be present as return type
|
// Can be present as return type
|
||||||
"${lowerBound.renderTypeAsKotlinType()}..${upperBound.renderTypeAsKotlinType()}"
|
"${lowerBound.renderTypeAsKotlinType()}..${upperBound.renderTypeAsKotlinType()}"
|
||||||
}
|
}
|
||||||
else -> error("Type $this should not be present in Kotlin declaration")
|
else -> firErrorWithAttachment("Type should not be present in Kotlin declaration", coneType = this)
|
||||||
}.replace('/', '.')
|
}.replace('/', '.')
|
||||||
return rendered + nullability.suffix
|
return rendered + nullability.suffix
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -18,7 +18,10 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMap
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.*
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.*
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession
|
||||||
|
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.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.project.structure.getKtModule
|
||||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||||
@@ -37,6 +40,7 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
object LowLevelFirApiFacadeForResolveOnAir {
|
object LowLevelFirApiFacadeForResolveOnAir {
|
||||||
|
|
||||||
@@ -87,7 +91,10 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declaration.accept(expressionLocator)
|
declaration.accept(expressionLocator)
|
||||||
return expressionLocator.result ?: error("Resolved on-air element was not found in containing declaration")
|
return expressionLocator.result ?: firErrorWithAttachment("Resolved on-air element was not found in containing declaration") {
|
||||||
|
withPsiAttachment("place", place)
|
||||||
|
withPsiAttachment("elementToResolve", elementToResolve)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onAirGetTowerContextProvider(
|
fun onAirGetTowerContextProvider(
|
||||||
@@ -152,7 +159,10 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
|||||||
|
|
||||||
|
|
||||||
val sameDeclarationInOriginalFile = PsiTreeUtil.findSameElementInCopy(dependencyNonLocalDeclaration, originalKtFile)
|
val sameDeclarationInOriginalFile = PsiTreeUtil.findSameElementInCopy(dependencyNonLocalDeclaration, originalKtFile)
|
||||||
?: error("Cannot find original function matching to ${dependencyNonLocalDeclaration.getElementTextInContext()} in $originalKtFile")
|
?: firErrorWithAttachment("Cannot find original function matching") {
|
||||||
|
withPsiAttachment("matchingPsi", dependencyNonLocalDeclaration)
|
||||||
|
withPsiAttachment("originalFile", originalKtFile)
|
||||||
|
}
|
||||||
|
|
||||||
recordOriginalDeclaration(
|
recordOriginalDeclaration(
|
||||||
targetDeclaration = dependencyNonLocalDeclaration,
|
targetDeclaration = dependencyNonLocalDeclaration,
|
||||||
@@ -183,7 +193,10 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
|||||||
fileAnnotation = annotationEntry,
|
fileAnnotation = annotationEntry,
|
||||||
replacement = replacement
|
replacement = replacement
|
||||||
)
|
)
|
||||||
val llFirResolvableSession = firFile.llFirResolvableSession ?: error("FirFile session expected to be a resolvable session")
|
val llFirResolvableSession = firFile.llFirResolvableSession
|
||||||
|
?: errorWithAttachment("FirFile session expected to be a resolvable session but was ${firFile.llFirSession::class.java}") {
|
||||||
|
withAttachment("firSession", firFile.llFirSession)
|
||||||
|
}
|
||||||
val declarationResolver = llFirResolvableSession.moduleComponents.lazyFirDeclarationsResolver
|
val declarationResolver = llFirResolvableSession.moduleComponents.lazyFirDeclarationsResolver
|
||||||
|
|
||||||
declarationResolver.resolveFileAnnotations(
|
declarationResolver.resolveFileAnnotations(
|
||||||
|
|||||||
+7
-2
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiClass
|
|||||||
import com.intellij.psi.PsiJavaFile
|
import com.intellij.psi.PsiJavaFile
|
||||||
import com.intellij.psi.PsiTypeParameter
|
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.sessions.LLFirSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withPsiAttachment
|
||||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
@@ -18,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
|
||||||
class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSessionComponent {
|
class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSessionComponent {
|
||||||
fun getFirClass(psiClass: PsiClass): FirRegularClassSymbol? {
|
fun getFirClass(psiClass: PsiClass): FirRegularClassSymbol? {
|
||||||
@@ -42,8 +44,11 @@ class LLFirFirClassByPsiClassProvider(private val session: LLFirSession) : FirSe
|
|||||||
val classId = psiClass.classIdIfNonLocal
|
val classId = psiClass.classIdIfNonLocal
|
||||||
?: error("No classId for non-local class")
|
?: error("No classId for non-local class")
|
||||||
val provider = session.nullableJavaSymbolProvider ?: session.symbolProvider
|
val provider = session.nullableJavaSymbolProvider ?: session.symbolProvider
|
||||||
val symbol = (provider.getClassLikeSymbolByClassId(classId)
|
val symbol = provider.getClassLikeSymbolByClassId(classId)
|
||||||
?: error("No classifier found with $classId"))
|
?: errorWithAttachment("No classifier found") {
|
||||||
|
withPsiAttachment("psiClass", psiClass)
|
||||||
|
withAttachment("classId", classId.asString())
|
||||||
|
}
|
||||||
return symbol as FirRegularClassSymbol
|
return symbol as FirRegularClassSymbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-2
@@ -11,11 +11,14 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firModuleData
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.*
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibrarySession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibrarySession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher
|
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.findSourceNonLocalFirDeclaration
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
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.KtModule
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
import org.jetbrains.kotlin.analysis.project.structure.getKtModule
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
|
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
|
||||||
@@ -32,6 +35,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
|||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||||
|
|
||||||
internal abstract class LLFirResolvableResolveSession(
|
internal abstract class LLFirResolvableResolveSession(
|
||||||
private val sessionProvider: LLFirSessionProvider,
|
private val sessionProvider: LLFirSessionProvider,
|
||||||
@@ -98,7 +103,10 @@ internal abstract class LLFirResolvableResolveSession(
|
|||||||
"Declaration should be resolvable module, instead it had ${module::class}"
|
"Declaration should be resolvable module, instead it had ${module::class}"
|
||||||
}
|
}
|
||||||
val nonLocalNamedDeclaration = ktDeclaration.getNonLocalContainingOrThisDeclaration()
|
val nonLocalNamedDeclaration = ktDeclaration.getNonLocalContainingOrThisDeclaration()
|
||||||
?: error("Declaration should have non-local container${ktDeclaration.getElementTextInContext()}")
|
?: errorWithAttachment("Declaration should have non-local container") {
|
||||||
|
withPsiAttachment("ktDeclaration", ktDeclaration)
|
||||||
|
withAttachmentDetailed("module", module) { it.moduleDescription }
|
||||||
|
}
|
||||||
|
|
||||||
if (ktDeclaration == nonLocalNamedDeclaration) {
|
if (ktDeclaration == nonLocalNamedDeclaration) {
|
||||||
val session = sessionProvider.getResolvableSession(module)
|
val session = sessionProvider.getResolvableSession(module)
|
||||||
|
|||||||
+19
-11
@@ -30,17 +30,20 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
|||||||
is KtNamedFunction -> findNonLocalFunction(ktDeclaration)
|
is KtNamedFunction -> findNonLocalFunction(ktDeclaration)
|
||||||
is KtProperty -> findNonLocalProperty(ktDeclaration)
|
is KtProperty -> findNonLocalProperty(ktDeclaration)
|
||||||
|
|
||||||
else -> error("Unsupported compiled declaration of type ${ktDeclaration::class}: ${ktDeclaration.getElementTextInContext()}")
|
else -> firErrorWithAttachment("Unsupported compiled declaration of type", psi = ktDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findNonLocalEnumEntry(declaration: KtEnumEntry): FirEnumEntry {
|
private fun findNonLocalEnumEntry(declaration: KtEnumEntry): FirEnumEntry {
|
||||||
require(!declaration.isLocal)
|
require(!declaration.isLocal)
|
||||||
val classId = declaration.containingClassOrObject?.getClassId()
|
val classId = declaration.containingClassOrObject?.getClassId()
|
||||||
?: error("Non-local class should have classId. The class is ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment(
|
||||||
|
"Non-local class should have classId. The class is ${declaration.getElementTextInContext()}",
|
||||||
|
psi = declaration
|
||||||
|
)
|
||||||
|
|
||||||
val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId)
|
val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId)
|
||||||
?: error("We should be able to find a symbol for $classId")
|
?: firErrorWithAttachment("We should be able to find a symbol for $classId", psi = declaration)
|
||||||
|
|
||||||
return (classCandidate.fir as? FirRegularClass)?.declarations?.first {
|
return (classCandidate.fir as? FirRegularClass)?.declarations?.first {
|
||||||
it is FirEnumEntry && it.name == declaration.nameAsName
|
it is FirEnumEntry && it.name == declaration.nameAsName
|
||||||
@@ -49,26 +52,31 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
|||||||
|
|
||||||
private fun findNonLocalClassLikeDeclaration(declaration: KtClassLikeDeclaration): FirClassLikeDeclaration {
|
private fun findNonLocalClassLikeDeclaration(declaration: KtClassLikeDeclaration): FirClassLikeDeclaration {
|
||||||
val classId = declaration.getClassId()
|
val classId = declaration.getClassId()
|
||||||
?: error("Non-local class should have classId. The class is ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment("Non-local class should have classId", psi = declaration)
|
||||||
|
|
||||||
val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId)
|
val classCandidate = symbolProvider.getClassLikeSymbolByClassId(classId)
|
||||||
?: error("We should be able to find a symbol for $classId")
|
?: firErrorWithAttachment("We should be able to find a symbol for $classId", psi = declaration) {
|
||||||
|
withAttachment(
|
||||||
|
"classId",
|
||||||
|
classId.asString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return classCandidate.fir
|
return classCandidate.fir
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findConstructorOfNonLocalClass(declaration: KtConstructor<*>): FirConstructor {
|
private fun findConstructorOfNonLocalClass(declaration: KtConstructor<*>): FirConstructor {
|
||||||
val containingClass = declaration.containingClassOrObject
|
val containingClass = declaration.containingClassOrObject
|
||||||
?: error("Constructor must have outer class: ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment("Constructor must have outer class", psi = declaration)
|
||||||
|
|
||||||
require(!containingClass.isLocal)
|
require(!containingClass.isLocal)
|
||||||
val classId = containingClass.getClassId()
|
val classId = containingClass.getClassId()
|
||||||
?: error("Non-local class should have classId. The class is ${containingClass.getElementTextInContext()}")
|
?: firErrorWithAttachment("Non-local class should have classId", psi = declaration)
|
||||||
|
|
||||||
val constructorCandidate =
|
val constructorCandidate =
|
||||||
symbolProvider.getClassDeclaredConstructors(classId)
|
symbolProvider.getClassDeclaredConstructors(classId)
|
||||||
.singleOrNull { representSameConstructor(declaration, it.fir) }
|
.singleOrNull { representSameConstructor(declaration, it.fir) }
|
||||||
?: error("We should be able to find a constructor: ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment("We should be able to find a constructor", psi = declaration)
|
||||||
|
|
||||||
return constructorCandidate.fir
|
return constructorCandidate.fir
|
||||||
}
|
}
|
||||||
@@ -79,7 +87,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
|||||||
val functionCandidate =
|
val functionCandidate =
|
||||||
symbolProvider.findFunctionCandidates(declaration)
|
symbolProvider.findFunctionCandidates(declaration)
|
||||||
.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
||||||
?: error("We should be able to find a symbol for function ${declaration.name}: ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment("We should be able to find a symbol for function", psi = declaration)
|
||||||
|
|
||||||
return functionCandidate.fir
|
return functionCandidate.fir
|
||||||
}
|
}
|
||||||
@@ -90,7 +98,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
|
|||||||
val propertyCandidate =
|
val propertyCandidate =
|
||||||
symbolProvider.findPropertyCandidates(declaration)
|
symbolProvider.findPropertyCandidates(declaration)
|
||||||
.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
.singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
|
||||||
?: error("We should be able to find a symbol for property ${declaration.name}: ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment("We should be able to find a symbol for property", psi = declaration)
|
||||||
|
|
||||||
return propertyCandidate.fir
|
return propertyCandidate.fir
|
||||||
}
|
}
|
||||||
@@ -112,7 +120,7 @@ private fun FirSymbolProvider.findCallableCandidates(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val containerClassId = declaration.containingClassOrObject?.getClassId()
|
val containerClassId = declaration.containingClassOrObject?.getClassId()
|
||||||
?: error("No containing non-local declaration found for ${declaration.getElementTextInContext()}")
|
?: firErrorWithAttachment("No containing non-local declaration found for", psi = declaration)
|
||||||
|
|
||||||
return getClassDeclaredFunctionSymbols(containerClassId, declaration.nameAsSafeName) +
|
return getClassDeclaredFunctionSymbols(containerClassId, declaration.nameAsSafeName) +
|
||||||
getClassDeclaredPropertySymbols(containerClassId, declaration.nameAsSafeName)
|
getClassDeclaredPropertySymbols(containerClassId, declaration.nameAsSafeName)
|
||||||
|
|||||||
+1
-1
@@ -17,6 +17,6 @@ fun FirDeclaration.getContainingFile(): FirFile? {
|
|||||||
is FirFile -> this
|
is FirFile -> this
|
||||||
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
||||||
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol)
|
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol)
|
||||||
else -> error("Unsupported declaration ${this::class.java}")
|
else -> firErrorWithAttachment("Unsupported declaration ${this::class.java}", fir = this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -30,7 +30,7 @@ internal fun KtDeclaration.findSourceNonLocalFirDeclaration(
|
|||||||
//TODO test what way faster
|
//TODO test what way faster
|
||||||
findSourceNonLocalFirDeclarationByProvider(firFileBuilder, provider, containerFirFile)?.let { return it }
|
findSourceNonLocalFirDeclarationByProvider(firFileBuilder, provider, containerFirFile)?.let { return it }
|
||||||
findSourceOfNonLocalFirDeclarationByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it }
|
findSourceOfNonLocalFirDeclarationByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it }
|
||||||
error("No fir element was found for\n${getElementTextInContext()}")
|
firErrorWithAttachment("No fir element was found for", psi = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclaration(
|
internal fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclaration(
|
||||||
@@ -45,7 +45,7 @@ internal fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclaration(
|
|||||||
firDeclaration.psi == this || firDeclaration.psi == originalDeclaration
|
firDeclaration.psi == this || firDeclaration.psi == originalDeclaration
|
||||||
}
|
}
|
||||||
return fir
|
return fir
|
||||||
?: error("FirDeclaration was not found for\n${getElementTextInContext()}")
|
?: firErrorWithAttachment("FirDeclaration was not found", psi = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified F : FirDeclaration> KtDeclaration.findFirDeclarationForAnyFirSourceDeclarationOfType(
|
internal inline fun <reified F : FirDeclaration> KtDeclaration.findFirDeclarationForAnyFirSourceDeclarationOfType(
|
||||||
@@ -95,12 +95,12 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider(
|
|||||||
}
|
}
|
||||||
this is KtConstructor<*> -> {
|
this is KtConstructor<*> -> {
|
||||||
val containingClass = containingClassOrObject
|
val containingClass = containingClassOrObject
|
||||||
?: error("Container class should be not null for KtConstructor")
|
?: firErrorWithAttachment("Container class should be not null for KtConstructor", psi = this)
|
||||||
val containerClassFir = containingClass.findFir(provider) as? FirRegularClass ?: return null
|
val containerClassFir = containingClass.findFir(provider) as? FirRegularClass ?: return null
|
||||||
containerClassFir.declarations.firstOrNull { it.psi === this }
|
containerClassFir.declarations.firstOrNull { it.psi === this }
|
||||||
}
|
}
|
||||||
this is KtTypeAlias -> findFir(provider)
|
this is KtTypeAlias -> findFir(provider)
|
||||||
else -> error("Invalid container ${this::class}\n${getElementTextInContext()}")
|
else -> firErrorWithAttachment("Invalid container", psi = this)
|
||||||
}
|
}
|
||||||
return candidate?.takeIf { it.realPsi == this }
|
return candidate?.takeIf { it.realPsi == this }
|
||||||
}
|
}
|
||||||
|
|||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.analysis.low.level.api.fir.util
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||||
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.psi
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRendererForDebugging
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithAttributes
|
||||||
|
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.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||||
|
import org.jetbrains.kotlin.utils.errorWithAttachment
|
||||||
|
import org.jetbrains.kotlin.utils.withAttachmentDetailed
|
||||||
|
|
||||||
|
|
||||||
|
fun KotlinExceptionWithAttachments.withFirAttachment(name: String, fir: FirElement): KotlinExceptionWithAttachments {
|
||||||
|
withAttachmentDetailed(name, fir, debugFirRenderer::renderElementAsString)
|
||||||
|
withPsiAttachment("${name}Psi", fir.psi)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KotlinExceptionWithAttachments.withFirSymbolAttachment(name: String, symbol: FirBasedSymbol<*>): KotlinExceptionWithAttachments {
|
||||||
|
withAttachment("${name}Class", symbol::class.java.name)
|
||||||
|
withFirAttachment("${name}Fir", symbol.fir)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KotlinExceptionWithAttachments.withConeTypeAttachment(name: String, coneType: ConeKotlinType): KotlinExceptionWithAttachments {
|
||||||
|
withAttachmentDetailed(name, coneType) {
|
||||||
|
buildString { ConeTypeRendererForDebugging(this).render(it) }
|
||||||
|
}
|
||||||
|
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(
|
||||||
|
message: String,
|
||||||
|
cause: Throwable? = null,
|
||||||
|
fir: FirElement? = null,
|
||||||
|
coneType: ConeKotlinType? = null,
|
||||||
|
psi: PsiElement? = null,
|
||||||
|
attachments: KotlinExceptionWithAttachments.() -> Unit = {}
|
||||||
|
): Nothing {
|
||||||
|
errorWithAttachment(message, cause) {
|
||||||
|
if (fir != null) {
|
||||||
|
withFirAttachment("fir", fir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psi != null) {
|
||||||
|
withPsiAttachment("psi", psi)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coneType != null) {
|
||||||
|
withConeTypeAttachment("coneType", coneType)
|
||||||
|
}
|
||||||
|
attachments ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val debugFirRenderer =
|
||||||
|
FirRenderer(resolvePhaseRenderer = FirResolvePhaseRenderer(), declarationRenderer = FirDeclarationRendererWithAttributes())
|
||||||
+5
-8
@@ -54,17 +54,14 @@ internal val FirElement.isErrorElement
|
|||||||
internal val FirDeclaration.ktDeclaration: KtDeclaration
|
internal val FirDeclaration.ktDeclaration: KtDeclaration
|
||||||
get() {
|
get() {
|
||||||
val psi = psi
|
val psi = psi
|
||||||
?: error("PSI element was not found for${render()}")
|
?: firErrorWithAttachment("PSI element was not found", fir = this)
|
||||||
return when (psi) {
|
return when (psi) {
|
||||||
is KtDeclaration -> psi
|
is KtDeclaration -> psi
|
||||||
is KtObjectLiteralExpression -> psi.objectDeclaration
|
is KtObjectLiteralExpression -> psi.objectDeclaration
|
||||||
else -> error(
|
else -> firErrorWithAttachment(
|
||||||
"""
|
"FirDeclaration.psi (${this::class.simpleName}) should be KtDeclaration but was ${psi::class.simpleName}",
|
||||||
FirDeclaration.psi (${this::class.simpleName}) should be KtDeclaration but was ${psi::class.simpleName}
|
fir = this,
|
||||||
${(psi as? KtElement)?.getElementTextInContext() ?: psi.text}
|
psi = psi,
|
||||||
|
|
||||||
${render()}
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,19 @@ open class KotlinExceptionWithAttachments : RuntimeException, ExceptionWithAttac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> KotlinExceptionWithAttachments.withAttachmentDetailed(
|
||||||
|
name: String,
|
||||||
|
content: T?,
|
||||||
|
render: (T) -> String
|
||||||
|
): KotlinExceptionWithAttachments {
|
||||||
|
withAttachment("${name}Class", content?.let { it::class.java.name })
|
||||||
|
withAttachment(name, content?.let(render))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
inline fun checkWithAttachment(value: Boolean, lazyMessage: () -> String, attachments: (KotlinExceptionWithAttachments) -> Unit = {}) {
|
inline fun checkWithAttachment(value: Boolean, lazyMessage: () -> String, attachments: (KotlinExceptionWithAttachments) -> Unit = {}) {
|
||||||
contract { returns() implies(value) }
|
contract { returns() implies (value) }
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
val e = KotlinExceptionWithAttachments(lazyMessage())
|
val e = KotlinExceptionWithAttachments(lazyMessage())
|
||||||
@@ -39,3 +49,14 @@ inline fun checkWithAttachment(value: Boolean, lazyMessage: () -> String, attach
|
|||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun errorWithAttachment(
|
||||||
|
message: String,
|
||||||
|
cause: Throwable? = null,
|
||||||
|
attachments: KotlinExceptionWithAttachments.() -> Unit = {}
|
||||||
|
): Nothing {
|
||||||
|
val exception = KotlinExceptionWithAttachments(message, cause)
|
||||||
|
attachments(exception)
|
||||||
|
throw exception
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user