File Coverage

blib/lib/PPI/Node.pm
Criterion Covered Total %
statement 227 249 91.1
branch 95 126 75.4
condition 9 12 75.0
subroutine 37 40 92.5
pod 19 20 95.0
total 387 447 86.5


line stmt bran cond sub pod time code
1             package PPI::Node;
2              
3             =pod
4              
5             =head1 NAME
6              
7             PPI::Node - Abstract PPI Node class, an Element that can contain other Elements
8              
9             =head1 INHERITANCE
10              
11             PPI::Node
12             isa PPI::Element
13              
14             =head1 SYNOPSIS
15              
16             # Create a typical node (a Document in this case)
17             my $Node = PPI::Document->new;
18            
19             # Add an element to the node( in this case, a token )
20             my $Token = PPI::Token::Word->new('my');
21             $Node->add_element( $Token );
22            
23             # Get the elements for the Node
24             my @elements = $Node->children;
25            
26             # Find all the barewords within a Node
27             my $barewords = $Node->find( 'PPI::Token::Word' );
28            
29             # Find by more complex criteria
30             my $my_tokens = $Node->find( sub { $_[1]->content eq 'my' } );
31            
32             # Remove all the whitespace
33             $Node->prune( 'PPI::Token::Whitespace' );
34            
35             # Remove by more complex criteria
36             $Node->prune( sub { $_[1]->content eq 'my' } );
37              
38             =head1 DESCRIPTION
39              
40             The C class provides an abstract base class for the Element
41             classes that are able to contain other elements L,
42             L, and L.
43              
44             As well as those listed below, all of the methods that apply to
45             L objects also apply to C objects.
46              
47             =head1 METHODS
48              
49             =cut
50              
51 65     65   482 use strict;
  65         125  
  65         1987  
52 65     65   377 use Carp ();
  65         488  
  65         1497  
53 65     65   821 use Scalar::Util qw{refaddr};
  65         173  
  65         3107  
54 65     65   402 use List::Util ();
  65         127  
  65         1815  
55 65     65   375 use Params::Util qw{_INSTANCE _CLASS _CODELIKE _NUMBER};
  65         158  
  65         3625  
56 65     65   444 use PPI::Element ();
  65         169  
  65         1674  
57 65     65   30817 use PPI::Singletons '%_PARENT';
  65         222  
  65         207257  
