Skip to content

Commit 103da6f

Browse files
committed
Improved call tracking
1 parent 485a140 commit 103da6f

File tree

1 file changed

+72
-36
lines changed

1 file changed

+72
-36
lines changed

src/extension.ts

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -186,42 +186,50 @@ async function generateFlowDiagramFromCallHierarchy(
186186
item: vscode.CallHierarchyItem,
187187
incomingCalls: vscode.CallHierarchyIncomingCall[] | undefined
188188
): Promise<{nodes: any[], edges: any[]}> {
189-
let nodes = [{
190-
id: 0,
189+
let newNodes = new Map();
190+
let newEdges: any[] = [];
191+
192+
// Add root node
193+
const rootKey = `${item.uri.fsPath}::${item.name}`;
194+
newNodes.set(rootKey, {
195+
id: 1,
191196
label: item.name,
192197
color: getRandomPastelColor(),
193198
file: item.uri.fsPath,
194199
line: item.range.start.line,
195200
character: item.selectionRange.start.character
196-
}];
197-
198-
let edges: {from: number, to: number, count: number}[] = [];
201+
});
199202

200203
if (incomingCalls) {
201-
let callCounts = new Map<string, number>();
202-
for (let call of incomingCalls) {
203-
const key = `${call.from.name}-${item.name}`;
204-
callCounts.set(key, (callCounts.get(key) || 0) + call.fromRanges.length);
205-
}
204+
incomingCalls.forEach((call, index) => {
205+
const callerKey = `${call.from.uri.fsPath}::${call.from.name}`;
206+
207+
// Only add the node if it's not already in our map
208+
if (!newNodes.has(callerKey)) {
209+
newNodes.set(callerKey, {
210+
id: newNodes.size + 1, // ID based on map size
211+
label: call.from.name,
212+
color: getRandomPastelColor(),
213+
file: call.from.uri.fsPath,
214+
line: call.from.range.start.line,
215+
character: call.from.selectionRange.start.character
216+
});
217+
}
206218

207-
let i = 1;
208-
for (let [key, count] of callCounts) {
209-
const [fromName] = key.split('-');
210-
const caller = incomingCalls.find(call => call.from.name === fromName)!;
211-
nodes.push({
212-
id: i,
213-
label: fromName,
214-
color: getRandomPastelColor(),
215-
file: caller.from.uri.fsPath,
216-
line: caller.from.range.start.line,
217-
character: caller.from.selectionRange.start.character
219+
// Add edge using the node's actual ID
220+
const callerId = newNodes.get(callerKey).id;
221+
newEdges.push({
222+
from: callerId,
223+
to: 1, // Root node's ID is always 1
224+
count: call.fromRanges.length
218225
});
219-
edges.push({from: i, to: 0, count: count});
220-
i++;
221-
}
226+
});
222227
}
223228

224-
return {nodes, edges};
229+
return {
230+
nodes: Array.from(newNodes.values()),
231+
edges: newEdges
232+
};
225233
}
226234

227235
async function goToDefinition(nodeId: number) {
@@ -560,24 +568,52 @@ function getWebviewContent(data: {nodes: any[], edges: any[]}) {
560568
}
561569

562570
function mergeFlowData(newData: {nodes: any[], edges: any[]}) {
563-
for (const newNode of newData.nodes) {
564-
const existingNode = globalData.nodes.find(n => n.label === newNode.label && n.file === newNode.file);
565-
if (!existingNode) {
571+
// Create a map of existing nodes by file+label combination
572+
const existingNodesMap = new Map(
573+
globalData.nodes.map(node => [`${node.file}-${node.label}`, node])
574+
);
575+
576+
// Process new nodes
577+
newData.nodes.forEach(newNode => {
578+
const key = `${newNode.file}-${newNode.label}`;
579+
if (!existingNodesMap.has(key)) {
580+
// If node doesn't exist, add it with a new ID
566581
newNode.id = nextNodeId++;
567582
globalData.nodes.push(newNode);
583+
existingNodesMap.set(key, newNode);
568584
}
569-
}
585+
});
570586

571-
for (const newEdge of newData.edges) {
572-
const fromNode = globalData.nodes.find(n => n.label === newData.nodes[newEdge.from].label && n.file === newData.nodes[newEdge.from].file);
573-
const toNode = globalData.nodes.find(n => n.label === newData.nodes[newEdge.to].label && n.file === newData.nodes[newEdge.to].file);
587+
// Process new edges
588+
newData.edges.forEach(newEdge => {
589+
// Find the actual node IDs from our existing nodes
590+
const fromNode = newData.nodes[newEdge.from - 1];
591+
const toNode = newData.nodes[newEdge.to - 1];
592+
574593
if (fromNode && toNode) {
575-
const existingEdge = globalData.edges.find(e => e.from === fromNode.id && e.to === toNode.id);
576-
if (!existingEdge) {
577-
globalData.edges.push({ from: fromNode.id, to: toNode.id });
594+
const fromKey = `${fromNode.file}-${fromNode.label}`;
595+
const toKey = `${toNode.file}-${toNode.label}`;
596+
597+
const actualFromNode = existingNodesMap.get(fromKey);
598+
const actualToNode = existingNodesMap.get(toKey);
599+
600+
if (actualFromNode && actualToNode) {
601+
// Check if edge already exists
602+
const edgeExists = globalData.edges.some(e =>
603+
e.from === actualFromNode.id &&
604+
e.to === actualToNode.id
605+
);
606+
607+
if (!edgeExists) {
608+
globalData.edges.push({
609+
from: actualFromNode.id,
610+
to: actualToNode.id,
611+
count: newEdge.count
612+
});
613+
}
578614
}
579615
}
580-
}
616+
});
581617
}
582618

583619
export function deactivate() {}

0 commit comments

Comments
 (0)