mirror of
https://github.com/microsoft/language-server-protocol.git
synced 2025-12-23 08:48:16 +00:00
Publish LSIF 0.5.0 version
This commit is contained in:
parent
56cf06cf95
commit
4200969f65
10 changed files with 1411 additions and 6 deletions
65
_data/lsif-0-5-0-toc.yml
Normal file
65
_data/lsif-0-5-0-toc.yml
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
- title: Table of Contents
|
||||
reveal: _general
|
||||
children:
|
||||
- title: General
|
||||
anchor: _general
|
||||
children:
|
||||
- title: Introduction
|
||||
anchor: lsifIntro
|
||||
- title: Motivation
|
||||
anchor: lsifMotivation
|
||||
- title: Ranges
|
||||
anchor: ranges
|
||||
- title: Result Sets
|
||||
anchor: resultSet
|
||||
- title: Language Features
|
||||
anchor: _languageFeatures
|
||||
children:
|
||||
- title: definition
|
||||
anchor: definition
|
||||
- title: declaration
|
||||
anchor: declaration
|
||||
- title: hover
|
||||
anchor: hover
|
||||
- title: references
|
||||
anchor: references
|
||||
- title: implementation
|
||||
anchor: implementation
|
||||
- title: typeDefinition
|
||||
anchor: typeDefinition
|
||||
- title: foldingRange
|
||||
anchor: foldingRange
|
||||
- title: documentLink
|
||||
anchor: documentLink
|
||||
- title: documentSymbol
|
||||
anchor: documentSymbol
|
||||
- title: diagnostic
|
||||
anchor: diagnostic
|
||||
- title: project
|
||||
anchor: projectContext
|
||||
- title: Embedding Contents
|
||||
anchor: embeddingContents
|
||||
- title: Advanced Concepts
|
||||
anchor: _advancedConcpets
|
||||
children:
|
||||
- title: Events
|
||||
anchor: events
|
||||
- title: Exports and Imports
|
||||
anchor: exportsImports
|
||||
- title: Multiple Projects
|
||||
anchor: multiProjects
|
||||
- title: Package Managers
|
||||
anchor: packageManagers
|
||||
- title: Result Ranges
|
||||
anchor: resultRanges
|
||||
- title: Meta Data
|
||||
anchor: metaData
|
||||
- title: Emitting Contstraints
|
||||
anchor: emittingContstraints
|
||||
- title: Additional Information
|
||||
anchor: _additionalInformation
|
||||
children:
|
||||
- title: Tools
|
||||
anchor: tools
|
||||
- title: Open Questions
|
||||
anchor: openQuestions
|
||||
|
|
@ -8,5 +8,7 @@
|
|||
- title: LSIF
|
||||
anchor: lsif
|
||||
children:
|
||||
- title: 0.4.0
|
||||
- title: 0.5.0 (Current)
|
||||
url: /specifications/lsif/0.5.0/specification
|
||||
- title: 0.4.0 (Previous)
|
||||
url: /specifications/lsif/0.4.0/specification
|
||||
|
|
|
|||
|
|
@ -7,10 +7,6 @@ toc: lsif-0-4-0-toc
|
|||
index: 2
|
||||
---
|
||||
|
||||
# Under Construction
|
||||
|
||||
The 0.4.0 version of LSIF is currently under construction.
|
||||
|
||||
## <a href="#lsifIntro" name="lsifIntro" class="anchor">Language Server Index Format</a>
|
||||
|
||||
The purpose of the Language Server Index Format (LSIF) is it to define a standard format for language servers or other programming tools to dump their knowledge about a workspace. This dump can later be used to answer language server [LSP](https://microsoft.github.io/language-server-protocol/) requests for the same workspace without running the language server itself. Since much of the information would be invalidated by a change to the workspace, the dumped information typically excludes requests used when mutating a document. So, for example, the result of a code complete request is typically not part of such a dump.
|
||||
|
|
@ -21,7 +17,7 @@ The purpose of the Language Server Index Format (LSIF) is it to define a standar
|
|||
|
||||
Up to version 0.4.0 the focus of the LSIF format was to ease the generation of the dump for language tool providers. However this made it very hard for consumers of the dump to efficiently import them into a DB unless the DB format one to one mapped to the LSIF format. This version of the specification tries to balance this by requiring tools providers to emit additional events of when certain data is ready to be consumed. It also adds support to partition data per document.
|
||||
|
||||
Since 0.4.0 changes some of the LSIF aspects more deeply an old 0.3.x version of the specification is available [here](./versions/specification-0-3-x.md)
|
||||
Since 0.4.0 changes some of the LSIF aspects more deeply an old 0.3.x version of the specification is available [here](https://github.com/microsoft/language-server-protocol/blob/master/indexFormat/versions/specification-0-3-x.md)
|
||||
|
||||
## <a href="#lsifMotivation" name="lsifMotivation" class="anchor">Motivation</a>
|
||||
|
||||
|
|
|
|||
BIN
_specifications/lsif/0.5.0/img/definitionResult.png
Normal file
BIN
_specifications/lsif/0.5.0/img/definitionResult.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
BIN
_specifications/lsif/0.5.0/img/foldingRange.png
Normal file
BIN
_specifications/lsif/0.5.0/img/foldingRange.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
_specifications/lsif/0.5.0/img/hoverResult.png
Normal file
BIN
_specifications/lsif/0.5.0/img/hoverResult.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
_specifications/lsif/0.5.0/img/referenceResult.png
Normal file
BIN
_specifications/lsif/0.5.0/img/referenceResult.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
_specifications/lsif/0.5.0/img/resultSet.png
Normal file
BIN
_specifications/lsif/0.5.0/img/resultSet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
114
_specifications/lsif/0.5.0/implementation.md
Normal file
114
_specifications/lsif/0.5.0/implementation.md
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# Building an LSIF exporter
|
||||
|
||||
With an LSIF (Language Server Index Format) exporter for your programming language of choice, you can use [Rich Code Navigation](https://code.visualstudio.com/blogs/2018/12/04/rich-navigation) on pull requests inside Visual Studio and Visual Studio Code. Users can navigate PRs with go-to-definition, find-all-references, and diagnostics, without requiring a local checkout.
|
||||
|
||||
In this guide, we cover how you can build an LSIF implementation that can be used for Rich Code Navigation. If you are new to LSIF, start with the [specification](specification.md), which covers motivation and implementation details of the protocol.
|
||||
|
||||
## The Rich Code Navigation scenario
|
||||
|
||||
With Rich Code Navigation, users use navigate features (peek definition, find all references, diagnostics, etc.) over PRs in their editor without having a local checkout. These navigation features are powered by a cloud language service, which uses an LSIF index. The index can be generated at a variety of places. For example, the index could be generated in a CI pipeline with the following steps:
|
||||
|
||||
1. User creates a new PR.
|
||||
1. The CI configured on the repo builds the PR.
|
||||
1. The LSIF exporter runs on CI and generates the LSIF index.
|
||||
|
||||
## LSIF exporters
|
||||
|
||||
| Language | Repository |
|
||||
|--|--|
|
||||
| TypeScript/JavaScript | [lsif-node](https://github.com/Microsoft/lsif-node) |
|
||||
| Java | [lsif-java](https://github.com/Microsoft/lsif-java) |
|
||||
| C# | |
|
||||
|
||||
> Are we missing an implementation? File a new issue on GitHub to add it here.
|
||||
|
||||
## LSIF exporter skeleton
|
||||
|
||||
As [detailed in the spec](specification.md#project-exports-and-external-imports), the LSIF exporter consists of two tools: the index exporter and the package linker.
|
||||
|
||||
### Index exporter
|
||||
|
||||
The index exporter generates an LSIF dump for a workspace by traversing through source files and storing LSP responses. For TypeScript/JavaScript, [`lsif-tsc`](https://github.com/Microsoft/lsif-node/tree/master/tsc) is the index exporter.
|
||||
|
||||
### Package linker
|
||||
|
||||
The package linker converts the LSIF output of the index exporter into a global friendly index. By using package metadata, export `moniker` vertices are linked to packages available on a registry. For instance, the `observable` export from the mobx dependency is linked to the mobx dependency available on NPM. The package metadata is used to create the `packageInformation` vertices that reference external packages.
|
||||
|
||||
For TypeScript/JavaScript, [`lsif-npm`](https://github.com/Microsoft/lsif-node/tree/master/npm) is the package manager linker for NPM.
|
||||
|
||||
## Testing and validation
|
||||
|
||||
### LSIF validation utility
|
||||
|
||||
The [`lsif-util`](https://github.com/microsoft/lsif-node/tree/master/util) tool can validate your generated LSIF output. Additionally, the tool can also be used to search the output and visualize via Graphviz.
|
||||
|
||||
### VS Code LSIF extension
|
||||
|
||||
With the [LSIF extension for VS Code](https://github.com/Microsoft/vscode-lsif-extension), you can dogfood an LSIF index to power navigation inside VS Code.
|
||||
|
||||
## Performance
|
||||
|
||||
Generating LSIF for a project is expected to take roughly the same time as compilation.
|
||||
|
||||
A primitive LSIF index exporter loops over source files, and for every symbol encountered, queries the language server for responses to LSP requests. With this approach, computing references can become very expensive: references are computed multiple times for the same symbol spread over files. This can be inefficient, depending on the language server implementation.
|
||||
|
||||
This approach can optimized by computing references only once for a symbol spread over files. The approach taken by the [lsif-tsc](https://github.com/Microsoft/lsif-node) tool is outlined below:
|
||||
|
||||
- Parse the project configuration to get source files
|
||||
- Loop over files, and run the following on the AST of each file
|
||||
- When you encounter a symbol, find out the binding of the symbol (declaration)
|
||||
- If the binding is local to the file, create a referencesResult data structure and add symbols with the same binding. When the parsing of the file is complete, we know that the referenceResult is complete and can be emitted.
|
||||
- If the binding is not local, keep result set in memory, and keep parsing other files.
|
||||
|
||||
## Recommended checklist
|
||||
|
||||
We have seen the following patterns work well in existing implementations.
|
||||
|
||||
### Method checklist
|
||||
|
||||
For an ideal integration with Rich Code Navigation, the following methods are required. For some languages, methods such as `textDocument/declaration` might not be applicable.
|
||||
|
||||
- [ ] `textDocument/hover`
|
||||
- [ ] `textDocument/definition`
|
||||
- [ ] `textDocument/references`
|
||||
- [ ] `textDocument/implementation`
|
||||
- [ ] `textDocument/declaration`
|
||||
- [ ] `textDocument/typeDefinition`
|
||||
- [ ] `textDocument/diagnostic`
|
||||
- [ ] Cross-repo navigation for dependencies
|
||||
|
||||
### Cross-platform
|
||||
|
||||
If the LSIF exporter does not work across platforms (Windows, Linux, Mac), platform dependencies should be called out.
|
||||
|
||||
### Output format
|
||||
|
||||
The LSIF exporter is expected to implement the [line-delimited JSON](https://en.wikipedia.org/wiki/JSON_streaming#Line-delimited_JSON) (also known as [JSON lines](http://jsonlines.org/)) output format: series of JSON objects (vertex or edge) separated by newline. Since JSON lines is suitable for streaming output and works better for larger repos, it is preferred over a JSON array output.
|
||||
|
||||
If an LSIF consumer requires a valid JSON array as input (for example, the VS Code LSIF extension), the JSON lines output can be converted into a JSON array by piping into a conversion tool.
|
||||
|
||||
```
|
||||
cat lsif.jsonl | sed '1s/^/[/;$!s/$/,/;$s/$/]/'
|
||||
```
|
||||
|
||||
If the LSIF exporter needs to log additional output, it is recommended to use `stderr`, since `stdout` is reserved for JSON line output.
|
||||
|
||||
### Project configuration
|
||||
|
||||
The LSIF index exporter can expose a flag to specify the root of the project directory. For example, the [TypeScript implementation](https://github.com/Microsoft/lsif-node) exposes the `--project` (`-p`) to specify the root of the tsconfig.json file.
|
||||
|
||||
```
|
||||
lsif-tsc --project ./frontend/tsconfig.json
|
||||
```
|
||||
|
||||
### Error behavior
|
||||
|
||||
The LSIF tool is expected to signal for error conditions, with a numeric exit code. A successful execution returns a 0, whereas error conditions (unable to build project, unable to find project file) return 1.
|
||||
|
||||
### Required documentation
|
||||
|
||||
Since LSIF is an evolving protocol, it is critical to document the [protocol version](specification.md#changelog) supported by the exporter.
|
||||
|
||||
## Support
|
||||
|
||||
Feel free to reach out to us for questions by raising an issue on GitHub.
|
||||
1228
_specifications/lsif/0.5.0/specification.md
Normal file
1228
_specifications/lsif/0.5.0/specification.md
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue