Implements formatting support within LSP. Current implementation
performs while file formatting, we just replace file with output of
Carbon::Format()
https://github.com/carbon-language/carbon-lang/pull/7687 independently
improves formatting so that this output is somewhat decent.
Assisted-With: Gemini / Antigravity
Add support for "jump to declaration", "find references", type
information on hover. This support is strictly single-file for now; only
references and declarations within the same file are found. We could go
a bit beyond that, but to properly handle cross-file references we'll
need to build an index and a compilation database, which is beyond the
scope of this change.
On hover, we provide the type information for the instruction under the
cursor as-is. This is frequently not very useful, as the type of a
function F is simply "<type of F>", but is a starting point for richer
information.
Assisted-by: Claude Code
We currently provide UTF-8 positions, since our source representation is
UTF-8 and we use byte offsets as column numbers, but the LSP protocol
default is UTF-16 column positions. Negotiate UTF-8 positions where
possible; this is supported by essentially every LSP client other than
VS Code.
In the case where we select a UTF-16 position, we continue to not do any
actual conversions, so our column offsets in such cases will continue to
be wrong on non-ASCII source files in VS Code.
Assisted by: Claude Code
Support multi-file compilation, and in particular imports of files from
the prelude, in `carbon language_server`.
In order to properly interface with `CompileDriver`, also switch over to
building a proper VFS from the documents we're given.
Assisted-by: Gemini via Antigravity
LSP assumes lines are index 0 to n-1, but Carbon Locs are index from 1
to n. We had the logic for this correct for the start of range but not
for the end of range (inclusive range).
Before this was the diagnostic span we would produce:
```carbon
fn F() {
return ();
<~~~~~~~~>
}
<~~~~~~~~~~~>
```
after:
```carbon
fn F() {
return ();
<~~~~~~~~>
}
```
Instead of taking the complete text of the Clang diagnostic and using it
as the message portion of a Carbon diagnostic, generate the individual
pieces separately and pass them into the Carbon diagnostic
infrastructure.
* Clang's context lines are generated by running a custom "diagnostic
renderer" and tracking which lines it wants to print as context for a
given source location. When mapping from a C++ source location back to a
Carbon location, the Carbon `Loc` structure is now fully populated,
including filling in the context line and the column number.
* Clang's snippet is generated by running a custom diagnostic renderer
that is a cut-down version of the full text diagnostic renderer that
only prints a snippet. This is then attached to the Carbon diagnostic
manually as an override for the snippet we'd usually create.
We no longer repeat the file location twice on each diagnostic, and no
longer produce a bogus "in import" line for all locations coming from
clang that point arbitrarily to the first C++ import in the Carbon file.
The `[diagnostic kind]` marker is now displayed at the end of the
diagnostic message, not on a line of its own after the snippet.
I believe we will need to eventually add the specific C++ import
information in `LocId`.
This also seems to fix the `LanguageServerDiagnosticInWrongFile` issue
(#5604).
We're still not in the state we want to be according to
https://github.com/carbon-language/carbon-lang/pull/5246#issuecomment-2784301206.
Will look into removing the location part from the `"In file included
from ..."` line.
Part of #5245.
Removes the nullptr default for safety.
Note, I think cpp support doesn't allow things like `<version>` or
inline code yet, and language-server support doesn't allow non-hermetic
files, so the best I can test is an error.
The language server is now able to subscribe to and apply incremental
changes to the document. Source code is assumed to be utf-8. It does not
currently handle utf-16 code points.
---------
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Without this, diagnostics will linger after closing a file.
This refactors towards a pattern of putting outgoing calls as methods on
`Context`. I'm mixed on this, mainly thinking it's an improvement on
using `outgoing` directly (because it shares the name and structure),
might want to move it to a side-class later that is _only_ LSP wrappers.
I could also make inheritance private on OutgoingMessages and these
kinds of methods public there, but I'm hesitant to adopt that approach
versus a type separation.
This PR adds a new command to the Carbon VSCode extension "carbon:
Restart language server" which acts similar to clangd / bazel
extensions. While not useful during regular working of the extension
this helps when LSP either crashes or the toolchain is updated.
In order to support graceful restart, I needed to add a Call handler for
"shutdown" which is noop for now. Lsp clients always call shutdown
before sending exit.
---------
Co-authored-by: jonmeow <jperkins@google.com>
Add caching of parsed documents, and testing of the textDocument
handlers. This is based on #4896, which splits out some of the
boilerplate to calls.
Note, this caches the entire parse state because we'll want to try to
emit diagnostics when we see the update, without waiting. It may be
helpful to do that asynchronously, but we don't want to wait for another
call (such as documentSymbol). Really, we'll probably want to also add
check for diagnostics, at least.