pub mod deps;
pub mod diff;
pub mod entrypoints;
pub mod find;
pub mod flow;
pub mod impact;
pub mod index;
pub mod init;
pub mod map;
pub mod rdeps;
pub mod refs;
pub mod setup;
pub mod similar;
pub mod sketch;
pub mod source;
pub mod status;
pub mod summary;
pub mod trace;
pub mod workspace;
use crate::core::graph::{Graph, Symbol};
pub fn resolve_symbol(graph: &Graph, name: &str) -> anyhow::Result<Symbol> {
if name.contains("::") {
let sym = graph.find_symbol_by_id_prefix(name)?;
if let Some(s) = sym {
return Ok(s);
}
}
let all = graph.find_all_matching_symbols(name)?;
match all.len() {
0 => {}
1 => {
if let Some(sym) = all.into_iter().next() {
return Ok(sym);
}
}
_ => {
let mut msg = format!(
"Ambiguous symbol '{}' matches {} definitions:\n",
name,
all.len()
);
for (i, s) in all.iter().enumerate() {
msg.push_str(&format!(
" {}. {} ({}) {}:{}\n",
i + 1,
s.name,
s.kind,
s.file_path,
s.line_start,
));
}
msg.push_str(&format!(
"\nUse a qualified name to disambiguate:\n scope <cmd> {}::{}::{}",
all[0].file_path, all[0].name, all[0].kind,
));
anyhow::bail!("{msg}");
}
}
if let Some(sym) = graph.find_symbol(name)? {
return Ok(sym);
}
anyhow::bail!(
"Symbol '{}' not found in index.\n\
Tip: Check spelling, or use 'scope find \"{}\"' for semantic search.",
name,
name,
);
}
pub fn warn_if_stale(graph: &Graph, project_root: &std::path::Path) {
if let Ok(true) = graph.has_stale_files(project_root) {
eprintln!(
"Warning: file(s) changed since last index. Run `scope index` for accurate results."
);
}
}
pub fn looks_like_file_path(input: &str) -> bool {
input.contains('/')
|| input.contains('\\')
|| input.ends_with(".ts")
|| input.ends_with(".tsx")
|| input.ends_with(".js")
|| input.ends_with(".jsx")
|| input.ends_with(".cs")
|| input.ends_with(".rs")
|| input.ends_with(".py")
|| input.ends_with(".go")
|| input.ends_with(".java")
}