diff --git a/src/file_depot.rs b/src/file_depot.rs index 561f114..ddef691 100644 --- a/src/file_depot.rs +++ b/src/file_depot.rs @@ -1,10 +1,14 @@ -use crate::{error, info, log_message, utils::is_header}; +use crate::utils::url_exists; +use crate::{error, log_message, utils::is_header}; use std::collections::HashMap; use std::collections::HashSet; use std::sync::Arc; use std::sync::Mutex; use tower_lsp::lsp_types::{MessageType, TextEdit, Url}; +#[cfg(test)] +use crate::info; + #[derive(Default, Clone)] struct FileEntry { text: Option, @@ -15,7 +19,6 @@ struct FileEntry { #[derive(Clone)] struct Data { root_dir: Option, // TODO: Maybe some type that allows only one assignment? - includes_prefix: String, entries: HashMap, } @@ -47,11 +50,28 @@ impl<'a> MyTextEdit<'a> { } } +fn build_path(root: &Url, includes_dir: &str, rel_path: &str) -> Option { + let Ok(dst) = root.join(includes_dir) else { + error!("failed to join {root} and {}", includes_dir); + return None; + }; + + let Ok(dst) = dst.join(rel_path) else { + error!("failed to join {root} and {}", rel_path); + return None; + }; + + if url_exists(&dst) { + Some(dst) + } else { + None + } +} + impl Data { fn new() -> Data { Data { root_dir: None, - includes_prefix: "include".to_string(), entries: HashMap::new(), } } @@ -112,17 +132,14 @@ impl Data { return None; }; - let Ok(dst) = root.join(&(self.includes_prefix.clone() + "/")) else { - error!("failed to join {root} and {}", self.includes_prefix); - return None; - }; - - let Ok(dst) = dst.join(rel_path) else { - error!("failed to join {root} and {}", rel_path); - return None; - }; - - Some(dst) + // TODO: make it configurable + for prefix in ["include/", "arch/", "scripts/dtc/include-prefixes/"] { + let dst = build_path(root, prefix, rel_path); + if dst.is_some() { + return dst; + } + } + None } fn add_include(&mut self, uri: &Url, include_uri: &Url) { @@ -188,6 +205,7 @@ impl Data { res.iter().cloned().collect() } + #[cfg(test)] fn dump(&self) { info!("===FILES==="); for (k, v) in &self.entries { @@ -210,10 +228,6 @@ impl Data { self.entries.get(uri).and_then(|x| x.text.clone()) } - fn set_includes_prefix(&mut self, prefix: &str) { - self.includes_prefix = prefix.to_string(); - } - fn set_root_dir(&mut self, uri: &Url) { /* root_dir comes from LSP client and it's better to * verify that there is a trailing slash */ @@ -260,6 +274,7 @@ impl FileDepot { data.insert(uri, text) } + #[cfg(test)] pub fn dump(&self) { { let lock = self.data.lock().unwrap(); @@ -297,12 +312,6 @@ impl FileDepot { self.data.lock().unwrap().get_real_path(uri) } - // TODO: Allow per-workspace include prefixes - #[allow(dead_code)] - pub fn set_includes_prefix(&self, prefix: &str) { - self.data.lock().unwrap().set_includes_prefix(prefix); - } - pub fn set_root_dir(&self, uri: &Url) { self.data.lock().unwrap().set_root_dir(uri); } diff --git a/src/functional_tests.rs b/src/functional_tests.rs index 90c3322..eef1bc8 100644 --- a/src/functional_tests.rs +++ b/src/functional_tests.rs @@ -366,7 +366,7 @@ async fn open_6() { be.mock_open(path).await; - assert_eq!(be.data.fd.size(), 2); + assert_eq!(be.data.fd.size(), 1); assert_eq!(be.data.fd.n_with_text(), 1); assert_eq!(be.data.ld.size(), 2); assert_eq!(be.data.rd.size(), 0); @@ -383,7 +383,7 @@ async fn open_6() { &rx, vec![( MessageType::WARNING, - format!("can't read file {missing_file}: entity not found"), + format!("Could not find include: {missing_file}"), )], ); } diff --git a/src/labels_depot.rs b/src/labels_depot.rs index 563d162..fd1da0b 100644 --- a/src/labels_depot.rs +++ b/src/labels_depot.rs @@ -48,7 +48,6 @@ impl Data { let mut to_visit = vec![uri.clone()]; let mut res = Vec::new(); - self.fd.dump(); let v = self.fd.get_component(uri); for f in &v { if !visited.contains(f) { diff --git a/src/utils.rs b/src/utils.rs index e505da6..371aff6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -82,3 +82,7 @@ pub trait Leakable { leak } } + +pub fn url_exists(uri: &Url) -> bool { + uri.to_file_path().map(|x| x.exists()).unwrap_or(false) +} diff --git a/src/workspace.rs b/src/workspace.rs index 972d95f..1007e7c 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -7,6 +7,7 @@ use crate::references_depot::ReferencesDepot; use crate::utils::convert_range; use crate::utils::extension_one_of; use crate::utils::is_header; +use crate::utils::url_exists; use crate::{error, log_message, warn}; use diagnostics::DiagnosticExt; use std::collections::HashMap; @@ -91,16 +92,19 @@ impl Workspace { let nodes = m.nodes_for_capture_index(0); for node in nodes { let label = node.utf8_text(text.as_bytes()).unwrap(); - let mut needs_fixup = false; - if label.ends_with('>') { - needs_fixup = true; - } + let label = label.trim_matches('"'); let label = label.trim_matches('<'); let label = label.trim_matches('>'); let mut new_url = uri.join(label).unwrap(); - if needs_fixup { - new_url = self.fd.get_real_path(label).unwrap(); + + if !url_exists(&new_url) { + if let Some(tmp) = self.fd.get_real_path(label) { + new_url = tmp; + } else { + warn!("Could not find include: {new_url}"); + continue; + } } v.push(new_url.clone()); self.fd.add_include(uri, &new_url);