FIR IDE: add cache in KtFirCallResolver
This commit is contained in:
committed by
Ilya Kirillov
parent
d2ed203528
commit
c19ed07fd1
+35
-25
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user