diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-03-31 13:04:42 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-31 13:04:42 -0400 |
commit | db89ce33f45a1604f544c70419271cae5de575f2 (patch) | |
tree | 2af140078ce2d8c2bbf9338d77f18784f20dc8f9 | |
parent | eb6f6ff33d5b1e5c4ac799936cd1a80aa6213bdf (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.rs | 22 |
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![] } |