@@ -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
227235async function goToDefinition ( nodeId : number ) {
@@ -560,24 +568,52 @@ function getWebviewContent(data: {nodes: any[], edges: any[]}) {
560568}
561569
562570function 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
583619export function deactivate ( ) { }
0 commit comments