summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-03-31 13:04:42 -0400
committerGitHub <noreply@github.com>2024-03-31 13:04:42 -0400
commitdb89ce33f45a1604f544c70419271cae5de575f2 (patch)
tree2af140078ce2d8c2bbf9338d77f18784f20dc8f9
parenteb6f6ff33d5b1e5c4ac799936cd1a80aa6213bdf (diff)
chore(lsp): remove recursion in recurse_dependents (#23153)
Was investigating a separate stack overflow (that I've now found in the node resolution code) and came across this. We should avoid recursion (this is very old code).
-rw-r--r--cli/lsp/documents.rs22
1 files changed, 12 insertions, 10 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs
index 8feeab8de..8479768a0 100644
--- a/cli/lsp/documents.rs
+++ b/cli/lsp/documents.rs
@@ -648,16 +648,20 @@ pub fn to_lsp_range(range: &deno_graph::Range) -> lsp::Range {
fn recurse_dependents(
specifier: &ModuleSpecifier,
map: &HashMap<ModuleSpecifier, HashSet<ModuleSpecifier>>,
- dependents: &mut HashSet<ModuleSpecifier>,
-) {
- if let Some(deps) = map.get(specifier) {
- for dep in deps {
- if !dependents.contains(dep) {
- dependents.insert(dep.clone());
- recurse_dependents(dep, map, dependents);
+) -> Vec<ModuleSpecifier> {
+ let mut dependents = HashSet::new();
+ let mut pending = VecDeque::new();
+ pending.push_front(specifier);
+ while let Some(specifier) = pending.pop_front() {
+ if let Some(deps) = map.get(specifier) {
+ for dep in deps {
+ if dependents.insert(dep) {
+ pending.push_front(dep);
+ }
}
}
}
+ dependents.into_iter().cloned().collect()
}
#[derive(Debug)]
@@ -1106,10 +1110,8 @@ impl Documents {
specifier: &ModuleSpecifier,
) -> Vec<ModuleSpecifier> {
self.calculate_dependents_if_dirty();
- let mut dependents = HashSet::new();
if let Some(specifier) = self.resolve_specifier(specifier) {
- recurse_dependents(&specifier, &self.dependents_map, &mut dependents);
- dependents.into_iter().collect()
+ recurse_dependents(&specifier, &self.dependents_map)
} else {
vec![]
}