Skip to content

Caching and incremental computation with Salsa #1212

@lionel-

Description

@lionel-

This issue tracks the transition to a Salsa database and associated queries in the Oak LSP.

As we're adding semantic analysis for symbols (origin, type, and NSE behaviour), we need to compute increasingly more derived properties. And these properties transitively depend on properties in other files. For instance:

  • The LSP sees a source("foo.R", local = T) call, which injects top-level exports into the symbol table of the calling environment. What are the top-level exports in that file? Requires parsing, building a semantic index to figure out scope nesting, and detect all top-level assignments.

  • I'm looking at test_that(...), is that an NSE function? Where is it defined? From a package? Does it have registered NSE properties? (In the future this will be: is it a function? does it have declarations?). Every single function call potentially changes the symbol tables, and whether they do depend on properties potentially defined outside the current file.

  • Library paths and the contents of installed packages will also be LSP inputs. We'll track when a package is reinstalled, when renv is added to the repo, etc. These events all change the state of the world.

The LSP will produce a ton of these queries, and they all potentially get invalidated at each keystroke when the user types in the frontend. These changes can produce a big blast across the world state (e.g. is it the ggplot or the ggplot2 package in that library() call), a small blast (the user just added a local variable), or no blast at all (a string or comment is being edited, the file was reformatted with Air, etc).

With Salsa, we're able to finely specify a dependency graph of computation (queries). Salsa caches each result and only recompute ones that are invalidated. That's the framework that makes Rust-Analyzer and ty perform well in an IDE environment.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions