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 {
@@ -48,18 +51,23 @@ where
4851 ) ,
4952 true ,
5053 process,
54+ visited_refs,
5155 ) ;
5256 }
5357
5458 if let Some ( reference) = decl. reference_def ( ) {
55- partitioner_inner (
56- ctx,
57- partitions,
58- parent_node,
59- Box :: new ( ctx. resolve_reference ( parent_node, & reference. target ) ) ,
60- flatten_namespaces,
61- process,
62- ) ;
59+ if visited_refs. insert ( reference. target . clone ( ) ) {
60+ partitioner_inner (
61+ ctx,
62+ partitions,
63+ parent_node,
64+ Box :: new ( ctx. resolve_reference ( parent_node, & reference. target ) ) ,
65+ flatten_namespaces,
66+ process,
67+ visited_refs,
68+ ) ;
69+ visited_refs. remove ( & reference. target ) ;
70+ }
6371 // hack until reference nodes are separate from normal symbols
6472 continue ' outer;
6573 }
7886 Box :: new ( doc_nodes) ,
7987 flatten_namespaces,
8088 process,
89+ & mut HashSet :: new ( ) ,
8190 ) ;
8291
8392 partitions
@@ -214,6 +223,7 @@ pub fn flatten_namespace<'a>(
214223 out : & mut Vec < Cow < ' a , DocNodeWithContext > > ,
215224 parent_node : Option < & DocNodeWithContext > ,
216225 doc_nodes : Box < dyn Iterator < Item = Cow < ' a , DocNodeWithContext > > + ' a > ,
226+ visited_refs : & mut HashSet < Location > ,
217227 ) {
218228 let nodes: Vec < _ > = doc_nodes. collect ( ) ;
219229
@@ -232,20 +242,25 @@ pub fn flatten_namespace<'a>(
232242 out,
233243 Some ( & * * node) ,
234244 Box :: new ( children. into_iter ( ) . map ( Cow :: Owned ) ) ,
245+ visited_refs,
235246 ) ;
236247 }
237248
238249 if let Some ( reference) = decl. reference_def ( ) {
239- let resolved: Vec < _ > = ctx
240- . resolve_reference ( parent_node, & reference. target )
241- . map ( |c| c. into_owned ( ) )
242- . collect ( ) ;
243- partitioner_inner (
244- ctx,
245- out,
246- parent_node,
247- Box :: new ( resolved. into_iter ( ) . map ( Cow :: Owned ) ) ,
248- ) ;
250+ if visited_refs. insert ( reference. target . clone ( ) ) {
251+ let resolved: Vec < _ > = ctx
252+ . resolve_reference ( parent_node, & reference. target )
253+ . map ( |c| c. into_owned ( ) )
254+ . collect ( ) ;
255+ partitioner_inner (
256+ ctx,
257+ out,
258+ parent_node,
259+ Box :: new ( resolved. into_iter ( ) . map ( Cow :: Owned ) ) ,
260+ visited_refs,
261+ ) ;
262+ visited_refs. remove ( & reference. target ) ;
263+ }
249264 // hack until reference nodes are separate from normal symbols
250265 continue ' outer;
251266 }
@@ -257,7 +272,13 @@ pub fn flatten_namespace<'a>(
257272
258273 let mut out = vec ! [ ] ;
259274
260- partitioner_inner ( ctx, & mut out, None , Box :: new ( doc_nodes) ) ;
275+ partitioner_inner (
276+ ctx,
277+ & mut out,
278+ None ,
279+ Box :: new ( doc_nodes) ,
280+ & mut HashSet :: new ( ) ,
281+ ) ;
261282
262283 out
263284}
0 commit comments