atomcode_core/graph/
resolve.rs1use std::path::Path;
2
3use super::{CodeGraph, SymbolId};
4
5pub fn resolve_callee(
13 graph: &CodeGraph,
14 callee_name: &str,
15 caller_file: &Path,
16 imported_names: &[String],
17) -> Option<SymbolId> {
18 let candidates = graph.find_by_name(callee_name);
19 if candidates.is_empty() {
20 return None;
21 }
22
23 let caller_dir = caller_file.parent();
24 let caller_root = top_component(caller_file);
25
26 let mut best_id: Option<SymbolId> = None;
27 let mut best_score: i32 = -1;
28
29 for node in &candidates {
30 let score = if node.file == caller_file {
31 4
32 } else if imported_names.contains(&node.name) {
33 3
34 } else if caller_dir.is_some() && node.file.parent() == caller_dir {
35 2
36 } else if caller_root.is_some() && top_component(&node.file) == caller_root {
37 1
38 } else {
39 0
40 };
41
42 if score > best_score {
43 best_score = score;
44 best_id = Some(node.id);
45 }
46 }
47
48 best_id
49}
50
51fn top_component(path: &Path) -> Option<String> {
52 path.components()
53 .next()
54 .map(|c| c.as_os_str().to_string_lossy().to_string())
55}