diff options
Diffstat (limited to 'support/texlab/crates/base-db/src/deps/graph.rs')
-rw-r--r-- | support/texlab/crates/base-db/src/deps/graph.rs | 93 |
1 files changed, 73 insertions, 20 deletions
diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs index e07368d078..aec5cea92b 100644 --- a/support/texlab/crates/base-db/src/deps/graph.rs +++ b/support/texlab/crates/base-db/src/deps/graph.rs @@ -1,4 +1,4 @@ -use std::{ffi::OsStr, path::PathBuf, rc::Rc}; +use std::{ffi::OsStr, path::PathBuf, rc::Rc, sync::Arc}; use distro::Language; use itertools::Itertools; @@ -22,7 +22,8 @@ pub struct Edge { #[derive(Debug, PartialEq, Eq, Clone, Hash)] pub enum EdgeData { - DirectLink(DirectLinkData), + DirectLink(Box<DirectLinkData>), + FileList(Arc<ProjectRoot>), AdditionalFiles, Artifact, } @@ -54,7 +55,11 @@ impl Graph { start: start.uri.clone(), }; - let root = ProjectRoot::walk_and_find(workspace, &start.dir); + let Some(start_dir) = &start.dir else { + return graph; + }; + + let root = ProjectRoot::walk_and_find(workspace, start_dir); let mut stack = vec![(start, Rc::new(root))]; let mut visited = FxHashSet::default(); @@ -74,6 +79,7 @@ impl Graph { if visited.insert(edge.target.clone()) { let new_root = match &edge.data { EdgeData::DirectLink(data) => data.new_root.clone(), + EdgeData::FileList(root) => Some(root.as_ref().clone()), _ => None, }; @@ -101,6 +107,10 @@ impl Graph { self.add_direct_links(workspace, start); self.add_artifacts(workspace, start); self.add_additional_files(workspace, start); + + if workspace.config().syntax.use_file_list { + self.add_file_list_links(workspace, start); + } } fn add_additional_files(&mut self, workspace: &Workspace, start: Start) { @@ -120,6 +130,43 @@ impl Graph { } } + fn add_file_list_links(&mut self, workspace: &Workspace, start: Start) -> Option<()> { + let file_list = start.source.data.as_file_list()?; + let home_dir = HOME_DIR.as_deref(); + + let working_dir = file_list + .working_dir + .as_deref() + .and_then(|dir| Url::from_directory_path(dir).ok()); + + let working_dir = working_dir.as_ref().or(start.source.dir.as_ref())?; + let new_root = Arc::new(ProjectRoot::from_config(workspace, working_dir)); + + for target_uri in file_list + .inputs + .iter() + .chain(file_list.outputs.iter()) + .filter(|path| { + path.is_relative() + || Language::from_path(&path) == Some(Language::Bib) + || home_dir.map_or(false, |home_dir| path.starts_with(home_dir)) + }) + .filter_map(|path| working_dir.join(path.to_str()?).ok()) + { + if workspace.lookup(&target_uri).is_some() { + self.edges.push(Edge { + source: start.source.uri.clone(), + target: target_uri, + data: EdgeData::FileList(Arc::clone(&new_root)), + }); + } else { + self.missing.push(target_uri); + } + } + + Some(()) + } + fn add_direct_links(&mut self, workspace: &Workspace, start: Start) -> Option<()> { let data = start.source.data.as_tex()?; @@ -159,7 +206,7 @@ impl Graph { for target_uri in file_names .iter() .flat_map(|file_name| { - util::expand_relative_path(&file_name, &start.root.src_dir, workspace.folders()) + util::expand_relative_path(file_name, &start.root.src_dir, workspace.folders()) }) .chain(distro_files) { @@ -169,7 +216,7 @@ impl Graph { .base_dir .as_deref() .and_then(|path| start.root.src_dir.join(path).ok()) - .map(|dir| ProjectRoot::walk_and_find(workspace, &dir)); + .map(|dir| ProjectRoot::from_config(workspace, &dir)); let link_data = DirectLinkData { link: link.clone(), @@ -179,7 +226,7 @@ impl Graph { self.edges.push(Edge { source: start.source.uri.clone(), target: target.uri.clone(), - data: EdgeData::DirectLink(link_data), + data: EdgeData::DirectLink(Box::new(link_data)), }); break; @@ -197,27 +244,33 @@ impl Graph { } let root = start.root; - let relative_path = root.compile_dir.make_relative(&start.source.uri).unwrap(); - - self.add_artifact( - workspace, - start.source, - &root.aux_dir.join(&relative_path).unwrap(), - "aux", - ); + self.add_artifact_group(workspace, start, &root.aux_dir, "aux"); + self.add_artifact_group(workspace, start, &root.log_dir, "log"); + self.add_artifact_group(workspace, start, &root.aux_dir, "fls"); + } - self.add_artifact(workspace, start.source, &root.aux_dir, "aux"); - self.add_artifact(workspace, start.source, &root.compile_dir, "aux"); + fn add_artifact_group( + &mut self, + workspace: &Workspace, + start: Start, + dir: &Url, + extension: &str, + ) { + let relative_path = start + .root + .compile_dir + .make_relative(&start.source.uri) + .unwrap(); self.add_artifact( workspace, start.source, - &root.log_dir.join(&relative_path).unwrap(), - "log", + &dir.join(&relative_path).unwrap(), + extension, ); - self.add_artifact(workspace, start.source, &root.log_dir, "log"); - self.add_artifact(workspace, start.source, &root.compile_dir, "log"); + self.add_artifact(workspace, start.source, &dir, extension); + self.add_artifact(workspace, start.source, &start.root.compile_dir, extension); } fn add_artifact( |