[LL FIR] fix user code leak from exceptions in :analysis:analysis-api-fir
Also, add more info to some exceptions
This commit is contained in:
committed by
Space Team
parent
e3d2bccb33
commit
7606aab0dd
+3
-1
@@ -623,7 +623,9 @@ private class BuilderCache<From, To : KtSymbol> {
|
||||
inline fun <reified S : To> cache(key: From, calculation: () -> S): S {
|
||||
val value = cache.getOrPut(key, calculation)
|
||||
return value as? S
|
||||
?: error("Cannot cast ${value::class} to ${S::class}\n${value}")
|
||||
?: errorWithAttachment("Cannot cast ${value::class} to ${S::class}") {
|
||||
withEntry("value", value.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -71,6 +71,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.exceptions.errorWithAttachment
|
||||
|
||||
internal class KtFirCallResolver(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -403,8 +404,13 @@ internal class KtFirCallResolver(
|
||||
val explicitReceiverPsi = when (psi) {
|
||||
is KtQualifiedExpression -> (psi.selectorExpression as KtCallExpression).calleeExpression
|
||||
is KtCallExpression -> psi.calleeExpression
|
||||
else -> error("unexpected PSI $psi for FirImplicitInvokeCall")
|
||||
} ?: error("missing calleeExpression in PSI $psi for FirImplicitInvokeCall")
|
||||
else -> errorWithAttachment("unexpected PSI ${psi::class} for FirImplicitInvokeCall") {
|
||||
withPsiEntry("psi", psi, analysisSession::getModule)
|
||||
}
|
||||
}
|
||||
?: errorWithAttachment("missing calleeExpression in PSI ${psi::class} for FirImplicitInvokeCall") {
|
||||
withPsiEntry("psi", psi, analysisSession::getModule)
|
||||
}
|
||||
|
||||
// Specially handle @ExtensionFunctionType
|
||||
if (dispatchReceiver.typeRef.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
|
||||
|
||||
+5
-1
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||
|
||||
internal class KtFirCompletionCandidateChecker(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -90,7 +92,9 @@ internal class KtFirCompletionCandidateChecker(
|
||||
): Sequence<ImplicitReceiverValue<*>?> {
|
||||
val towerDataContext = analysisSession.firResolveSession.getTowerContextProvider(originalFile)
|
||||
.getClosestAvailableParentContext(fakeNameExpression)
|
||||
?: error("Cannot find enclosing declaration for ${fakeNameExpression.getElementTextWithContext()}")
|
||||
?: errorWithAttachment("Cannot find enclosing declaration for ${fakeNameExpression::class}") {
|
||||
withPsiEntry("fakeNameExpression", fakeNameExpression)
|
||||
}
|
||||
|
||||
return sequence {
|
||||
yield(null) // otherwise explicit receiver won't be checked when there are no implicit receivers in completion position
|
||||
|
||||
+8
-3
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransf
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.unwrapParenthesesLabelsAndAnnotations
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||
|
||||
internal class KtFirExpressionInfoProvider(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -172,8 +174,9 @@ internal class KtFirExpressionInfoProvider(
|
||||
false
|
||||
|
||||
!is KtExpression ->
|
||||
error("Unhandled Non-KtExpression parent of KtExpression: ${parent::class}")
|
||||
|
||||
errorWithAttachment("Unhandled Non-KtExpression parent of KtExpression: ${parent::class}") {
|
||||
withPsiEntry("parent", parent)
|
||||
}
|
||||
/**
|
||||
* EXPRESSIONS
|
||||
*/
|
||||
@@ -351,7 +354,9 @@ internal class KtFirExpressionInfoProvider(
|
||||
false
|
||||
|
||||
else ->
|
||||
error("Unhandled KtElement subtype: ${parent::class}")
|
||||
errorWithAttachment("Unhandled KtElement subtype: ${parent::class}") {
|
||||
withPsiEntry("parent", parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -42,6 +42,8 @@ import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||
|
||||
internal class KtFirImportOptimizer(
|
||||
override val token: KtLifetimeToken,
|
||||
@@ -444,7 +446,9 @@ private sealed interface TypeQualifier {
|
||||
}
|
||||
|
||||
qualifier.getCalleeExpressionIfAny() as? KtNameReferenceExpression
|
||||
?: error("Cannot get referenced name from '${qualifier.text}'")
|
||||
?: errorWithAttachment("Cannot get referenced name from '${qualifier::class}'") {
|
||||
withPsiEntry("qualifier", qualifier)
|
||||
}
|
||||
}
|
||||
|
||||
override val referencedByName: Name
|
||||
@@ -469,7 +473,9 @@ private sealed interface TypeQualifier {
|
||||
|
||||
override val referencedByName: Name
|
||||
get() = qualifier.referenceExpression?.getReferencedNameAsName()
|
||||
?: error("Cannot get referenced name from '${qualifier.text}'")
|
||||
?: errorWithAttachment("Cannot get referenced name from '${qualifier::class}'") {
|
||||
withPsiEntry("qualifier", qualifier)
|
||||
}
|
||||
|
||||
override val isQualified: Boolean
|
||||
get() = qualifier.qualifier != null
|
||||
|
||||
+7
-2
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
internal class KtFirReferenceShortener(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -520,7 +521,9 @@ private class ElementsToShortenCollector(
|
||||
is FirNestedClassifierScope -> klass.classId
|
||||
is FirNestedClassifierScopeWithSubstitution -> originalScope.correspondingClassIdIfExists()
|
||||
is FirClassUseSiteMemberScope -> classId
|
||||
else -> error("FirScope `$this` is expected to be one of FirNestedClassifierScope and FirClassUseSiteMemberScope to get ClassId")
|
||||
else -> errorWithAttachment("FirScope ${this::class}` is expected to be one of FirNestedClassifierScope and FirClassUseSiteMemberScope to get ClassId") {
|
||||
withEntry("firScope", this@correspondingClassIdIfExists) { it.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.idWithoutCompanion() = if (shortClassName == SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT) outerClassId else this
|
||||
@@ -1095,7 +1098,9 @@ private class ElementsToShortenCollector(
|
||||
|
||||
val distinctCandidates = candidates.distinctBy { it.callableId }
|
||||
return distinctCandidates.singleOrNull()
|
||||
?: error("Expected all candidates to have same callableId, but got: ${distinctCandidates.map { it.callableId }}")
|
||||
?: errorWithAttachment("Expected all candidates to have same callableId but some of them but was different") {
|
||||
withEntry("callableIds", distinctCandidates.map { it.callableId.asSingleFqName() }.joinToString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun findFakePackageToShorten(wholeQualifiedExpression: KtDotQualifiedExpression): ShortenQualifier? {
|
||||
|
||||
+5
-1
@@ -51,6 +51,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||
|
||||
internal class KtFirScopeProvider(
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
@@ -194,7 +196,9 @@ internal class KtFirScopeProvider(
|
||||
): KtScopeContext {
|
||||
val towerDataContext =
|
||||
analysisSession.firResolveSession.getTowerContextProvider(originalFile).getClosestAvailableParentContext(positionInFakeFile)
|
||||
?: error("Cannot find enclosing declaration for ${positionInFakeFile.getElementTextWithContext()}")
|
||||
?: errorWithAttachment("Cannot find enclosing declaration for ${positionInFakeFile::class}") {
|
||||
withPsiEntry("positionInFakeFile", positionInFakeFile)
|
||||
}
|
||||
val towerDataElementsIndexed = towerDataContext.towerDataElements.asReversed().withIndex()
|
||||
|
||||
val implicitReceivers = towerDataElementsIndexed.flatMap { (index, towerDataElement) ->
|
||||
|
||||
+11
-3
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.fir.contracts.description.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.contracts.description.LogicOperationKind
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
internal fun KtEffectDeclaration<ConeKotlinType, ConeDiagnostic>.coneEffectDeclarationToAnalysisApi(
|
||||
builder: KtSymbolByFirBuilder,
|
||||
@@ -51,12 +53,16 @@ private class ConeContractDescriptionElementToAnalysisApi(
|
||||
when (value) {
|
||||
ConeContractConstantValues.TRUE -> KtContractConstantType.TRUE
|
||||
ConeContractConstantValues.FALSE -> KtContractConstantType.FALSE
|
||||
else -> error("Can't convert $value to the Analysis API")
|
||||
else -> errorWithAttachment("Can't convert ${value::class} to the Analysis API") {
|
||||
withEntry("value", value) { value.toString() }
|
||||
}
|
||||
},
|
||||
builder.token
|
||||
)
|
||||
)
|
||||
else -> error("Can't convert $returnsEffect to the Analysis API")
|
||||
else -> errorWithAttachment("Can't convert ${returnsEffect::class} to the Analysis API") {
|
||||
withEntry("value", value) { value.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCallsEffectDeclaration(callsEffect: KtCallsEffectDeclaration<ConeKotlinType, ConeDiagnostic>, data: Unit): KtContractCallsInPlaceContractEffectDeclaration =
|
||||
@@ -116,7 +122,9 @@ private class ConeContractDescriptionElementToAnalysisApi(
|
||||
constructor: (KtParameterSymbol) -> T
|
||||
): T = constructor(
|
||||
if (valueParameterReference.parameterIndex == -1) firFunctionSymbol.receiverParameter
|
||||
?: error("$firFunctionSymbol should contain a receiver")
|
||||
?: errorWithAttachment("${firFunctionSymbol::class} should contain a receiver") {
|
||||
withFirEntry("fir", firFunctionSymbol.firSymbol.fir)
|
||||
}
|
||||
else firFunctionSymbol.valueParameters[valueParameterReference.parameterIndex]
|
||||
)
|
||||
|
||||
|
||||
+10
-2
@@ -22,6 +22,9 @@ import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
||||
|
||||
internal class KtFirReceiverParameterSymbol(
|
||||
val firSymbol: FirCallableSymbol<*>,
|
||||
@@ -31,11 +34,16 @@ internal class KtFirReceiverParameterSymbol(
|
||||
override val psi: PsiElement? = withValidityAssertion{ firSymbol.fir.receiverParameter?.typeRef?.psi }
|
||||
|
||||
init {
|
||||
require(firSymbol.fir.receiverParameter != null) { "$firSymbol doesn't have an extension receiver." }
|
||||
requireWithAttachment(firSymbol.fir.receiverParameter != null, { "${firSymbol::class} doesn't have an extension receiver." }) {
|
||||
withFirEntry("callable", firSymbol.fir)
|
||||
}
|
||||
}
|
||||
|
||||
override val type: KtType by cached {
|
||||
firSymbol.receiverType(analysisSession.firSymbolBuilder) ?: error("$firSymbol doesn't have an extension receiver.")
|
||||
firSymbol.receiverType(analysisSession.firSymbolBuilder)
|
||||
?: errorWithAttachment("${firSymbol::class} doesn't have an extension receiver") {
|
||||
withFirEntry("callable", firSymbol.fir)
|
||||
}
|
||||
}
|
||||
|
||||
override val owningCallableSymbol: KtCallableSymbol by cached { analysisSession.firSymbolBuilder.callableBuilder.buildCallableSymbol(firSymbol) }
|
||||
|
||||
+5
-1
@@ -25,7 +25,9 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
internal class KtFirValueParameterSymbol(
|
||||
override val firSymbol: FirValueParameterSymbol,
|
||||
@@ -51,7 +53,9 @@ internal class KtFirValueParameterSymbol(
|
||||
return@cached if (firSymbol.isVararg) {
|
||||
// There SHOULD always be an array element type (even if it is an error type, e.g., unresolved).
|
||||
val arrayElementType = returnType.arrayElementType()
|
||||
?: error("No array element type for vararg value parameter: ${firSymbol.fir.renderWithType()}")
|
||||
?: errorWithAttachment("No array element type for vararg value parameter") {
|
||||
withFirEntry("fir", firSymbol.fir)
|
||||
}
|
||||
builder.typeBuilder.buildKtType(arrayElementType)
|
||||
} else {
|
||||
builder.typeBuilder.buildKtType(returnType)
|
||||
|
||||
+5
-12
@@ -16,31 +16,24 @@ import org.jetbrains.kotlin.analysis.api.impl.base.KtContextReceiverImpl
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
|
||||
internal fun FirCallableSymbol<*>.invalidModalityError(): Nothing {
|
||||
val rendered = FirRenderer.withResolvePhase().renderElementWithTypeAsString(fir)
|
||||
error(
|
||||
"""|Symbol modality should not be null, looks like the FIR symbol was not properly resolved
|
||||
|
|
||||
|$rendered
|
||||
|
|
||||
|${(fir.psi as? KtDeclaration)?.getElementTextWithContext()}""".trimMargin()
|
||||
)
|
||||
errorWithAttachment("Symbol modality should not be null, looks like the FIR symbol was not properly resolved") {
|
||||
withFirEntry("fir", this@invalidModalityError.fir)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirFunctionSymbol<*>.createKtValueParameters(builder: KtSymbolByFirBuilder): List<KtValueParameterSymbol> {
|
||||
|
||||
+5
-1
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
|
||||
|
||||
internal object UsualClassTypeQualifierBuilder {
|
||||
fun buildQualifiers(
|
||||
@@ -104,7 +106,9 @@ internal object UsualClassTypeQualifierBuilder {
|
||||
is FirAnonymousObject -> listOf(declaration)
|
||||
is FirRegularClass -> declaration.collectForLocal()
|
||||
is FirTypeAlias -> listOf(declaration) // TODO: handle type aliases
|
||||
else -> error("Invalid declaration ${declaration.renderWithType()}")
|
||||
else -> errorWithAttachment("Invalid declaration ${declaration::class}") {
|
||||
withFirEntry("declaration", declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user