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}
337