[analysis api] fix ArrayIndexOutOfBoundsException on KtDiagnostic creation
The problem was caused by concurrent access to the non-thread safe List. This list is not needed anymore, previously it was used to store strong references to FIR diagnostics corresponding references in KtDiagnostics were weak references. ^KTIJ-21449 fixed
This commit is contained in:
-2
@@ -52,10 +52,8 @@ internal interface KtFirAnalysisSessionComponent {
|
|||||||
fun ConeDiagnostic.asKtDiagnostic(
|
fun ConeDiagnostic.asKtDiagnostic(
|
||||||
source: KtSourceElement,
|
source: KtSourceElement,
|
||||||
qualifiedAccessSource: KtSourceElement?,
|
qualifiedAccessSource: KtSourceElement?,
|
||||||
diagnosticCache: MutableList<KtDiagnostic>
|
|
||||||
): KtDiagnosticWithPsi<*>? {
|
): KtDiagnosticWithPsi<*>? {
|
||||||
val firDiagnostic = toFirDiagnostics(analysisSession.useSiteSession, source, qualifiedAccessSource).firstOrNull() ?: return null
|
val firDiagnostic = toFirDiagnostics(analysisSession.useSiteSession, source, qualifiedAccessSource).firstOrNull() ?: return null
|
||||||
diagnosticCache += firDiagnostic
|
|
||||||
check(firDiagnostic is KtPsiDiagnostic)
|
check(firDiagnostic is KtPsiDiagnostic)
|
||||||
return firDiagnostic.asKtDiagnostic()
|
return firDiagnostic.asKtDiagnostic()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-6
@@ -66,8 +66,6 @@ internal class KtFirCallResolver(
|
|||||||
override val analysisSession: KtFirAnalysisSession,
|
override val analysisSession: KtFirAnalysisSession,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : AbstractKtCallResolver(), KtFirAnalysisSessionComponent {
|
) : AbstractKtCallResolver(), KtFirAnalysisSessionComponent {
|
||||||
private val diagnosticCache = mutableListOf<KtDiagnostic>()
|
|
||||||
|
|
||||||
private val equalsSymbolInAny: FirNamedFunctionSymbol by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
private val equalsSymbolInAny: FirNamedFunctionSymbol by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
val session = analysisSession.useSiteSession
|
val session = analysisSession.useSiteSession
|
||||||
val scope = session.declaredMemberScope(session.builtinTypes.anyType.toRegularClassSymbol(session)!!)
|
val scope = session.declaredMemberScope(session.builtinTypes.anyType.toRegularClassSymbol(session)!!)
|
||||||
@@ -150,7 +148,7 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
is FirErrorNamedReference -> {
|
is FirErrorNamedReference -> {
|
||||||
val diagnostic = calleeReference.diagnostic
|
val diagnostic = calleeReference.diagnostic
|
||||||
val ktDiagnostic = (source?.let { diagnostic.asKtDiagnostic(it, psi.toKtPsiSourceElement(), diagnosticCache) }
|
val ktDiagnostic = (source?.let { diagnostic.asKtDiagnostic(it, psi.toKtPsiSourceElement()) }
|
||||||
?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token))
|
?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token))
|
||||||
|
|
||||||
if (diagnostic is ConeHiddenCandidateError)
|
if (diagnostic is ConeHiddenCandidateError)
|
||||||
@@ -171,8 +169,7 @@ internal class KtFirCallResolver(
|
|||||||
val delegatedConstructorCall = this as? FirDelegatedConstructorCall ?: return null
|
val delegatedConstructorCall = this as? FirDelegatedConstructorCall ?: return null
|
||||||
val errorTypeRef = delegatedConstructorCall.constructedTypeRef as? FirErrorTypeRef ?: return null
|
val errorTypeRef = delegatedConstructorCall.constructedTypeRef as? FirErrorTypeRef ?: return null
|
||||||
val psiSource = psi.toKtPsiSourceElement()
|
val psiSource = psi.toKtPsiSourceElement()
|
||||||
val ktDiagnostic =
|
val ktDiagnostic = errorTypeRef.diagnostic.asKtDiagnostic(source ?: psiSource, psiSource) ?: return null
|
||||||
errorTypeRef.diagnostic.asKtDiagnostic(source ?: psiSource, psiSource, diagnosticCache) ?: return null
|
|
||||||
KtErrorCallInfo(emptyList(), ktDiagnostic, token)
|
KtErrorCallInfo(emptyList(), ktDiagnostic, token)
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
@@ -812,7 +809,7 @@ internal class KtFirCallResolver(
|
|||||||
val diagnostic = createConeDiagnosticForCandidateWithError(candidate.currentApplicability, candidate)
|
val diagnostic = createConeDiagnosticForCandidateWithError(candidate.currentApplicability, candidate)
|
||||||
if (diagnostic is ConeHiddenCandidateError) return null
|
if (diagnostic is ConeHiddenCandidateError) return null
|
||||||
val ktDiagnostic =
|
val ktDiagnostic =
|
||||||
functionCall.source?.let { diagnostic.asKtDiagnostic(it, element.toKtPsiSourceElement(), diagnosticCache) }
|
functionCall.source?.let { diagnostic.asKtDiagnostic(it, element.toKtPsiSourceElement()) }
|
||||||
?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token)
|
?: KtNonBoundToPsiErrorDiagnostic(factoryName = null, diagnostic.reason, token)
|
||||||
return KtInapplicableCallCandidateInfo(call, isInBestCandidates, ktDiagnostic)
|
return KtInapplicableCallCandidateInfo(call, isInBestCandidates, ktDiagnostic)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user