Skip to main content

oak_lsp/
types.rs

1use oak_core::{Arc, Range, language::UniversalElementRole};
2pub use oak_folding::FoldingRange;
3
4/// A range in the source code.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct LspRange {
8    /// The start offset.
9    pub start: usize,
10    /// The end offset.
11    pub end: usize,
12}
13
14impl From<Range<usize>> for LspRange {
15    fn from(range: Range<usize>) -> Self {
16        Self { start: range.start, end: range.end }
17    }
18}
19
20impl From<LspRange> for Range<usize> {
21    fn from(range: LspRange) -> Self {
22        Self { start: range.start, end: range.end }
23    }
24}
25
26/// A location in a resource.
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29#[cfg_attr(feature = "serde", serde(bound(serialize = "R: serde::Serialize", deserialize = "R: serde::Deserialize<'de>")))]
30pub struct Location<R = Range<usize>> {
31    /// The URI of the resource.
32    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_arc_str"))]
33    pub uri: Arc<str>,
34    /// The range within the resource.
35    pub range: R,
36}
37
38/// A specialized location type for byte-based ranges.
39#[derive(Debug, Clone, PartialEq, Eq, Hash)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub struct LocationRange {
42    /// The URI of the resource.
43    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_arc_str"))]
44    pub uri: Arc<str>,
45    /// The byte range within the resource.
46    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
47    pub range: Range<usize>,
48}
49
50impl From<LocationRange> for Location<Range<usize>> {
51    fn from(loc: LocationRange) -> Self {
52        Self { uri: loc.uri, range: loc.range }
53    }
54}
55
56impl From<Location<Range<usize>>> for LocationRange {
57    fn from(loc: Location<Range<usize>>) -> Self {
58        Self { uri: loc.uri, range: loc.range }
59    }
60}
61
62impl From<oak_navigation::Location> for Location<Range<usize>> {
63    fn from(loc: oak_navigation::Location) -> Self {
64        Self { uri: loc.uri, range: loc.range }
65    }
66}
67
68impl From<oak_navigation::Location> for LocationRange {
69    fn from(loc: oak_navigation::Location) -> Self {
70        Self { uri: loc.uri, range: loc.range }
71    }
72}
73
74/// A source position with line, column, and offset.
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77pub struct SourcePosition {
78    /// Line number (1-indexed).
79    pub line: u32,
80    /// Column number (1-indexed).
81    pub column: u32,
82    /// Byte offset (0-indexed).
83    pub offset: usize,
84    /// Length of the token/element.
85    pub length: usize,
86}
87
88/// Represents a source location with an optional URL.
89#[derive(Debug, Clone, PartialEq, Eq, Hash)]
90#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
91pub struct SourceLocation {
92    /// Line number (1-indexed).
93    pub line: u32,
94    /// Column number (1-indexed).
95    pub column: u32,
96    /// Optional URL of the source file.
97    pub url: Option<url::Url>,
98}
99
100impl Default for SourceLocation {
101    /// Creates a default `SourceLocation` at line 1, column 1.
102    fn default() -> Self {
103        Self { line: 1, column: 1, url: None }
104    }
105}
106
107/// Represents a document highlight kind.
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
109#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
110pub enum DocumentHighlightKind {
111    /// A textual occurrence.
112    Text = 1,
113    /// Read-access of a symbol, like reading a variable.
114    Read = 2,
115    /// Write-access of a symbol, like writing to a variable.
116    Write = 3,
117}
118
119/// Represents a document highlight.
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122pub struct DocumentHighlight {
123    /// The range this highlight applies to.
124    pub range: LspRange,
125    /// The highlight kind, default is DocumentHighlightKind.Text.
126    pub kind: Option<DocumentHighlightKind>,
127}
128
129/// Represents a color in RGBA space.
130#[derive(Debug, Clone, Copy, PartialEq)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
132pub struct Color {
133    /// The red component of this color in the range [0-1].
134    pub red: f32,
135    /// The green component of this color in the range [0-1].
136    pub green: f32,
137    /// The blue component of this color in the range [0-1].
138    pub blue: f32,
139    /// The alpha component of this color in the range [0-1].
140    pub alpha: f32,
141}
142
143/// Represents a color range from a document.
144#[derive(Debug, Clone, Copy, PartialEq)]
145#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
146pub struct ColorInformation {
147    /// The range in the document where this color appears.
148    pub range: LspRange,
149    /// The actual color value for this range.
150    pub color: Color,
151}
152
153/// Represents hover information.
154#[derive(Debug, Clone)]
155#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
156pub struct Hover {
157    /// The hover's content as a markdown string.
158    pub contents: String,
159    /// An optional span to which this hover applies.
160    #[cfg_attr(feature = "serde", serde(with = "serde_range_opt"))]
161    pub range: Option<Range<usize>>,
162}
163
164#[cfg(feature = "serde")]
165mod serde_range_opt {
166    use super::*;
167    use serde::{Deserialize, Deserializer, Serializer};
168
169    pub fn serialize<S>(value: &Option<Range<usize>>, serializer: S) -> Result<S::Ok, S::Error>
170    where
171        S: Serializer,
172    {
173        match value {
174            Some(range) => oak_core::serde_range::serialize(range, serializer),
175            None => serializer.serialize_none(),
176        }
177    }
178
179    #[derive(Deserialize)]
180    struct RangeDef {
181        start: usize,
182        end: usize,
183    }
184
185    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Range<usize>>, D::Error>
186    where
187        D: Deserializer<'de>,
188    {
189        let opt: Option<RangeDef> = Option::deserialize(deserializer)?;
190        Ok(opt.map(|def| Range { start: def.start, end: def.end }))
191    }
192}
193
194/// Represents an item in the document structure (e.g., in an outline or breadcrumbs).
195#[derive(Debug, Clone)]
196#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
197pub struct StructureItem {
198    /// The name of this item (e.g., function name, class name).
199    pub name: String,
200    /// More detail about this item (e.g., function signature, type).
201    pub detail: Option<String>,
202    /// The universal role of this element.
203    pub role: UniversalElementRole,
204    /// The symbol kind.
205    pub kind: SymbolKind,
206    /// The range of the entire element in the source code.
207    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
208    pub range: Range<usize>,
209    /// The range that should be selected when clicking on this item.
210    /// Usually the range of the identifier.
211    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
212    pub selection_range: Range<usize>,
213    /// Whether this item is deprecated.
214    pub deprecated: bool,
215    /// Nested structure items (e.g., methods within a class).
216    pub children: Vec<StructureItem>,
217}
218
219/// Parameters for the `initialize` request.
220#[derive(Debug, Clone, Default)]
221#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
222pub struct InitializeParams {
223    /// The root URI of the workspace.
224    pub root_uri: Option<String>,
225    /// The workspace folders.
226    pub workspace_folders: Vec<WorkspaceFolder>,
227}
228
229/// A workspace folder.
230#[derive(Debug, Clone)]
231#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
232pub struct WorkspaceFolder {
233    /// The URI of the workspace folder.
234    pub uri: String,
235    /// The name of the workspace folder.
236    pub name: String,
237}
238
239/// Represents a symbol kind.
240#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
241#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
242pub enum SymbolKind {
243    /// File symbol kind.
244    File = 1,
245    /// Module symbol kind.
246    Module = 2,
247    /// Namespace symbol kind.
248    Namespace = 3,
249    /// Package symbol kind.
250    Package = 4,
251    /// Class symbol kind.
252    Class = 5,
253    /// Method symbol kind.
254    Method = 6,
255    /// Property symbol kind.
256    Property = 7,
257    /// Field symbol kind.
258    Field = 8,
259    /// Constructor symbol kind.
260    Constructor = 9,
261    /// Enum symbol kind.
262    Enum = 10,
263    /// Interface symbol kind.
264    Interface = 11,
265    /// Function symbol kind.
266    Function = 12,
267    /// Variable symbol kind.
268    Variable = 13,
269    /// Constant symbol kind.
270    Constant = 14,
271    /// String symbol kind.
272    String = 15,
273    /// Number symbol kind.
274    Number = 16,
275    /// Boolean symbol kind.
276    Boolean = 17,
277    /// Array symbol kind.
278    Array = 18,
279    /// Object symbol kind.
280    Object = 19,
281    /// Key symbol kind.
282    Key = 20,
283    /// Null symbol kind.
284    Null = 21,
285    /// EnumMember symbol kind.
286    EnumMember = 22,
287    /// Struct symbol kind.
288    Struct = 23,
289    /// Event symbol kind.
290    Event = 24,
291    /// Operator symbol kind.
292    Operator = 25,
293    /// TypeParameter symbol kind.
294    TypeParameter = 26,
295}
296
297/// Represents a workspace symbol.
298#[derive(Debug, Clone)]
299#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
300pub struct WorkspaceSymbol {
301    /// The name of the symbol.
302    pub name: String,
303    /// The kind of the symbol.
304    pub kind: SymbolKind,
305    /// The location of the symbol.
306    pub location: LocationRange,
307    /// The name of the container this symbol is in.
308    pub container_name: Option<String>,
309}
310
311/// Represents information about a symbol (e.g., function, variable, class).
312#[derive(Debug, Clone)]
313#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
314pub struct SymbolInformation {
315    /// The name of the symbol.
316    pub name: String,
317    /// The kind of the symbol.
318    pub kind: SymbolKind,
319    /// The location of the symbol.
320    pub location: LocationRange,
321    /// The name of the container this symbol is in.
322    pub container_name: Option<String>,
323}
324
325/// Represents a change to the workspace.
326#[derive(Debug, Clone, Default)]
327#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
328pub struct WorkspaceEdit {
329    /// The changes to the workspace.
330    pub changes: std::collections::HashMap<String, Vec<TextEdit>>,
331}
332
333/// Represents a text edit.
334#[derive(Debug, Clone)]
335#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
336pub struct TextEdit {
337    /// The range of the text edit.
338    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
339    pub range: Range<usize>,
340    /// The new text.
341    pub new_text: String,
342}
343
344/// Represents a completion item.
345#[derive(Debug, Clone)]
346#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
347pub struct CompletionItem {
348    /// The label of the completion item.
349    pub label: String,
350    /// The kind of the completion item.
351    pub kind: Option<CompletionItemKind>,
352    /// A human-readable string with additional information about this item.
353    pub detail: Option<String>,
354    /// A human-readable string that contains documentation about this item.
355    pub documentation: Option<String>,
356    /// The text that should be inserted when selecting this completion item.
357    pub insert_text: Option<String>,
358}
359
360/// Represents a completion item kind.
361#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
362#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
363pub enum CompletionItemKind {
364    /// Text completion.
365    Text = 1,
366    /// Method completion.
367    Method = 2,
368    /// Function completion.
369    Function = 3,
370    /// Constructor completion.
371    Constructor = 4,
372    /// Field completion.
373    Field = 5,
374    /// Variable completion.
375    Variable = 6,
376    /// Class completion.
377    Class = 7,
378    /// Interface completion.
379    Interface = 8,
380    /// Module completion.
381    Module = 9,
382    /// Property completion.
383    Property = 10,
384    /// Unit completion.
385    Unit = 11,
386    /// Value completion.
387    Value = 12,
388    /// Enum completion.
389    Enum = 13,
390    /// Keyword completion.
391    Keyword = 14,
392    /// Snippet completion.
393    Snippet = 15,
394    /// Color completion.
395    Color = 16,
396    /// File completion.
397    File = 17,
398    /// Reference completion.
399    Reference = 18,
400    /// Folder completion.
401    Folder = 19,
402    /// EnumMember completion.
403    EnumMember = 20,
404    /// Constant completion.
405    Constant = 21,
406    /// Struct completion.
407    Struct = 22,
408    /// Event completion.
409    Event = 23,
410    /// Operator completion.
411    Operator = 24,
412    /// TypeParameter completion.
413    TypeParameter = 25,
414}
415
416/// Represents a diagnostic.
417#[derive(Debug, Clone)]
418#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
419pub struct Diagnostic {
420    /// The range of the diagnostic.
421    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
422    pub range: Range<usize>,
423    /// The severity of the diagnostic.
424    pub severity: Option<DiagnosticSeverity>,
425    /// The diagnostic's code.
426    pub code: Option<String>,
427    /// The source of the diagnostic.
428    pub source: Option<String>,
429    /// The diagnostic's message.
430    pub message: String,
431}
432
433/// Represents a diagnostic severity.
434#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
435#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
436pub enum DiagnosticSeverity {
437    /// Reports an error.
438    Error = 1,
439    /// Reports a warning.
440    Warning = 2,
441    /// Reports an information.
442    Information = 3,
443    /// Reports a hint.
444    Hint = 4,
445}
446
447/// Represents a semantic token.
448#[derive(Debug, Clone)]
449#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
450pub struct SemanticToken {
451    /// The line delta relative to the previous token.
452    pub delta_line: u32,
453    /// The start character delta relative to the previous token.
454    pub delta_start: u32,
455    /// The length of the token.
456    pub length: u32,
457    /// The token type index.
458    pub token_type: u32,
459    /// The token modifiers bitset.
460    pub token_modifiers_bitset: u32,
461}
462
463/// Represents semantic tokens.
464#[derive(Debug, Clone)]
465#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
466pub struct SemanticTokens {
467    /// An optional result ID.
468    pub result_id: Option<String>,
469    /// The actual semantic token data.
470    pub data: Vec<SemanticToken>,
471}
472
473/// Represents a selection range.
474#[derive(Debug, Clone)]
475#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
476pub struct SelectionRange {
477    /// The range of the selection.
478    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
479    pub range: Range<usize>,
480    /// The parent selection range.
481    pub parent: Option<Box<SelectionRange>>,
482}
483
484/// Represents parameter information.
485#[derive(Debug, Clone)]
486#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
487pub struct ParameterInformation {
488    /// The label of the parameter.
489    pub label: String,
490    /// The documentation of the parameter.
491    pub documentation: Option<String>,
492}
493
494/// Represents signature information.
495#[derive(Debug, Clone)]
496#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
497pub struct SignatureInformation {
498    /// The label of the signature.
499    pub label: String,
500    /// The documentation of the signature.
501    pub documentation: Option<String>,
502    /// The parameters of the signature.
503    pub parameters: Option<Vec<ParameterInformation>>,
504    /// The index of the active parameter.
505    pub active_parameter: Option<u32>,
506}
507
508/// Represents signature help.
509#[derive(Debug, Clone)]
510#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
511pub struct SignatureHelp {
512    /// The signatures.
513    pub signatures: Vec<SignatureInformation>,
514    /// The index of the active signature.
515    pub active_signature: Option<u32>,
516    /// The index of the active parameter.
517    pub active_parameter: Option<u32>,
518}
519
520/// Represents an inlay hint.
521#[derive(Debug, Clone)]
522#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
523pub struct InlayHint {
524    /// The position of the inlay hint.
525    pub position: SourcePosition,
526    /// The label of the inlay hint.
527    pub label: String,
528    /// The kind of the inlay hint.
529    pub kind: Option<InlayHintKind>,
530    /// The tooltip of the inlay hint.
531    pub tooltip: Option<String>,
532    /// Padding before the hint.
533    pub padding_left: Option<bool>,
534    /// Padding after the hint.
535    pub padding_right: Option<bool>,
536}
537
538/// Represents an inlay hint kind.
539#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
540#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
541pub enum InlayHintKind {
542    /// Type inlay hint.
543    Type = 1,
544    /// Parameter inlay hint.
545    Parameter = 2,
546}
547
548/// Represents a code action.
549#[derive(Debug, Clone)]
550#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
551pub struct CodeAction {
552    /// The title of the code action.
553    pub title: String,
554    /// The kind of the code action.
555    pub kind: Option<String>,
556    /// The diagnostics this code action resolves.
557    pub diagnostics: Option<Vec<Diagnostic>>,
558    /// The workspace edit this code action performs.
559    pub edit: Option<WorkspaceEdit>,
560    /// A command this code action executes.
561    pub command: Option<Command>,
562    /// Whether this code action is preferred.
563    pub is_preferred: Option<bool>,
564    /// Why this code action is disabled.
565    pub disabled: Option<CodeActionDisabled>,
566}
567
568/// Represents a disabled code action.
569#[derive(Debug, Clone)]
570#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
571pub struct CodeActionDisabled {
572    /// The reason why the code action is disabled.
573    pub reason: String,
574}
575
576/// Represents a command.
577#[derive(Debug, Clone)]
578#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
579pub struct Command {
580    /// The title of the command.
581    pub title: String,
582    /// The identifier of the command.
583    pub command: String,
584    /// The arguments of the command.
585    pub arguments: Option<Vec<serde_json::Value>>,
586}
587
588impl From<UniversalElementRole> for SymbolKind {
589    fn from(role: UniversalElementRole) -> Self {
590        match role {
591            UniversalElementRole::Root => SymbolKind::File,
592            UniversalElementRole::Container => SymbolKind::Module,
593            UniversalElementRole::Definition => SymbolKind::Function,
594            UniversalElementRole::Binding => SymbolKind::Variable,
595            UniversalElementRole::Reference => SymbolKind::Variable,
596            UniversalElementRole::Typing => SymbolKind::Class,
597            UniversalElementRole::Statement => SymbolKind::Function,
598            UniversalElementRole::Expression => SymbolKind::Variable,
599            UniversalElementRole::Call => SymbolKind::Function,
600            UniversalElementRole::Metadata => SymbolKind::Property,
601            UniversalElementRole::Attribute => SymbolKind::Property,
602            UniversalElementRole::Documentation => SymbolKind::String,
603            UniversalElementRole::Value => SymbolKind::Constant,
604            UniversalElementRole::Error => SymbolKind::Null,
605            _ => SymbolKind::Function,
606        }
607    }
608}
609
610impl From<oak_symbols::SymbolInformation> for WorkspaceSymbol {
611    fn from(s: oak_symbols::SymbolInformation) -> Self {
612        Self { name: s.name, kind: SymbolKind::from(s.role), location: LocationRange { uri: s.uri, range: s.range }, container_name: s.container_name }
613    }
614}
615
616impl From<oak_symbols::SymbolInformation> for StructureItem {
617    fn from(s: oak_symbols::SymbolInformation) -> Self {
618        Self { name: s.name, detail: None, role: s.role, kind: SymbolKind::from(s.role), range: s.range.clone(), selection_range: s.range.clone(), deprecated: false, children: vec![] }
619    }
620}