tinymist_query/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
//! # tinymist-query
//!
//! **Note: this crate is under development. it currently doesn't ensure stable
//! APIs, and heavily depending on some unstable crates.**
//!
//! This crate provides a set of APIs to query the information about the source
//! code. Currently it provides:
//! + language queries defined by the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/).

pub use analysis::{CompletionFeat, LocalContext, LocalContextGuard, LspWorldExt};
pub use completion::{CompletionRequest, PostfixSnippet};
pub use typlite::ColorTheme;
pub use upstream::with_vm;

pub use check::*;
pub use code_action::*;
pub use code_context::*;
pub use code_lens::*;
pub use color_presentation::*;
pub use diagnostics::*;
pub use document_color::*;
pub use document_highlight::*;
pub use document_link::*;
pub use document_metrics::*;
pub use document_symbol::*;
pub use folding_range::*;
pub use goto_declaration::*;
pub use goto_definition::*;
pub use hover::*;
pub use inlay_hint::*;
pub use jump::*;
pub use lsp_typst_boundary::*;
pub use on_enter::*;
pub use prepare_rename::*;
pub use references::*;
pub use rename::*;
pub use selection_range::*;
pub use semantic_tokens_delta::*;
pub use semantic_tokens_full::*;
pub use signature_help::*;
pub use symbol::*;
pub use will_rename_files::*;
pub use workspace_label::*;

pub mod analysis;
pub mod docs;
pub mod package;
pub mod syntax;
pub mod testing;
pub use tinymist_analysis::{ty, upstream};

/// The physical position in a document.
pub type FramePosition = typst::layout::Position;

mod adt;
mod lsp_typst_boundary;
mod prelude;

mod bib;
mod check;
mod code_action;
mod code_context;
mod code_lens;
mod color_presentation;
mod completion;
mod diagnostics;
mod document_color;
mod document_highlight;
mod document_link;
mod document_metrics;
mod document_symbol;
mod folding_range;
mod goto_declaration;
mod goto_definition;
mod hover;
mod inlay_hint;
mod jump;
mod on_enter;
mod prepare_rename;
mod references;
mod rename;
mod selection_range;
mod semantic_tokens_delta;
mod semantic_tokens_full;
mod signature_help;
mod symbol;
mod will_rename_files;
mod workspace_label;

use typst::syntax::Source;

use tinymist_analysis::{adt::interner::Interned, log_debug_ct};
use tinymist_project::LspComputeGraph;

/// A reference to the interned string
pub(crate) type StrRef = Interned<str>;

/// A request handler with given syntax information.
pub trait SyntaxRequest {
    /// The response type of the request.
    type Response;

    /// Request the information from the given source.
    fn request(
        self,
        source: &Source,
        positing_encoding: PositionEncoding,
    ) -> Option<Self::Response>;
}

/// A request handler with given (semantic) analysis context.
pub trait SemanticRequest {
    /// The response type of the request.
    type Response;

    /// Request the information from the given context.
    fn request(self, ctx: &mut LocalContext) -> Option<Self::Response>;
}

/// A request handler with given (semantic) analysis context and a project
/// snapshot.
pub trait StatefulRequest {
    /// The response type of the request.
    type Response;

    /// Request the information from the given context.
    fn request(self, ctx: &mut LocalContext, graph: LspComputeGraph) -> Option<Self::Response>;
}

#[allow(missing_docs)]
mod polymorphic {
    use completion::CompletionList;
    use lsp_types::TextEdit;
    use serde::{Deserialize, Serialize};
    use tinymist_project::ProjectTask;
    use typst::foundations::Dict;

    use super::prelude::*;
    use super::*;

    #[derive(Debug, Clone)]
    pub struct OnExportRequest {
        /// The path of the document to export.
        pub path: PathBuf,
        /// The export task to run.
        pub task: ProjectTask,
        /// Whether to open the exported file(s) after the export is done.
        pub open: bool,
    }

    #[derive(Debug, Clone)]
    pub struct FormattingRequest {
        /// The path of the document to get semantic tokens for.
        pub path: PathBuf,
    }

    #[derive(Debug, Clone)]
    pub struct ServerInfoRequest {}

    #[derive(Debug, Clone, Serialize, Deserialize)]
    #[serde(rename_all = "camelCase")]
    pub struct ServerInfoResponse {
        pub root: Option<PathBuf>,
        pub font_paths: Vec<PathBuf>,
        pub inputs: Dict,
        pub stats: HashMap<String, String>,
    }

    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    pub enum FoldRequestFeature {
        PinnedFirst,
        Unique,
        Mergeable,
        ContextFreeUnique,
    }

    #[derive(Debug, Clone, strum::IntoStaticStr)]
    pub enum CompilerQueryRequest {
        OnExport(OnExportRequest),
        Hover(HoverRequest),
        GotoDefinition(GotoDefinitionRequest),
        GotoDeclaration(GotoDeclarationRequest),
        References(ReferencesRequest),
        InlayHint(InlayHintRequest),
        DocumentColor(DocumentColorRequest),
        DocumentLink(DocumentLinkRequest),
        DocumentHighlight(DocumentHighlightRequest),
        ColorPresentation(ColorPresentationRequest),
        CodeAction(CodeActionRequest),
        CodeLens(CodeLensRequest),
        Completion(CompletionRequest),
        SignatureHelp(SignatureHelpRequest),
        Rename(RenameRequest),
        WillRenameFiles(WillRenameFilesRequest),
        PrepareRename(PrepareRenameRequest),
        DocumentSymbol(DocumentSymbolRequest),
        Symbol(SymbolRequest),
        SemanticTokensFull(SemanticTokensFullRequest),
        SemanticTokensDelta(SemanticTokensDeltaRequest),
        Formatting(FormattingRequest),
        FoldingRange(FoldingRangeRequest),
        SelectionRange(SelectionRangeRequest),
        InteractCodeContext(InteractCodeContextRequest),

