-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Originally reported in scalameta/metals#4060
TL;DR
- I'm looking for a way to cache the result of
InteractiveDriver.run - I believe we can invalidate the cache by checking
- input file isn't updated from the last compilation
- there's no change in the classpath from the last compilation
- If yes, where should I handle it? In
InteractiveDriveror its consumers (likemetalsside)? - If no, what we need to check for cache invalidation?
Background
While I CPU profile Metals using async-profiler, I realized that Metals (in Scala3 project) invokes InteractiveDriver.run quite frequently, especially from HoverProvider.hover (that invokes when users hover on symbol in the editors).
This is because we invoke InteractiveDriver.run every time when Metals uses information from presentation compilers.
For example, HoverProvider.hover runs InteractiveDriver.run for every invocations anyway.
https://github.com/scalameta/metals/blob/eab3df81d3a55445f558c959ee5d2fa24308be82/mtags/src/main/scala-3/scala/meta/internal/pc/HoverProvider.scala#L39
It might be a big CPU saver if we don't run InteractiveDriver.run if the input is the same (that is likely to happen especially when we're code reading and doing hover or navigations).
A little bit of experiments
I tried to experiment, maybe we can cache invalidate by checking the combination of file content and runId scalameta/metals#4100
However, I realized that this work only if we edit files only in Metals.
// initial
// src/main/scala/A.scala
trait A {
def foo: Int
}
// src/main/scala/B.scala
object B:
val a: A = _
val v = a.foo // call hover on `v` - should show `Int`
// then do changes in A.scala outside of Metals (which means there's no compilation in InteractiveDriver, but it should be compiled by the build server like bloop or sbt and classpath will be updated)
// src/main/scala/A.scala
trait A {
def foo: String
}
// src/main/scala/B.scala
object B:
val a: A = _
val v@@ = a.foo // it should show `String`
// but if there's a cache by file content of `B.scala` and `runId`
// it will show `Int` on hover.We need to know if there are changes on the classpath. 🤔
Questions
- I believe we can cache invalidate by the file content and checking there was a change on classpath that
InteractiveDriveraware of, no? - If yes, where should we handle it,
InteractiveDriverside or Metals side? (Or do you think we shouldn't cache it?) - If no, what we should check in addition to the classpath and content?
Any opinions are welcome!
BTW, I heard that someone is already taking a look at this topic, maybe @jchyb ? (sorry if I mistaken)