File Coverage

blib/lib/PPI/Element.pm
Criterion Covered Total %
statement 182 200 91.0
branch 66 94 70.2
condition 9 15 60.0
subroutine 50 54 92.5
pod 27 27 100.0
total 334 390 85.6


line stmt bran cond sub pod time code
1             package PPI::Element;
2              
3             =pod
4              
5             =head1 NAME
6              
7             PPI::Element - The abstract Element class, a base for all source objects
8              
9             =head1 INHERITANCE
10              
11             PPI::Element is the root of the PDOM tree
12              
13             =head1 DESCRIPTION
14              
15             The abstract C<PPI::Element> serves as a base class for all source-related
16             objects, from a single whitespace token to an entire document. It provides
17             a basic set of methods to provide a common interface and basic
18             implementations.
19              
20             =head1 METHODS
21              
22             =cut
23              
24 67     67   342 use strict;
  67         1603  
  67         2433  
25 67     67   27998 use Clone 0.30 ();
  67         27179  
  67         2191  
26 67     67   382 use Scalar::Util qw{refaddr};
  67         96  
  67         3223  
27 67     67   297 use Params::Util qw{_INSTANCE _ARRAY};
  67         100  
  67         3812  
28 67     67   638 use PPI::Util ();
  67         91  
  67         789  
29 67     67   31891 use PPI::Node ();
  67         166  
  67         1923  
30 67     67   361 use PPI::Singletons '%_PARENT', '%_POSITION_CACHE';
  67         71  
  67         7645  
31              
32             our $VERSION = '1.284';
33              
34             our $errstr = "";
35              
36 67     67   352 use overload 'bool' => \&PPI::Util::TRUE;
  67         85  
  67         383  
37 67     67   3639 use overload '""' => 'content';
  67         82  
  67         186  
38 67     67   3133 use overload '==' => '__equals';
  67         79  
  67         159  
39 67     67   2558 use overload '!=' => '__nequals';
  67         115  
  67         211  
40 67     67   2623 use overload 'eq' => '__eq';
  67         76  
  67         134  
41 67     67   2946 use overload 'ne' => '__ne';
  67         91  
  67         212  