58              
59             our $VERSION = '1.277';
60              
61             our @ISA = "PPI::Element";
62              
63              
64              
65              
66              
67             #####################################################################
68             # The basic constructor
69              
70             sub new {
71 16767   33 16767 0 56514 my $class = ref $_[0] || $_[0];
72 16767         56842 bless { children => [] }, $class;
73             }
74              
75              
76              
77              
78              
79             #####################################################################
80             # PDOM Methods
81              
82             =pod
83              
84             =head2 scope
85              
86             The C method returns true if the node represents a lexical scope
87             boundary, or false if it does not.
88              
89             =cut
90              
91             ### XS -> PPI/XS.xs:_PPI_Node__scope 0.903+
92             sub scope() { '' }
93              
94             =pod
95              
96             =head2 add_element $Element
97              
98             The C method adds a L object to the end of a
99             C. Because Elements maintain links to their parent, an
100             Element can only be added to a single Node.
101              
102             Returns true if the L was added. Returns C if the
103             Element was already within another Node, or the method is not passed
104             a L object.
105              
106             =cut
107              
108             sub add_element {
109 1     1 1 15 my $self = shift;
110              
111             # Check the element
112 1 50       10 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
113 1 50       6 $_PARENT{refaddr $Element} and return undef;
114              
115             # Add the argument to the elements
116 1         2 push @{$self->{children}}, $Element;
  1         5  
117             Scalar::Util::weaken(
118 1         8 $_PARENT{refaddr $Element} = $self
119             );
120              
121 1         2 1;
122             }
123              
124             # In a typical run profile, add_element is the number 1 resource drain.
125             # This is a highly optimised unsafe version, for internal use only.
126             sub __add_element {
127             Scalar::Util::weaken(
128 0     0   0 $_PARENT{refaddr $_[1]} = $_[0]
129             );
130 0         0 push @{$_[0]->{children}}, $_[1];
  0         0  
131             }
132              
133             =pod
134              
135             =head2 elements
136              
137             The C method accesses all child elements B within
138             the C object. Note that in the base of the L
139             classes, this C include the brace tokens at either end of the
140             structure.
141              
142             Returns a list of zero or more L objects.
143              
144             Alternatively, if called in the scalar context, the C method
145             returns a count of the number of elements.
146              
147             =cut
148              
149             sub elements {
150 2 50   2 1 941 if ( wantarray ) {
151 2         4 return @{$_[0]->{children}};
  2         7  
152             } else {
153 0         0 return scalar @{$_[0]->{children}};
  0         0  
154             }
155             }
156              
157             =pod
158              
159             =head2 first_element
160              
161             The C method accesses the first element structurally within
162             the C object. As for the C method, this does include
163             the brace tokens for L objects.
164              
165             Returns a L object, or C if for some reason the
166             C object does not contain any elements.
167              
168             =cut
169              
170             # Normally the first element is also the first child
171             sub first_element {
172 15     15 1 3158 $_[0]->{children}->[0];
173             }
174              
175             =pod
176              
177             =head2 last_element
178              
179             The C method accesses the last element structurally within
180             the C object. As for the C method, this does include
181             the brace tokens for L objects.
182              
183             Returns a L object, or C if for some reason the
184             C object does not contain any elements.
185              
186             =cut
187              
188             # Normally the last element is also the last child
189             sub last_element {
190 11     11 1 62 $_[0]->{children}->[-1];
191             }
192              
193             =pod
194              
195             =head2 children
196              
197             The C method accesses all child elements lexically within the
198             C object. Note that in the case of the L
199             classes, this does B include the brace tokens at either end of the
200             structure.
201              
202             Returns a list of zero of more L objects.
203              
204             Alternatively, if called in the scalar context, the C method
205             returns a count of the number of lexical children.
206              
207             =cut
208              
209             # In the default case, this is the same as for the elements method
210             sub children {
211 2150 50   2150 1 126842 wantarray ? @{$_[0]->{children}} : scalar @{$_[0]->{children}};
  2150         8064  
  0         0  
212             }
213              
214             =pod
215              
216             =head2 schildren
217              
218             The C method is really just a convenience, the significant-only
219             variation of the normal C method.
220              
221             In list context, returns a list of significant children. In scalar context,
222             returns the number of significant children.
223              
224             =cut
225              
226             sub schildren {
227 60172 100   60172 1 9015898 return grep { $_->significant } @{$_[0]->{children}} if wantarray;
  120715         234492  
  29949         62744  
228 30223         42981 my $count = 0;
229 30223         38870 foreach ( @{$_[0]->{children}} ) {
  30223         67720  
230 105601 100       234253 $count++ if $_->significant;
231             }
232 30223         92942 return $count;
233             }
234              
235             =pod
236              
237             =head2 child $index
238              
239             The C method accesses a child L object by its
240             position within the Node.
241              
242             Returns a L object, or C if there is no child
243             element at that node.
244              
245             =cut
246              
247             sub child {
248 860     860 1 117227 my ( $self, $index ) = @_;
249 860 100       2878 PPI::Exception->throw( "method child() needs an index" )
250             if not defined _NUMBER $index;
251 858         3844 $self->{children}->[$index];
252             }
253              
254             =pod
255              
256             =head2 schild $index
257              
258             The lexical structure of the Perl language ignores 'insignificant' items,
259             such as whitespace and comments, while L treats these items as valid
260             tokens so that it can reassemble the file at any time. Because of this,
261             in many situations there is a need to find an Element within a Node by
262             index, only counting lexically significant Elements.
263              
264             The C method returns a child Element by index, ignoring
265             insignificant Elements. The index of a child Element is specified in the
266             same way as for a normal array, with the first Element at index 0, and
267             negative indexes used to identify a "from the end" position.
268              
269             =cut
270              
271             sub schild {
272 146348     146348 1 8407551 my $self = shift;
273 146348         210195 my $idx = 0 + shift;
274 146348         216438 my $el = $self->{children};
275 146348 100       264068 if ( $idx < 0 ) {
276 24223         30223 my $cursor = 0;
277 24223         54350 while ( exists $el->[--$cursor] ) {
278 25451 100 100     128465 return $el->[$cursor] if $el->[$cursor]->significant and ++$idx >= 0;
279             }
280             } else {
281 122125         155664 my $cursor = -1;
282 122125         251871 while ( exists $el->[++$cursor] ) {
283 160545 100 100     934362 return $el->[$cursor] if $el->[$cursor]->significant and --$idx < 0;
284             }
285             }
286 3396         10677 undef;
287             }
288              
289             =pod
290              
291             =head2 contains $Element
292              
293             The C method is used to determine if another L
294             object is logically "within" a C. For the special case of the
295             brace tokens at either side of a L object, they are
296             generally considered "within" a L object, even if they are
297             not actually in the elements for the L.
298              
299             Returns true if the L is within us, false if not, or C
300             on error.
301              
302             =cut
303              
304             sub contains {
305 34     34 1 18794 my $self = shift;
306 34 100       288 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
307              
308             # Iterate up the Element's parent chain until we either run out
309             # of parents, or get to ourself.
310 29         118 while ( $Element = $Element->parent ) {
311 79 100       307 return 1 if refaddr($self) == refaddr($Element);
312             }
313              
314 0         0 '';
315             }
316              
317             =pod
318              
319             =head2 find $class | \&wanted
320              
321             The C method is used to search within a code tree for
322             L objects that meet a particular condition.
323              
324             To specify the condition, the method can be provided with either a simple
325             class name (full or shortened), or a C/function reference.
326              
327             # Find all single quotes in a Document (which is a Node)
328             $Document->find('PPI::Quote::Single');
329            
330             # The same thing with a shortened class name
331             $Document->find('Quote::Single');
332            
333             # Anything more elaborate, we go with the sub
334             $Document->find( sub {
335             # At the top level of the file...
336             $_[1]->parent == $_[0]
337             and (
338             # ...find all comments and POD
339             $_[1]->isa('PPI::Token::Pod')
340             or
341             $_[1]->isa('PPI::Token::Comment')
342             )
343             } );
344              
345             The function will be passed two arguments, the top-level C
346             you are searching in and the current L that the condition
347             is testing.
348              
349             The anonymous function should return one of three values. Returning true
350             indicates a condition match, defined-false (C<0> or C<''>) indicates
351             no-match, and C indicates no-match and no-descend.
352              
353             In the last case, the tree walker will skip over anything below the
354             C-returning element and move on to the next element at the same
355             level.
356              
357             To halt the entire search and return C immediately, a condition
358             function should throw an exception (i.e. C).
359              
360             Note that this same wanted logic is used for all methods documented to
361             have a C<\&wanted> parameter, as this one does.
362              
363             The C method returns a reference to an array of L
364             objects that match the condition, false (but defined) if no Elements match
365             the condition, or C if you provide a bad condition, or an error
366             occurs during the search process.
367              
368             In the case of a bad condition, a warning will be emitted as well.
369              
370             =cut
371              
372             sub find {
373 5141     5141 1 5286248 my $self = shift;
374 5141 100       12840 my $wanted = $self->_wanted(shift) or return undef;
375              
376             # Use a queue based search, rather than a recursive one
377 5138         8991 my @found;
378 5138         6734 my @queue = @{$self->{children}};
  5138         15274  
379 5138         8199 my $ok = eval {
380 5138         11584 while ( @queue ) {
381 344194         453256 my $Element = shift @queue;
382 344194         1793531 my $rv = &$wanted( $self, $Element );
383 344194 100       1079530 push @found, $Element if $rv;
384              
385             # Support "don't descend on undef return"
386 344194 50       514259 next unless defined $rv;
387              
388             # Skip if the Element doesn't have any children
389 344194 100       933568 next unless $Element->isa('PPI::Node');
390              
391             # Depth-first keeps the queue size down and provides a
392             # better logical order.
393 58556 100       133613 if ( $Element->isa('PPI::Structure') ) {
394 21495 100       43822 unshift @queue, $Element->finish if $Element->finish;
395 21495         31125 unshift @queue, @{$Element->{children}};
  21495         62167  
396 21495 50       45250 unshift @queue, $Element->start if $Element->start;
397             } else {
398 37061         45687 unshift @queue, @{$Element->{children}};
  37061         144488  
399             }
400             }
401 5138         9463 1;
402             };
403 5138 50       9988 if ( !$ok ) {
404             # Caught exception thrown from the wanted function
405 0         0 return undef;
406             }
407              
408 5138 100       33497 @found ? \@found : '';
409             }
410              
411             =pod
412              
413             =head2 find_first $class | \&wanted
414              
415             If the normal C method is like a grep, then C is
416             equivalent to the L C function.
417              
418             Given an element class or a wanted function, it will search depth-first
419             through a tree until it finds something that matches the condition,
420             returning the first Element that it encounters.
421              
422             See the C method for details on the format of the search condition.
423              
424             Returns the first L object that matches the condition, false
425             if nothing matches the condition, or C if given an invalid condition,
426             or an error occurs.
427              
428             =cut
429              
430             sub find_first {
431 2209     2209 1 49003 my $self = shift;
432 2209 50       5426 my $wanted = $self->_wanted(shift) or return undef;
433              
434             # Use the same queue-based search as for ->find
435 2209         4372 my @queue = @{$self->{children}};
  2209         11327  
436 2209         3315 my $rv;
437 2209         3415 my $ok = eval {
438             # The defined() here prevents a ton of calls to PPI::Util::TRUE
439 2209         5575 while ( @queue ) {
440 734080         1011573 my $Element = shift @queue;
441 734080         10303375 my $element_rv = $wanted->( $self, $Element );
442 734080 100       1379860 if ( $element_rv ) {
443 39         67 $rv = $Element;
444 39         81 last;
445             }
446              
447             # Support "don't descend on undef return"
448 734041 100       1167490 next if !defined $element_rv;
449              
450             # Skip if the Element doesn't have any children
451 710333 100       2014706 next if !$Element->isa('PPI::Node');
452              
453             # Depth-first keeps the queue size down and provides a
454             # better logical order.
455 110558 100       257961 if ( $Element->isa('PPI::Structure') ) {
456 41863 100       87812 unshift @queue, $Element->finish if defined($Element->finish);
457 41863         57519 unshift @queue, @{$Element->{children}};
  41863         132324  
458 41863 50       79329 unshift @queue, $Element->start if defined($Element->start);
459             } else {
460 68695         92949 unshift @queue, @{$Element->{children}};
  68695         342405  
461             }
462             }
463 2209         4958 1;
464             };
465 2209 50       5040 if ( !$ok ) {
466             # Caught exception thrown from the wanted function
467 0         0 return undef;
468             }
469              
470 2209 100       22637 $rv or '';
471             }
472              
473             =pod
474              
475             =head2 find_any $class | \&wanted
476              
477             The C method is a short-circuiting true/false method that behaves
478             like the normal C method, but returns true as soon as it finds any
479             Elements that match the search condition.
480              
481             See the C method for details on the format of the search condition.
482              
483             Returns true if any Elements that match the condition can be found, false if
484             not, or C if given an invalid condition, or an error occurs.
485              
486             =cut
487              
488             sub find_any {
489 2169     2169 1 614597 my $self = shift;
490 2169         5692 my $rv = $self->find_first(@_);
491 2169 100       13827 $rv ? 1 : $rv; # false or undef
492             }
493              
494             =pod
495              
496             =head2 remove_child $Element
497              
498             If passed a L object that is a direct child of the Node,
499             the C method will remove the C intact, along
500             with any of its children. As such, this method acts essentially as a
501             'cut' function.
502              
503             If successful, returns the removed element. Otherwise, returns C.
504              
505             =cut
506              
507             sub remove_child {
508 66     66 1 107 my $self = shift;
509 66 50       319 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
510              
511             # Find the position of the child
512 66         158 my $key = refaddr $child;
513             my $p = List::Util::first {
514 201     201   360 refaddr $self->{children}[$_] == $key
515 66         227 } 0..$#{$self->{children}};
  66         232  
516 66 100       239 return undef unless defined $p;
517              
518             # Splice it out, and remove the child's parent entry
519 65         80 splice( @{$self->{children}}, $p, 1 );
  65         139  
520 65         176 delete $_PARENT{$key};
521              
522 65         217 $child;
523             }
524              
525             =head2 replace_child $Element, $Replacement
526              
527             If successful, returns the replace element. Otherwise, returns C.
528              
529             =cut
530              
531             sub replace_child {
532 4     4 1 20 my $self = shift;
533              
534 4 50       31 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
535 4 50       63 my $replacement = _INSTANCE(shift, 'PPI::Element') or return undef;
536              
537 4         20 my $success = $self->__replace_child( $child, $replacement );
538              
539 4 100       15 return $success ? $replacement : undef;
540             }
541              
542             =pod
543              
544             =head2 prune $class | \&wanted
545              
546             The C method is used to strip L objects out of a code
547             tree. The argument is the same as for the C method, either a class
548             name, or an anonymous subroutine which returns true/false. Any Element
549             that matches the class|wanted will be deleted from the code tree, along
550             with any of its children.
551              
552             The C method returns the number of C objects that matched
553             and were removed, B. This might also be zero, so avoid a
554             simple true/false test on the return false of the C method. It
555             returns C on error, which you probably B test for.
556              
557             =cut
558              
559             sub prune {
560 30     30 1 3224 my $self = shift;
561 30 50       85 my $wanted = $self->_wanted(shift) or return undef;
562              
563             # Use a depth-first queue search
564 30         52 my $pruned = 0;
565 30         86 my @queue = $self->children;
566 30         52 my $ok = eval {
567 30         100 while ( my $element = shift @queue ) {
568 269         2588 my $rv = &$wanted( $self, $element );
569 269 100       507 if ( $rv ) {
570             # Delete the child
571 62 50       166 $element->delete or return undef;
572 62         97 $pruned++;
573 62         160 next;
574             }
575              
576             # Support the undef == "don't descend"
577 207 50       348 next unless defined $rv;
578              
579 207 100       1128 if ( _INSTANCE($element, 'PPI::Node') ) {
580             # Depth-first keeps the queue size down
581 43         123 unshift @queue, $element->children;
582             }
583             }
584 30         61 1;
585             };
586 30 50       74 if ( !$ok ) {
587             # Caught exception thrown from the wanted function
588 0         0 return undef;
589             }
590              
591 30         223 $pruned;
592             }
593              
594             # This method is likely to be very heavily used, so take
595             # it slowly and carefully.
596             ### NOTE: Renaming this function or changing either to self will probably
597             ### break File::Find::Rule::PPI
598             sub _wanted {
599 7380     7380   10822 my $either = shift;
600 7380 100       17376 my $it = defined($_[0]) ? shift : do {
601 1 50       7 Carp::carp('Undefined value passed as search condition') if $^W;
602 1         10 return undef;
603             };
604              
605             # Has the caller provided a wanted function directly
606 7379 100       30000 return $it if _CODELIKE($it);
607 3652 100       8730 if ( ref $it ) {
608             # No other ref types are supported
609 1 50       8 Carp::carp('Illegal non-CODE reference passed as search condition') if $^W;
610 1         6 return undef;
611             }
612              
613             # The first argument should be an Element class, possibly in shorthand
614 3651 100       13456 $it = "PPI::$it" unless substr($it, 0, 5) eq 'PPI::';
615 3651 100 66     11723 unless ( _CLASS($it) and $it->isa('PPI::Element') ) {
616             # We got something, but it isn't an element
617 1 50       24 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
618 1         17 return undef;
619             }
620              
621             # Create the class part of the wanted function
622 3650         73015 my $wanted_class = "\n\treturn '' unless \$_[1]->isa('$it');";
623              
624             # Have we been given a second argument to check the content
625 3650         5477 my $wanted_content = '';
626 3650 50       8328 if ( defined $_[0] ) {
627 0         0 my $content = shift;
628 0 0       0 if ( ref $content eq 'Regexp' ) {
    0          
629 0         0 $content = "$content";
630             } elsif ( ref $content ) {
631             # No other ref types are supported
632 0 0       0 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
633 0         0 return undef;
634             } else {
635 0         0 $content = quotemeta $content;
636             }
637              
638             # Complete the content part of the wanted function
639 0         0 $wanted_content .= "\n\treturn '' unless defined \$_[1]->{content};";
640 0         0 $wanted_content .= "\n\treturn '' unless \$_[1]->{content} =~ /$content/;";
641             }
642              
643             # Create the complete wanted function
644 3650         8227 my $code = "sub {"
645             . $wanted_class
646             . $wanted_content
647             . "\n\t1;"
648             . "\n}";
649              
650             # Compile the wanted function
651 3650         338849 $code = eval $code;
652 3650 50       22210 (ref $code eq 'CODE') ? $code : undef;
653             }
654              
655              
656              
657              
658              
659             ####################################################################
660             # PPI::Element overloaded methods
661              
662             sub tokens {
663 77518     77518 1 89936 map { $_->tokens } @{$_[0]->{children}};
  361486         605004  
  77518         173456  
664             }
665              
666             ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
667             sub content {
668 87566     87566 1 151168 join '', map { $_->content } @{$_[0]->{children}};
  403691         689411  
  87566         168081  
669             }
670              
671             # Clone as normal, but then go down and relink all the _PARENT entries
672             sub clone {
673 6     6 1 1141 my $self = shift;
674 6         31 my $clone = $self->SUPER::clone;
675 6         51 $clone->__link_children;
676 6         26 $clone;
677             }
678              
679             sub location {
680 7979     7979 1 22802 my $self = shift;
681 7979 50       37605 my $first = $self->{children}->[0] or return undef;
682 7979         14424 $first->location;
683             }
684              
685              
686              
687              
688              
689             #####################################################################
690             # Internal Methods
691              
692             sub DESTROY {
693 97246     97246   9865176 local $_;
694 97246 100       188288 if ( $_[0]->{children} ) {
695 16792         33073 my @queue = $_[0];
696 16792         41443 while ( defined($_ = shift @queue) ) {
697 407722 100       749820 unshift @queue, @{delete $_->{children}} if $_->{children};
  97226         214096  
698              
699             # Remove all internal/private weird crosslinking so that
700             # the cascading DESTROY calls will get called properly.
701 407722         1020949 %$_ = ();
702             }
703             }
704              
705             # Remove us from our parent node as normal
706 97246         408033 delete $_PARENT{refaddr $_[0]};
707             }
708              
709             # Find the position of a child
710             sub __position {
711 0     0   0 my $key = refaddr $_[1];
712 0     0   0 List::Util::first { refaddr $_[0]{children}[$_] == $key } 0..$#{$_[0]{children}};
  0         0  
  0         0  
713             }
714              
715             # Insert one or more elements before a child
716             sub __insert_before_child {
717 2     2   5 my $self = shift;
718 2         5 my $key = refaddr shift;
719             my $p = List::Util::first {
720 8     8   16 refaddr $self->{children}[$_] == $key
721 2         12 } 0..$#{$self->{children}};
  2         10  
722 2         16 foreach ( @_ ) {
723             Scalar::Util::weaken(
724 2         11 $_PARENT{refaddr $_} = $self
725             );
726             }
727 2         4 splice( @{$self->{children}}, $p, 0, @_ );
  2         7  
728 2         6 1;
729             }
730              
731             # Insert one or more elements after a child
732             sub __insert_after_child {
733 2     2   4 my $self = shift;
734 2         7 my $key = refaddr shift;
735             my $p = List::Util::first {
736 6     6   14 refaddr $self->{children}[$_] == $key
737 2         14 } 0..$#{$self->{children}};
  2         10  
738 2         10 foreach ( @_ ) {
739             Scalar::Util::weaken(
740 2         14 $_PARENT{refaddr $_} = $self
741             );
742             }
743 2         5 splice( @{$self->{children}}, $p + 1, 0, @_ );
  2         8  
744 2         6 1;
745             }
746              
747             # Replace a child
748             sub __replace_child {
749 4     4   6 my $self = shift;
750 4         10 my $old_child_addr = refaddr shift;
751              
752             # Cache parent of new children
753             my $old_child_index = List::Util::first {
754 12     12   25 refaddr $self->{children}[$_] == $old_child_addr
755 4         19 } 0..$#{$self->{children}};
  4         19  
756              
757 4 100       33 return undef if !defined $old_child_index;
758              
759 3         9 foreach ( @_ ) {
760             Scalar::Util::weaken(
761 3         18 $_PARENT{refaddr $_} = $self
762             );
763             }
764              
765             # Replace old child with new children
766 3         5 splice( @{$self->{children}}, $old_child_index, 1, @_ );
  3         10  
767              
768             # Uncache parent of old child
769 3         9 delete $_PARENT{$old_child_addr};
770 3         6 1;
771             }
772              
773             # Create PARENT links for an entire tree.
774             # Used when cloning or thawing.
775             sub __link_children {
776 12     12   25 my $self = shift;
777              
778             # Relink all our children ( depth first )
779 12         40 my @queue = ( $self );
780 12         64 while ( my $Node = shift @queue ) {
781             # Link our immediate children
782 33         45 foreach my $Element ( @{$Node->{children}} ) {
  33         87  
783             Scalar::Util::weaken(
784 117         400 $_PARENT{refaddr($Element)} = $Node
785             );
786 117 100       379 unshift @queue, $Element if $Element->isa('PPI::Node');
787             }
788              
789             # If it's a structure, relink the open/close braces
790 33 100       179 next unless $Node->isa('PPI::Structure');
791             Scalar::Util::weaken(
792 4 50       20 $_PARENT{refaddr($Node->start)} = $Node
793             ) if $Node->start;
794             Scalar::Util::weaken(
795 4 50       20 $_PARENT{refaddr($Node->finish)} = $Node
796             ) if $Node->finish;
797             }
798              
799 12         65 1;
800             }
801              
802             1;
803              
804             =pod
805              
806             =head1 TO DO
807              
808             - Move as much as possible to L
809              
810             =head1 SUPPORT
811              
812             See the L in the main module.
813              
814             =head1 AUTHOR
815              
816             Adam Kennedy Eadamk@cpan.orgE
817              
818             =head1 COPYRIGHT
819              
820             Copyright 2001 - 2011 Adam Kennedy.
821              
822             This program is free software; you can redistribute
823             it and/or modify it under the same terms as Perl itself.
824              
825             The full text of the license can be found in the
826             LICENSE file included with this module.
827              
828             =cut