lsp_types/
lsif.rs

1//! Types of Language Server Index Format (LSIF). LSIF is a standard format
2//! for language servers or other programming tools to dump their knowledge
3//! about a workspace.
4//!
5//! Based on <https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/>
6
7use crate::{Range, Url};
8use serde::{Deserialize, Serialize};
9
10pub type Id = crate::NumberOrString;
11
12#[derive(Debug, PartialEq, Serialize, Deserialize)]
13#[serde(untagged)]
14pub enum LocationOrRangeId {
15    Location(crate::Location),
16    RangeId(Id),
17}
18
19#[derive(Debug, PartialEq, Serialize, Deserialize)]
20#[serde(rename_all = "camelCase")]
21pub struct Entry {
22    pub id: Id,
23    #[serde(flatten)]
24    pub data: Element,
25}
26
27#[derive(Debug, PartialEq, Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29#[serde(tag = "type")]
30pub enum Element {
31    Vertex(Vertex),
32    Edge(Edge),
33}
34
35#[derive(Debug, PartialEq, Serialize, Deserialize)]
36pub struct ToolInfo {
37    pub name: String,
38    #[serde(default = "Default::default")]
39    #[serde(skip_serializing_if = "Vec::is_empty")]
40    pub args: Vec<String>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub version: Option<String>,
43}
44
45#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Copy)]
46pub enum Encoding {
47    /// Currently only 'utf-16' is supported due to the limitations in LSP.
48    #[serde(rename = "utf-16")]
49    Utf16,
50}
51
52#[derive(Debug, PartialEq, Serialize, Deserialize)]
53pub struct RangeBasedDocumentSymbol {
54    pub id: Id,
55    #[serde(default = "Default::default")]
56    #[serde(skip_serializing_if = "Vec::is_empty")]
57    pub children: Vec<RangeBasedDocumentSymbol>,
58}
59
60#[derive(Debug, PartialEq, Serialize, Deserialize)]
61#[serde(rename_all = "camelCase")]
62#[serde(untagged)]
63pub enum DocumentSymbolOrRangeBasedVec {
64    DocumentSymbol(Vec<crate::DocumentSymbol>),
65    RangeBased(Vec<RangeBasedDocumentSymbol>),
66}
67
68#[derive(Debug, PartialEq, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct DefinitionTag {
71    /// The text covered by the range     
72    text: String,
73    /// The symbol kind.
74    kind: crate::SymbolKind,
75    /// Indicates if this symbol is deprecated.
76    #[serde(default)]
77    #[serde(skip_serializing_if = "std::ops::Not::not")]
78    deprecated: bool,
79    /// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code.
80    /// The range must be included in fullRange.
81    full_range: Range,
82    /// Optional detail information for the definition.
83    #[serde(skip_serializing_if = "Option::is_none")]
84    detail: Option<String>,
85}
86
87#[derive(Debug, PartialEq, Serialize, Deserialize)]
88#[serde(rename_all = "camelCase")]
89pub struct DeclarationTag {
90    /// The text covered by the range     
91    text: String,
92    /// The symbol kind.
93    kind: crate::SymbolKind,
94    /// Indicates if this symbol is deprecated.
95    #[serde(default)]
96    deprecated: bool,
97    /// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code.
98    /// The range must be included in fullRange.
99    full_range: Range,
100    /// Optional detail information for the definition.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    detail: Option<String>,
103}
104
105#[derive(Debug, PartialEq, Serialize, Deserialize)]
106#[serde(rename_all = "camelCase")]
107pub struct ReferenceTag {
108    text: String,
109}
110
111#[derive(Debug, PartialEq, Serialize, Deserialize)]
112#[serde(rename_all = "camelCase")]
113pub struct UnknownTag {
114    text: String,
115}
116
117#[derive(Debug, PartialEq, Serialize, Deserialize)]
118#[serde(rename_all = "camelCase")]
119#[serde(tag = "type")]
120pub enum RangeTag {
121    Definition(DefinitionTag),
122    Declaration(DeclarationTag),
123    Reference(ReferenceTag),
124    Unknown(UnknownTag),
125}
126
127#[derive(Debug, PartialEq, Serialize, Deserialize)]
128#[serde(rename_all = "camelCase")]
129#[serde(tag = "label")]
130pub enum Vertex {
131    MetaData(MetaData),
132    /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex>
133    Project(Project),
134    Document(Document),
135    /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#ranges>
136    Range {
137        #[serde(flatten)]
138        range: Range,
139        #[serde(skip_serializing_if = "Option::is_none")]
140        tag: Option<RangeTag>,
141    },
142    /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set>
143    ResultSet(ResultSet),
144    Moniker(crate::Moniker),
145    PackageInformation(PackageInformation),
146
147    #[serde(rename = "$event")]
148    Event(Event),
149
150    DefinitionResult,
151    DeclarationResult,
152    TypeDefinitionResult,
153    ReferenceResult,
154    ImplementationResult,
155    FoldingRangeResult {
156        result: Vec<crate::FoldingRange>,
157    },
158    HoverResult {
159        result: crate::Hover,
160    },
161    DocumentSymbolResult {
162        result: DocumentSymbolOrRangeBasedVec,
163    },
164    DocumentLinkResult {
165        result: Vec<crate::DocumentLink>,
166    },
167    DiagnosticResult {
168        result: Vec<crate::Diagnostic>,
169    },
170}
171
172#[derive(Debug, PartialEq, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub enum EventKind {
175    Begin,
176    End,
177}
178
179#[derive(Debug, PartialEq, Serialize, Deserialize)]
180#[serde(rename_all = "camelCase")]
181pub enum EventScope {
182    Document,
183    Project,
184}
185
186#[derive(Debug, PartialEq, Serialize, Deserialize)]
187pub struct Event {
188    pub kind: EventKind,
189    pub scope: EventScope,
190    pub data: Id,
191}
192
193#[derive(Debug, PartialEq, Serialize, Deserialize)]
194#[serde(rename_all = "camelCase")]
195#[serde(tag = "label")]
196pub enum Edge {
197    Contains(EdgeDataMultiIn),
198    Moniker(EdgeData),
199    NextMoniker(EdgeData),
200    Next(EdgeData),
201    PackageInformation(EdgeData),
202    Item(Item),
203
204    // Methods
205    #[serde(rename = "textDocument/definition")]
206    Definition(EdgeData),
207    #[serde(rename = "textDocument/declaration")]
208    Declaration(EdgeData),
209    #[serde(rename = "textDocument/hover")]
210    Hover(EdgeData),
211    #[serde(rename = "textDocument/references")]
212    References(EdgeData),
213    #[serde(rename = "textDocument/implementation")]
214    Implementation(EdgeData),
215    #[serde(rename = "textDocument/typeDefinition")]
216    TypeDefinition(EdgeData),
217    #[serde(rename = "textDocument/foldingRange")]
218    FoldingRange(EdgeData),
219    #[serde(rename = "textDocument/documentLink")]
220    DocumentLink(EdgeData),
221    #[serde(rename = "textDocument/documentSymbol")]
222    DocumentSymbol(EdgeData),
223    #[serde(rename = "textDocument/diagnostic")]
224    Diagnostic(EdgeData),
225}
226
227#[derive(Debug, PartialEq, Serialize, Deserialize)]
228#[serde(rename_all = "camelCase")]
229pub struct EdgeData {
230    pub in_v: Id,
231    pub out_v: Id,
232}
233
234#[derive(Debug, PartialEq, Serialize, Deserialize)]
235#[serde(rename_all = "camelCase")]
236pub struct EdgeDataMultiIn {
237    pub in_vs: Vec<Id>,
238    pub out_v: Id,
239}
240
241#[derive(Debug, PartialEq, Serialize, Deserialize)]
242#[serde(untagged)]
243pub enum DefinitionResultType {
244    Scalar(LocationOrRangeId),
245    Array(LocationOrRangeId),
246}
247
248#[derive(Debug, PartialEq, Serialize, Deserialize)]
249#[serde(rename_all = "camelCase")]
250pub enum ItemKind {
251    Declarations,
252    Definitions,
253    References,
254    ReferenceResults,
255    ImplementationResults,
256}
257
258#[derive(Debug, PartialEq, Serialize, Deserialize)]
259#[serde(rename_all = "camelCase")]
260pub struct Item {
261    pub document: Id,
262    #[serde(skip_serializing_if = "Option::is_none")]
263    pub property: Option<ItemKind>,
264    #[serde(flatten)]
265    pub edge_data: EdgeDataMultiIn,
266}
267
268#[derive(Debug, PartialEq, Serialize, Deserialize)]
269#[serde(rename_all = "camelCase")]
270pub struct Document {
271    pub uri: Url,
272    pub language_id: String,
273}
274
275/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set>
276#[derive(Debug, PartialEq, Serialize, Deserialize)]
277#[serde(rename_all = "camelCase")]
278pub struct ResultSet {
279    #[serde(skip_serializing_if = "Option::is_none")]
280    pub key: Option<String>,
281}
282
283/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex>
284#[derive(Debug, PartialEq, Serialize, Deserialize)]
285#[serde(rename_all = "camelCase")]
286pub struct Project {
287    #[serde(skip_serializing_if = "Option::is_none")]
288    pub resource: Option<Url>,
289    #[serde(skip_serializing_if = "Option::is_none")]
290    pub content: Option<String>,
291    pub kind: String,
292}
293
294#[derive(Debug, PartialEq, Serialize, Deserialize)]
295#[serde(rename_all = "camelCase")]
296pub struct MetaData {
297    /// The version of the LSIF format using semver notation. See <https://semver.org/>. Please note
298    /// the version numbers starting with 0 don't adhere to semver and adopters have to assume
299    /// that each new version is breaking.
300    pub version: String,
301
302    /// The project root (in form of an URI) used to compute this dump.
303    pub project_root: Url,
304
305    /// The string encoding used to compute line and character values in
306    /// positions and ranges.
307    pub position_encoding: Encoding,
308
309    /// Information about the tool that created the dump
310    #[serde(skip_serializing_if = "Option::is_none")]
311    pub tool_info: Option<ToolInfo>,
312}
313
314#[derive(Debug, PartialEq, Serialize, Deserialize)]
315#[serde(rename_all = "camelCase")]
316pub struct Repository {
317    pub r#type: String,
318    pub url: String,
319    #[serde(skip_serializing_if = "Option::is_none")]
320    pub commit_id: Option<String>,
321}
322
323#[derive(Debug, PartialEq, Serialize, Deserialize)]
324#[serde(rename_all = "camelCase")]
325pub struct PackageInformation {
326    pub name: String,
327    pub manager: String,
328    #[serde(skip_serializing_if = "Option::is_none")]
329    pub uri: Option<Url>,
330    #[serde(skip_serializing_if = "Option::is_none")]
331    pub content: Option<String>,
332    #[serde(skip_serializing_if = "Option::is_none")]
333    pub repository: Option<Repository>,
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub version: Option<String>,
336}