Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for generalized "references" queries #1911

Open
Tracked by #69349
adonovan opened this issue Mar 21, 2024 · 1 comment
Open
Tracked by #69349

support for generalized "references" queries #1911

adonovan opened this issue Mar 21, 2024 · 1 comment
Labels
feature-request Request for new features or functionality references
Milestone

Comments

@adonovan
Copy link

adonovan commented Mar 21, 2024

The LSP's references method takes the client editor's selected range, and returns a set of locations--of all the identifiers that refer to the same symbol as the selected identifier. A large variety of useful queries can be expressed as minor variations on this theme. For example:

  • show all implicit references to the selected identifier. For example, in Go, Point2D{1, 2} is shorthand for Point2D{X: 1, Y: 2}, and it might be useful to highlight it when finding references to X or Y.
  • show all free variables of the selected text. These are the variables that would need to become parameters in an "extract function" refactoring, but it's often useful to enumerate them even when just reading.
  • show all statements that use the selected variable as an l-value. For example, x = 1, x.a[i] = 2 and p = &x all use x as an l-value, whereas y = x and print(x) use it as an r-value. When trying to comprehend aliasing and mutation, this difference is crucial.
  • show all function declarations (including anonymous lambdas) that satisfy a particular function type (and vice versa).
  • show all argument expressions that assign the selected parameter. For example, a query on y func f(x, y int) might report the expression 456 in the call f(123, 456).
  • show all locations that construct a variable of the selected type (even as part of a larger aggregate).
  • show all supertypes or subtypes of a selected type T. (The textDocument/implementation feature reports supertypes if T is concrete and subtypes if T is an interface, but gives no way to request superinterfaces of an interface or subtypes of a Java abstract class.)
  • show all expressions that convert a value to the selected type. For example, writer = file might implicitly convert an *os.File to an io.Writer.

These examples use Go, but I'm sure you can think of other examples in your second-favorite language. ;-)

I'm not going to prescribe any particular implementation, but I think it would be very useful if the LSP allowed a server to respond to a CodeAction query with a command that tells the client: the result of this command should be displayed with a similar user interface to an ordinary 'references' query.

One subtlety: some of these queries produce slightly more information than a set of locations, especially when describing implicit operations with no obvious syntax; they need an annotation too. For example, the first query might annotate the location of Point2D{1, 2} with "implicit reference to Point.X", or x.f with "shorthand for x.A.B.C.f"; the second query might annotate each free variable with its type information; and the last one might annotate the assignment with "RHS has type *os.File". Thus the result type would need to be a list of (Location, string) pairs.

What do you think?

@HighCommander4
Copy link

A related enhancement proposal to the references request is #396, with filtering read vs. write (rvalue vs. lvalue) references being a use case discussed there too.

I like the approach you describe though, in that it avoids the need to build anything specific (like a notion of read vs. write references) into the protocol -- that customization can take the form of the server offering whatever variations of the request are relevant as different code actions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for new features or functionality references
Projects
None yet
Development

No branches or pull requests

3 participants