diff --git a/Cargo.lock b/Cargo.lock index c9f7160..6ae15f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,55 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -102,6 +151,52 @@ version = "1.0.0" source = "registry+/~https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "dashmap" version = "5.5.3" @@ -119,6 +214,7 @@ dependencies = [ name = "dts-lsp" version = "0.1.5" dependencies = [ + "clap", "lazy_static", "streaming-iterator", "tokio", @@ -225,6 +321,12 @@ version = "0.14.5" source = "registry+/~https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -247,6 +349,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" version = "1.0.11" @@ -554,6 +662,12 @@ version = "0.1.9" source = "registry+/~https://github.com/rust-lang/crates.io-index" checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.79" @@ -775,6 +889,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+/~https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 43dbeee..d7827ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = { version = "4.5.20", features = ["derive"] } lazy_static = "1.4.0" streaming-iterator = "0.1.9" tokio = { version = "1.40.0", features = [ "full" ] } diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..4b010cb --- /dev/null +++ b/src/config.rs @@ -0,0 +1,35 @@ +use clap::Parser; +use std::sync::OnceLock; + +#[derive(clap::Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + /// Enable experimental features + #[arg(long)] + experimental: bool, +} + +#[derive(Debug)] +pub struct Config { + #[allow(dead_code)] + pub experimental: bool, + pub process_neighbours: bool, +} + +impl Default for Config { + fn default() -> Self { + Self { + experimental: false, + process_neighbours: true, + } + } +} + +pub static CONFIG: OnceLock = OnceLock::new(); + +pub fn get() -> &'static Config { + CONFIG.get_or_init(|| Config { + experimental: Args::parse().experimental, + ..Default::default() + }) +} diff --git a/src/functional_tests.rs b/src/functional_tests.rs index 025d4d8..69604d9 100644 --- a/src/functional_tests.rs +++ b/src/functional_tests.rs @@ -5,15 +5,24 @@ use logger::LogProcessor; use std::fs::read_to_string; use std::sync::mpsc; use utils::current_url; +use utils::Leakable; + +impl Leakable for Config {} async fn make_backend_ext(path: &str, process_neighbours: bool) -> Backend { // Go to test directory, each test directory emulates a workspace let handle = tokio::runtime::Handle::current(); LogProcessor::local_set(LogProcessor::Strict); - let be = Backend { - data: Workspace::new(handle, None), + let config = Config { process_neighbours, + ..Default::default() + } + .leak(); + + let be = Backend { + data: Workspace::new(handle, None, config), client: None, + config, }; let mut root = current_url().unwrap(); let root_path = root.path().to_string() + "/" + path; diff --git a/src/main.rs b/src/main.rs index 2ee15ac..58b4468 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use config::Config; use logger::log_message; use logger::Logger; use std::collections::HashMap; @@ -12,6 +13,7 @@ use tree_sitter::Parser; use tree_sitter::Point; use utils::convert_range; +mod config; mod diagnostics; mod file_depot; mod includes_depot; @@ -29,15 +31,15 @@ use workspace::Workspace; struct Backend { data: Workspace, client: Option, - process_neighbours: bool, + config: &'static Config, } impl Backend { - fn new(handle: Handle, client: Client) -> Self { + fn new(handle: Handle, client: Client, config: &'static Config) -> Self { Backend { - data: Workspace::new(handle, Some(client.clone())), - process_neighbours: true, + data: Workspace::new(handle, Some(client.clone()), config), client: Some(client), + config, } } @@ -118,7 +120,7 @@ impl LanguageServer for Backend { let text = params.text_document.text.as_str(); self.data.handle_file(uri, Some(text.to_string())); - if self.process_neighbours { + if self.config.process_neighbours { self.data.open_neighbours(uri); } } @@ -353,7 +355,7 @@ async fn main() { let (service, socket) = LspService::new(|client| { let handle = tokio::runtime::Handle::current(); Logger::set(Logger::Lsp(handle.clone(), client.clone())); - Backend::new(handle, client) + Backend::new(handle, client, config::get()) }); Server::new(stdin, stdout, socket).serve(service).await; } diff --git a/src/utils.rs b/src/utils.rs index 36b6257..e505da6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,6 @@ use std::borrow::Cow; +#[cfg(test)] +use std::sync::Mutex; use tower_lsp::jsonrpc::Error; use tower_lsp::jsonrpc::Result; use tower_lsp::lsp_types::{Position, Range, Url}; @@ -63,3 +65,20 @@ pub fn current_url() -> Result { }; Ok(uri) } + +// Leak object, but keep reference in static array to avoid valgrind errors +#[cfg(test)] +pub trait Leakable { + fn leak(self) -> &'static Self + where + Self: Sized, + Self: Sync, + Self: Send, + { + static LEAKED: Mutex> = Mutex::new(Vec::new()); + let leak = Box::leak(Box::new(self)); + let mut v = LEAKED.lock().unwrap(); + v.push(leak); + leak + } +} diff --git a/src/workspace.rs b/src/workspace.rs index 8689f83..82d2bfc 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -1,3 +1,4 @@ +use crate::config::Config; use crate::file_depot; use crate::file_depot::FileDepot; use crate::includes_depot::IncludesDepot; @@ -22,6 +23,7 @@ use tree_sitter::Tree; use crate::diagnostics; pub struct Workspace { + config: &'static Config, handle: Handle, client: Option, pub fd: FileDepot, @@ -31,9 +33,10 @@ pub struct Workspace { } impl Workspace { - pub fn new(handle: Handle, client: Option) -> Workspace { + pub fn new(handle: Handle, client: Option, config: &'static Config) -> Workspace { let fd = FileDepot::new(); Workspace { + config, ld: LabelsDepot::new(&fd), rd: ReferencesDepot::new(&fd), id: IncludesDepot::new(&fd), @@ -43,8 +46,6 @@ impl Workspace { } } - // TODO: Temporarily disabled due to false positives - #[allow(dead_code)] fn process_diagnostics(&self, tree: &Tree, uri: &Url) { let diagnostics = diagnostics::gather(tree); let u = uri.clone(); @@ -204,7 +205,9 @@ impl Workspace { } self.process_labels(&tree, uri, &text); - //self.process_diagnostics(&tree, uri); + if self.config.experimental { + self.process_diagnostics(&tree, uri); + } self.process_references(&tree, uri, &text); self.process_includes(&tree, uri, &text) }