CachedValueProvider#compute called multiple times for same element

Answered

Hi,

I'm trying to use a CachedValuesManager in a LocalInspectionTool in the most basic form and for some reason I see multiple invocations of compute for the same elements.

I mean I see multiple prints of "inside cachedValue" with the same identityHashCode where the element (import statement) hasn't changed at all.

What I do is open a project with a scala file and 3 import statements and then I just try to add a new variable (without touching the import area or anything related to imports yet because I haven't declared the variable's type) I see the second invocation of compute.

I'd really love some help understanding what I'm doing wrong since this seems to me like the most basic usage of the cache...

 

class ScalaInspection extends LocalInspectionTool {
override def buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = {
new ScalaElementVisitor {
override def visitImportExpr(expr: ScImportExpr): Unit = {
println(s"visitImportExpr: ${expr.reference.map(_.qualName)}")
CachedValuesManager.getCachedValue(expr, new ScalaCachedValueProvider(expr))
}

}
}
}
class ScalaCachedValueProvider(expr: ScImportExpr) extends CachedValueProvider[String] {
override def compute(): CachedValueProvider.Result[String] = {
//some expensive computation happens here
println(s"inside cachedValue: ${expr.reference.map(_.qualName)}, ${expr.hashCode}, ${System.identityHashCode(expr)}")
CachedValueProvider.Result.create("5",expr)
}
}
2 comments
Comment actions Permalink
Official comment

Hi, 

That is because you pass `expr` as a `dependency`:

CachedValueProvider.Result.create("5",expr)

Such caches are cleared on any change of a containing file. From java doc of `com.intellij.psi.util.CachedValueProvider.Result#getDependencyItems`:

* Dependencies can be following:
* <ul>
* <li/>Instances of {@link com.intellij.openapi.util.ModificationTracker} returning stamps explicitly
* <li/>Constant fields of {@link PsiModificationTracker} class, e.g. {@link PsiModificationTracker#MODIFICATION_COUNT}
* <li/>{@link com.intellij.psi.PsiElement} or {@link com.intellij.openapi.vfs.VirtualFile} objects. Such cache would be dropped
* on any change in the corresponding file
* </ul>

When you would want to invalidate you caches?

Comment actions Permalink

Thanks!
I’d like to invalidate it if the import statement in that file has changed. I thought expr represents just that...

0

Please sign in to leave a comment.