5 A set of iterator functions for traversing the various trees and indexes.
6 Each iterator expects closures that operate on the elements in the iterated
12 Params: $node, &$loopsub, &$skipsub, &$applysub, &$recursesub
14 Iterate over $node\'s children. For each iteration:
16 If loopsub( $node, $kid ) returns false, the loop is terminated.
17 If skipsub( $node, $kid ) returns true, the element is skipped.
19 Applysub( $node, $kid ) is called
20 If recursesub( $node, $kid ) returns true, the function recurses into
27 my ( $root, $loopcond, $skipcond, $applysub, $recursecond ) = @_;
30 foreach my $node ( @
{$root->{Kids
}} ) {
32 if ( defined $loopcond ) {
33 return 0 unless $loopcond->( $root, $node );
36 if ( defined $skipcond ) {
37 next if $skipcond->( $root, $node );
40 my $ret = $applysub->( $root, $node );
41 return $ret if defined $ret && $ret;
43 if ( defined $recursecond
44 && $recursecond->( $root, $node ) ) {
45 $ret = Generic
( $node, $loopcond, $skipcond,
46 $applysub, $recursecond)->();
59 my ( $root, $applysub, $recurse ) = @_;
61 return Generic
( $root, undef,
63 return !( $node->{NodeType
} eq "class"
64 || $node->{NodeType
} eq "struct" );
66 $applysub, $recurse );
71 Params: $root, $recurse?, $commonsub, $compoundsub, $membersub,
74 Traverse the ast tree starting at $root, skipping if skipsub returns true.
76 Applying $commonsub( $node, $kid),
77 then $compoundsub( $node, $kid ) or $membersub( $node, $kid ) depending on
78 the Compound flag of the node.
84 my ( $rootnode, $recurse, $commonsub, $compoundsub, $membersub,
87 my $recsub = $recurse ?
sub { return 1 if $_[1]->{Compound
}; }
90 Generic
( $rootnode, undef, $skipsub,
92 my ( $root, $node ) = @_;
95 if ( defined $commonsub ) {
96 $ret = $commonsub->( $root, $node );
97 return $ret if defined $ret;
100 if ( $node->{Compound
} && defined $compoundsub ) {
101 $ret = $compoundsub->( $root, $node );
102 return $ret if defined $ret;
105 if( !$node->{Compound
} && defined $membersub ) {
106 $ret = $membersub->( $root, $node );
107 return $ret if defined $ret;
115 =head2 LocalCompounds
117 Apply $compoundsub( $node ) to all locally defined compound nodes
118 (ie nodes that are not external to the library being processed).
124 my ( $rootnode, $compoundsub ) = @_;
126 return unless defined $rootnode && defined $rootnode->{Kids
};
128 foreach my $kid ( sort { $a->{astNodeName
} cmp $b->{astNodeName
} }
129 @
{$rootnode->{Kids
}} ) {
130 next if !defined $kid->{Compound
};
132 $compoundsub->( $kid ) unless defined $kid->{ExtSource
};
133 LocalCompounds
( $kid, $compoundsub );
139 Params: $node, $levelDownSub, $printSub, $levelUpSub
141 This allows easy hierarchy traversal and printing.
143 Traverses the inheritance hierarchy starting at $node, calling printsub
144 for each node. When recursing downward into the tree, $levelDownSub($node) is
145 called, the recursion takes place, and $levelUpSub is called when the
146 recursion call is completed.
152 my ( $node, $ldownsub, $printsub, $lupsub, $nokidssub ) = @_;
154 return if defined $node->{ExtSource
}
155 && (!defined $node->{InBy
}
156 || !kdocAstUtil
::hasLocalInheritor
( $node ));
158 $printsub->( $node );
160 if ( defined $node->{InBy
} ) {
161 $ldownsub->( $node );
164 sort {$a->{astNodeName
} cmp $b->{astNodeName
}}
165 @
{ $node->{InBy
} } ) {
166 Hierarchy
( $kid, $ldownsub, $printsub, $lupsub );
171 elsif ( defined $nokidssub ) {
172 $nokidssub->( $node );
180 Call $printsub for each outer scope of $node.
185 my ( $node, $printsub ) = @_;
187 my @heritage = kdocAstUtil
::refHeritage
($node);
189 foreach my $innode ( @heritage ) {
190 next if $innode == $node;
191 $printsub->( $innode, $innode->{astNodeName
},
192 $innode->{Type
}, $innode->{TmplType
} )
193 unless !defined $printsub;
202 Call $printsub for each *direct* ancestor of $node.
203 Only multiple inheritance can lead to $printsub being called more than once.
208 my ( $node, $rootnode, $noancessub, $startsub, $printsub,
212 return if $node eq $rootnode;
214 if ( !exists $node->{InList
} ) {
215 $noancessub->( $node ) unless !defined $noancessub;
219 foreach my $innode ( @
{ $node->{InList
} } ) {
220 my $nref = $innode->{Node
}; # real ancestor
221 next if defined $nref && $nref == $rootnode;
223 push @anlist, $innode;
226 if ( $#anlist < 0 ) {
227 $noancessub->( $node ) unless !defined $noancessub;
231 $startsub->( $node ) unless !defined $startsub;
233 foreach my $innode ( sort { $a->{astNodeName
} cmp $b->{astNodeName
} }
237 $printsub->( $innode->{Node
}, $innode->{astNodeName
},
238 $innode->{Type
}, $innode->{TmplType
} )
239 unless !defined $printsub;
242 $endsub->( $node ) unless !defined $endsub;
250 my ( $node, $nodescsub, $startsub, $printsub, $endsub ) = @_;
252 if ( !exists $node->{InBy
} ) {
253 $nodescsub->( $node ) unless !defined $nodescsub;
259 DescendantList
( \
@desclist, $node );
261 if ( $#desclist < 0 ) {
262 $nodescsub->( $node ) unless !defined $nodescsub;
266 $startsub->( $node ) unless !defined $startsub;
268 foreach my $innode ( sort { $a->{astNodeName
} cmp $b->{astNodeName
} }
271 $printsub->( $innode)
272 unless !defined $printsub;
275 $endsub->( $node ) unless !defined $endsub;
283 my ( $list, $node ) = @_;
285 return unless exists $node->{InBy
};
287 foreach my $kid ( @
{ $node->{InBy
} } ) {
289 DescendantList
( $list, $kid );
299 my ( $rootnode, $allowforward, $recurse,
300 $commonsub, $compoundsub, $membersub ) = @_;
302 Generic
( $rootnode, undef,
304 my( $node, $kid ) = @_;
306 unless (!(defined $kid->{ExtSource
})
307 && ($allowforward || $kid->{NodeType
} ne "Forward")
308 && ($main::doPrivate
|| !($kid->{Access
} =~ /private/))
309 && exists $kid->{DocNode
} ) {
317 my ( $root, $node ) = @_;
321 if ( defined $commonsub ) {
322 $ret = $commonsub->( $root, $node );
323 return $ret if defined $ret;
326 if ( $node->{Compound
} && defined $compoundsub ) {
327 $ret = $compoundsub->( $root, $node );
328 return $ret if defined $ret;
330 elsif( defined $membersub ) {
331 $ret = $membersub->( $root, $node );
332 return $ret if defined $ret;
337 sub { return 1 if $recurse; return; } # recurse
344 my ( $node, $startgrpsub, $methodsub, $endgrpsub, $nokidssub ) = @_;
354 # private (if enabled)
356 if ( !defined $node->{Kids
} ) {
357 $nokidssub->( $node ) if defined $nokidssub;
361 foreach my $acc ( qw
/public protected private/ ) {
362 next if $acc eq "private" && !$main::doPrivate
;
369 my @k_dcop_signals = ();
370 my @k_dcop_hiddens = ();
378 foreach my $kid ( @
{$node->{Kids
}} ) {
379 next unless ( $kid->{Access
} =~ /$access/
380 && !$kid->{ExtSource
})
381 || ( $access eq "public"
382 && ( $kid->{Access
} eq "signals"
383 || $kid->{Access
} =~ "k_dcop" # note the =~
384 || $kid->{Access
} eq "K_DCOP"));
386 my $type = $kid->{NodeType
};
388 if ( $type eq "method" ) {
389 if ( $kid->{Flags
} =~ "s" ) {
392 elsif ( $kid->{Flags
} =~ "l" ) {
395 elsif ( $kid->{Flags
} =~ "n" ) {
398 elsif ( $kid->{Flags
} =~ "d" ) {
401 elsif ( $kid->{Flags
} =~ "z" ) {
402 push @k_dcop_signals, $kid;
404 elsif ( $kid->{Flags
} =~ "y" ) {
405 push @k_dcop_hiddens, $kid;
408 push @methods, $kid; }
410 elsif ( $kid->{Compound
} ) {
411 if ( $type eq "module" ) {
414 elsif ( $type eq "interface" ) {
415 push @interfaces, $kid;
421 elsif ( $type eq "typedef" || $type eq "enum" ) {
430 $uc_access = ucfirst( $access );
432 doGroup
( "$uc_access Types", $node, \
@types, $startgrpsub,
433 $methodsub, $endgrpsub);
434 doGroup
( "Modules", $node, \
@modules, $startgrpsub,
435 $methodsub, $endgrpsub);
436 doGroup
( "Interfaces", $node, \
@interfaces, $startgrpsub,
437 $methodsub, $endgrpsub);
438 doGroup
( "$uc_access Methods", $node, \
@methods, $startgrpsub,
439 $methodsub, $endgrpsub);
440 doGroup
( "$uc_access Slots", $node, \
@slots, $startgrpsub,
441 $methodsub, $endgrpsub);
442 doGroup
( "Signals", $node, \
@signals, $startgrpsub,
443 $methodsub, $endgrpsub);
444 doGroup
( "k_dcop", $node, \
@k_dcops, $startgrpsub,
445 $methodsub, $endgrpsub);
446 doGroup
( "k_dcop_signals", $node, \
@k_dcop_signals, $startgrpsub,
447 $methodsub, $endgrpsub);
448 doGroup
( "k_dcop_hiddens", $node, \
@k_dcop_hiddens, $startgrpsub,
449 $methodsub, $endgrpsub);
450 doGroup
( "$uc_access Static Methods", $node, \
@static,
451 $startgrpsub, $methodsub, $endgrpsub);
452 doGroup
( "$uc_access Members", $node, \
@data, $startgrpsub,
453 $methodsub, $endgrpsub);
459 my ( $name, $node, $list, $startgrpsub, $methodsub, $endgrpsub ) = @_;
461 my ( $hasMembers ) = 0;
462 foreach my $kid ( @
$list ) {
463 if ( !exists $kid->{DocNode
}->{Reimplemented
} ) {
468 return if !$hasMembers;
470 if ( defined $methodsub ) {
471 foreach my $kid ( @
$list ) {
472 if ( !exists $kid->{DocNode
}->{Reimplemented
} ) {
473 $methodsub->( $node, $kid );
478 $endgrpsub->( $name ) if defined $endgrpsub;
483 my ( $root, $startgrpsub, $itemsub, $endgrpsub ) = @_;
485 return 0 unless defined $root->{Groups
};
487 foreach my $groupname ( sort keys %{$root->{Groups
}} ) {
488 next if $groupname eq "astNodeName"||$groupname eq "NodeType";
490 my $group = $root->{Groups
}->{ $group };
491 next unless $group->{Kids
};
493 $startgrpsub->( $group->{astNodeName
}, $group->{Desc
} );
495 foreach my $kid (sort {$a->{astNodeName
} cmp $b->{astNodeName
}}
497 $itemsub->( $root, $kid );
499 $endgrpsub->( $group->{Desc
} );
507 my ( $node, $nonesub, $startsub, $printsub, $endsub ) = @_;
509 if( !defined $node ) {
516 if ( $node->{NodeType
} ne "DocNode" ) {
517 $doc = $node->{DocNode
};
518 if ( !defined $doc ) {
519 $nonesub->() if defined $nonesub;
524 if ( !defined $doc->{See
} ) {
525 $nonesub->() if defined $nonesub;
529 my $see = $doc->{See
};
530 my $ref = $doc->{SeeRef
};
533 $nonesub->() if defined $nonesub;
537 $startsub->( $node ) if defined $startsub;
539 for my $i ( 0..$#$see ) {
540 my $seelabel = $see->[ $i ];
542 if ( defined $ref ) {
543 $seenode = $ref->[ $i ];
546 $printsub->( $seelabel, $seenode ) if defined $printsub;
549 $endsub->( $node ) if defined $endsub;