Best practices for CachedValuesManager.getProjectPsiDependentCache ?
Answered
I'm building a custom language plugin, and it seems like almost all values "should" be cached in the projectPsiDependentCache.
class WBinaryExpression(astNode: ASTNode) : WExpression(astNode) {
// Structured traversal methods can be cached:
fun lhs() : WExpression =
CachedValuesManager.getProjectPsiDependentCache(this) {
PsiTreeUtil.getChildOfType(it, WExpression::class.java)
}
// Computation of Intermediate Representation can be cached:
fun term() : WTerm =
CachedValuesManager.getProjectPsiDependentCache(this) {
computeTerm(it)
}
}
// Type Inference can be cached:
fun type() : WType =
CachedValuesManager.getProjectPsiDependentCache(this) {
computeType(it)
}
}
// Construction of PsiReference can be cached:
override fun getReference() =
CachedValuesManager.getProjectPsiDependentCache(this) {
WElementReference(it)
}
}
class WElementReference(private val referenceElement: WExpression):
PsiReferenceBase<WExpression>(referenceElement) {
// Actually resolving the reference can also be cached:
override fun resolve() =
CachedValuesManager.getProjectPsiDependentCache(referenceElement) {
resolveForWExpression(it)
}
}
Are all of these correct uses of the projectPsiDependent cache? Is this a standard paradigm for language plugins? Is it possible to OVERUSE the cache?
If this is standard, has any kotlin developer made a "by PsiDependentCache()" delegate yet?
Please sign in to leave a comment.
Another thing that would be useful for me is having an easy way to implement cached properties that get invalidated when the subtree of the PsiElement changes.
It's impossible to give generic advice on caching, as it depends on too many implementation and runtime factors (e.g., project size, hardware, additional plugins, ...) Please profile first and only if it turns out to be a real world bottleneck, start optimizing at this level.
Reference https://plugins.jetbrains.com/docs/intellij/performance.html#cache-results-of-heavy-computations