update graph
This commit is contained in:
+79
-2
@@ -41,9 +41,37 @@ class LocalGraph:
|
||||
self.add_edge(src, target, "imports")
|
||||
|
||||
def _add_call_edges(self, src: str, calls: list[str], file_path: str):
|
||||
"""Enhanced call edges that work cross-file by searching the entire graph."""
|
||||
for cal in calls:
|
||||
target = f"rust::function::{file_path}::{cal}"
|
||||
self.add_edge(src, target, "calls")
|
||||
if not cal or not isinstance(cal, str):
|
||||
continue
|
||||
|
||||
# Try to find the called function in the graph
|
||||
target_found = False
|
||||
|
||||
# Search for functions with this name across ALL files
|
||||
for node_id, data in self.graph.nodes(data=True):
|
||||
if (data.get('type') in ['function', 'method', 'async_function', 'constructor'] and
|
||||
data.get('name') == cal):
|
||||
# Found a matching function - create call edge
|
||||
self.add_edge(src, node_id, "calls")
|
||||
target_found = True
|
||||
# Don't break - a function might be called from multiple places
|
||||
|
||||
# If not found, create a symbolic node for the call target
|
||||
if not target_found:
|
||||
# Create a canonical function node (file-less) for cross-file references
|
||||
symbolic_id = f"rust::function::{cal}" # Assuming Rust for now
|
||||
if symbolic_id not in self.graph.nodes:
|
||||
self.add_node(
|
||||
symbolic_id,
|
||||
type="function",
|
||||
name=cal,
|
||||
file="", # No specific file
|
||||
lang="rust",
|
||||
is_symbolic=True
|
||||
)
|
||||
self.add_edge(src, symbolic_id, "calls")
|
||||
|
||||
|
||||
|
||||
@@ -284,3 +312,52 @@ class LocalGraph:
|
||||
entities.append(f"{entity_type}:{entity_name}")
|
||||
|
||||
return entities
|
||||
|
||||
def find_nodes_by_attributes(self, **filters):
|
||||
"""Find nodes by attributes (not just exact matches)."""
|
||||
for node_id, data in self.graph.nodes(data=True):
|
||||
if all(data.get(k) == v for k, v in filters.items()):
|
||||
yield node_id, data
|
||||
|
||||
def get_node_by_name_and_file(self, name: str, file_path: str, node_type: str = None, lang: str = None):
|
||||
"""Find a node by name and file path with optional type/language filtering."""
|
||||
candidates = []
|
||||
for node_id, data in self.graph.nodes(data=True):
|
||||
if (data.get('name') == name and
|
||||
data.get('file') == file_path and
|
||||
(node_type is None or data.get('type') == node_type) and
|
||||
(lang is None or data.get('lang') == lang)):
|
||||
candidates.append((node_id, data))
|
||||
return candidates
|
||||
|
||||
def get_cross_file_relationships(self, node_id: str, current_file: str):
|
||||
"""Get relationships that cross file boundaries."""
|
||||
if node_id not in self.graph.nodes:
|
||||
return [], []
|
||||
|
||||
cross_file_out = []
|
||||
cross_file_in = []
|
||||
|
||||
# Outgoing cross-file relationships
|
||||
for neighbor_id in self.graph.successors(node_id):
|
||||
if neighbor_id in self.graph.nodes:
|
||||
neighbor_file = self.graph.nodes[neighbor_id].get('file', '')
|
||||
if neighbor_file and neighbor_file != current_file:
|
||||
edge_data = self.graph.edges[node_id, neighbor_id]
|
||||
rel_type = edge_data.get('type', 'related')
|
||||
neighbor_name = self.graph.nodes[neighbor_id].get('name', '')
|
||||
neighbor_type = self.graph.nodes[neighbor_id].get('type', '')
|
||||
cross_file_out.append(f"{rel_type}:{neighbor_type}:{neighbor_name}@{neighbor_file}")
|
||||
|
||||
# Incoming cross-file relationships
|
||||
for predecessor_id in self.graph.predecessors(node_id):
|
||||
if predecessor_id in self.graph.nodes:
|
||||
pred_file = self.graph.nodes[predecessor_id].get('file', '')
|
||||
if pred_file and pred_file != current_file:
|
||||
edge_data = self.graph.edges[predecessor_id, node_id]
|
||||
rel_type = edge_data.get('type', 'related')
|
||||
pred_name = self.graph.nodes[predecessor_id].get('name', '')
|
||||
pred_type = self.graph.nodes[predecessor_id].get('type', '')
|
||||
cross_file_in.append(f"{rel_type}:{pred_type}:{pred_name}@{pred_file}")
|
||||
|
||||
return cross_file_out, cross_file_in
|
||||
|
||||
Reference in New Issue
Block a user