分析文件的函数调用
(
&self,
file_path: &PathBuf,
function_ids: &[Uuid],
call_graph: &mut PetCodeGraph,
)
| 183 | |
| 184 | /// 分析文件的函数调用 |
| 185 | fn _analyze_file_calls( |
| 186 | &self, |
| 187 | file_path: &PathBuf, |
| 188 | function_ids: &[Uuid], |
| 189 | call_graph: &mut PetCodeGraph, |
| 190 | ) -> Result<(), String> { |
| 191 | let symbols = self.ts_parser.parse_file(file_path) |
| 192 | .map_err(|e| format!("Failed to parse file for call analysis: {:?}", e))?; |
| 193 | |
| 194 | for symbol in symbols { |
| 195 | let symbol_guard = symbol.read(); |
| 196 | let symbol_ref = symbol_guard.as_ref(); |
| 197 | |
| 198 | if symbol_ref.symbol_type() == crate::codegraph::treesitter::structs::SymbolType::FunctionCall { |
| 199 | let call_name = symbol_ref.name(); |
| 200 | let call_line = symbol_ref.full_range().start_point.row + 1; |
| 201 | |
| 202 | // 查找调用者函数 |
| 203 | if let Some(caller_id) = self._find_caller_function(file_path, call_line, function_ids) { |
| 204 | // 查找被调用函数(先在本文件,再全局) |
| 205 | if let Some(callee_id) = self._find_callee_function(call_name, function_ids, call_graph) { |
| 206 | let relation = CallRelation { |
| 207 | caller_id: *caller_id, |
| 208 | callee_id, |
| 209 | caller_name: "".to_string(), // 会在add_call_relation中填充 |
| 210 | callee_name: call_name.to_string(), |
| 211 | caller_file: file_path.clone(), |
| 212 | callee_file: file_path.clone(), |
| 213 | line_number: call_line, |
| 214 | is_resolved: true, |
| 215 | }; |
| 216 | if let Err(e) = call_graph.add_call_relation(relation) { |
| 217 | warn!("Failed to add call relation: {}", e); |
| 218 | } |
| 219 | } else { |
| 220 | // 未解析的调用 |
| 221 | self._handle_unresolved_call(caller_id, call_name, file_path, call_line, call_graph); |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | Ok(()) |
| 228 | } |
| 229 | |
| 230 | /// 查找调用者函数 |
| 231 | fn _find_caller_function<'a>(&self, file_path: &PathBuf, call_line: usize, function_ids: &'a [Uuid]) -> Option<&'a Uuid> { |
no test coverage detected