@@ -239,9 +239,12 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
239239
240240 // NOTE: we may wont to make the caches have more lifetime
241241 // than build so that we can return &'cache [NodeId] after writing.
242+ // TODO: in process of changing signature so that it does not return anything & we just get
243+ // from the built cache.
242244 fn build_header (
243245 & mut self ,
244246 hid : Hid ,
247+ // TODO: understand why this exists!
245248 visited_scopes : & mut HashSet < ScopeId > ,
246249 parent_cluster : Option < ClusterId > ,
247250 ) -> ( NodeId , Vec < NodeId > ) {
@@ -260,11 +263,8 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
260263 . get ( & hid)
261264 . map ( Vec :: as_slice)
262265 . unwrap_or ( & [ ] ) ;
263- let has_md = !md_children. is_empty ( ) ;
264- let has_nested = !nested_children. is_empty ( ) ;
265- let is_branching = header. label_kind == HeaderLabelKind :: If ;
266266
267- if !has_md && !has_nested {
267+ if md_children . is_empty ( ) && nested_children . is_empty ( ) {
268268 let node_id = self . new_node_id ( ) ;
269269 let span = SerializedSpan :: serialize ( & header. span ) ;
270270 self . span_map . insert ( node_id, span. clone ( ) ) ;
@@ -282,65 +282,19 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
282282 return ( node_id, vec ! [ node_id] ) ;
283283 }
284284
285- let total_children = md_children. len ( ) + nested_children. len ( ) ;
286- let mut single_nested_child_has_multiple_items = false ;
287- if nested_children. len ( ) == 1 {
288- let child_root = self . by_hid [ & nested_children[ 0 ] ] ;
289- let count = self . index . headers_in_scope_iter ( child_root. scope ) . count ( ) ;
290- single_nested_child_has_multiple_items = count > 1 ;
291- }
292- let should_flatten = !is_branching
293- && total_children <= MAX_CHILDREN_TO_FLATTEN
294- && !( nested_children. len ( ) == 1 && single_nested_child_has_multiple_items) ;
295-
296- if should_flatten {
297- let node_id = self . new_node_id ( ) ;
298- let span = SerializedSpan :: serialize ( & header. span ) ;
299- self . span_map . insert ( node_id, span. clone ( ) ) ;
300- let kind = if is_branching {
301- NodeKind :: Decision ( hid, Some ( span. clone ( ) ) )
302- } else {
303- NodeKind :: Header ( hid, Some ( span. clone ( ) ) )
304- } ;
305- self . graph . nodes . push ( Node {
306- id : node_id,
307- label : header. title . as_ref ( ) ,
308- kind,
309- cluster : parent_cluster,
310- } ) ;
311- self . header_entry . insert ( hid, node_id) ;
312- let exits = if md_children. len ( ) == 1 {
313- let ( c_entry, c_exits) =
314- self . build_header ( md_children[ 0 ] , visited_scopes, parent_cluster) ;
315- self . graph . edges . push ( Edge {
316- from : node_id,
317- to : c_entry,
318- } ) ;
319- c_exits
320- } else if nested_children. len ( ) == 1 {
321- let child_root_hid = nested_children[ 0 ] ;
322- let child_scope = self . by_hid [ & child_root_hid] . scope ;
323- self . build_scope_sequence ( child_scope, visited_scopes, parent_cluster) ;
324- let ( c_entry, c_exits) =
325- self . build_header ( child_root_hid, visited_scopes, parent_cluster) ;
326- self . graph . edges . push ( Edge {
327- from : node_id,
328- to : c_entry,
329- } ) ;
330- c_exits
331- } ;
332- self . header_exits . insert ( hid, exits) ;
333- return ( node_id, exits) ;
334- }
285+ if header. label_kind == HeaderLabelKind :: If {
286+ // pre-order/post-order notation:
287+ // <pre/post>-order: <name> [[output] <- <dependency list>]
335288
336- if is_branching {
289+ // pre-order: assign cluster ids: cluster_id <- header, parent_cluster
337290 let cluster_id = self . new_cluster_id ( ) ;
338291 self . graph . clusters . push ( Cluster {
339292 id : cluster_id,
340293 label : header. title . as_ref ( ) ,
341294 parent : parent_cluster,
342295 } ) ;
343296
297+ // pre-order: insert entry <- header, cluster_id
344298 let decision_id = self . new_node_id ( ) ;
345299 let span = SerializedSpan :: serialize ( & header. span ) ;
346300 self . span_map . insert ( decision_id, span. clone ( ) ) ;
@@ -351,33 +305,56 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
351305 cluster : Some ( cluster_id) ,
352306 } ) ;
353307 self . header_entry . insert ( hid, decision_id) ;
308+
309+ // unordered: render_calls_for_header <- header_entry, cluster_id
310+
354311 if self . cfg . show_call_nodes {
355312 self . render_calls_for_header ( hid, decision_id, Some ( cluster_id) ) ;
356313 }
357314
358- let mut branch_exits = Vec :: new ( ) ;
359- for child_root_hid in nested_children. iter ( ) {
360- let child_scope = self . by_hid [ child_root_hid] . scope ;
315+ // post-order: build scope sequence for scope & build header
316+ // header_entry, header_exit <- cluster_id.
317+ // For some reason it can't work without a visited_scopes? That's pre-order data.
318+ for child_root_id in nested_children {
319+ let child_scope = self . by_hid [ child_root_id] . scope ;
361320 self . build_scope_sequence ( child_scope, visited_scopes, Some ( cluster_id) ) ;
362- let ( entry, exits) =
363- self . build_header ( * child_root_hid, visited_scopes, Some ( cluster_id) ) ;
364- self . graph . edges . push ( Edge {
321+ self . build_header ( * child_root_id, visited_scopes, Some ( cluster_id) ) ;
322+ }
323+
324+ // post-order: build header for each of the markdown children <- cluster_id.
325+ // Same doubt wrt visited_scopes.
326+ for child in md_children {
327+ self . build_header ( * child, visited_scopes, Some ( cluster_id) ) ;
328+ }
329+
330+ // unordered: add edges from decision id to children <- decision_id
331+ self . graph
332+ . edges
333+ . extend ( nested_children. iter ( ) . map ( |child_root_id| Edge {
365334 from : decision_id,
366- to : entry,
367- } ) ;
368- if self . cfg . show_call_nodes {
369- self . render_calls_for_header ( * child_root_hid, entry, Some ( cluster_id) ) ;
335+ to : self . header_entry [ child_root_id] ,
336+ } ) ) ;
337+
338+ // unordered: render_calls_for_header <- header_entry, cluster_id
339+ if self . cfg . show_call_nodes {
340+ for child_root_hid in nested_children {
341+ self . render_calls_for_header (
342+ * child_root_hid,
343+ self . header_entry [ child_root_hid] ,
344+ Some ( cluster_id) ,
345+ ) ;
370346 }
371- branch_exits. extend ( exits) ;
372347 }
373348
374- // NOTE: here we discard the Vec<> from `build_header`!
375- let md_ids_only : Vec < _ > = md_children
349+ // post-order: collect branch exits <- header_exits
350+ let branch_exits : Vec < _ > = nested_children
376351 . iter ( )
352+ . flat_map ( |child_hid| & self . header_exits [ child_hid] )
377353 . copied ( )
378- . map ( |ch| self . build_header ( ch, visited_scopes, Some ( cluster_id) ) . 0 )
379354 . collect ( ) ;
380355
356+ let md_ids_only: Vec < _ > = md_children. iter ( ) . map ( |ch| self . header_entry [ ch] ) . collect ( ) ;
357+
381358 if let Some ( first_md) = md_ids_only. first ( ) . copied ( ) {
382359 if !branch_exits. is_empty ( ) {
383360 for e in branch_exits. iter ( ) {
@@ -393,10 +370,11 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
393370 } ) ;
394371 }
395372 }
396- for win in md_ids_only. windows ( 2 ) {
397- let ( a, b) = ( & win[ 0 ] , & win[ 1 ] ) ;
398- self . graph . edges . push ( Edge { from : * a, to : * b } ) ;
399- }
373+ self . graph . edges . extend ( md_ids_only. windows ( 2 ) . map ( |win| {
374+ let from = win[ 0 ] ;
375+ let to = win[ 1 ] ;
376+ Edge { from, to }
377+ } ) ) ;
400378 let outward = if let Some ( last) = md_ids_only. last ( ) . copied ( ) {
401379 vec ! [ last]
402380 } else {
@@ -406,6 +384,54 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
406384 return ( decision_id, outward) ;
407385 }
408386
387+ let single_nested_child_has_multiple_items = nested_children. len ( ) == 1 && {
388+ let child_root = self . by_hid [ & nested_children[ 0 ] ] ;
389+ let count = self . index . headers_in_scope_iter ( child_root. scope ) . count ( ) ;
390+ count > 1
391+ } ;
392+
393+ let total_children = md_children. len ( ) + nested_children. len ( ) ;
394+
395+ let should_flatten =
396+ total_children <= MAX_CHILDREN_TO_FLATTEN && !single_nested_child_has_multiple_items;
397+
398+ if should_flatten {
399+ let node_id = self . new_node_id ( ) ;
400+ let span = SerializedSpan :: serialize ( & header. span ) ;
401+ self . span_map . insert ( node_id, span. clone ( ) ) ;
402+ self . graph . nodes . push ( Node {
403+ id : node_id,
404+ label : header. title . as_ref ( ) ,
405+ kind : NodeKind :: Header ( hid, Some ( span. clone ( ) ) ) ,
406+ cluster : parent_cluster,
407+ } ) ;
408+ self . header_entry . insert ( hid, node_id) ;
409+ let exits = if md_children. len ( ) == 1 {
410+ let ( c_entry, c_exits) =
411+ self . build_header ( md_children[ 0 ] , visited_scopes, parent_cluster) ;
412+ self . graph . edges . push ( Edge {
413+ from : node_id,
414+ to : c_entry,
415+ } ) ;
416+ c_exits
417+ } else if nested_children. len ( ) == 1 {
418+ let child_root_hid = nested_children[ 0 ] ;
419+ let child_scope = self . by_hid [ & child_root_hid] . scope ;
420+ self . build_scope_sequence ( child_scope, visited_scopes, parent_cluster) ;
421+ let ( c_entry, c_exits) =
422+ self . build_header ( child_root_hid, visited_scopes, parent_cluster) ;
423+ self . graph . edges . push ( Edge {
424+ from : node_id,
425+ to : c_entry,
426+ } ) ;
427+ c_exits
428+ } else {
429+ vec ! [ node_id]
430+ } ;
431+ self . header_exits . insert ( hid, exits. clone ( ) ) ;
432+ return ( node_id, exits) ;
433+ }
434+
409435 let cluster_id = self . new_cluster_id ( ) ;
410436 self . graph . clusters . push ( Cluster {
411437 id : cluster_id,
@@ -415,6 +441,7 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
415441 } ) ;
416442
417443 // Merge markdown children and direct nested roots, preserving each list's internal order
444+ // NOTE: we could do this merge beforehand! & get both nested & md_children.
418445 let items_merged = merge_by_pos ( self . by_hid , & md_children, & nested_children) ;
419446
420447 let mut first_rep: Option < _ > = None ;
@@ -472,6 +499,8 @@ impl<'index, 'pre> GraphBuilder<'index, 'pre> {
472499 ( entry, exits)
473500 }
474501
502+ /// If header is in [`HeaderIndex::header_calls`], inserts & links a call node to the
503+ /// given header node.
475504 fn render_calls_for_header (
476505 & mut self ,
477506 hid : Hid ,
0 commit comments