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   358 use strict;
  65         100  
  65         1561  
52 65     65   274 use Carp ();
  65         387  
  65         1200  
53 65     65   613 use Scalar::Util qw{refaddr};
  65         123  
  65         2352  
54 65     65   336 use List::Util ();
  65         159  
  65         1428  
55 65     65   285 use Params::Util qw{_INSTANCE _CLASS _CODELIKE _NUMBER};
  65         121  
  65         2803  
56 65     65   339 use PPI::Element ();
  65         126  
  65         1380  
57 65     65   22216 use PPI::Singletons '%_PARENT';
  65         166  
  65         164465  
58              
59             our $VERSION = '1.276';
60              
61             our @ISA = "PPI::Element";
62              
63              
64              
65              
66              
67             #####################################################################
68             # The basic constructor
69              
70             sub new {
71 16710   33 16710 0 45359 my $class = ref $_[0] || $_[0];
72 16710         45844 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 8 my $self = shift;
110              
111             # Check the element
112 1 50       8 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
113 1 50       5 $_PARENT{refaddr $Element} and return undef;
114              
115             # Add the argument to the elements
116 1         1 push @{$self->{children}}, $Element;
  1         2  
117             Scalar::Util::weaken(
118 1         6 $_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 804 if ( wantarray ) {
151 2         3 return @{$_[0]->{children}};
  2         8  
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 1387 $_[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 55 $_[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 2138 50   2138 1 106448 wantarray ? @{$_[0]->{children}} : scalar @{$_[0]->{children}};
  2138         6433  
  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 60545 100   60545 1 1527348 return grep { $_->significant } @{$_[0]->{children}} if wantarray;
  121263         191402  
  30138         50417  
228 30407         34197 my $count = 0;
229 30407         30663 foreach ( @{$_[0]->{children}} ) {
  30407         53153  
230 106144 100       193106 $count++ if $_->significant;
231             }
232 30407         77496 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 83774 my ( $self, $index ) = @_;
249 860 100       2350 PPI::Exception->throw( "method child() needs an index" )
250             if not defined _NUMBER $index;
251 858         3294 $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 145538     145538 1 6798484 my $self = shift;
273 145538         164242 my $idx = 0 + shift;
274 145538         181698 my $el = $self->{children};
275 145538 100       210620 if ( $idx < 0 ) {
276 24551         26756 my $cursor = 0;
277 24551         44237 while ( exists $el->[--$cursor] ) {
278 25764 100 100     105739 return $el->[$cursor] if $el->[$cursor]->significant and ++$idx >= 0;
279             }
280             } else {
281 120987         123785 my $cursor = -1;
282 120987         199750 while ( exists $el->[++$cursor] ) {
283 159428 100 100     744707 return $el->[$cursor] if $el->[$cursor]->significant and --$idx < 0;
284             }
285             }
286 3429         8425 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 15790 my $self = shift;
306 34 100       239 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         98 while ( $Element = $Element->parent ) {
311 79 100       262 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 5217     5217 1 971663 my $self = shift;
374 5217 100       9673 my $wanted = $self->_wanted(shift) or return undef;
375              
376             # Use a queue based search, rather than a recursive one
377 5214         7285 my @found;
378 5214         5406 my @queue = @{$self->{children}};
  5214         11966  
379 5214         6793 my $ok = eval {
380 5214         9216 while ( @queue ) {
381 344380         412747 my $Element = shift @queue;
382 344380         1561966 my $rv = &$wanted( $self, $Element );
383 344380 100       964204 push @found, $Element if $rv;
384              
385             # Support "don't descend on undef return"
386 344380 50       431157 next unless defined $rv;
387              
388             # Skip if the Element doesn't have any children
389 344380 100       815599 next unless $Element->isa('PPI::Node');
390              
391             # Depth-first keeps the queue size down and provides a
392             # better logical order.
393 58698 100       111926 if ( $Element->isa('PPI::Structure') ) {
394 21529 100       36695 unshift @queue, $Element->finish if $Element->finish;
395 21529         24643 unshift @queue, @{$Element->{children}};
  21529         47762  
396 21529 50       32734 unshift @queue, $Element->start if $Element->start;
397             } else {
398 37169         36788 unshift @queue, @{$Element->{children}};
  37169         115534  
399             }
400             }
401 5214         7709 1;
402             };
403 5214 50       8205 if ( !$ok ) {
404             # Caught exception thrown from the wanted function
405 0         0 return undef;
406             }
407              
408 5214 100       28783 @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 2179     2179 1 14827 my $self = shift;
432 2179 50       4450 my $wanted = $self->_wanted(shift) or return undef;
433              
434             # Use the same queue-based search as for ->find
435 2179         3250 my @queue = @{$self->{children}};
  2179         9536  
436 2179         3098 my $rv;
437 2179         2752 my $ok = eval {
438             # The defined() here prevents a ton of calls to PPI::Util::TRUE
439 2179         4081 while ( @queue ) {
440 739035         850184 my $Element = shift @queue;
441 739035         8597153 my $element_rv = $wanted->( $self, $Element );
442 739035 100       1170467 if ( $element_rv ) {
443 39         66 $rv = $Element;
444 39         72 last;
445             }
446              
447             # Support "don't descend on undef return"
448 738996 100       948472 next if !defined $element_rv;
449              
450             # Skip if the Element doesn't have any children
451 715462 100       1678775 next if !$Element->isa('PPI::Node');
452              
453             # Depth-first keeps the queue size down and provides a
454             # better logical order.
455 112192 100       212407 if ( $Element->isa('PPI::Structure') ) {
456 42640 100       74630 unshift @queue, $Element->finish if defined($Element->finish);
457 42640         47707 unshift @queue, @{$Element->{children}};
  42640         102978  
458 42640 50       64528 unshift @queue, $Element->start if defined($Element->start);
459             } else {
460 69552         69787 unshift @queue, @{$Element->{children}};
  69552         258929  
461             }
462             }
463 2179         3532 1;
464             };
465 2179 50       3808 if ( !$ok ) {
466             # Caught exception thrown from the wanted function
467 0         0 return undef;
468             }
469              
470 2179 100       17907 $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 2139     2139 1 486669 my $self = shift;
490 2139         4873 my $rv = $self->find_first(@_);
491 2139 100       10785 $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 78 my $self = shift;
509 66 50       287 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
510              
511             # Find the position of the child
512 66         457 my $key = refaddr $child;
513             my $p = List::Util::first {
514 201     201   308 refaddr $self->{children}[$_] == $key
515 66         195 } 0..$#{$self->{children}};
  66         191  
516 66 100       185 return undef unless defined $p;
517              
518             # Splice it out, and remove the child's parent entry
519 65         71 splice( @{$self->{children}}, $p, 1 );
  65         103  
520 65         172 delete $_PARENT{refaddr $child};
521              
522 65         190 $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 27 my $self = shift;
533              
534 4 50       23 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
535 4 50       50 my $replacement = _INSTANCE(shift, 'PPI::Element') or return undef;
536              
537 4         14 my $success = $self->__replace_child( $child, $replacement );
538              
539 4 100       12 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 1364 my $self = shift;
561 30 50       86 my $wanted = $self->_wanted(shift) or return undef;
562              
563             # Use a depth-first queue search
564 30         51 my $pruned = 0;
565 30         80 my @queue = $self->children;
566 30         44 my $ok = eval {
567 30         97 while ( my $element = shift @queue ) {
568 269         2135 my $rv = &$wanted( $self, $element );
569 269 100       421 if ( $rv ) {
570             # Delete the child
571 62 50       196 $element->delete or return undef;
572 62         90 $pruned++;
573 62         126 next;
574             }
575              
576             # Support the undef == "don't descend"
577 207 50       266 next unless defined $rv;
578              
579 207 100       980 if ( _INSTANCE($element, 'PPI::Node') ) {
580             # Depth-first keeps the queue size down
581 43         100 unshift @queue, $element->children;
582             }
583             }
584 30         57 1;
585             };
586 30 50       59 if ( !$ok ) {
587             # Caught exception thrown from the wanted function
588 0         0 return undef;
589             }
590              
591 30         159 $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 7426     7426   8773 my $either = shift;
600 7426 100       14106 my $it = defined($_[0]) ? shift : do {
601 1 50       4 Carp::carp('Undefined value passed as search condition') if $^W;
602 1         6 return undef;
603             };
604              
605             # Has the caller provided a wanted function directly
606 7425 100       23441 return $it if _CODELIKE($it);
607 3718 100       6741 if ( ref $it ) {
608             # No other ref types are supported
609 1 50       3 Carp::carp('Illegal non-CODE reference passed as search condition') if $^W;
610 1         5 return undef;
611             }
612              
613             # The first argument should be an Element class, possibly in shorthand
614 3717 100       11116 $it = "PPI::$it" unless substr($it, 0, 5) eq 'PPI::';
615 3717 100 66     9969 unless ( _CLASS($it) and $it->isa('PPI::Element') ) {
616             # We got something, but it isn't an element
617 1 50       18 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
618 1         5 return undef;
619             }
620              
621             # Create the class part of the wanted function
622 3716         58496 my $wanted_class = "\n\treturn '' unless \$_[1]->isa('$it');";
623              
624             # Have we been given a second argument to check the content
625 3716         5142 my $wanted_content = '';
626 3716 50       6944 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 3716         7100 my $code = "sub {"
645             . $wanted_class
646             . $wanted_content
647             . "\n\t1;"
648             . "\n}";
649              
650             # Compile the wanted function
651 3716         279096 $code = eval $code;
652 3716 50       18571 (ref $code eq 'CODE') ? $code : undef;
653             }
654              
655              
656              
657              
658              
659             ####################################################################
660             # PPI::Element overloaded methods
661              
662             sub tokens {
663 77474     77474 1 74822 map { $_->tokens } @{$_[0]->{children}};
  359294         492320  
  77474         132608  
664             }
665              
666             ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
667             sub content {
668 88083     88083 1 117792 join '', map { $_->content } @{$_[0]->{children}};
  404789         567311  
  88083         136249  
669             }
670              
671             # Clone as normal, but then go down and relink all the _PARENT entries
672             sub clone {
673 6     6 1 752 my $self = shift;
674 6         32 my $clone = $self->SUPER::clone;
675 6         30 $clone->__link_children;
676 6         21 $clone;
677             }
678              
679             sub location {
680 7969     7969 1 18231 my $self = shift;
681 7969 50       25104 my $first = $self->{children}->[0] or return undef;
682 7969         12300 $first->location;
683             }
684              
685              
686              
687              
688              
689             #####################################################################
690             # Internal Methods
691              
692             sub DESTROY {
693 97492     97492   8429820 local $_;
694 97492 100       151040 if ( $_[0]->{children} ) {
695 16735         26891 my @queue = $_[0];
696 16735         32927 while ( defined($_ = shift @queue) ) {
697 406408 100       602532 unshift @queue, @{delete $_->{children}} if $_->{children};
  97472         168454  
698              
699             # Remove all internal/private weird crosslinking so that
700             # the cascading DESTROY calls will get called properly.
701 406408         801759 %$_ = ();
702             }
703             }
704              
705             # Remove us from our parent node as normal
706 97492         314364 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   3 my $self = shift;
718 2         4 my $key = refaddr shift;
719             my $p = List::Util::first {
720 8     8   12 refaddr $self->{children}[$_] == $key
721 2         9 } 0..$#{$self->{children}};
  2         8  
722 2         7 foreach ( @_ ) {
723             Scalar::Util::weaken(
724 2         8 $_PARENT{refaddr $_} = $self
725             );
726             }
727 2         4 splice( @{$self->{children}}, $p, 0, @_ );
  2         3  
728 2         4 1;
729             }
730              
731             # Insert one or more elements after a child
732             sub __insert_after_child {
733 2     2   3 my $self = shift;
734 2         5 my $key = refaddr shift;
735             my $p = List::Util::first {
736 6     6   10 refaddr $self->{children}[$_] == $key
737 2         8 } 0..$#{$self->{children}};
  2         8  
738 2         8 foreach ( @_ ) {
739             Scalar::Util::weaken(
740 2         8 $_PARENT{refaddr $_} = $self
741             );
742             }
743 2         3 splice( @{$self->{children}}, $p + 1, 0, @_ );
  2         16  
744 2         5 1;
745             }
746              
747             # Replace a child
748             sub __replace_child {
749 4     4   5 my $self = shift;
750 4         7 my $old_child_addr = refaddr shift;
751              
752             # Cache parent of new children
753             my $old_child_index = List::Util::first {
754 12     12   21 refaddr $self->{children}[$_] == $old_child_addr
755 4         15 } 0..$#{$self->{children}};
  4         14  
756              
757 4 100       14 return undef if !defined $old_child_index;
758              
759 3         7 foreach ( @_ ) {
760             Scalar::Util::weaken(
761 3         11 $_PARENT{refaddr $_} = $self
762             );
763             }
764              
765             # Replace old child with new children
766 3         4 splice( @{$self->{children}}, $old_child_index, 1, @_ );
  3         8  
767              
768             # Uncache parent of old child
769 3         6 delete $_PARENT{$old_child_addr};
770 3         5 1;
771             }
772              
773             # Create PARENT links for an entire tree.
774             # Used when cloning or thawing.
775             sub __link_children {
776 12     12   22 my $self = shift;
777              
778             # Relink all our children ( depth first )
779 12         21 my @queue = ( $self );
780 12         51 while ( my $Node = shift @queue ) {
781             # Link our immediate children
782 33         42 foreach my $Element ( @{$Node->{children}} ) {
  33         60  
783             Scalar::Util::weaken(
784 117         339 $_PARENT{refaddr($Element)} = $Node
785             );
786 117 100       338 unshift @queue, $Element if $Element->isa('PPI::Node');
787             }
788              
789             # If it's a structure, relink the open/close braces
790 33 100       190 next unless $Node->isa('PPI::Structure');
791             Scalar::Util::weaken(
792 4 50       16 $_PARENT{refaddr($Node->start)} = $Node
793             ) if $Node->start;
794             Scalar::Util::weaken(
795 4 50       31 $_PARENT{refaddr($Node->finish)} = $Node
796             ) if $Node->finish;
797             }
798              
799 12         56 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