7 PPI::Node - Abstract PPI Node class, an Element that can contain other Elements
16 # Create a typical node (a Document in this case)
17 my $Node = PPI::Document->new;
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 );
23 # Get the elements for the Node
24 my @elements = $Node->children;
26 # Find all the barewords within a Node
27 my $barewords = $Node->find( 'PPI::Token::Word' );
29 # Find by more complex criteria
30 my $my_tokens = $Node->find( sub { $_[1]->content eq 'my' } );
32 # Remove all the whitespace
33 $Node->prune( 'PPI::Token::Whitespace' );
35 # Remove by more complex criteria
36 $Node->prune( sub { $_[1]->content eq 'my' } );
40 The C<PPI::Node> class provides an abstract base class for the Element
41 classes that are able to contain other elements L<PPI::Document>,
42 L<PPI::Statement>, and L<PPI::Structure>.
44 As well as those listed below, all of the methods that apply to
45 L<PPI::Element> objects also apply to C<PPI::Node> objects.
53 use Scalar::Util qw{refaddr};
54 use List::MoreUtils ();
55 use Params::Util qw{_INSTANCE _CLASS _CODELIKE};
58 use vars qw{$VERSION @ISA *_PARENT};
61 @ISA = 'PPI::Element';
62 *_PARENT = *PPI::Element::_PARENT;
69 #####################################################################
70 # The basic constructor
73 my $class = ref $_[0] || $_[0];
74 bless { children => [] }, $class;
81 #####################################################################
88 The C<scope> method returns true if the node represents a lexical scope
89 boundary, or false if it does not.
93 ### XS -> PPI/XS.xs:_PPI_Node__scope 0.903+
98 =head2 add_element $Element
100 The C<add_element> method adds a L<PPI::Element> object to the end of a
101 C<PPI::Node>. Because Elements maintain links to their parent, an
102 Element can only be added to a single Node.
104 Returns true if the L<PPI::Element> was added. Returns C<undef> if the
105 Element was already within another Node, or the method is not passed
106 a L<PPI::Element> object.
114 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
115 $_PARENT{refaddr $Element} and return undef;
117 # Add the argument to the elements
118 push @{$self->{children}}, $Element;
119 Scalar::Util::weaken(
120 $_PARENT{refaddr $Element} = $self
126 # In a typical run profile, add_element is the number 1 resource drain.
127 # This is a highly optimised unsafe version, for internal use only.
129 Scalar::Util::weaken(
130 $_PARENT{refaddr $_[1]} = $_[0]
132 push @{$_[0]->{children}}, $_[1];
139 The C<elements> method accesses all child elements B<structurally> within
140 the C<PPI::Node> object. Note that in the base of the L<PPI::Structure>
141 classes, this C<DOES> include the brace tokens at either end of the
144 Returns a list of zero or more L<PPI::Element> objects.
146 Alternatively, if called in the scalar context, the C<elements> method
147 returns a count of the number of elements.
153 return @{$_[0]->{children}};
155 return scalar @{$_[0]->{children}};
163 The C<first_element> method accesses the first element structurally within
164 the C<PPI::Node> object. As for the C<elements> method, this does include
165 the brace tokens for L<PPI::Structure> objects.
167 Returns a L<PPI::Element> object, or C<undef> if for some reason the
168 C<PPI::Node> object does not contain any elements.
172 # Normally the first element is also the first child
174 $_[0]->{children}->[0];
181 The C<last_element> method accesses the last element structurally within
182 the C<PPI::Node> object. As for the C<elements> method, this does include
183 the brace tokens for L<PPI::Structure> objects.
185 Returns a L<PPI::Element> object, or C<undef> if for some reason the
186 C<PPI::Node> object does not contain any elements.
190 # Normally the last element is also the last child
192 $_[0]->{children}->[-1];
199 The C<children> method accesses all child elements lexically within the
200 C<PPI::Node> object. Note that in the case of the L<PPI::Structure>
201 classes, this does B<NOT> include the brace tokens at either end of the
204 Returns a list of zero of more L<PPI::Element> objects.
206 Alternatively, if called in the scalar context, the C<children> method
207 returns a count of the number of lexical children.
211 # In the default case, this is the same as for the elements method
213 wantarray ? @{$_[0]->{children}} : scalar @{$_[0]->{children}};
220 The C<schildren> method is really just a convenience, the significant-only
221 variation of the normal C<children> method.
223 In list context, returns a list of significant children. In scalar context,
224 returns the number of significant children.
229 return grep { $_->significant } @{$_[0]->{children}} if wantarray;
231 foreach ( @{$_[0]->{children}} ) {
232 $count++ if $_->significant;
241 The C<child> method accesses a child L<PPI::Element> object by its
242 position within the Node.
244 Returns a L<PPI::Element> object, or C<undef> if there is no child
245 element at that node.
250 $_[0]->{children}->[$_[1]];
257 The lexical structure of the Perl language ignores 'insignificant' items,
258 such as whitespace and comments, while L<PPI> 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.
263 The C<schild> 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.
273 my $el = $self->{children};
276 while ( exists $el->[--$cursor] ) {
277 return $el->[$cursor] if $el->[$cursor]->significant and ++$idx >= 0;
281 while ( exists $el->[++$cursor] ) {
282 return $el->[$cursor] if $el->[$cursor]->significant and --$idx < 0;
290 =head2 contains $Element
292 The C<contains> method is used to determine if another L<PPI::Element>
293 object is logically "within" a C<PPI::Node>. For the special case of the
294 brace tokens at either side of a L<PPI::Structure> object, they are
295 generally considered "within" a L<PPI::Structure> object, even if they are
296 not actually in the elements for the L<PPI::Structure>.
298 Returns true if the L<PPI::Element> is within us, false if not, or C<undef>
305 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
307 # Iterate up the Element's parent chain until we either run out
308 # of parents, or get to ourself.
309 while ( $Element = $Element->parent ) {
310 return 1 if refaddr($self) == refaddr($Element);
318 =head2 find $class | \&wanted
320 The C<find> method is used to search within a code tree for
321 L<PPI::Element> objects that meet a particular condition.
323 To specify the condition, the method can be provided with either a simple
324 class name (full or shortened), or a C<CODE>/function reference.
326 # Find all single quotes in a Document (which is a Node)
327 $Document->find('PPI::Quote::Single');
329 # The same thing with a shortened class name
330 $Document->find('Quote::Single');
332 # Anything more elaborate, we so with the sub
333 $Document->find( sub {
334 # At the top level of the file...
335 $_[1]->parent == $_[0]
337 # ...find all comments and POD
338 $_[1]->isa('PPI::Token::Pod')
340 $_[1]->isa('PPI::Token::Comment')
344 The function will be passed two arguments, the top-level C<PPI::Node>
345 you are searching in and the current L<PPI::Element> that the condition
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<undef> indicates no-match and no-descend.
352 In the last case, the tree walker will skip over anything below the
353 C<undef>-returning element and move on to the next element at the same
356 To halt the entire search and return C<undef> immediately, a condition
357 function should throw an exception (i.e. C<die>).
359 Note that this same wanted logic is used for all methods documented to
360 have a C<\&wanted> parameter, as this one does.
362 The C<find> method returns a reference to an array of L<PPI::Element>
363 objects that match the condition, false (but defined) if no Elements match
364 the condition, or C<undef> if you provide a bad condition, or an error
365 occurs during the search process.
367 In the case of a bad condition, a warning will be emitted as well.
373 my $wanted = $self->_wanted(shift) or return undef;
375 # Use a queue based search, rather than a recursive one
377 my @queue = $self->children;
379 while ( my $Element = shift @queue ) {
380 my $rv = &$wanted( $self, $Element );
381 push @found, $Element if $rv;
383 # Support "don't descend on undef return"
384 next unless defined $rv;
386 # Skip if the Element doesn't have any children
387 next unless $Element->isa('PPI::Node');
389 # Depth-first keeps the queue size down and provides a
390 # better logical order.
391 if ( $Element->isa('PPI::Structure') ) {
392 unshift @queue, $Element->finish if $Element->finish;
393 unshift @queue, $Element->children;
394 unshift @queue, $Element->start if $Element->start;
396 unshift @queue, $Element->children;
401 # Caught exception thrown from the wanted function
405 @found ? \@found : '';
410 =head2 find_first $class | \&wanted
412 If the normal C<find> method is like a grep, then C<find_first> is
413 equivalent to the L<Scalar::Util> C<first> function.
415 Given an element class or a wanted function, it will search depth-first
416 through a tree until it finds something that matches the condition,
417 returning the first Element that it encounters.
419 See the C<find> method for details on the format of the search condition.
421 Returns the first L<PPI::Element> object that matches the condition, false
422 if nothing matches the condition, or C<undef> if given an invalid condition,
429 my $wanted = $self->_wanted(shift) or return undef;
431 # Use the same queue-based search as for ->find
432 my @queue = $self->children;
434 # The defined() here prevents a ton of calls to PPI::Util::TRUE
435 while ( defined( my $Element = shift @queue ) ) {
436 my $rv = &$wanted( $self, $Element );
437 return $Element if $rv;
439 # Support "don't descend on undef return"
440 next unless defined $rv;
442 # Skip if the Element doesn't have any children
443 next unless $Element->isa('PPI::Node');
445 # Depth-first keeps the queue size down and provides a
446 # better logical order.
447 if ( $Element->isa('PPI::Structure') ) {
448 unshift @queue, $Element->finish if defined($Element->finish);
449 unshift @queue, $Element->children;
450 unshift @queue, $Element->start if defined($Element->start);
452 unshift @queue, $Element->children;
457 # Caught exception thrown from the wanted function
466 =head2 find_any $class | \&wanted
468 The C<find_any> method is a short-circuiting true/false method that behaves
469 like the normal C<find> method, but returns true as soon as it finds any
470 Elements that match the search condition.
472 See the C<find> method for details on the format of the search condition.
474 Returns true if any Elements that match the condition can be found, false if
475 not, or C<undef> if given an invalid condition, or an error occurs.
481 my $rv = $self->find_first(@_);
482 $rv ? 1 : $rv; # false or undef
487 =head2 remove_child $Element
489 If passed a L<PPI::Element> object that is a direct child of the Node,
490 the C<remove_element> method will remove the C<Element> intact, along
491 with any of its children. As such, this method acts essentially as a
494 If successful, returns the removed element. Otherwise, returns C<undef>.
500 my $child = _INSTANCE(shift, 'PPI::Element') or return undef;
502 # Find the position of the child
503 my $key = refaddr $child;
504 my $p = List::MoreUtils::firstidx {
506 } @{$self->{children}};
507 return undef unless defined $p;
509 # Splice it out, and remove the child's parent entry
510 splice( @{$self->{children}}, $p, 1 );
511 delete $_PARENT{refaddr $child};
518 =head2 prune $class | \&wanted
520 The C<prune> method is used to strip L<PPI::Element> objects out of a code
521 tree. The argument is the same as for the C<find> method, either a class
522 name, or an anonymous subroutine which returns true/false. Any Element
523 that matches the class|wanted will be deleted from the code tree, along
524 with any of its children.
526 The C<prune> method returns the number of C<Element> objects that matched
527 and were removed, B<non-recursively>. This might also be zero, so avoid a
528 simple true/false test on the return false of the C<prune> method. It
529 returns C<undef> on error, which you probably B<should> test for.
531 =begin testing prune 2
533 # Avoids a bug in old Perls relating to the detection of scripts
534 # Known to occur in ActivePerl 5.6.1 and at least one 5.6.2 install.
535 my $hashbang = reverse 'lrep/nib/rsu/!#';
536 my $document = PPI::Document->new( \<<"END_PERL" );
553 isa_ok( $document, 'PPI::Document' );
554 ok( defined($document->prune ('PPI::Statement::Sub')),
555 'Pruned multiple subs ok' );
563 my $wanted = $self->_wanted(shift) or return undef;
565 # Use a depth-first queue search
567 my @queue = $self->children;
569 while ( my $element = shift @queue ) {
570 my $rv = &$wanted( $self, $element );
573 $element->delete or return undef;
578 # Support the undef == "don't descend"
579 next unless defined $rv;
581 if ( _INSTANCE($element, 'PPI::Node') ) {
582 # Depth-first keeps the queue size down
583 unshift @queue, $element->children;
588 # Caught exception thrown from the wanted function
595 # This method is likely to be very heavily used, to take
596 # it slowly and carefuly.
597 ### NOTE: Renaming this function or changing either to self will probably
598 ### break File::Find::Rule::PPI
601 my $it = defined($_[0]) ? shift : do {
602 Carp::carp('Undefined value passed as search condition') if $^W;
606 # Has the caller provided a wanted function directly
607 return $it if _CODELIKE($it);
609 # No other ref types are supported
610 Carp::carp('Illegal non-CODE reference passed as search condition') if $^W;
614 # The first argument should be an Element class, possibly in shorthand
615 $it = "PPI::$it" unless substr($it, 0, 5) eq 'PPI::';
616 unless ( _CLASS($it) and $it->isa('PPI::Element') ) {
617 # We got something, but it isn't an element
618 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
622 # Create the class part of the wanted function
623 my $wanted_class = "\n\treturn '' unless \$_[1]->isa('$it');";
625 # Have we been given a second argument to check the content
626 my $wanted_content = '';
627 if ( defined $_[0] ) {
629 if ( ref $content eq 'Regexp' ) {
630 $content = "$content";
631 } elsif ( ref $content ) {
632 # No other ref types are supported
633 Carp::carp("Cannot create search condition for '$it': Not a PPI::Element") if $^W;
636 $content = quotemeta $content;
639 # Complete the content part of the wanted function
640 $wanted_content .= "\n\treturn '' unless defined \$_[1]->{content};";
641 $wanted_content .= "\n\treturn '' unless \$_[1]->{content} =~ /$content/;";
644 # Create the complete wanted function
651 # Compile the wanted function
653 (ref $code eq 'CODE') ? $code : undef;
660 ####################################################################
661 # PPI::Element overloaded methods
664 map { $_->tokens } @{$_[0]->{children}};
667 ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
669 join '', map { $_->content } @{$_[0]->{children}};
672 # Clone as normal, but then go down and relink all the _PARENT entries
675 my $clone = $self->SUPER::clone;
676 $clone->__link_children;
682 my $first = $self->{children}->[0] or return undef;
690 #####################################################################
695 if ( $_[0]->{children} ) {
697 while ( defined($_ = shift @queue) ) {
698 unshift @queue, @{delete $_->{children}} if $_->{children};
700 # Remove all internal/private weird crosslinking so that
701 # the cascading DESTROY calls will get called properly.
706 # Remove us from our parent node as normal
707 delete $_PARENT{refaddr $_[0]};
710 # Find the position of a child
712 my $key = refaddr $_[1];
713 List::MoreUtils::firstidx { refaddr $_ == $key } @{$_[0]->{children}};
716 # Insert one or more elements before a child
717 sub __insert_before_child {
719 my $key = refaddr shift;
720 my $p = List::MoreUtils::firstidx {
722 } @{$self->{children}};
724 Scalar::Util::weaken(
725 $_PARENT{refaddr $_} = $self
728 splice( @{$self->{children}}, $p, 0, @_ );
732 # Insert one or more elements after a child
733 sub __insert_after_child {
735 my $key = refaddr shift;
736 my $p = List::MoreUtils::firstidx {
738 } @{$self->{children}};
740 Scalar::Util::weaken(
741 $_PARENT{refaddr $_} = $self
744 splice( @{$self->{children}}, $p + 1, 0, @_ );
749 sub __replace_child {
751 my $key = refaddr shift;
752 my $p = List::MoreUtils::firstidx {
754 } @{$self->{children}};
756 Scalar::Util::weaken(
757 $_PARENT{refaddr $_} = $self
760 splice( @{$self->{children}}, $p, 1, @_ );
764 # Create PARENT links for an entire tree.
765 # Used when cloning or thawing.
766 sub __link_children {
769 # Relink all our children ( depth first )
770 my @queue = ( $self );
771 while ( my $Node = shift @queue ) {
772 # Link our immediate children
773 foreach my $Element ( @{$Node->{children}} ) {
774 Scalar::Util::weaken(
775 $_PARENT{refaddr($Element)} = $Node
777 unshift @queue, $Element if $Element->isa('PPI::Node');
780 # If it's a structure, relink the open/close braces
781 next unless $Node->isa('PPI::Structure');
782 Scalar::Util::weaken(
783 $_PARENT{refaddr($Node->start)} = $Node
785 Scalar::Util::weaken(
786 $_PARENT{refaddr($Node->finish)} = $Node
799 - Move as much as possible to L<PPI::XS>
803 See the L<support section|PPI/SUPPORT> in the main module.
807 Adam Kennedy E<lt>adamk@cpan.orgE<gt>
811 Copyright 2001 - 2009 Adam Kennedy.
813 This program is free software; you can redistribute
814 it and/or modify it under the same terms as Perl itself.
816 The full text of the license can be found in the
817 LICENSE file included with this module.