42              
43              
44              
45              
46              
47             #####################################################################
48             # General Properties
49              
50             =pod
51              
52             =head2 significant
53              
54             Because we treat whitespace and other non-code items as Tokens (in order to
55             be able to "round trip" the L<PPI::Document> back to a file) the
56             C<significant> method allows us to distinguish between tokens that form a
57             part of the code, and tokens that aren't significant, such as whitespace,
58             POD, or the portion of a file after (and including) the C<__END__> token.
59              
60             Returns true if the Element is significant, or false it not.
61              
62             =cut
63              
64             ### XS -> PPI/XS.xs:_PPI_Element__significant 0.845+
65             sub significant() { 1 }
66              
67             =pod
68              
69             =head2 class
70              
71             The C<class> method is provided as a convenience, and really does nothing
72             more than returning C<ref($self)>. However, some people have found that
73             they appreciate the laziness of C<$Foo-E<gt>class eq 'whatever'>, so I
74             have caved to popular demand and included it.
75              
76             Returns the class of the Element as a string
77              
78             =cut
79              
80 0     0 1 0 sub class { ref($_[0]) }
81              
82             =pod
83              
84             =head2 tokens
85              
86             The C<tokens> method returns a list of L<PPI::Token> objects for the
87             Element, essentially getting back that part of the document as if it had
88             not been lexed.
89              
90             This also means there are no Statements and no Structures in the list,
91             just the Token classes.
92              
93             =cut
94              
95 302817     302817 1 467740 sub tokens { $_[0] }
96              
97             =pod
98              
99             =head2 content
100              
101             For B<any> C<PPI::Element>, the C<content> method will reconstitute the
102             base code for it as a single string. This method is also the method used
103             for overloading stringification. When an Element is used in a double-quoted
104             string for example, this is the method that is called.
105              
106             B<WARNING:>
107              
108             You should be aware that because of the way that here-docs are handled, any
109             here-doc content is not included in C<content>, and as such you should
110             B<not> eval or execute the result if it contains any L<PPI::Token::HereDoc>.
111              
112             The L<PPI::Document> method C<serialize> should be used to stringify a PDOM
113             document into something that can be executed as expected.
114              
115             Returns the basic code as a string (excluding here-doc content).
116              
117             =cut
118              
119             ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
120             sub content() { '' }
121              
122              
123              
124              
125              
126             #####################################################################
127             # Navigation Methods
128              
129             =pod
130              
131             =head2 parent
132              
133             Elements themselves are not intended to contain other Elements, that is
134             left to the L<PPI::Node> abstract class, a subclass of C<PPI::Element>.
135             However, all Elements can be contained B<within> a parent Node.
136              
137             If an Element is within a parent Node, the C<parent> method returns the
138             Node.
139              
140             =cut
141              
142 308191     308191 1 746017 sub parent { $_PARENT{refaddr $_[0]} }
143              
144             =pod
145              
146             =head2 descendant_of $element
147              
148             Answers whether a C<PPI::Element> is contained within another one.
149              
150             C<PPI::Element>s are considered to be descendants of themselves.
151              
152             =cut
153              
154             sub descendant_of {
155 6     6 1 2682 my $cursor = shift;
156 6 50       36 my $parent = shift or return undef;
157 6         25 while ( refaddr $cursor != refaddr $parent ) {
158 17 100       80 $cursor = $_PARENT{refaddr $cursor} or return '';
159             }
160 3         16 return 1;
161             }
162              
163             =pod
164              
165             =head2 ancestor_of $element
166              
167             Answers whether a C<PPI::Element> is contains another one.
168              
169             C<PPI::Element>s are considered to be ancestors of themselves.
170              
171             =cut
172              
173             sub ancestor_of {
174 6     6 1 2893 my $self = shift;
175 6 50       26 my $cursor = shift or return undef;
176 6         18 while ( refaddr $cursor != refaddr $self ) {
177 17 100       64 $cursor = $_PARENT{refaddr $cursor} or return '';
178             }
179 3         10 return 1;
180             }
181              
182             =pod
183              
184             =head2 statement
185              
186             For a C<PPI::Element> that is contained (at some depth) within a
187             L<PPI::Statement>, the C<statement> method will return the first parent
188             Statement object lexically 'above' the Element.
189              
190             Returns a L<PPI::Statement> object, which may be the same Element if the
191             Element is itself a L<PPI::Statement> object.
192              
193             Returns false if the Element is not within a Statement and is not itself
194             a Statement.
195              
196             =cut
197              
198             sub statement {
199 0     0 1 0 my $cursor = shift;
200 0         0 while ( ! _INSTANCE($cursor, 'PPI::Statement') ) {
201 0 0       0 $cursor = $_PARENT{refaddr $cursor} or return '';
202             }
203 0         0 $cursor;
204             }
205              
206             =pod
207              
208             =head2 top
209              
210             For a C<PPI::Element> that is contained within a PDOM tree, the C<top> method
211             will return the top-level Node in the tree. Most of the time this should be
212             a L<PPI::Document> object, however this will not always be so. For example,
213             if a subroutine has been removed from its Document, to be moved to another
214             Document.
215              
216             Returns the top-most PDOM object, which may be the same Element, if it is
217             not within any parent PDOM object.
218              
219             =cut
220              
221             sub top {
222 425747     425747 1 419404 my $cursor = shift;
223 425747         976961 while ( my $parent = $_PARENT{refaddr $cursor} ) {
224 426123         756854 $cursor = $parent;
225             }
226 425747         549732 $cursor;
227             }
228              
229             =pod
230              
231             =head2 document
232              
233             For an Element that is contained within a L<PPI::Document> object,
234             the C<document> method will return the top-level Document for the Element.
235              
236             Returns the L<PPI::Document> for this Element, or false if the Element is not
237             contained within a Document.
238              
239             =cut
240              
241             sub document {
242 425735     425735 1 547542 my $top = shift->top;
243 425735 50       2307032 _INSTANCE($top, 'PPI::Document') and $top;
244             }
245              
246             =pod
247              
248             =head2 next_sibling
249              
250             All L<PPI::Node> objects (specifically, our parent Node) contain a number of
251             C<PPI::Element> objects. The C<next_sibling> method returns the C<PPI::Element>
252             immediately after the current one, or false if there is no next sibling.
253              
254             =cut
255              
256             sub next_sibling {
257 83     83 1 89 my $self = shift;
258 83         95 my $key = refaddr $self;
259 83 100       328 my $parent = $_PARENT{$key} or return '';
260 78         93 my $elements = $parent->{children};
261 78         152 my $position = $parent->__position($self);
262 78 100       226 $elements->[$position + 1] || '';
263             }
264              
265             =pod
266              
267             =head2 snext_sibling
268              
269             As per the other 's' methods, the C<snext_sibling> method returns the next
270             B<significant> sibling of the C<PPI::Element> object.
271              
272             Returns a C<PPI::Element> object, or false if there is no 'next' significant
273             sibling.
274              
275             =cut
276              
277             sub snext_sibling {
278 2323     2323 1 7284 my $self = shift;
279 2323         2860 my $key = refaddr $self;
280 2323 100       7386 my $parent = $_PARENT{$key} or return '';
281 2316         2976 my $elements = $parent->{children};
282 2316         4211 my $position = $parent->__position($self);
283 2316         4802 while ( defined(my $it = $elements->[++$position]) ) {
284 2299 100       6676 return $it if $it->significant;
285             }
286 25         74 '';
287             }
288              
289             =pod
290              
291             =head2 previous_sibling
292              
293             All L<PPI::Node> objects (specifically, our parent Node) contain a number of
294             C<PPI::Element> objects. The C<previous_sibling> method returns the Element
295             immediately before the current one, or false if there is no 'previous'
296             C<PPI::Element> object.
297              
298             =cut
299              
300             sub previous_sibling {
301 76     76 1 68 my $self = shift;
302 76         66 my $key = refaddr $self;
303 76 100       177 my $parent = $_PARENT{$key} or return '';
304 72         74 my $elements = $parent->{children};
305 72         98 my $position = $parent->__position($self);
306 72 100 66     213 $position and $elements->[$position - 1] or '';
307             }
308              
309             =pod
310              
311             =head2 sprevious_sibling
312              
313             As per the other 's' methods, the C<sprevious_sibling> method returns
314             the previous B<significant> sibling of the C<PPI::Element> object.
315              
316             Returns a C<PPI::Element> object, or false if there is no 'previous' significant
317             sibling.
318              
319             =cut
320              
321             sub sprevious_sibling {
322 1284902     1284902 1 1216570 my $self = shift;
323 1284902         1202800 my $key = refaddr $self;
324 1284902 100       2717773 my $parent = $_PARENT{$key} or return '';
325 1217663         1332688 my $elements = $parent->{children};
326 1217663         1600159 my $position = $parent->__position($self);
327 1217663   66     2657031 while ( $position-- and defined(my $it = $elements->[$position]) ) {
328 3641599 100       9892231 return $it if $it->significant;
329             }
330 174596         332344 '';
331             }
332              
333             =pod
334              
335             =head2 first_token
336              
337             As a support method for higher-order algorithms that deal specifically with
338             tokens and actual Perl content, the C<first_token> method finds the first
339             PPI::Token object within or equal to this one.
340              
341             That is, if called on a L<PPI::Node> subclass, it will descend until it
342             finds a L<PPI::Token>. If called on a L<PPI::Token> object, it will return
343             the same object.
344              
345             Returns a L<PPI::Token> object, or dies on error (which should be extremely
346             rare and only occur if an illegal empty L<PPI::Statement> exists below the
347             current Element somewhere.)
348              
349             =cut
350              
351             sub first_token {
352 15     15 1 2481 my $cursor = shift;
353 15         31 while ( $cursor->isa('PPI::Node') ) {
354 18 50       50 $cursor = $cursor->first_element
355             or die "Found empty PPI::Node while getting first token";
356             }
357 15         26 $cursor;
358             }
359              
360              
361             =pod
362              
363             =head2 last_token
364              
365             As a support method for higher-order algorithms that deal specifically with
366             tokens and actual Perl content, the C<last_token> method finds the last
367             PPI::Token object within or equal to this one.
368              
369             That is, if called on a L<PPI::Node> subclass, it will descend until it
370             finds a L<PPI::Token>. If called on a L<PPI::Token> object, it will return
371             the itself.
372              
373             Returns a L<PPI::Token> object, or dies on error (which should be extremely
374             rare and only occur if an illegal empty L<PPI::Statement> exists below the
375             current Element somewhere.)
376              
377             =cut
378              
379             sub last_token {
380 14     14 1 1067 my $cursor = shift;
381 14         35 while ( $cursor->isa('PPI::Node') ) {
382 18 50       64 $cursor = $cursor->last_element
383             or die "Found empty PPI::Node while getting first token";
384             }
385 14         25 $cursor;
386             }
387              
388             =pod
389              
390             =head2 next_token
391              
392             As a support method for higher-order algorithms that deal specifically with
393             tokens and actual Perl content, the C<next_token> method finds the
394             L<PPI::Token> object that is immediately after the current Element, even if
395             it is not within the same parent L<PPI::Node> as the one for which the
396             method is being called.
397              
398             Note that this is B<not> defined as a L<PPI::Token>-specific method,
399             because it can be useful to find the next token that is after, say, a
400             L<PPI::Statement>, although obviously it would be useless to want the
401             next token after a L<PPI::Document>.
402              
403             Returns a L<PPI::Token> object, or false if there are no more tokens after
404             the Element.
405              
406             =cut
407              
408             sub next_token {
409 61     61 1 427 my $cursor = shift;
410              
411             # Find the next element, going upwards as needed
412 61         51 while ( 1 ) {
413 74         137 my $element = $cursor->next_sibling;
414 74 100       127 if ( $element ) {
415 52 100       151 return $element if $element->isa('PPI::Token');
416 10         33 return $element->first_token;
417             }
418 22 100       34 $cursor = $cursor->parent or return '';
419 18 100 66     60 if ( $cursor->isa('PPI::Structure') and $cursor->finish ) {
420 5         6 return $cursor->finish;
421             }
422             }
423             }
424              
425             =pod
426              
427             =head2 previous_token
428              
429             As a support method for higher-order algorithms that deal specifically with
430             tokens and actual Perl content, the C<previous_token> method finds the
431             L<PPI::Token> object that is immediately before the current Element, even
432             if it is not within the same parent L<PPI::Node> as this one.
433              
434             Note that this is not defined as a L<PPI::Token>-only method, because it can
435             be useful to find the token is before, say, a L<PPI::Statement>, although
436             obviously it would be useless to want the next token before a
437             L<PPI::Document>.
438              
439             Returns a L<PPI::Token> object, or false if there are no more tokens before
440             the C<Element>.
441              
442             =cut
443              
444             sub previous_token {
445 59     59 1 403 my $cursor = shift;
446              
447             # Find the previous element, going upwards as needed
448 59         48 while ( 1 ) {
449 70         102 my $element = $cursor->previous_sibling;
450 70 100       101 if ( $element ) {
451 51 100       109 return $element if $element->isa('PPI::Token');
452 9         35 return $element->last_token;
453             }
454 19 100       27 $cursor = $cursor->parent or return '';
455 16 100 66     43 if ( $cursor->isa('PPI::Structure') and $cursor->start ) {
456 5         8 return $cursor->start;
457             }
458             }
459             }
460              
461             =head2 presumed_features
462              
463             Returns a hash that indicates which features appear to be active for the given
464             element.
465              
466             =cut
467              
468             sub presumed_features {
469 67238     67238 1 95142 my ($self) = @_;
470              
471 67238         70087 my @feature_mods;
472 67238         67437 my $walker = $self;
473 67238         127203 while ($walker) {
474 244063         274147 my $sib_walk = $walker;
475 244063         396769 while ($sib_walk) {
476 1285543 100       2420774 push @feature_mods, $sib_walk if $sib_walk->can("feature_mods");
477 1285543         1514690 $sib_walk = $sib_walk->sprevious_sibling;
478             }
479 244063         384485 $walker = $walker->parent;
480             }
481              
482 67238         215389 my %feature_mods = map %{$_}, reverse grep defined, map $_->feature_mods,
  152         425  
483             @feature_mods;
484              
485 67238         944152 return \%feature_mods;
486             }
487              
488             #####################################################################
489             # Manipulation
490              
491             =pod
492              
493             =head2 clone
494              
495             As per the L<Clone> module, the C<clone> method makes a perfect copy of
496             an Element object. In the generic case, the implementation is done using
497             the L<Clone> module's mechanism itself. In higher-order cases, such as for
498             Nodes, there is more work involved to keep the parent-child links intact.
499              
500             =cut
501              
502             sub clone {
503 6     6 1 297 Clone::clone(shift);
504             }
505              
506             =pod
507              
508             =head2 insert_before @Elements
509              
510             The C<insert_before> method allows you to insert lexical perl content, in
511             the form of C<PPI::Element> objects, before the calling C<Element>. You
512             need to be very careful when modifying perl code, as it's easy to break
513             things.
514              
515             In its initial incarnation, this method allows you to insert a single
516             Element, and will perform some basic checking to prevent you inserting
517             something that would be structurally wrong (in PDOM terms).
518              
519             In future, this method may be enhanced to allow the insertion of multiple
520             Elements, inline-parsed code strings or L<PPI::Document::Fragment> objects.
521              
522             Returns true if the Element was inserted, false if it can not be inserted,
523             or C<undef> if you do not provide a C<PPI::Element> object as a parameter.
524              
525             =cut
526              
527             sub __insert_before {
528 2     2   4 my $self = shift;
529 2         26 $self->parent->__insert_before_child( $self, @_ );
530             }
531              
532             =pod
533              
534             =head2 insert_after @Elements
535              
536             The C<insert_after> method allows you to insert lexical perl content, in
537             the form of C<PPI::Element> objects, after the calling C<Element>. You need
538             to be very careful when modifying perl code, as it's easy to break things.
539              
540             In its initial incarnation, this method allows you to insert a single
541             Element, and will perform some basic checking to prevent you inserting
542             something that would be structurally wrong (in PDOM terms).
543              
544             In future, this method may be enhanced to allow the insertion of multiple
545             Elements, inline-parsed code strings or L<PPI::Document::Fragment> objects.
546              
547             Returns true if the Element was inserted, false if it can not be inserted,
548             or C<undef> if you do not provide a C<PPI::Element> object as a parameter.
549              
550             =cut
551              
552             sub __insert_after {
553 2     2   4 my $self = shift;
554 2         8 $self->parent->__insert_after_child( $self, @_ );
555             }
556              
557             =pod
558              
559             =head2 remove
560              
561             For a given C<PPI::Element>, the C<remove> method will remove it from its
562             parent B<intact>, along with all of its children.
563              
564             Returns the C<Element> itself as a convenience, or C<undef> if an error
565             occurs while trying to remove the C<Element>.
566              
567             =cut
568              
569             sub remove {
570 64     64 1 93 my $self = shift;
571 64 50       141 my $parent = $self->parent or return $self;
572 64         153 $parent->remove_child( $self );
573             }
574              
575             =pod
576              
577             =head2 delete
578              
579             For a given C<PPI::Element>, the C<delete> method will remove it from its
580             parent, immediately deleting the C<Element> and all of its children (if it
581             has any).
582              
583             Returns true if the C<Element> was successfully deleted, or C<undef> if
584             an error occurs while trying to remove the C<Element>.
585              
586             =cut
587              
588             sub delete {
589 64 50   64 1 117 $_[0]->remove or return undef;
590 64         150 $_[0]->DESTROY;
591 64         107 1;
592             }
593              
594             =pod
595              
596             =head2 replace $Element
597              
598             Although some higher level class support more exotic forms of replace,
599             at the basic level the C<replace> method takes a single C<Element> as
600             an argument and replaces the current C<Element> with it.
601              
602             To prevent accidental damage to code, in this initial implementation the
603             replacement element B<must> be of the same class (or a subclass) as the
604             one being replaced.
605              
606             If successful, returns the replace element. Otherwise, returns C<undef>.
607              
608             =cut
609              
610             sub replace {
611 1 50   1 1 3 my $self = ref $_[0] ? shift : return undef;
612 1 50       10 my $replace = _INSTANCE(shift, ref $self) or return undef;
613 1         4 return $self->parent->replace_child( $self, $replace );
614             }
615              
616             =pod
617              
618             =head2 location
619              
620             If the Element exists within a L<PPI::Document> that has
621             indexed the Element locations using C<PPI::Document::index_locations>, the
622             C<location> method will return the location of the first character of the
623             Element within the Document.
624              
625             Returns the location as a reference to a five-element array in the form C<[
626             $line, $rowchar, $col, $logical_line, $logical_file_name ]>. The values are in
627             a human format, with the first character of the file located at C<[ 1, 1, 1, ?,
628             'something' ]>.
629              
630             The second and third numbers are similar, except that the second is the
631             literal horizontal character, and the third is the visual column, taking
632             into account tabbing (see L<PPI::Document/"tab_width [ $width ]">).
633              
634             The fourth number is the line number, taking into account any C<#line>
635             directives. The fifth element is the name of the file that the element was
636             found in, if available, taking into account any C<#line> directives.
637              
638             Returns C<undef> on error, or if the L<PPI::Document> object has not been
639             indexed.
640              
641             =cut
642              
643             sub location {
644 81550     81550 1 493171 my $self = shift;
645              
646 81550 50       88339 $self->_ensure_location_present or return undef;
647              
648             # Return a copy, not the original
649 81550         75671 return [ @{$self->{_location}} ];
  81550         172326  
650             }
651              
652             =pod
653              
654             =head2 line_number
655              
656             If the Element exists within a L<PPI::Document> that has indexed the Element
657             locations using C<PPI::Document::index_locations>, the C<line_number> method
658             will return the line number of the first character of the Element within the
659             Document.
660              
661             Returns C<undef> on error, or if the L<PPI::Document> object has not been
662             indexed.
663              
664             =cut
665              
666             sub line_number {
667 94     94 1 13398 my $self = shift;
668              
669 94 50       164 my $location = $self->location() or return undef;
670 94         218 return $location->[0];
671             }
672              
673             =pod
674              
675             =head2 column_number
676              
677             If the Element exists within a L<PPI::Document> that has indexed the Element
678             locations using C<PPI::Document::index_locations>, the C<column_number> method
679             will return the column number of the first character of the Element within the
680             Document.
681              
682             Returns C<undef> on error, or if the L<PPI::Document> object has not been
683             indexed.
684              
685             =cut
686              
687             sub column_number {
688 1     1 1 659 my $self = shift;
689              
690 1 50       12 my $location = $self->location() or return undef;
691 1         4 return $location->[1];
692             }
693              
694             =pod
695              
696             =head2 visual_column_number
697              
698             If the Element exists within a L<PPI::Document> that has indexed the Element
699             locations using C<PPI::Document::index_locations>, the C<visual_column_number>
700             method will return the visual column number of the first character of the
701             Element within the Document, according to the value of
702             L<PPI::Document/"tab_width [ $width ]">.
703              
704             Returns C<undef> on error, or if the L<PPI::Document> object has not been
705             indexed.
706              
707             =cut
708              
709             sub visual_column_number {
710 1     1 1 563 my $self = shift;
711              
712 1 50       4 my $location = $self->location() or return undef;
713 1         4 return $location->[2];
714             }
715              
716             =pod
717              
718             =head2 logical_line_number
719              
720             If the Element exists within a L<PPI::Document> that has indexed the Element
721             locations using C<PPI::Document::index_locations>, the C<logical_line_number>
722             method will return the line number of the first character of the Element within
723             the Document, taking into account any C<#line> directives.
724              
725             Returns C<undef> on error, or if the L<PPI::Document> object has not been
726             indexed.
727              
728             =cut
729              
730             sub logical_line_number {
731 1     1 1 605 my $self = shift;
732              
733 1         4 return $self->location()->[3];
734             }
735              
736             =pod
737              
738             =head2 logical_filename
739              
740             If the Element exists within a L<PPI::Document> that has indexed the Element
741             locations using C<PPI::Document::index_locations>, the C<logical_filename>
742             method will return the logical file name containing the first character of the
743             Element within the Document, taking into account any C<#line> directives.
744              
745             Returns C<undef> on error, or if the L<PPI::Document> object has not been
746             indexed.
747              
748             =cut
749              
750             sub logical_filename {
751 11     11 1 5057 my $self = shift;
752              
753 11 50       42 my $location = $self->location() or return undef;
754 11         75 return $location->[4];
755             }
756              
757             sub _ensure_location_present {
758 81550     81550   74139 my $self = shift;
759              
760 81550 100       125452 unless ( exists $self->{_location} ) {
761             # Are we inside a normal document?
762 176 50       733 my $Document = $self->document or return undef;
763 176 50       1766 if ( $Document->isa('PPI::Document::Fragment') ) {
764             # Because they can't be serialized, document fragments
765             # do not support the concept of location.
766 0         0 return undef;
767             }
768              
769             # Generate the locations. If they need one location, then
770             # the chances are they'll want more, and it's better that
771             # everything is already pre-generated.
772 176 50       987 $Document->index_locations or return undef;
773 176 50       588 unless ( exists $self->{_location} ) {
774             # erm... something went very wrong here
775 0         0 return undef;
776             }
777             }
778              
779 81550         114664 return 1;
780             }
781              
782             # Although flush_locations is only publically a Document-level method,
783             # we are able to implement it at an Element level, allowing us to
784             # selectively flush only the part of the document that occurs after the
785             # element for which the flush is called.
786             sub _flush_locations {
787 1     1   3 my $self = shift;
788 1 50       7 unless ( $self == $self->top ) {
789 0         0 return $self->top->_flush_locations( $self );
790             }
791              
792             # Get the full list of all Tokens
793 1         8 my @Tokens = $self->tokens;
794              
795             # Optionally allow starting from an arbitrary element (or rather,
796             # the first Token equal-to-or-within an arbitrary element)
797 1 50       8 if ( _INSTANCE($_[0], 'PPI::Element') ) {
798 0         0 my $start = shift->first_token;
799 0         0 while ( my $Token = shift @Tokens ) {
800 0 0       0 return 1 unless $Token->{_location};
801 0 0       0 next unless refaddr($Token) == refaddr($start);
802              
803             # Found the start. Flush its location
804 0         0 delete $$Token->{_location};
805 0         0 last;
806             }
807             }
808              
809             # Iterate over any remaining Tokens and flush their location
810 1         4 foreach my $Token ( @Tokens ) {
811 169         210 delete $Token->{_location};
812             }
813              
814 1         8 1;
815             }
816              
817              
818              
819              
820              
821             #####################################################################
822             # XML Compatibility Methods
823              
824             sub _xml_name {
825 5   33 5   27 my $class = ref $_[0] || $_[0];
826 5         23 my $name = lc join( '_', split /::/, $class );
827 5         22 substr($name, 4);
828             }
829              
830             sub _xml_attr {
831 5     5   17 return {};
832             }
833              
834             sub _xml_content {
835 5 100   5   24 defined $_[0]->{content} ? $_[0]->{content} : '';
836             }
837              
838              
839              
840              
841              
842             #####################################################################
843             # Internals
844              
845             # Set the error string
846             sub _error {
847 0     0   0 $errstr = $_[1];
848 0         0 undef;
849             }
850              
851             # Clear the error string
852             sub _clear {
853 0     0   0 $errstr = '';
854 0         0 $_[0];
855             }
856              
857             # Being DESTROYed in this manner, rather than by an explicit
858             # ->delete means our reference count has probably fallen to zero.
859             # Therefore we don't need to remove ourselves from our parent,
860             # just the index ( just in case ).
861             sub DESTROY {
862 474811     474811   760835 delete $_PARENT{refaddr $_[0]};
863 474811         1039105 delete $_POSITION_CACHE{refaddr $_[0]};
864             }
865              
866             # Operator overloads
867 769 50   769   2759 sub __equals { ref $_[1] and refaddr($_[0]) == refaddr($_[1]) }
868 1     1   5 sub __nequals { !__equals(@_) }
869             sub __eq {
870 6225 50   6225   2447098 my $self = _INSTANCE($_[0], 'PPI::Element') ? $_[0]->content : $_[0];
871 6225 100       17786 my $other = _INSTANCE($_[1], 'PPI::Element') ? $_[1]->content : $_[1];
872 6225         14808 $self eq $other;
873             }
874 1     1   6 sub __ne { !__eq(@_) }
875              
876             1;
877              
878             =pod
879              
880             =head1 TO DO
881              
882             It would be nice if C<location> could be used in an ad-hoc manner. That is,
883             if called on an Element within a Document that has not been indexed, it will
884             do a one-off calculation to find the location. It might be very painful if
885             someone started using it a lot, without remembering to index the document,
886             but it would be handy for things that are only likely to use it once, such
887             as error handlers.
888              
889             =head1 SUPPORT
890              
891             See the L<support section|PPI/SUPPORT> in the main module.
892              
893             =head1 AUTHOR
894              
895             Adam Kennedy E<lt>adamk@cpan.orgE<gt>
896              
897             =head1 COPYRIGHT
898              
899             Copyright 2001 - 2011 Adam Kennedy.
900              
901             This program is free software; you can redistribute
902             it and/or modify it under the same terms as Perl itself.
903              
904             The full text of the license can be found in the
905             LICENSE file included with this module.
906              
907             =cut