11use super :: DocNodeWithContext ;
22use super :: GenerateCtx ;
33use crate :: DeclarationDef ;
4+ use crate :: Location ;
45use crate :: js_doc:: JsDocTag ;
56use indexmap:: IndexMap ;
67use std:: borrow:: Cow ;
78use std:: cell:: RefCell ;
89use std:: cmp:: Ordering ;
910use std:: collections:: HashMap ;
11+ use std:: collections:: HashSet ;
1012
1113pub type Partitions < T > = IndexMap < T , Vec < DocNodeWithContext > > ;
1214
2628 doc_nodes : Box < dyn Iterator < Item = Cow < ' a , DocNodeWithContext > > + ' a > ,
2729 flatten_namespaces : bool ,
2830 process : & F ,
31+ visited_refs : & mut HashSet < Location > ,
2932 ) where
3033 F : Fn ( & mut IndexMap < T , Vec < DocNodeWithContext > > , & DocNodeWithContext ) ,
3134 {
@@ -50,19 +53,24 @@ where
5053 ) ,
5154 true ,
5255 process,
56+ visited_refs,
5357 ) ;
5458 }
5559
5660 if let Some ( reference) = decl. reference_def ( ) {
5761 has_reference = true ;
58- partitioner_inner (
59- ctx,
60- partitions,
61- parent_node,
62- Box :: new ( ctx. resolve_reference ( parent_node, & reference. target ) ) ,
63- flatten_namespaces,
64- process,
65- ) ;
62+ if visited_refs. insert ( reference. target . clone ( ) ) {
63+ partitioner_inner (
64+ ctx,
65+ partitions,
66+ parent_node,
67+ Box :: new ( ctx. resolve_reference ( parent_node, & reference. target ) ) ,
68+ flatten_namespaces,
69+ process,
70+ visited_refs,
71+ ) ;
72+ visited_refs. remove ( & reference. target ) ;
73+ }
6674 }
6775 }
6876
97105 Box :: new ( doc_nodes) ,
98106 flatten_namespaces,
99107 process,
108+ & mut HashSet :: new ( ) ,
100109 ) ;
101110
102111 partitions
@@ -233,6 +242,7 @@ pub fn flatten_namespace<'a>(
233242 out : & mut Vec < Cow < ' a , DocNodeWithContext > > ,
234243 parent_node : Option < & DocNodeWithContext > ,
235244 doc_nodes : Box < dyn Iterator < Item = Cow < ' a , DocNodeWithContext > > + ' a > ,
245+ visited_refs : & mut HashSet < Location > ,
236246 ) {
237247 let nodes: Vec < _ > = doc_nodes. collect ( ) ;
238248
@@ -253,21 +263,26 @@ pub fn flatten_namespace<'a>(
253263 out,
254264 Some ( & * * node) ,
255265 Box :: new ( children. into_iter ( ) . map ( Cow :: Owned ) ) ,
266+ visited_refs,
256267 ) ;
257268 }
258269
259270 if let Some ( reference) = decl. reference_def ( ) {
260271 has_reference = true ;
261- let resolved: Vec < _ > = ctx
262- . resolve_reference ( parent_node, & reference. target )
263- . map ( |c| c. into_owned ( ) )
264- . collect ( ) ;
265- partitioner_inner (
266- ctx,
267- out,
268- parent_node,
269- Box :: new ( resolved. into_iter ( ) . map ( Cow :: Owned ) ) ,
270- ) ;
272+ if visited_refs. insert ( reference. target . clone ( ) ) {
273+ let resolved: Vec < _ > = ctx
274+ . resolve_reference ( parent_node, & reference. target )
275+ . map ( |c| c. into_owned ( ) )
276+ . collect ( ) ;
277+ partitioner_inner (
278+ ctx,
279+ out,
280+ parent_node,
281+ Box :: new ( resolved. into_iter ( ) . map ( Cow :: Owned ) ) ,
282+ visited_refs,
283+ ) ;
284+ visited_refs. remove ( & reference. target ) ;
285+ }
271286 }
272287 }
273288
@@ -295,7 +310,13 @@ pub fn flatten_namespace<'a>(
295310
296311 let mut out = vec ! [ ] ;
297312
298- partitioner_inner ( ctx, & mut out, None , Box :: new ( doc_nodes) ) ;
313+ partitioner_inner (
314+ ctx,
315+ & mut out,
316+ None ,
317+ Box :: new ( doc_nodes) ,
318+ & mut HashSet :: new ( ) ,
319+ ) ;
299320
300321 out
301322}
0 commit comments