1use crate::error::GraphynError;
2use crate::graph::GraphynGraph;
3use crate::ir::SymbolId;
4
5pub fn find_symbol_id(
6 graph: &GraphynGraph,
7 symbol: &str,
8 file: Option<&str>,
9) -> Result<SymbolId, GraphynError> {
10 let Some(ids_ref) = graph.name_index.get(symbol) else {
11 return Err(GraphynError::SymbolNotFound(symbol.to_string()));
12 };
13 let ids = ids_ref.value().clone();
14 drop(ids_ref);
15
16 if let Some(file) = file {
17 for id in ids {
18 if let Some(sym) = graph.symbols.get(&id) {
19 if sym.file == file {
20 return Ok(id);
21 }
22 }
23 }
24 return Err(GraphynError::SymbolNotFound(format!("{symbol} in {file}")));
25 }
26
27 if ids.len() == 1 {
28 return Ok(ids[0].clone());
29 }
30
31 let mut candidates = Vec::new();
32 for id in ids {
33 if let Some(sym) = graph.symbols.get(&id) {
34 candidates.push(sym.file.clone());
35 }
36 }
37 candidates.sort();
38 candidates.dedup();
39
40 Err(GraphynError::AmbiguousSymbol {
41 symbol: symbol.to_string(),
42 candidates,
43 })
44}