FIR IDE: add cache in KtFirCallResolver

This commit is contained in:
Tianyu Geng
2021-08-27 11:21:08 -07:00
committed by Ilya Kirillov
parent d2ed203528
commit c19ed07fd1
@@ -48,12 +48,14 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.findAssignment import org.jetbrains.kotlin.psi.psiUtil.findAssignment
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.concurrent.ConcurrentHashMap
internal class KtFirCallResolver( internal class KtFirCallResolver(
override val analysisSession: KtFirAnalysisSession, override val analysisSession: KtFirAnalysisSession,
override val token: ValidityToken, override val token: ValidityToken,
) : KtCallResolver(), KtFirAnalysisSessionComponent { ) : KtCallResolver(), KtFirAnalysisSessionComponent {
private val diagnosticCache = mutableListOf<FirDiagnostic>() private val diagnosticCache = mutableListOf<FirDiagnostic>()
private val cache: ConcurrentHashMap<KtElement, KtCall?> = ConcurrentHashMap()
override fun resolveAccessorCall(call: KtSimpleNameExpression): KtCall? = withValidityAssertion { override fun resolveAccessorCall(call: KtSimpleNameExpression): KtCall? = withValidityAssertion {
when (val fir = call.getOrBuildFir(firResolveState)) { when (val fir = call.getOrBuildFir(firResolveState)) {
@@ -88,44 +90,52 @@ internal class KtFirCallResolver(
} }
override fun resolveCall(call: KtBinaryExpression): KtCall? = withValidityAssertion { override fun resolveCall(call: KtBinaryExpression): KtCall? = withValidityAssertion {
when (val fir = call.getOrBuildFir(firResolveState)) { cache.computeIfAbsent(call) {
is FirFunctionCall -> resolveCall(fir) when (val fir = call.getOrBuildFir(firResolveState)) {
is FirComparisonExpression -> resolveCall(fir.compareToCall) is FirFunctionCall -> resolveCall(fir)
is FirEqualityOperatorCall -> null // TODO is FirComparisonExpression -> resolveCall(fir.compareToCall)
else -> null is FirEqualityOperatorCall -> null // TODO
else -> null
}
} }
} }
override fun resolveCall(call: KtUnaryExpression): KtCall? = withValidityAssertion { override fun resolveCall(call: KtUnaryExpression): KtCall? = withValidityAssertion {
when (val fir = call.getOrBuildFir(firResolveState)) { cache.computeIfAbsent(call) {
is FirFunctionCall -> resolveCall(fir) when (val fir = call.getOrBuildFir(firResolveState)) {
is FirBlock -> { is FirFunctionCall -> resolveCall(fir)
// Desugared increment or decrement block. See [BaseFirBuilder#generateIncrementOrDecrementBlock] is FirBlock -> {
// There would be corresponding inc()/dec() call that is assigned back to a temp variable. // Desugared increment or decrement block. See [BaseFirBuilder#generateIncrementOrDecrementBlock]
val prefix = fir.statements.filterIsInstance<FirVariableAssignment>().find { it.rValue is FirFunctionCall } // There would be corresponding inc()/dec() call that is assigned back to a temp variable.
(prefix?.rValue as? FirFunctionCall)?.let { resolveCall(it) } val prefix = fir.statements.filterIsInstance<FirVariableAssignment>().find { it.rValue is FirFunctionCall }
(prefix?.rValue as? FirFunctionCall)?.let { resolveCall(it) }
}
is FirCheckNotNullCall -> null // TODO
else -> null
} }
is FirCheckNotNullCall -> null // TODO
else -> null
} }
} }
override fun resolveCall(call: KtCallElement): KtCall? = withValidityAssertion { override fun resolveCall(call: KtCallElement): KtCall? = withValidityAssertion {
return when (val fir = call.getOrBuildFir(firResolveState)) { cache.computeIfAbsent(call) {
is FirArrayOfCall -> resolveArrayOfCall(fir) when (val fir = call.getOrBuildFir(firResolveState)) {
is FirFunctionCall -> resolveCall(fir) is FirArrayOfCall -> resolveArrayOfCall(fir)
is FirAnnotationCall -> fir.asAnnotationCall() is FirFunctionCall -> resolveCall(fir)
is FirDelegatedConstructorCall -> fir.asDelegatedConstructorCall() is FirAnnotationCall -> fir.asAnnotationCall()
is FirConstructor -> fir.asDelegatedConstructorCall() is FirDelegatedConstructorCall -> fir.asDelegatedConstructorCall()
is FirSafeCallExpression -> fir.regularQualifiedAccess.safeAs<FirFunctionCall>()?.let { resolveCall(it) } is FirConstructor -> fir.asDelegatedConstructorCall()
else -> null is FirSafeCallExpression -> fir.regularQualifiedAccess.safeAs<FirFunctionCall>()?.let { resolveCall(it) }
else -> null
}
} }
} }
override fun resolveCall(call: KtArrayAccessExpression): KtCall? = withValidityAssertion { override fun resolveCall(call: KtArrayAccessExpression): KtCall? = withValidityAssertion {
return when (val fir = call.getOrBuildFir(firResolveState)) { cache.computeIfAbsent(call) {
is FirFunctionCall -> resolveCall(fir) when (val fir = call.getOrBuildFir(firResolveState)) {
else -> null is FirFunctionCall -> resolveCall(fir)
else -> null
}
} }
} }