summaryrefslogtreecommitdiff
path: root/support/texlab/src/lib.rs
blob: 9a7b587ab82808f84b867549be149de0566c5ea5 (plain)
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
#![allow(clippy::needless_lifetimes)]

pub(crate) mod citation;
mod client;
pub mod db;
pub(crate) mod distro;
pub mod features;
mod options;
pub mod parser;
mod server;
pub mod syntax;
pub(crate) mod util;

pub use self::{options::*, server::Server};

#[salsa::jar(db = Db)]
pub struct Jar(
    db::Word,
    db::Location,
    db::Location_path,
    db::Contents,
    db::Contents_line_index,
    db::LinterData,
    db::Document,
    db::Document_parse,
    db::Document_can_be_index,
    db::Document_can_be_built,
    db::parse::TexDocumentData,
    db::parse::TexDocumentData_analyze,
    db::parse::BibDocumentData,
    db::parse::LogDocumentData,
    db::analysis::TexLink,
    db::analysis::label::Number,
    db::analysis::label::Name,
    db::analysis::TheoremEnvironment,
    db::analysis::GraphicsPath,
    db::analysis::TexAnalysis,
    db::MissingDependencies,
    db::hidden_dependency,
    db::source_dependency,
    db::dependency_graph,
    db::Workspace,
    db::Workspace_working_dir,
    db::Workspace_output_dir,
    db::Workspace_parents,
    db::Workspace_related,
    db::Workspace_number_of_label,
    db::diagnostics::tex::collect,
    db::diagnostics::bib::collect,
    db::diagnostics::log::collect,
    db::diagnostics::collect,
    db::diagnostics::collect_filtered,
);

pub trait Db: salsa::DbWithJar<Jar> {}

impl<DB> Db for DB where DB: ?Sized + salsa::DbWithJar<Jar> {}

#[salsa::db(crate::Jar)]
pub struct Database {
    storage: salsa::Storage<Self>,
}

impl Default for Database {
    fn default() -> Self {
        let storage = salsa::Storage::default();
        let db = Self { storage };
        db::Workspace::new(
            &db,
            Default::default(),
            Default::default(),
            Default::default(),
            Default::default(),
            Default::default(),
            Default::default(),
        );

        db
    }
}

impl salsa::Database for Database {}

impl salsa::ParallelDatabase for Database {
    fn snapshot(&self) -> salsa::Snapshot<Self> {
        salsa::Snapshot::new(Self {
            storage: self.storage.snapshot(),
        })
    }
}

pub(crate) fn normalize_uri(uri: &mut lsp_types::Url) {
    fn fix_drive_letter(text: &str) -> Option<String> {
        if !text.is_ascii() {
            return None;
        }

        match &text[1..] {
            ":" => Some(text.to_ascii_uppercase()),
            "%3A" | "%3a" => Some(format!("{}:", text[0..1].to_ascii_uppercase())),
            _ => None,
        }
    }

    if let Some(mut segments) = uri.path_segments() {
        if let Some(mut path) = segments.next().and_then(fix_drive_letter) {
            for segment in segments {
                path.push('/');
                path.push_str(segment);
            }

            uri.set_path(&path);
        }
    }

    uri.set_fragment(None);
}

#[cfg(test)]
mod tests;