        OnEnter(OnEnterRequest),

        DocumentMetrics(DocumentMetricsRequest),
        WorkspaceLabel(WorkspaceLabelRequest),
        ServerInfo(ServerInfoRequest),
    }

    impl CompilerQueryRequest {
        pub fn fold_feature(&self) -> FoldRequestFeature {
            use FoldRequestFeature::*;
            match self {
                Self::OnExport(..) => Mergeable,
                Self::Hover(..) => PinnedFirst,
                Self::GotoDefinition(..) => PinnedFirst,
                Self::GotoDeclaration(..) => PinnedFirst,
                Self::References(..) => PinnedFirst,
                Self::InlayHint(..) => Unique,
                Self::DocumentColor(..) => PinnedFirst,
                Self::DocumentLink(..) => PinnedFirst,
                Self::DocumentHighlight(..) => PinnedFirst,
                Self::ColorPresentation(..) => ContextFreeUnique,
                Self::CodeAction(..) => Unique,
                Self::CodeLens(..) => Unique,
                Self::Completion(..) => Mergeable,
                Self::SignatureHelp(..) => PinnedFirst,
                Self::Rename(..) => Mergeable,
                Self::WillRenameFiles(..) => Mergeable,
                Self::PrepareRename(..) => Mergeable,
                Self::DocumentSymbol(..) => ContextFreeUnique,
                Self::WorkspaceLabel(..) => Mergeable,
                Self::Symbol(..) => Mergeable,
                Self::SemanticTokensFull(..) => PinnedFirst,
                Self::SemanticTokensDelta(..) => PinnedFirst,
                Self::Formatting(..) => ContextFreeUnique,
                Self::FoldingRange(..) => ContextFreeUnique,
                Self::SelectionRange(..) => ContextFreeUnique,
                Self::InteractCodeContext(..) => PinnedFirst,

                Self::OnEnter(..) => ContextFreeUnique,

                Self::DocumentMetrics(..) => PinnedFirst,
                Self::ServerInfo(..) => Mergeable,
            }
        }

        pub fn associated_path(&self) -> Option<&Path> {
            Some(match self {
                Self::OnExport(..) => return None,
                Self::Hover(req) => &req.path,
                Self::GotoDefinition(req) => &req.path,
                Self::GotoDeclaration(req) => &req.path,
                Self::References(req) => &req.path,
                Self::InlayHint(req) => &req.path,
                Self::DocumentColor(req) => &req.path,
                Self::DocumentLink(req) => &req.path,
                Self::DocumentHighlight(req) => &req.path,
                Self::ColorPresentation(req) => &req.path,
                Self::CodeAction(req) => &req.path,
                Self::CodeLens(req) => &req.path,
                Self::Completion(req) => &req.path,
                Self::SignatureHelp(req) => &req.path,
                Self::Rename(req) => &req.path,
                Self::WillRenameFiles(..) => return None,
                Self::PrepareRename(req) => &req.path,
                Self::DocumentSymbol(req) => &req.path,
                Self::Symbol(..) => return None,
                Self::WorkspaceLabel(..) => return None,
                Self::SemanticTokensFull(req) => &req.path,
                Self::SemanticTokensDelta(req) => &req.path,
                Self::Formatting(req) => &req.path,
                Self::FoldingRange(req) => &req.path,
                Self::SelectionRange(req) => &req.path,
                Self::InteractCodeContext(req) => &req.path,

                Self::OnEnter(req) => &req.path,

                Self::DocumentMetrics(req) => &req.path,
                Self::ServerInfo(..) => return None,
            })
        }
    }

    #[derive(Debug, Clone, Serialize, Deserialize)]
    #[serde(untagged)]
    pub enum CompilerQueryResponse {
        OnExport(Option<PathBuf>),
        Hover(Option<Hover>),
        GotoDefinition(Option<GotoDefinitionResponse>),
        GotoDeclaration(Option<GotoDeclarationResponse>),
        References(Option<Vec<LspLocation>>),
        InlayHint(Option<Vec<InlayHint>>),
        DocumentColor(Option<Vec<ColorInformation>>),
        DocumentLink(Option<Vec<DocumentLink>>),
        DocumentHighlight(Option<Vec<DocumentHighlight>>),
        ColorPresentation(Option<Vec<ColorPresentation>>),
        CodeAction(Option<Vec<CodeActionOrCommand>>),
        CodeLens(Option<Vec<CodeLens>>),
        Completion(Option<CompletionList>),
        SignatureHelp(Option<SignatureHelp>),
        PrepareRename(Option<PrepareRenameResponse>),
        Rename(Option<WorkspaceEdit>),
        WillRenameFiles(Option<WorkspaceEdit>),
        DocumentSymbol(Option<DocumentSymbolResponse>),
        Symbol(Option<Vec<SymbolInformation>>),
        WorkspaceLabel(Option<Vec<SymbolInformation>>),
        SemanticTokensFull(Option<SemanticTokensResult>),
        SemanticTokensDelta(Option<SemanticTokensFullDeltaResult>),
        Formatting(Option<Vec<TextEdit>>),
        FoldingRange(Option<Vec<FoldingRange>>),
        SelectionRange(Option<Vec<SelectionRange>>),
        InteractCodeContext(Option<Vec<Option<InteractCodeContextResponse>>>),

        OnEnter(Option<Vec<TextEdit>>),

        DocumentMetrics(Option<DocumentMetricsResponse>),
        ServerInfo(Option<HashMap<String, ServerInfoResponse>>),
    }
}

pub use polymorphic::*;

#[cfg(test)]
mod tests;