Skip to content

Support for local definitions in "Go to definition" #8631

@lionel-

Description

@lionel-

Our "go to definition" handling is currently on par with RStudio, but in the landscape of LSPs we have incomplete support. Here is where we stand right now with static definitions:

  • Top-level function
  • Top-level variable (not supported in RStudio)
  • Local variable
  • Local variable inside an NSE function with local scope (local(), with(), etc)

While RStudio doesn't support jumping to variable definitions, this is a common LSP feature that I think we should support. In general, the "go to definition" feature should be consistent with "unknown symbol" diagnostics. If the LSP knows that a variable is defined then it should jump to the most relevant (closest) definition.

We already made it possible to jump to top-level variables, which was mainly a byproduct of making top-level variables exported as workspace symbols (see #5274). We still need to support local variables. Here are some examples of how this should all work:

foo <- 1
foo # Jump to top-level variable 1

foo <- function(foo = 2) {
    foo # Jump to parameter 2

    foo <- 3
    foo # Jump to local variable 3

    if (cond) {
        foo <- 4
    }

    foo # Ambiguous, but I guess we want to jump to `foo <- 4` here

    if (cond) {
        foo <- 5
    } else {
        foo <- 6
    }
    foo # In this case jump to `foo <- 5`? I.e. first occurrence in the diverging paths?
        # Also fine to jump to 6 for consistency (last definition seen)
}

foo # Jump to top-level function (not variable)


local({
    foo <- 7
    foo # Jump to local variable 7
})

# Requires NSE handling: Ark should understand local scope inside `local()`
foo # Jump to top-level function

foo <- 8
foo <- foo + 1 # If cursor is on LHS, stay there. If cursor is on RHS, jump to 8

Currently Ark only supports top-level definitions because the "goto definition" handler is built around our workspace indexer.

To support local definitions, we'd ideally build a semantic index with symbol resolution information that would be used by multiple LSP features, including jump to definition. This sort of integrated data structure can wait for the independent LSP rewrite though, so we can design it holistically.

In the mean time, we could switch to the same sort of algorithm we use for "unknown symbol" diagnostics to add support for local variables. This first implementation would ignore any complications from NSE.

Metadata

Metadata

Assignees

No fields configured for Enhancement.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions