summaryrefslogtreecommitdiff
path: root/support/texlab/crates/base-db/src/deps/graph.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/base-db/src/deps/graph.rs')
-rw-r--r--support/texlab/crates/base-db/src/deps/graph.rs93
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(