Skip to content

Commit

Permalink
fix: add default include paths for Linux
Browse files Browse the repository at this point in the history
Without this fix we can't find some files when they are in include
statements.
  • Loading branch information
igor-prusov committed Oct 29, 2024
1 parent 456db55 commit 91d1a48
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 33 deletions.
57 changes: 33 additions & 24 deletions src/file_depot.rs
Original file line number Diff line number Diff line change
@@ -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<String>,
Expand All @@ -15,7 +19,6 @@ struct FileEntry {
#[derive(Clone)]
struct Data {
root_dir: Option<Url>, // TODO: Maybe some type that allows only one assignment?
includes_prefix: String,
entries: HashMap<Url, FileEntry>,
}

Expand Down Expand Up @@ -47,11 +50,28 @@ impl<'a> MyTextEdit<'a> {
}
}

fn build_path(root: &Url, includes_dir: &str, rel_path: &str) -> Option<Url> {
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(),
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -188,6 +205,7 @@ impl Data {
res.iter().cloned().collect()
}

#[cfg(test)]
fn dump(&self) {
info!("===FILES===");
for (k, v) in &self.entries {
Expand All @@ -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 */
Expand Down Expand Up @@ -260,6 +274,7 @@ impl FileDepot {
data.insert(uri, text)
}

#[cfg(test)]
pub fn dump(&self) {
{
let lock = self.data.lock().unwrap();
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions src/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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}"),
)],
);
}
Expand Down
1 change: 0 additions & 1 deletion src/labels_depot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
16 changes: 10 additions & 6 deletions src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 91d1a48

Please sign in to comment.