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 69     69   1890 use strict;
  69         1664  
  69         2450  
52 69     69   274 use Carp ();
  69         3258  
  69         4294  
53 69     69   1943 use Scalar::Util qw{refaddr};
  69         3305  
  69         6244  
54 69     69   1778 use Params::Util qw{_INSTANCE _CLASS _CODELIKE _NUMBER};
  69         3575  
  69         7530  
55 69     69   3345 use PPI::Element ();
  69         131  
  69         9544  
56 69     69   30808 use PPI::Singletons '%_PARENT', '%_POSITION_CACHE';
  69         183  
  69         170436  
57              
58             our $VERSION = '1.291';
59              
60             our @ISA = "PPI::Element";
61              
62              
63              
64              
65              
66             #####################################################################
67             # The basic constructor
68              
69             sub new {
70 16845   33 16845 0 50028 my $class = ref $_[0] || $_[0];
71 16845         51138 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       10 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
112 1 50       4 $_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         1 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 860 if ( wantarray ) {
150 2         5 return @{$_[0]->{children}};
  2         11  
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 17     17 1 2802 $_[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 12     12 1 60 $_[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 137043 wantarray ? @{$_[0]->{children}} : scalar @{$_[0]->{children}};
  2191         7598  
  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 62006 100   62006 1 9760853 return grep { $_->significant } @{$_[0]->{children}} if wantarray;
  124134         219258  
  30867         52642  
227 31139         35295 my $count = 0;
228 31139         31916 foreach ( @{$_[0]->{children}} ) {
  31139         59588  
229 108946 100       209993 $count++ if $_->significant;
230             }
231 31139         80636 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 106917 my ( $self, $index ) = @_;
248 860 100       3100 PPI::Exception->throw( "method child() needs an index" )
249             if not defined _NUMBER $index;
250 858         4102 $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 176395     176395 1 7627179 my $self = shift;
272 176395         214648 my $idx = 0 + shift;
273 176395         222629 my $el = $self->{children};
274 176395 100       258850 if ( $idx < 0 ) {
275 32665         35384 my $cursor = 0;
276 32665         59107 while ( exists $el->[--$cursor] ) {
277 33998 100 100     131789 return $el->[$cursor] if $el->[$cursor]->significant and ++$idx >= 0;
278             }
279             } else {
280 143730         152489 my $cursor = -1;
281 143730         265644 while ( exists $el->[++$cursor] ) {
282 195447 100 100     959752 return $el->[$cursor] if $el->[$cursor]->significant and --$idx < 0;
283             }
284             }
285 3519         7894 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 19913 my $self = shift;
305 34 100       275 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         114 while ( $Element = $Element->parent ) {
310 79 100       217 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 5204     5204 1 5200455 my $self = shift;
373 5204 100       14837 my $wanted = $self->_wanted(shift) or return undef;
374              
375             # Use a queue based search, rather than a recursive one
376 5201         7227 my @found;
377 5201         7023 my @queue = @{$self->{children}};
  5201         16173  
378 5201         7492 my $ok = eval {
379 5201         10204 while ( @queue ) {
380 355562         346240 my $Element = shift @queue;
381 355562         1405576 my $rv = &$wanted( $self, $Element );
382 355562 100       852918 push @found, $Element if $rv;
383              
384             # Support "don't descend on undef return"
385 355562 50       411288 next unless defined $rv;
386              
387             # Skip if the Element doesn't have any children
388 355562 100       751706 next unless $Element->isa('PPI::Node');
389              
390             # Depth-first keeps the queue size down and provides a
391             # better logical order.
392 60328 100       111162 if ( $Element->isa('PPI::Structure') ) {
393 22148 100       36959 unshift @queue, $Element->finish if $Element->finish;
394 22148         23005 unshift @queue, @{$Element->{children}};
  22148         42001  
395 22148 50       34540 unshift @queue, $Element->start if $Element->start;
396             } else {
397 38180         37267 unshift @queue, @{$Element->{children}};
  38180         101666  
398             }
399             }
400 5201         7674 1;
401             };
402 5201 50       9308 if ( !$ok ) {
403             # Caught exception thrown from the wanted function
404 0         0 return undef;
405             }
406              
407 5201 100       31521 @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 2262     2262 1 39566 my $self = shift;
431 2262 50       5993 my $wanted = $self->_wanted(shift) or return undef;
432              
433             # Use the same queue-based search as for ->find
434 2262         3542 my @queue = @{$self->{children}};
  2262         14404  
435 2262         3751 my $rv;
436 2262         3039 my $ok = eval {
437             # The defined() here prevents a ton of calls to PPI::Util::TRUE
438 2262         4470 while ( @queue ) {
439 773971         708647 my $Element = shift @queue;
440 773971         7496653 my $element_rv = $wanted->( $self, $Element );
441 773971 100       984871 if ( $element_rv ) {
442 41         54 $rv = $Element;
443 41         76 last;
444             }
445              
446             # Support "don't descend on undef return"
447 773930 100       853174 next if !defined $element_rv;
448              
449             # Skip if the Element doesn't have any children
450 749822 100       1470334 next if !$Element->isa('PPI::Node');
451              
452             # Depth-first keeps the queue size down and provides a
453             # better logical order.
454 114860 100       187509 if ( $Element->isa('PPI::Structure') ) {
455 43420 100       65078 unshift @queue, $Element->finish if defined($Element->finish);
456 43420         42459 unshift @queue, @{$Element->{children}};
  43420         84228  
457 43420 50       60394 unshift @queue, $Element->start if defined($Element->start);
458             } else {
459 71440         67171 unshift @queue, @{$Element->{children}};
  71440         193571  
460             }
461             }
462 2262         3388 1;
463             };
464 2262 50       4131 if ( !$ok ) {
465             # Caught exception thrown from the wanted function
466 0         0 return undef;
467             }
468              
469 2262 100       22544 $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 2220     2220 1 602493 my $self = shift;
489 2220         6816 my $rv = $self->find_first(@_);
490 2220 100       11424 $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 71 my $self = shift;
508 66 50       213 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
509              
510             # Find the position of the child
511 66         77 my $key = refaddr $child;
512 66         143 my $p = $self->__position($child);
513 66 100       93 return undef unless defined $p;
514              
515             # Splice it out, and remove the child's parent entry
516 65         60 splice( @{$self->{children}}, $p, 1 );
  65         95  
517 65         90 delete $_PARENT{$key};
518              
519 65         139 $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 6     6 1 14 my $self = shift;
530              
531 6 50       36 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
532 6 50       56 my $replacement = _INSTANCE(shift, 'PPI::Element') or return undef;
533              
534 6         24 my $success = $self->__replace_child( $child, $replacement );
535              
536 6 100       20 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 2874 my $self = shift;
558 30 50       1419 my $wanted = $self->_wanted(shift) or return undef;
559              
560             # Use a depth-first queue search
561 30         35 my $pruned = 0;
562 30         65 my @queue = $self->children;
563 30         34 my $ok = eval {
564 30         72 while ( my $element = shift @queue ) {
565 269         1753 my $rv = &$wanted( $self, $element );
566 269 100       367 if ( $rv ) {
567             # Delete the child
568 62 50       119 $element->delete or return undef;
569 62         59 $pruned++;
570 62         105 next;
571             }
572              
573             # Support the undef == "don't descend"
574 207 50       236 next unless defined $rv;
575              
576 207 100       701 if ( _INSTANCE($element, 'PPI::Node') ) {
577             # Depth-first keeps the queue size down
578 43         73 unshift @queue, $element->children;
579             }
580             }
581 30         51 1;
582             };
583 30 50       50 if ( !$ok ) {
584             # Caught exception thrown from the wanted function
585 0         0 return undef;
586             }
587              
588 30         166 $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 7496     7496   10754 my $either = shift;
597 7496 100       18198 my $it = defined($_[0]) ? shift : do {
598 1 50       7 Carp::carp('Undefined value passed as search condition') if $^W;
599 1         8 return undef;
600             };
601              
602             # Has the caller provided a wanted function directly
603 7495 100       32949 return $it if _CODELIKE($it);
604 3705 100       7974 if ( ref $it ) {
605             # No other ref types are supported
606 1 50       5 Carp::carp('Illegal non-CODE reference passed as search condition') if $^W;
607 1         7 return undef;
608             }
609              
610             # The first argument should be an Element class, possibly in shorthand
611 3704 100       13754 $it = "PPI::$it" unless substr($it, 0, 5) eq 'PPI::';
612 3704 100 66     12525 unless ( _CLASS($it) and $it->isa('PPI::Element') ) {
613             # We got something, but it isn't an element
614 1 50       27 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
615 1         7 return undef;
616             }
617              
618             # Create the class part of the wanted function
619 3703         72606 my $wanted_class = "\n\treturn '' unless \$_[1]->isa('$it');";
620              
621             # Have we been given a second argument to check the content
622 3703         5864 my $wanted_content = '';
623 3703 50       7609 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 3703         7430 my $code = "sub {"
642             . $wanted_class
643             . $wanted_content
644             . "\n\t1;"
645             . "\n}";
646              
647             # Compile the wanted function
648 3703         358822 $code = eval $code;
649 3703 50       21445 (ref $code eq 'CODE') ? $code : undef;
650             }
651              
652              
653              
654              
655              
656             ####################################################################
657             # PPI::Element overloaded methods
658              
659             sub tokens {
660 79742     79742 1 74647 map { $_->tokens } @{$_[0]->{children}};
  377480         520626  
  79742         134908  
661             }
662              
663             ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
664             sub content {
665 102036     102036 1 130268 join '', map { $_->content } @{$_[0]->{children}};
  613977         772263  
  102036         150629  
666             }
667              
668             # Clone as normal, but then go down and relink all the _PARENT entries
669             sub clone {
670 8     8 1 810 my $self = shift;
671 8         38 my $clone = $self->SUPER::clone;
672 8         33 $clone->__link_children;
673 8         31 $clone;
674             }
675              
676             sub location {
677 8243     8243 1 18582 my $self = shift;
678 8243 100       23671 my $first = $self->{children}->[0] or return undef;
679 8240         11876 $first->location;
680             }
681              
682              
683              
684              
685              
686             #####################################################################
687             # Internal Methods
688              
689             sub DESTROY {
690 117999     117999   10690162 local $_;
691 117999 100       189230 if ( $_[0]->{children} ) {
692 16872         35666 my @queue = $_[0];
693 16872         45965 while ( defined($_ = shift @queue) ) {
694 627001 100       867579 unshift @queue, @{delete $_->{children}} if $_->{children};
  117979         215505  
695              
696             # Remove all internal/private weird crosslinking so that
697             # the cascading DESTROY calls will get called properly.
698 627001         1122821 %$_ = ();
699             }
700             }
701              
702 117999         198107 $_[0]->SUPER::DESTROY;
703             }
704              
705             sub __position {
706 4174     4174   5035 my ( $self, $child ) = @_;
707 4174         4612 my $key = refaddr $child;
708              
709             return undef unless #
710 4174 50       6182 my $elements = $self->{children};
711              
712 4174 100       6821 if (defined (my $position = $_POSITION_CACHE{$key})) {
713 2345         2462 my $maybe_child = $elements->[$position];
714 2345 100 100     6895 return $position if defined $maybe_child and refaddr $maybe_child == $key;
715             }
716              
717 1865         2092 delete $_POSITION_CACHE{$key};
718              
719 1865         1886 $_POSITION_CACHE{refaddr $elements->[$_]} = $_ for 0 .. $#{$elements};
  1865         15321  
720              
721 1865         3327 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         5 my $key = refaddr $child;
728 2         5 my $p = $self->__position($child);
729 2         4 foreach ( @insertions ) {
730             Scalar::Util::weaken(
731 2         7 $_PARENT{refaddr $_} = $self
732             );
733             }
734 2         3 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   4 my ( $self, $child, @insertions ) = @_;
741 2         4 my $key = refaddr $child;
742 2         6 my $p = $self->__position($child);
743 2         2 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         5 1;
750             }
751              
752             # Replace a child
753             sub __replace_child {
754 6     6   15 my ( $self, $old_child, @replacements ) = @_;
755 6         15 my $old_child_addr = refaddr $old_child;
756              
757             # Cache parent of new children
758 6         21 my $old_child_index = $self->__position($old_child);
759              
760 6 100       15 return undef if !defined $old_child_index;
761              
762 5         7 foreach ( @replacements ) {
763             Scalar::Util::weaken(
764 5         14 $_PARENT{refaddr $_} = $self
765             );
766             }
767              
768             # Replace old child with new children
769 5         5 splice( @{$self->{children}}, $old_child_index, 1, @replacements );
  5         13  
770              
771             # Uncache parent of old child
772 5         9 delete $_PARENT{$old_child_addr};
773 5         8 1;
774             }
775              
776             # Create PARENT links for an entire tree.
777             # Used when cloning or thawing.
778             sub __link_children {
779 14     14   21 my $self = shift;
780              
781             # Relink all our children ( depth first )
782 14         50 my @queue = ( $self );
783 14         57 while ( my $Node = shift @queue ) {
784             # Link our immediate children
785 35         36 foreach my $Element ( @{$Node->{children}} ) {
  35         86  
786             Scalar::Util::weaken(
787 133         227 $_PARENT{refaddr($Element)} = $Node
788             );
789 133 100       323 unshift @queue, $Element if $Element->isa('PPI::Node');
790             }
791              
792             # If it's a structure, relink the open/close braces
793 35 100       148 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       1270 $_PARENT{refaddr($Node->finish)} = $Node
799             ) if $Node->finish;
800             }
801              
802 14         86 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