File Coverage

blib/lib/PPI/Node.pm
Criterion Covered Total %
statement 226 244 92.6
branch 101 132 76.5
condition 12 15 80.0
subroutine 33 34 97.0
pod 19 20 95.0
total 391 445 87.8


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 68     68   369 use strict;
  68         1672  
  68         3949  
52 68     68   300 use Carp ();
  68         1555  
  68         2688  
53 68     68   3328 use Scalar::Util qw{refaddr};
  68         1547  
  68         6420  
54 68     68   3334 use Params::Util qw{_INSTANCE _CLASS _CODELIKE _NUMBER};
  68         1723  
  68         6009  
55 68     68   6275 use PPI::Element ();
  68         101  
  68         7456  
56 68     68   29552 use PPI::Singletons '%_PARENT', '%_POSITION_CACHE';
  68         175  
  68         162679  
57              
58             our $VERSION = '1.287';
59              
60             our @ISA = "PPI::Element";
61              
62              
63              
64              
65              
66             #####################################################################
67             # The basic constructor
68              
69             sub new {
70 16840   33 16840 0 50506 my $class = ref $_[0] || $_[0];
71 16840         52914 bless { children => [] }, $class;
72             }
73              
74              
75              
76              
77              
78             #####################################################################
79             # PDOM Methods
80              
81             =pod
82              
83             =head2 scope
84              
85             The C method returns true if the node represents a lexical scope
86             boundary, or false if it does not.
87              
88             =cut
89              
90             ### XS -> PPI/XS.xs:_PPI_Node__scope 0.903+
91             sub scope() { '' }
92              
93             =pod
94              
95             =head2 add_element $Element
96              
97             The C method adds a L object to the end of a
98             C. Because Elements maintain links to their parent, an
99             Element can only be added to a single Node.
100              
101             Returns true if the L was added. Returns C if the
102             Element was already within another Node, or the method is not passed
103             a L object.
104              
105             =cut
106              
107             sub add_element {
108 1     1 1 10 my $self = shift;
109              
110             # Check the element
111 1 50       9 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
112 1 50       5 $_PARENT{refaddr $Element} and return undef;
113              
114             # Add the argument to the elements
115 1         1 push @{$self->{children}}, $Element;
  1         3  
116             Scalar::Util::weaken(
117 1         3 $_PARENT{refaddr $Element} = $self
118             );
119              
120 1         2 1;
121             }
122              
123             # In a typical run profile, add_element is the number 1 resource drain.
124             # This is a highly optimised unsafe version, for internal use only.
125             sub __add_element {
126             Scalar::Util::weaken(
127 0     0   0 $_PARENT{refaddr $_[1]} = $_[0]
128             );
129 0         0 push @{$_[0]->{children}}, $_[1];
  0         0  
130             }
131              
132             =pod
133              
134             =head2 elements
135              
136             The C method accesses all child elements B within
137             the C object. Note that in the base of the L
138             classes, this C include the brace tokens at either end of the
139             structure.
140              
141             Returns a list of zero or more L objects.
142              
143             Alternatively, if called in the scalar context, the C method
144             returns a count of the number of elements.
145              
146             =cut
147              
148             sub elements {
149 2 50   2 1 2262 if ( wantarray ) {
150 2         3 return @{$_[0]->{children}};
  2         7  
151             } else {
152 0         0 return scalar @{$_[0]->{children}};
  0         0  
153             }
154             }
155              
156             =pod
157              
158             =head2 first_element
159              
160             The C method accesses the first element structurally within
161             the C object. As for the C method, this does include
162             the brace tokens for L objects.
163              
164             Returns a L object, or C if for some reason the
165             C object does not contain any elements.
166              
167             =cut
168              
169             # Normally the first element is also the first child
170             sub first_element {
171 15     15 1 2753 $_[0]->{children}->[0];
172             }
173              
174             =pod
175              
176             =head2 last_element
177              
178             The C method accesses the last element structurally within
179             the C object. As for the C method, this does include
180             the brace tokens for L objects.
181              
182             Returns a L object, or C if for some reason the
183             C object does not contain any elements.
184              
185             =cut
186              
187             # Normally the last element is also the last child
188             sub last_element {
189 11     11 1 54 $_[0]->{children}->[-1];
190             }
191              
192             =pod
193              
194             =head2 children
195              
196             The C method accesses all child elements lexically within the
197             C object. Note that in the case of the L
198             classes, this does B include the brace tokens at either end of the
199             structure.
200              
201             Returns a list of zero of more L objects.
202              
203             Alternatively, if called in the scalar context, the C method
204             returns a count of the number of lexical children.
205              
206             =cut
207              
208             # In the default case, this is the same as for the elements method
209             sub children {
210 2191 50   2191 1 138952 wantarray ? @{$_[0]->{children}} : scalar @{$_[0]->{children}};
  2191         8232  
  0         0  
211             }
212              
213             =pod
214              
215             =head2 schildren
216              
217             The C method is really just a convenience, the significant-only
218             variation of the normal C method.
219              
220             In list context, returns a list of significant children. In scalar context,
221             returns the number of significant children.
222              
223             =cut
224              
225             sub schildren {
226 61963 100   61963 1 9212572 return grep { $_->significant } @{$_[0]->{children}} if wantarray;
  124094         211209  
  30847         52037  
227 31116         37501 my $count = 0;
228 31116         32283 foreach ( @{$_[0]->{children}} ) {
  31116         61914  
229 108903 100       206708 $count++ if $_->significant;
230             }
231 31116         78915 return $count;
232             }
233              
234             =pod
235              
236             =head2 child $index
237              
238             The C method accesses a child L object by its
239             position within the Node.
240              
241             Returns a L object, or C if there is no child
242             element at that node.
243              
244             =cut
245              
246             sub child {
247 860     860 1 114259 my ( $self, $index ) = @_;
248 860 100       3287 PPI::Exception->throw( "method child() needs an index" )
249             if not defined _NUMBER $index;
250 858         4068 $self->{children}->[$index];
251             }
252              
253             =pod
254              
255             =head2 schild $index
256              
257             The lexical structure of the Perl language ignores 'insignificant' items,
258             such as whitespace and comments, while L treats these items as valid
259             tokens so that it can reassemble the file at any time. Because of this,
260             in many situations there is a need to find an Element within a Node by
261             index, only counting lexically significant Elements.
262              
263             The C method returns a child Element by index, ignoring
264             insignificant Elements. The index of a child Element is specified in the
265             same way as for a normal array, with the first Element at index 0, and
266             negative indexes used to identify a "from the end" position.
267              
268             =cut
269              
270             sub schild {
271 175742     175742 1 7590426 my $self = shift;
272 175742         202349 my $idx = 0 + shift;
273 175742         232849 my $el = $self->{children};
274 175742 100       256816 if ( $idx < 0 ) {
275 32531         35024 my $cursor = 0;
276 32531         62662 while ( exists $el->[--$cursor] ) {
277 33855 100 100     132962 return $el->[$cursor] if $el->[$cursor]->significant and ++$idx >= 0;
278             }
279             } else {
280 143211         153221 my $cursor = -1;
281 143211         260231 while ( exists $el->[++$cursor] ) {
282 194884 100 100     954264 return $el->[$cursor] if $el->[$cursor]->significant and --$idx < 0;
283             }
284             }
285 3450         8732 undef;
286             }
287              
288             =pod
289              
290             =head2 contains $Element
291              
292             The C method is used to determine if another L
293             object is logically "within" a C. For the special case of the
294             brace tokens at either side of a L object, they are
295             generally considered "within" a L object, even if they are
296             not actually in the elements for the L.
297              
298             Returns true if the L is within us, false if not, or C
299             on error.
300              
301             =cut
302              
303             sub contains {
304 34     34 1 20614 my $self = shift;
305 34 100       284 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
306              
307             # Iterate up the Element's parent chain until we either run out
308             # of parents, or get to ourself.
309 29         134 while ( $Element = $Element->parent ) {
310 79 100       244 return 1 if refaddr($self) == refaddr($Element);
311             }
312              
313 0         0 '';
314             }
315              
316             =pod
317              
318             =head2 find $class | \&wanted
319              
320             The C method is used to search within a code tree for
321             L objects that meet a particular condition.
322              
323             To specify the condition, the method can be provided with either a simple
324             class name (full or shortened), or a C/function reference.
325              
326             # Find all single quotes in a Document (which is a Node)
327             $Document->find('PPI::Quote::Single');
328            
329             # The same thing with a shortened class name
330             $Document->find('Quote::Single');
331            
332             # Anything more elaborate, we go with the sub
333             $Document->find( sub {
334             # At the top level of the file...
335             $_[1]->parent == $_[0]
336             and (
337             # ...find all comments and POD
338             $_[1]->isa('PPI::Token::Pod')
339             or
340             $_[1]->isa('PPI::Token::Comment')
341             )
342             } );
343              
344             The function will be passed two arguments, the top-level C
345             you are searching in and the current L that the condition
346             is testing.
347              
348             The anonymous function should return one of three values. Returning true
349             indicates a condition match, defined-false (C<0> or C<''>) indicates
350             no-match, and C indicates no-match and no-descend.
351              
352             In the last case, the tree walker will skip over anything below the
353             C-returning element and move on to the next element at the same
354             level.
355              
356             To halt the entire search and return C immediately, a condition
357             function should throw an exception (i.e. C).
358              
359             Note that this same wanted logic is used for all methods documented to
360             have a C<\&wanted> parameter, as this one does.
361              
362             The C method returns a reference to an array of L
363             objects that match the condition, false (but defined) if no Elements match
364             the condition, or C if you provide a bad condition, or an error
365             occurs during the search process.
366              
367             In the case of a bad condition, a warning will be emitted as well.
368              
369             =cut
370              
371             sub find {
372 5202     5202 1 5435595 my $self = shift;
373 5202 100       16104 my $wanted = $self->_wanted(shift) or return undef;
374              
375             # Use a queue based search, rather than a recursive one
376 5199         8146 my @found;
377 5199         7680 my @queue = @{$self->{children}};
  5199         16919  
378 5199         8032 my $ok = eval {
379 5199         10990 while ( @queue ) {
380 355156         339958 my $Element = shift @queue;
381 355156         1374081 my $rv = &$wanted( $self, $Element );
382 355156 100       843330 push @found, $Element if $rv;
383              
384             # Support "don't descend on undef return"
385 355156 50       417914 next unless defined $rv;
386              
387             # Skip if the Element doesn't have any children
388 355156 100       730428 next unless $Element->isa('PPI::Node');
389              
390             # Depth-first keeps the queue size down and provides a
391             # better logical order.
392 60244 100       111042 if ( $Element->isa('PPI::Structure') ) {
393 22114 100       39271 unshift @queue, $Element->finish if $Element->finish;
394 22114         22680 unshift @queue, @{$Element->{children}};
  22114         42871  
395 22114 50       33694 unshift @queue, $Element->start if $Element->start;
396             } else {
397 38130         37385 unshift @queue, @{$Element->{children}};
  38130         101325  
398             }
399             }
400 5199         8356 1;
401             };
402 5199 50       8983 if ( !$ok ) {
403             # Caught exception thrown from the wanted function
404 0         0 return undef;
405             }
406              
407 5199 100       34606 @found ? \@found : '';
408             }
409              
410             =pod
411              
412             =head2 find_first $class | \&wanted
413              
414             If the normal C method is like a grep, then C is
415             equivalent to the L C function.
416              
417             Given an element class or a wanted function, it will search depth-first
418             through a tree until it finds something that matches the condition,
419             returning the first Element that it encounters.
420              
421             See the C method for details on the format of the search condition.
422              
423             Returns the first L object that matches the condition, false
424             if nothing matches the condition, or C if given an invalid condition,
425             or an error occurs.
426              
427             =cut
428              
429             sub find_first {
430 2257     2257 1 42154 my $self = shift;
431 2257 50       7077 my $wanted = $self->_wanted(shift) or return undef;
432              
433             # Use the same queue-based search as for ->find
434 2257         3585 my @queue = @{$self->{children}};
  2257         15503  
435 2257         3236 my $rv;
436 2257         3552 my $ok = eval {
437             # The defined() here prevents a ton of calls to PPI::Util::TRUE
438 2257         5253 while ( @queue ) {
439 769889         723729 my $Element = shift @queue;
440 769889         7998054 my $element_rv = $wanted->( $self, $Element );
441 769889 100       1021630 if ( $element_rv ) {
442 39         52 $rv = $Element;
443 39         69 last;
444             }
445              
446             # Support "don't descend on undef return"
447 769850 100       872895 next if !defined $element_rv;
448              
449             # Skip if the Element doesn't have any children
450 745742 100       1521776 next if !$Element->isa('PPI::Node');
451              
452             # Depth-first keeps the queue size down and provides a
453             # better logical order.
454 114359 100       205051 if ( $Element->isa('PPI::Structure') ) {
455 43255 100       74487 unshift @queue, $Element->finish if defined($Element->finish);
456 43255         43121 unshift @queue, @{$Element->{children}};
  43255         88991  
457 43255 50       68272 unshift @queue, $Element->start if defined($Element->start);
458             } else {
459 71104         65557 unshift @queue, @{$Element->{children}};
  71104         211465  
460             }
461             }
462 2257         3859 1;
463             };
464 2257 50       4394 if ( !$ok ) {
465             # Caught exception thrown from the wanted function
466 0         0 return undef;
467             }
468              
469 2257 100       24738 $rv or '';
470             }
471              
472             =pod
473              
474             =head2 find_any $class | \&wanted
475              
476             The C method is a short-circuiting true/false method that behaves
477             like the normal C method, but returns true as soon as it finds any
478             Elements that match the search condition.
479              
480             See the C method for details on the format of the search condition.
481              
482             Returns true if any Elements that match the condition can be found, false if
483             not, or C if given an invalid condition, or an error occurs.
484              
485             =cut
486              
487             sub find_any {
488 2217     2217 1 642511 my $self = shift;
489 2217         7134 my $rv = $self->find_first(@_);
490 2217 100       13641 $rv ? 1 : $rv; # false or undef
491             }
492              
493             =pod
494              
495             =head2 remove_child $Element
496              
497             If passed a L object that is a direct child of the Node,
498             the C method will remove the C intact, along
499             with any of its children. As such, this method acts essentially as a
500             'cut' function.
501              
502             If successful, returns the removed element. Otherwise, returns C.
503              
504             =cut
505              
506             sub remove_child {
507 66     66 1 81 my $self = shift;
508 66 50       289 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
509              
510             # Find the position of the child
511 66         88 my $key = refaddr $child;
512 66         156 my $p = $self->__position($child);
513 66 100       118 return undef unless defined $p;
514              
515             # Splice it out, and remove the child's parent entry
516 65         65 splice( @{$self->{children}}, $p, 1 );
  65         119  
517 65         106 delete $_PARENT{$key};
518              
519 65         213 $child;
520             }
521              
522             =head2 replace_child $Element, $Replacement
523              
524             If successful, returns the replace element. Otherwise, returns C.
525              
526             =cut
527              
528             sub replace_child {
529 4     4 1 16 my $self = shift;
530              
531 4 50       31 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
532 4 50       54 my $replacement = _INSTANCE(shift, 'PPI::Element') or return undef;
533              
534 4         21 my $success = $self->__replace_child( $child, $replacement );
535              
536 4 100       13 return $success ? $replacement : undef;
537             }
538              
539             =pod
540              
541             =head2 prune $class | \&wanted
542              
543             The C method is used to strip L objects out of a code
544             tree. The argument is the same as for the C method, either a class
545             name, or an anonymous subroutine which returns true/false. Any Element
546             that matches the class|wanted will be deleted from the code tree, along
547             with any of its children.
548              
549             The C method returns the number of C objects that matched
550             and were removed, B. This might also be zero, so avoid a
551             simple true/false test on the return false of the C method. It
552             returns C on error, which you probably B test for.
553              
554             =cut
555              
556             sub prune {
557 30     30 1 3081 my $self = shift;
558 30 50       1368 my $wanted = $self->_wanted(shift) or return undef;
559              
560             # Use a depth-first queue search
561 30         35 my $pruned = 0;
562 30         95 my @queue = $self->children;
563 30         36 my $ok = eval {
564 30         94 while ( my $element = shift @queue ) {
565 269         2244 my $rv = &$wanted( $self, $element );
566 269 100       369 if ( $rv ) {
567             # Delete the child
568 62 50       148 $element->delete or return undef;
569 62         77 $pruned++;
570 62         134 next;
571             }
572              
573             # Support the undef == "don't descend"
574 207 50       255 next unless defined $rv;
575              
576 207 100       772 if ( _INSTANCE($element, 'PPI::Node') ) {
577             # Depth-first keeps the queue size down
578 43         75 unshift @queue, $element->children;
579             }
580             }
581 30         38 1;
582             };
583 30 50       71 if ( !$ok ) {
584             # Caught exception thrown from the wanted function
585 0         0 return undef;
586             }
587              
588 30         190 $pruned;
589             }
590              
591             # This method is likely to be very heavily used, so take
592             # it slowly and carefully.
593             ### NOTE: Renaming this function or changing either to self will probably
594             ### break File::Find::Rule::PPI
595             sub _wanted {
596 7489     7489   11362 my $either = shift;
597 7489 100       19763 my $it = defined($_[0]) ? shift : do {
598 1 50       3 Carp::carp('Undefined value passed as search condition') if $^W;
599 1         6 return undef;
600             };
601              
602             # Has the caller provided a wanted function directly
603 7488 100       33860 return $it if _CODELIKE($it);
604 3698 100       8725 if ( ref $it ) {
605             # No other ref types are supported
606 1 50       3 Carp::carp('Illegal non-CODE reference passed as search condition') if $^W;
607 1         6 return undef;
608             }
609              
610             # The first argument should be an Element class, possibly in shorthand
611 3697 100       14247 $it = "PPI::$it" unless substr($it, 0, 5) eq 'PPI::';
612 3697 100 66     13600 unless ( _CLASS($it) and $it->isa('PPI::Element') ) {
613             # We got something, but it isn't an element
614 1 50       20 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
615 1         4 return undef;
616             }
617              
618             # Create the class part of the wanted function
619 3696         76438 my $wanted_class = "\n\treturn '' unless \$_[1]->isa('$it');";
620              
621             # Have we been given a second argument to check the content
622 3696         5878 my $wanted_content = '';
623 3696 50       8598 if ( defined $_[0] ) {
624 0         0 my $content = shift;
625 0 0       0 if ( ref $content eq 'Regexp' ) {
    0          
626 0         0 $content = "$content";
627             } elsif ( ref $content ) {
628             # No other ref types are supported
629 0 0       0 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
630 0         0 return undef;
631             } else {
632 0         0 $content = quotemeta $content;
633             }
634              
635             # Complete the content part of the wanted function
636 0         0 $wanted_content .= "\n\treturn '' unless defined \$_[1]->{content};";
637 0         0 $wanted_content .= "\n\treturn '' unless \$_[1]->{content} =~ /$content/;";
638             }
639              
640             # Create the complete wanted function
641 3696         8325 my $code = "sub {"
642             . $wanted_class
643             . $wanted_content
644             . "\n\t1;"
645             . "\n}";
646              
647             # Compile the wanted function
648 3696         368347 $code = eval $code;
649 3696 50       21822 (ref $code eq 'CODE') ? $code : undef;
650             }
651              
652              
653              
654              
655              
656             ####################################################################
657             # PPI::Element overloaded methods
658              
659             sub tokens {
660 79491     79491 1 77672 map { $_->tokens } @{$_[0]->{children}};
  375987         547541  
  79491         142546  
661             }
662              
663             ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
664             sub content {
665 101916     101916 1 131916 join '', map { $_->content } @{$_[0]->{children}};
  613426         777032  
  101916         156404  
666             }
667              
668             # Clone as normal, but then go down and relink all the _PARENT entries
669             sub clone {
670 6     6 1 815 my $self = shift;
671 6         30 my $clone = $self->SUPER::clone;
672 6         25 $clone->__link_children;
673 6         23 $clone;
674             }
675              
676             sub location {
677 8227     8227 1 18815 my $self = shift;
678 8227 100       22802 my $first = $self->{children}->[0] or return undef;
679 8224         12564 $first->location;
680             }
681              
682              
683              
684              
685              
686             #####################################################################
687             # Internal Methods
688              
689             sub DESTROY {
690 117797     117797   10599014 local $_;
691 117797 100       193297 if ( $_[0]->{children} ) {
692 16865         33873 my @queue = $_[0];
693 16865         44314 while ( defined($_ = shift @queue) ) {
694 625709 100       904517 unshift @queue, @{delete $_->{children}} if $_->{children};
  117777         222131  
695              
696             # Remove all internal/private weird crosslinking so that
697             # the cascading DESTROY calls will get called properly.
698 625709         1151288 %$_ = ();
699             }
700             }
701              
702 117797         202064 $_[0]->SUPER::DESTROY;
703             }
704              
705             sub __position {
706 4167     4167   4863 my ( $self, $child ) = @_;
707 4167         13388 my $key = refaddr $child;
708              
709             return undef unless #
710 4167 50       5740 my $elements = $self->{children};
711              
712 4167 100       7015 if (defined (my $position = $_POSITION_CACHE{$key})) {
713 2344         2441 my $maybe_child = $elements->[$position];
714 2344 100 100     6918 return $position if defined $maybe_child and refaddr $maybe_child == $key;
715             }
716              
717 1859         2012 delete $_POSITION_CACHE{$key};
718              
719 1859         1859 $_POSITION_CACHE{refaddr $elements->[$_]} = $_ for 0 .. $#{$elements};
  1859         16214  
720              
721 1859         3276 return $_POSITION_CACHE{$key};
722             }
723              
724             # Insert one or more elements before a child
725             sub __insert_before_child {
726 2     2   4 my ( $self, $child, @insertions ) = @_;
727 2         3 my $key = refaddr $child;
728 2         6 my $p = $self->__position($child);
729 2         5 foreach ( @insertions ) {
730             Scalar::Util::weaken(
731 2         6 $_PARENT{refaddr $_} = $self
732             );
733             }
734 2         4 splice( @{$self->{children}}, $p, 0, @insertions );
  2         5  
735 2         4 1;
736             }
737              
738             # Insert one or more elements after a child
739             sub __insert_after_child {
740 2     2   20 my ( $self, $child, @insertions ) = @_;
741 2         2 my $key = refaddr $child;
742 2         10 my $p = $self->__position($child);
743 2         5 foreach ( @insertions ) {
744             Scalar::Util::weaken(
745 2         6 $_PARENT{refaddr $_} = $self
746             );
747             }
748 2         3 splice( @{$self->{children}}, $p + 1, 0, @insertions );
  2         6  
749 2         6 1;
750             }
751              
752             # Replace a child
753             sub __replace_child {
754 4     4   9 my ( $self, $old_child, @replacements ) = @_;
755 4         7 my $old_child_addr = refaddr $old_child;
756              
757             # Cache parent of new children
758 4         16 my $old_child_index = $self->__position($old_child);
759              
760 4 100       7 return undef if !defined $old_child_index;
761              
762 3         7 foreach ( @replacements ) {
763             Scalar::Util::weaken(
764 3         7 $_PARENT{refaddr $_} = $self
765             );
766             }
767              
768             # Replace old child with new children
769 3         3 splice( @{$self->{children}}, $old_child_index, 1, @replacements );
  3         7  
770              
771             # Uncache parent of old child
772 3         6 delete $_PARENT{$old_child_addr};
773 3         5 1;
774             }
775              
776             # Create PARENT links for an entire tree.
777             # Used when cloning or thawing.
778             sub __link_children {
779 12     12   16 my $self = shift;
780              
781             # Relink all our children ( depth first )
782 12         18 my @queue = ( $self );
783 12         50 while ( my $Node = shift @queue ) {
784             # Link our immediate children
785 33         35 foreach my $Element ( @{$Node->{children}} ) {
  33         53  
786             Scalar::Util::weaken(
787 117         197 $_PARENT{refaddr($Element)} = $Node
788             );
789 117 100       272 unshift @queue, $Element if $Element->isa('PPI::Node');
790             }
791              
792             # If it's a structure, relink the open/close braces
793 33 100       141 next unless $Node->isa('PPI::Structure');
794             Scalar::Util::weaken(
795 4 50       16 $_PARENT{refaddr($Node->start)} = $Node
796             ) if $Node->start;
797             Scalar::Util::weaken(
798 4 50       1436 $_PARENT{refaddr($Node->finish)} = $Node
799             ) if $Node->finish;
800             }
801              
802 12         49 1;
803             }
804              
805             1;
806              
807             =pod
808              
809             =head1 TO DO
810              
811             - Move as much as possible to L
812              
813             =head1 SUPPORT
814              
815             See the L in the main module.
816              
817             =head1 AUTHOR
818              
819             Adam Kennedy Eadamk@cpan.orgE
820              
821             =head1 COPYRIGHT
822              
823             Copyright 2001 - 2011 Adam Kennedy.
824              
825             This program is free software; you can redistribute
826             it and/or modify it under the same terms as Perl itself.
827              
828             The full text of the license can be found in the
829             LICENSE file included with this module.
830              
831             =cut