Skip to content

Commit

Permalink
Avoid extending resolution paths to files already visited
Browse files Browse the repository at this point in the history
  • Loading branch information
ggiraldez committed Jan 22, 2025
1 parent aca4ba3 commit de03aee
Showing 1 changed file with 51 additions and 36 deletions.
87 changes: 51 additions & 36 deletions crates/metaslang/bindings/src/graph/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use stack_graphs::arena::Handle;
use stack_graphs::graph::{Degree, Edge, StackGraph};
use stack_graphs::partial::{PartialPath, PartialPaths};
use stack_graphs::stitching::{
Database, DatabaseCandidates, ForwardCandidates, ForwardPartialPathStitcher, StitcherConfig,
ToAppendable,
Database, ForwardCandidates, ForwardPartialPathStitcher, StitcherConfig, ToAppendable,
};
use stack_graphs::{CancellationError, NoCancellation};

Expand Down Expand Up @@ -105,7 +104,7 @@ impl Resolver {
let checkpoint = self.partials.save_checkpoint();
let mut reference_paths = Vec::new();

if allow_recursion {
let extensions = if allow_recursion {
// look for extension scopes to apply to the reference
let ref_parents = self.resolve_parents(owner, reference);
let mut extensions = HashSet::new();
Expand All @@ -123,40 +122,27 @@ impl Resolver {
}
}
}
let extensions = extensions.drain().collect::<Vec<_>>();
let mut database = ExtendedDatabase::new(&mut self.database);

ForwardPartialPathStitcher::find_all_complete_partial_paths(
&mut DatabaseCandidatesExtended::new(
owner,
&mut self.partials,
&mut database,
extensions,
),
once(reference),
StitcherConfig::default(),
&NoCancellation,
|_graph, _partials, path| {
reference_paths.push(path.clone());
},
)
.expect("not cancelled");
extensions.drain().collect::<Vec<_>>()
} else {
ForwardPartialPathStitcher::find_all_complete_partial_paths(
&mut DatabaseCandidates::new(
&owner.stack_graph,
&mut self.partials,
&mut self.database,
),
once(reference),
StitcherConfig::default(),
&NoCancellation,
|_graph, _partials, path| {
reference_paths.push(path.clone());
},
)
.expect("not cancelled");
}
Vec::new()
};
let mut database = ExtendedDatabase::new(&mut self.database);

ForwardPartialPathStitcher::find_all_complete_partial_paths(
&mut DatabaseCandidatesExtended::new(
owner,
&mut self.partials,
&mut database,
extensions,
),
once(reference),
StitcherConfig::default(),
&NoCancellation,
|_graph, _partials, path| {
reference_paths.push(path.clone());
},
)
.expect("not cancelled");

let mut results = Vec::new();
for reference_path in &reference_paths {
Expand Down Expand Up @@ -280,9 +266,38 @@ impl<'a, KT: KindTypes + 'static>
path,
&mut db_candidates,
);

let mut visited_files = HashSet::new();
if self.owner.stack_graph[node].is_root() {
for edge in path.edges.iter(self.partials) {
if let Some(file) = edge.source_node_id.file() {
visited_files.insert(file);
}
}
}

result.extend(
db_candidates
.iter()
.filter(|candidate| {
// For partial paths ending at the root, this prevents
// extending them to files that are already part of the
// partial path, reducing resolution time when there are
// cyclic imports
if visited_files.is_empty() {
true
} else {
let candidate = &self.database.database[**candidate];
!self.owner.stack_graph[candidate.end_node]
.file()
.map_or(false, |end_file| visited_files.contains(&end_file))
|| candidate.edges.iter(self.partials).any(|edge| {
edge.source_node_id.file().map_or(false, |file_handle| {
visited_files.contains(&file_handle)
})
})
}
})
.map(|candidate| ExtendedHandle::Handle(*candidate)),
);

Expand Down

0 comments on commit de03aee

Please sign in to comment.