← Index
NYTProf Performance Profile   « line view »
For /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/bin/perlcritic
  Run on Sat Mar 19 22:12:22 2016
Reported on Sat Mar 19 22:14:10 2016

Filename/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Element.pm
StatementsExecuted 1237739 statements in 4.31s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
105472941.08s1.77sPPI::Element::::__eqPPI::Element::__eq
30261104519ms916msPPI::Element::::snext_siblingPPI::Element::snext_sibling
9437253338ms389msPPI::Element::::DESTROYPPI::Element::DESTROY
104217129301ms2.04sPPI::Element::::__nePPI::Element::__ne
184039176163ms163msPPI::Element::::significantPPI::Element::significant
16529411133ms133msPPI::Element::::tokensPPI::Element::tokens
237257485.9ms98.7msPPI::Element::::parentPPI::Element::parent
97635447.2ms61.3msPPI::Element::::locationPPI::Element::location
97631114.1ms14.1msPPI::Element::::_ensure_location_presentPPI::Element::_ensure_location_present
286525.54ms8.20msPPI::Element::::statementPPI::Element::statement
339535.42ms15.3msPPI::Element::::sprevious_siblingPPI::Element::sprevious_sibling
226212.79ms17.6msPPI::Element::::next_siblingPPI::Element::next_sibling
1111.90ms2.06msPPI::Element::::BEGIN@30PPI::Element::BEGIN@30
1111.12ms1.57msPPI::Element::::BEGIN@25PPI::Element::BEGIN@25
14411908┬Ás3.55msPPI::Element::::logical_filenamePPI::Element::logical_filename
111736┬Ás6.30msPPI::Element::::BEGIN@28PPI::Element::BEGIN@28
19881721┬Ás2.54msPPI::Element::::logical_line_numberPPI::Element::logical_line_number
111462┬Ás1.59msPPI::Element::::BEGIN@29PPI::Element::BEGIN@29
311102┬Ás127┬ÁsPPI::Element::::topPPI::Element::top
61128┬Ás83┬ÁsPPI::Element::::line_numberPPI::Element::line_number
11115┬Ás30┬ÁsPPI::Element::::BEGIN@46PPI::Element::BEGIN@46
11111┬Ás23┬ÁsPPI::Element::::BEGIN@24PPI::Element::BEGIN@24
1118┬Ás32┬ÁsPPI::Element::::BEGIN@26PPI::Element::BEGIN@26
1118┬Ás30┬ÁsPPI::Element::::BEGIN@41PPI::Element::BEGIN@41
1117┬Ás31┬ÁsPPI::Element::::BEGIN@27PPI::Element::BEGIN@27
1117┬Ás45┬ÁsPPI::Element::::BEGIN@32PPI::Element::BEGIN@32
1116┬Ás21┬ÁsPPI::Element::::BEGIN@44PPI::Element::BEGIN@44
1116┬Ás19┬ÁsPPI::Element::::BEGIN@43PPI::Element::BEGIN@43
1115┬Ás21┬ÁsPPI::Element::::BEGIN@42PPI::Element::BEGIN@42
1115┬Ás19┬ÁsPPI::Element::::BEGIN@45PPI::Element::BEGIN@45
1114┬Ás4┬ÁsPPI::Element::::BEGIN@33PPI::Element::BEGIN@33
0000s0sPPI::Element::::__ANON__[:346]PPI::Element::__ANON__[:346]
0000s0sPPI::Element::::__ANON__[:369]PPI::Element::__ANON__[:369]
0000s0sPPI::Element::::__ANON__[:394]PPI::Element::__ANON__[:394]
0000s0sPPI::Element::::__ANON__[:417]PPI::Element::__ANON__[:417]
0000s0sPPI::Element::::__equalsPPI::Element::__equals
0000s0sPPI::Element::::__insert_afterPPI::Element::__insert_after
0000s0sPPI::Element::::__insert_beforePPI::Element::__insert_before
0000s0sPPI::Element::::__nequalsPPI::Element::__nequals
0000s0sPPI::Element::::_clearPPI::Element::_clear
0000s0sPPI::Element::::_errorPPI::Element::_error
0000s0sPPI::Element::::_flush_locationsPPI::Element::_flush_locations
0000s0sPPI::Element::::_xml_attrPPI::Element::_xml_attr
0000s0sPPI::Element::::_xml_contentPPI::Element::_xml_content
0000s0sPPI::Element::::_xml_namePPI::Element::_xml_name
0000s0sPPI::Element::::ancestor_ofPPI::Element::ancestor_of
0000s0sPPI::Element::::classPPI::Element::class
0000s0sPPI::Element::::clonePPI::Element::clone
0000s0sPPI::Element::::column_numberPPI::Element::column_number
0000s0sPPI::Element::::contentPPI::Element::content
0000s0sPPI::Element::::deletePPI::Element::delete
0000s0sPPI::Element::::descendant_ofPPI::Element::descendant_of
0000s0sPPI::Element::::documentPPI::Element::document
0000s0sPPI::Element::::first_tokenPPI::Element::first_token
0000s0sPPI::Element::::last_tokenPPI::Element::last_token
0000s0sPPI::Element::::next_tokenPPI::Element::next_token
0000s0sPPI::Element::::previous_siblingPPI::Element::previous_sibling
0000s0sPPI::Element::::previous_tokenPPI::Element::previous_token
0000s0sPPI::Element::::removePPI::Element::remove
0000s0sPPI::Element::::replacePPI::Element::replace
0000s0sPPI::Element::::visual_column_numberPPI::Element::visual_column_number
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package PPI::Element;
2
3=pod
4
5=head1 NAME
6
7PPI::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
15The abstract C<PPI::Element> serves as a base class for all source-related
16objects, from a single whitespace token to an entire document. It provides
17a basic set of methods to provide a common interface and basic
18implementations.
19
20=head1 METHODS
21
22=cut
23
24219┬Ás235┬Ás
# spent 23┬Ás (11+12) within PPI::Element::BEGIN@24 which was called: # once (11┬Ás+12┬Ás) by PPI::Token::BEGIN@25 at line 24
use strict;
# spent 23┬Ás making 1 call to PPI::Element::BEGIN@24 # spent 12┬Ás making 1 call to strict::import
25279┬Ás11.57ms
# spent 1.57ms (1.12+445┬Ás) within PPI::Element::BEGIN@25 which was called: # once (1.12ms+445┬Ás) by PPI::Token::BEGIN@25 at line 25
use Clone ();
# spent 1.57ms making 1 call to PPI::Element::BEGIN@25
26224┬Ás256┬Ás
# spent 32┬Ás (8+24) within PPI::Element::BEGIN@26 which was called: # once (8┬Ás+24┬Ás) by PPI::Token::BEGIN@25 at line 26
use Scalar::Util qw{refaddr};
# spent 32┬Ás making 1 call to PPI::Element::BEGIN@26 # spent 24┬Ás making 1 call to Exporter::import
27220┬Ás255┬Ás
# spent 31┬Ás (7+24) within PPI::Element::BEGIN@27 which was called: # once (7┬Ás+24┬Ás) by PPI::Token::BEGIN@25 at line 27
use Params::Util qw{_INSTANCE _ARRAY};
# spent 31┬Ás making 1 call to PPI::Element::BEGIN@27 # spent 24┬Ás making 1 call to Exporter::import
28299┬Ás16.30ms
# spent 6.30ms (736┬Ás+5.56) within PPI::Element::BEGIN@28 which was called: # once (736┬Ás+5.56ms) by PPI::Token::BEGIN@25 at line 28
use List::MoreUtils ();
# spent 6.30ms making 1 call to PPI::Element::BEGIN@28
29278┬Ás11.59ms
# spent 1.59ms (462┬Ás+1.13) within PPI::Element::BEGIN@29 which was called: # once (462┬Ás+1.13ms) by PPI::Token::BEGIN@25 at line 29
use PPI::Util ();
# spent 1.59ms making 1 call to PPI::Element::BEGIN@29
30299┬Ás12.06ms
# spent 2.06ms (1.90+163┬Ás) within PPI::Element::BEGIN@30 which was called: # once (1.90ms+163┬Ás) by PPI::Token::BEGIN@25 at line 30
use PPI::Node ();
# spent 2.06ms making 1 call to PPI::Element::BEGIN@30
31
32232┬Ás282┬Ás
# spent 45┬Ás (7+38) within PPI::Element::BEGIN@32 which was called: # once (7┬Ás+38┬Ás) by PPI::Token::BEGIN@25 at line 32
use vars qw{$VERSION $errstr %_PARENT};
# spent 45┬Ás making 1 call to PPI::Element::BEGIN@32 # spent 38┬Ás making 1 call to vars::import
33
# spent 4┬Ás within PPI::Element::BEGIN@33 which was called: # once (4┬Ás+0s) by PPI::Token::BEGIN@25 at line 39
BEGIN {
341400ns $VERSION = '1.215';
351200ns $errstr = '';
36
37 # Master Child -> Parent index
3814┬Ás %_PARENT = ();
39120┬Ás14┬Ás}
# spent 4┬Ás making 1 call to PPI::Element::BEGIN@33
40
41224┬Ás253┬Ás
# spent 30┬Ás (8+23) within PPI::Element::BEGIN@41 which was called: # once (8┬Ás+23┬Ás) by PPI::Token::BEGIN@25 at line 41
use overload 'bool' => \&PPI::Util::TRUE;
# spent 30┬Ás making 1 call to PPI::Element::BEGIN@41 # spent 23┬Ás making 1 call to overload::import
42220┬Ás237┬Ás
# spent 21┬Ás (5+16) within PPI::Element::BEGIN@42 which was called: # once (5┬Ás+16┬Ás) by PPI::Token::BEGIN@25 at line 42
use overload '""' => 'content';
# spent 21┬Ás making 1 call to PPI::Element::BEGIN@42 # spent 16┬Ás making 1 call to overload::import
43229┬Ás233┬Ás
# spent 19┬Ás (6+14) within PPI::Element::BEGIN@43 which was called: # once (6┬Ás+14┬Ás) by PPI::Token::BEGIN@25 at line 43
use overload '==' => '__equals';
# spent 19┬Ás making 1 call to PPI::Element::BEGIN@43 # spent 14┬Ás making 1 call to overload::import
44219┬Ás236┬Ás
# spent 21┬Ás (6+15) within PPI::Element::BEGIN@44 which was called: # once (6┬Ás+15┬Ás) by PPI::Token::BEGIN@25 at line 44
use overload '!=' => '__nequals';
# spent 21┬Ás making 1 call to PPI::Element::BEGIN@44 # spent 15┬Ás making 1 call to overload::import
45228┬Ás233┬Ás
# spent 19┬Ás (5+14) within PPI::Element::BEGIN@45 which was called: # once (5┬Ás+14┬Ás) by PPI::Token::BEGIN@25 at line 45
use overload 'eq' => '__eq';
# spent 19┬Ás making 1 call to PPI::Element::BEGIN@45 # spent 14┬Ás making 1 call to overload::import
4621.59ms244┬Ás
# spent 30┬Ás (15+14) within PPI::Element::BEGIN@46 which was called: # once (15┬Ás+14┬Ás) by PPI::Token::BEGIN@25 at line 46
use overload 'ne' => '__ne';
# spent 30┬Ás making 1 call to PPI::Element::BEGIN@46 # spent 14┬Ás making 1 call to overload::import
47
- -
52#####################################################################
53# General Properties
54
55=pod
56
57=head2 significant
58
59Because we treat whitespace and other non-code items as Tokens (in order to
60be able to "round trip" the L<PPI::Document> back to a file) the
61C<significant> method allows us to distinguish between tokens that form a
62part of the code, and tokens that aren't significant, such as whitespace,
63POD, or the portion of a file after (and including) the C<__END__> token.
64
65Returns true if the Element is significant, or false it not.
66
67=cut
68
69### XS -> PPI/XS.xs:_PPI_Element__significant 0.845+
70184039549ms
# spent 163ms within PPI::Element::significant which was called 184039 times, avg 883ns/call: # 39289 times (36.3ms+0s) by PPI::Lexer::_lex_statement at line 608 of PPI/Lexer.pm, avg 925ns/call # 33407 times (29.6ms+0s) by PPI::Node::schild at line 282 of PPI/Node.pm, avg 885ns/call # 29775 times (24.6ms+0s) by PPI::Element::snext_sibling at line 370, avg 826ns/call # 26762 times (25.1ms+0s) by PPI::Tokenizer::_previous_significant_tokens at line 699 of PPI/Tokenizer.pm, avg 940ns/call # 13303 times (12.3ms+0s) by PPI::Lexer::_lex_structure at line 1321 of PPI/Lexer.pm, avg 923ns/call # 10544 times (8.64ms+0s) by PPI::Node::schildren at line 232 of PPI/Node.pm, avg 819ns/call # 10537 times (8.47ms+0s) by PPI::Node::schildren at line 229 of PPI/Node.pm, avg 804ns/call # 7986 times (6.27ms+0s) by PPI::Statement::Variable::type at line 67 of PPI/Statement/Variable.pm, avg 785ns/call # 6486 times (5.74ms+0s) by PPI::Node::schild at line 277 of PPI/Node.pm, avg 885ns/call # 3024 times (2.95ms+0s) by PPI::Lexer::_lex_document at line 272 of PPI/Lexer.pm, avg 977ns/call # 1022 times (844┬Ás+0s) by PPI::Lexer::_statement at line 501 of PPI/Lexer.pm, avg 826ns/call # 981 times (886┬Ás+0s) by PPI::Lexer::_statement at line 543 of PPI/Lexer.pm, avg 903ns/call # 321 times (283┬Ás+0s) by Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions::_has_topic_side_effect at line 121 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm, avg 882ns/call # 218 times (193┬Ás+0s) by PPI::Element::sprevious_sibling at line 418, avg 884ns/call # 203 times (169┬Ás+0s) by PPI::Lexer::_statement at line 430 of PPI/Lexer.pm, avg 834ns/call # 129 times (120┬Ás+0s) by PPI::Lexer::_curly at line 1264 of PPI/Lexer.pm, avg 926ns/call # 52 times (46┬Ás+0s) by PPI::Tokenizer::_last_significant_token at line 680 of PPI/Tokenizer.pm, avg 894ns/call
sub significant { 1 }
71
72=pod
73
74=head2 class
75
76The C<class> method is provided as a convenience, and really does nothing
77more than returning C<ref($self)>. However, some people have found that
78they appreciate the laziness of C<$Foo-E<gt>class eq 'whatever'>, so I
79have caved to popular demand and included it.
80
81Returns the class of the Element as a string
82
83=cut
84
85sub class { ref($_[0]) }
86
87=pod
88
89=head2 tokens
90
91The C<tokens> method returns a list of L<PPI::Token> objects for the
92Element, essentially getting back that part of the document as if it had
93not been lexed.
94
95This also means there are no Statements and no Structures in the list,
96just the Token classes.
97
98=cut
99
100165294372ms
# spent 133ms within PPI::Element::tokens which was called 165294 times, avg 802ns/call: # 165294 times (133ms+0s) by PPI::Node::tokens at line 666 of PPI/Node.pm, avg 802ns/call
sub tokens { $_[0] }
101
102=pod
103
104=head2 content
105
106For B<any> C<PPI::Element>, the C<content> method will reconstitute the
107base code for it as a single string. This method is also the method used
108for overloading stringification. When an Element is used in a double-quoted
109string for example, this is the method that is called.
110
111B<WARNING:>
112
113You should be aware that because of the way that here-docs are handled, any
114here-doc content is not included in C<content>, and as such you should
115B<not> eval or execute the result if it contains any L<PPI::Token::HereDoc>.
116
117The L<PPI::Document> method C<serialize> should be used to stringify a PDOM
118document into something that can be executed as expected.
119
120Returns the basic code as a string (excluding here-doc content).
121
122=cut
123
124### XS -> PPI/XS.xs:_PPI_Element__content 0.900+
125sub content { '' }
126
- -
131#####################################################################
132# Naigation Methods
133
134=pod
135
136=head2 parent
137
138Elements themselves are not intended to contain other Elements, that is
139left to the L<PPI::Node> abstract class, a subclass of C<PPI::Element>.
140However, all Elements can be contained B<within> a parent Node.
141
142If an Element is within a parent Node, the C<parent> method returns the
143Node.
144
145=cut
146
14723725120ms2372512.8ms
# spent 98.7ms (85.9+12.8) within PPI::Element::parent which was called 23725 times, avg 4┬Ás/call: # 11584 times (43.0ms+5.87ms) by Perl::Critic::Utils::is_hash_key at line 716 of Perl/Critic/Utils.pm, avg 4┬Ás/call # 11584 times (40.9ms+6.45ms) by Perl::Critic::Utils::is_hash_key at line 714 of Perl/Critic/Utils.pm, avg 4┬Ás/call # 286 times (976┬Ás+233┬Ás) by Perl::Critic::Policy::TestingAndDebugging::RequireUseStrict::__ANON__[/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Perl/Critic/Policy/TestingAndDebugging/RequireUseStrict.pm:116] at line 93 of Perl/Critic/Policy/TestingAndDebugging/RequireUseStrict.pm, avg 4┬Ás/call # 108 times (289┬Ás+66┬Ás) by PPI::Lexer::_curly at line 1253 of PPI/Lexer.pm, avg 3┬Ás/call # 61 times (314┬Ás+52┬Ás) by PPI::Lexer::_curly at line 1248 of PPI/Lexer.pm, avg 6┬Ás/call # 51 times (241┬Ás+74┬Ás) by Perl::Critic::Annotation::_init at line 68 of Perl/Critic/Annotation.pm, avg 6┬Ás/call # 51 times (144┬Ás+27┬Ás) by Perl::Critic::Annotation::_init at line 69 of Perl/Critic/Annotation.pm, avg 3┬Ás/call
sub parent { $_PARENT{refaddr $_[0]} }
# spent 12.8ms making 23725 calls to Scalar::Util::refaddr, avg 539ns/call
148
149=pod
150
151=head2 descendant_of $element
152
153Answers whether a C<PPI::Element> is contained within another one.
154
155C<PPI::Element>s are considered to be descendants of themselves.
156
157=begin testing descendant_of 9
158
159my $Document = PPI::Document->new( \'( [ thingy ] ); $blarg = 1' );
160isa_ok( $Document, 'PPI::Document' );
161ok(
162 $Document->descendant_of($Document),
163 'Document is a descendant of itself.',
164);
165
166my $words = $Document->find('Token::Word');
167is(scalar @{$words}, 1, 'Document contains 1 Word.');
168my $word = $words->[0];
169ok(
170 $word->descendant_of($word),
171 'Word is a descendant of itself.',
172);
173ok(
174 $word->descendant_of($Document),
175 'Word is a descendant of the Document.',
176);
177ok(
178 ! $Document->descendant_of($word),
179 'Document is not a descendant of the Word.',
180);
181
182my $symbols = $Document->find('Token::Symbol');
183is(scalar @{$symbols}, 1, 'Document contains 1 Symbol.');
184my $symbol = $symbols->[0];
185ok(
186 ! $word->descendant_of($symbol),
187 'Word is not a descendant the Symbol.',
188);
189ok(
190 ! $symbol->descendant_of($word),
191 'Symbol is not a descendant the Word.',
192);
193
194=end testing
195
196=cut
197
198sub descendant_of {
199 my $cursor = shift;
200 my $parent = shift or return undef;
201 while ( refaddr $cursor != refaddr $parent ) {
202 $cursor = $_PARENT{refaddr $cursor} or return '';
203 }
204 return 1;
205}
206
207=pod
208
209=head2 ancestor_of $element
210
211Answers whether a C<PPI::Element> is contains another one.
212
213C<PPI::Element>s are considered to be ancestors of themselves.
214
215=begin testing ancestor_of 9
216
217my $Document = PPI::Document->new( \'( [ thingy ] ); $blarg = 1' );
218isa_ok( $Document, 'PPI::Document' );
219ok(
220 $Document->ancestor_of($Document),
221 'Document is an ancestor of itself.',
222);
223
224my $words = $Document->find('Token::Word');
225is(scalar @{$words}, 1, 'Document contains 1 Word.');
226my $word = $words->[0];
227ok(
228 $word->ancestor_of($word),
229 'Word is an ancestor of itself.',
230);
231ok(
232 ! $word->ancestor_of($Document),
233 'Word is not an ancestor of the Document.',
234);
235ok(
236 $Document->ancestor_of($word),
237 'Document is an ancestor of the Word.',
238);
239
240my $symbols = $Document->find('Token::Symbol');
241is(scalar @{$symbols}, 1, 'Document contains 1 Symbol.');
242my $symbol = $symbols->[0];
243ok(
244 ! $word->ancestor_of($symbol),
245 'Word is not an ancestor the Symbol.',
246);
247ok(
248 ! $symbol->ancestor_of($word),
249 'Symbol is not an ancestor the Word.',
250);
251
252=end testing
253
254=cut
255
256sub ancestor_of {
257 my $self = shift;
258 my $cursor = shift or return undef;
259 while ( refaddr $cursor != refaddr $self ) {
260 $cursor = $_PARENT{refaddr $cursor} or return '';
261 }
262 return 1;
263}
264
265=pod
266
267=head2 statement
268
269For a C<PPI::Element> that is contained (at some depth) within a
270L<PPI::Statment>, the C<statement> method will return the first parent
271Statement object lexically 'above' the Element.
272
273Returns a L<PPI::Statement> object, which may be the same Element if the
274Element is itself a L<PPI::Statement> object.
275
276Returns false if the Element is not within a Statement and is not itself
277a Statement.
278
279=cut
280
281
# spent 8.20ms (5.54+2.66) within PPI::Element::statement which was called 286 times, avg 29┬Ás/call: # 77 times (3.41ms+707┬Ás) by Perl::Critic::Utils::is_included_module_name at line 744 of Perl/Critic/Utils.pm, avg 54┬Ás/call # 77 times (750┬Ás+678┬Ás) by Perl::Critic::Utils::is_label_pointer at line 765 of Perl/Critic/Utils.pm, avg 19┬Ás/call # 77 times (716┬Ás+676┬Ás) by Perl::Critic::Utils::is_package_declaration at line 808 of Perl/Critic/Utils.pm, avg 18┬Ás/call # 52 times (623┬Ás+569┬Ás) by Perl::Critic::Utils::is_subroutine_name at line 821 of Perl/Critic/Utils.pm, avg 23┬Ás/call # 3 times (34┬Ás+30┬Ás) by Perl::Critic::Violation::_line_containing_violation at line 303 of Perl/Critic/Violation.pm, avg 21┬Ás/call
sub statement {
28228650┬Ás my $cursor = shift;
2832861.64ms5721.46ms while ( ! _INSTANCE($cursor, 'PPI::Statement') ) {
# spent 1.18ms making 286 calls to Params::Util::_INSTANCE, avg 4┬Ás/call # spent 279┬Ás making 286 calls to UNIVERSAL::isa, avg 976ns/call
2842866.09ms14301.65ms $cursor = $_PARENT{refaddr $cursor} or return '';
# spent 1.01ms making 286 calls to Params::Util::_INSTANCE, avg 4┬Ás/call # spent 305┬Ás making 572 calls to PPI::Util::TRUE, avg 533ns/call # spent 174┬Ás making 286 calls to Scalar::Util::refaddr, avg 607ns/call # spent 166┬Ás making 286 calls to UNIVERSAL::isa, avg 580ns/call
285 }
286286537┬Ás $cursor;
287}
288
289=pod
290
291=head2 top
292
293For a C<PPI::Element> that is contained within a PDOM tree, the C<top> method
294will return the top-level Node in the tree. Most of the time this should be
295a L<PPI::Document> object, however this will not always be so. For example,
296if a subroutine has been removed from its Document, to be moved to another
297Document.
298
299Returns the top-most PDOM object, which may be the same Element, if it is
300not within any parent PDOM object.
301
302=cut
303
304
# spent 127┬Ás (102+25) within PPI::Element::top which was called 3 times, avg 42┬Ás/call: # 3 times (102┬Ás+25┬Ás) by Perl::Critic::Violation::new at line 85 of Perl/Critic/Violation.pm, avg 42┬Ás/call
sub top {
30531┬Ás my $cursor = shift;
3063119┬Ás5125┬Ás while ( my $parent = $_PARENT{refaddr $cursor} ) {
# spent 14┬Ás making 27 calls to Scalar::Util::refaddr, avg 519ns/call # spent 11┬Ás making 24 calls to PPI::Util::TRUE, avg 475ns/call
307 $cursor = $parent;
308 }
30937┬Ás $cursor;
310}
311
312=pod
313
314=head2 document
315
316For an Element that is contained within a L<PPI::Document> object,
317the C<document> method will return the top-level Document for the Element.
318
319Returns the L<PPI::Document> for this Element, or false if the Element is not
320contained within a Document.
321
322=cut
323
324sub document {
325 my $top = shift->top;
326 _INSTANCE($top, 'PPI::Document') and $top;
327}
328
329=pod
330
331=head2 next_sibling
332
333All L<PPI::Node> objects (specifically, our parent Node) contain a number of
334C<PPI::Element> objects. The C<next_sibling> method returns the C<PPI::Element>
335immediately after the current one, or false if there is no next sibling.
336
337=cut
338
339
# spent 17.6ms (2.79+14.8) within PPI::Element::next_sibling which was called 226 times, avg 78┬Ás/call: # 216 times (2.68ms+14.7ms) by Perl::Critic::Annotation::_init at line 108 of Perl/Critic/Annotation.pm, avg 80┬Ás/call # 10 times (109┬Ás+87┬Ás) by Perl::Critic::Annotation::_init at line 119 of Perl/Critic/Annotation.pm, avg 20┬Ás/call
sub next_sibling {
34022642┬Ás my $self = shift;
3412261.11ms452241┬Ás my $parent = $_PARENT{refaddr $self} or return '';
# spent 121┬Ás making 226 calls to Scalar::Util::refaddr, avg 535ns/call # spent 120┬Ás making 226 calls to PPI::Util::TRUE, avg 532ns/call
342226460┬Ás226123┬Ás my $key = refaddr $self;
# spent 123┬Ás making 226 calls to Scalar::Util::refaddr, avg 545ns/call
34322674┬Ás my $elements = $parent->{children};
344 my $position = List::MoreUtils::firstidx {
345578913.6ms57892.49ms refaddr $_ == $key
# spent 2.49ms making 5789 calls to Scalar::Util::refaddr, avg 430ns/call
346226387┬Ás22614.3ms } @$elements;
# spent 14.3ms making 226 calls to List::MoreUtils::firstidx, avg 63┬Ás/call
3472262.64ms216132┬Ás $elements->[$position + 1] || '';
# spent 132┬Ás making 216 calls to PPI::Util::TRUE, avg 611ns/call
348}
349
350=pod
351
352=head2 snext_sibling
353
354As per the other 's' methods, the C<snext_sibling> method returns the next
355B<significant> sibling of the C<PPI::Element> object.
356
357Returns a C<PPI::Element> object, or false if there is no 'next' significant
358sibling.
359
360=cut
361
362
# spent 916ms (519+397) within PPI::Element::snext_sibling which was called 30261 times, avg 30┬Ás/call: # 14319 times (253ms+208ms) by Perl::Critic::Utils::_is_followed_by_parens at line 735 of Perl/Critic/Utils.pm, avg 32┬Ás/call # 11399 times (196ms+141ms) by Perl::Critic::Utils::is_hash_key at line 722 of Perl/Critic/Utils.pm, avg 30┬Ás/call # 2101 times (32.1ms+23.4ms) by Perl::Critic::Policy::Subroutines::ProhibitReturnSort::violates at line 39 of Perl/Critic/Policy/Subroutines/ProhibitReturnSort.pm, avg 26┬Ás/call # 2101 times (32.8ms+18.6ms) by Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef::violates at line 39 of Perl/Critic/Policy/Subroutines/ProhibitExplicitReturnUndef.pm, avg 24┬Ás/call # 105 times (1.45ms+2.07ms) by Perl::Critic::Utils::parse_arg_list at line 975 of Perl/Critic/Utils.pm, avg 34┬Ás/call # 77 times (1.14ms+1.24ms) by Perl::Critic::Utils::is_class_name at line 790 of Perl/Critic/Utils.pm, avg 31┬Ás/call # 66 times (989┬Ás+1.13ms) by Perl::Critic::Utils::first_arg at line 922 of Perl/Critic/Utils.pm, avg 32┬Ás/call # 57 times (812┬Ás+580┬Ás) by Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions::_is_assignment_to_topic at line 136 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm, avg 24┬Ás/call # 18 times (283┬Ás+181┬Ás) by Perl::Critic::Utils::parse_arg_list at line 939 of Perl/Critic/Utils.pm, avg 26┬Ás/call # 18 times (254┬Ás+167┬Ás) by Perl::Critic::Utils::parse_arg_list at line 970 of Perl/Critic/Utils.pm, avg 23┬Ás/call
sub snext_sibling {
363302615.35ms my $self = shift;
36430261167ms6052233.7ms my $parent = $_PARENT{refaddr $self} or return '';
# spent 17.5ms making 30261 calls to Scalar::Util::refaddr, avg 578ns/call # spent 16.2ms making 30261 calls to PPI::Util::TRUE, avg 536ns/call
3653026177.2ms3026117.3ms my $key = refaddr $self;
# spent 17.3ms making 30261 calls to Scalar::Util::refaddr, avg 570ns/call
3663026110.6ms my $elements = $parent->{children};
367 my $position = List::MoreUtils::firstidx {
36895278324ms9527847.5ms refaddr $_ == $key
# spent 47.5ms making 95278 calls to Scalar::Util::refaddr, avg 498ns/call
3693026156.8ms30261294ms } @$elements;
# spent 294ms making 30261 calls to List::MoreUtils::firstidx, avg 10┬Ás/call
37030261151ms5500551.3ms while ( defined(my $it = $elements->[++$position]) ) {
# spent 26.7ms making 25219 calls to PPI::Token::Whitespace::significant, avg 1┬Ás/call # spent 24.6ms making 29775 calls to PPI::Element::significant, avg 826ns/call # spent 14┬Ás making 11 calls to PPI::Token::Comment::significant, avg 1┬Ás/call
371 return $it if $it->significant;
372 }
3734861.07ms '';
374}
375
376=pod
377
378=head2 previous_sibling
379
380All L<PPI::Node> objects (specifically, our parent Node) contain a number of
381C<PPI::Element> objects. The C<previous_sibling> method returns the Element
382immediately before the current one, or false if there is no 'previous'
383C<PPI::Element> object.
384
385=cut
386
387sub previous_sibling {
388 my $self = shift;
389 my $parent = $_PARENT{refaddr $self} or return '';
390 my $key = refaddr $self;
391 my $elements = $parent->{children};
392 my $position = List::MoreUtils::firstidx {
393 refaddr $_ == $key
394 } @$elements;
395 $position and $elements->[$position - 1] or '';
396}
397
398=pod
399
400=head2 sprevious_sibling
401
402As per the other 's' methods, the C<sprevious_sibling> method returns
403the previous B<significant> sibling of the C<PPI::Element> object.
404
405Returns a C<PPI::Element> object, or false if there is no 'previous' significant
406sibling.
407
408=cut
409
410
# spent 15.3ms (5.42+9.88) within PPI::Element::sprevious_sibling which was called 339 times, avg 45┬Ás/call: # 77 times (1.26ms+3.01ms) by Perl::Critic::Utils::is_method_call at line 781 of Perl/Critic/Utils.pm, avg 56┬Ás/call # 77 times (1.15ms+1.26ms) by Perl::Critic::Utils::is_subroutine_name at line 819 of Perl/Critic/Utils.pm, avg 31┬Ás/call # 77 times (1.13ms+1.22ms) by Perl::Critic::Utils::is_label_pointer at line 768 of Perl/Critic/Utils.pm, avg 31┬Ás/call # 57 times (703┬Ás+531┬Ás) by Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions::_is_assignment_to_topic at line 141 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm, avg 22┬Ás/call # 51 times (1.17ms+3.87ms) by Perl::Critic::Annotation::_is_single_line_annotation_on_simple_statement at line 188 of Perl/Critic/Annotation.pm, avg 99┬Ás/call
sub sprevious_sibling {
41133972┬Ás my $self = shift;
4123391.64ms678368┬Ás my $parent = $_PARENT{refaddr $self} or return '';
# spent 192┬Ás making 339 calls to PPI::Util::TRUE, avg 565ns/call # spent 176┬Ás making 339 calls to Scalar::Util::refaddr, avg 519ns/call
413339731┬Ás339192┬Ás my $key = refaddr $self;
# spent 192┬Ás making 339 calls to Scalar::Util::refaddr, avg 567ns/call
414339130┬Ás my $elements = $parent->{children};
415 my $position = List::MoreUtils::firstidx {
41624378.90ms24371.13ms refaddr $_ == $key
# spent 1.13ms making 2437 calls to Scalar::Util::refaddr, avg 464ns/call
417339789┬Ás3398.81ms } @$elements;
# spent 8.81ms making 339 calls to List::MoreUtils::firstidx, avg 26┬Ás/call
4183391.43ms498513┬Ás while ( $position-- and defined(my $it = $elements->[$position]) ) {
# spent 309┬Ás making 270 calls to PPI::Token::Whitespace::significant, avg 1┬Ás/call # spent 193┬Ás making 218 calls to PPI::Element::significant, avg 884ns/call # spent 12┬Ás making 10 calls to PPI::Token::Comment::significant, avg 1┬Ás/call
419 return $it if $it->significant;
420 }
421121290┬Ás '';
422}
423
424=pod
425
426=head2 first_token
427
428As a support method for higher-order algorithms that deal specifically with
429tokens and actual Perl content, the C<first_token> method finds the first
430PPI::Token object within or equal to this one.
431
432That is, if called on a L<PPI::Node> subclass, it will descend until it
433finds a L<PPI::Token>. If called on a L<PPI::Token> object, it will return
434the same object.
435
436Returns a L<PPI::Token> object, or dies on error (which should be extremely
437rare and only occur if an illegal empty L<PPI::Statement> exists below the
438current Element somewhere.
439
440=cut
441
442sub first_token {
443 my $cursor = shift;
444 while ( $cursor->isa('PPI::Node') ) {
445 $cursor = $cursor->first_element
446 or die "Found empty PPI::Node while getting first token";
447 }
448 $cursor;
449}
450
451
452=pod
453
454=head2 last_token
455
456As a support method for higher-order algorithms that deal specifically with
457tokens and actual Perl content, the C<last_token> method finds the last
458PPI::Token object within or equal to this one.
459
460That is, if called on a L<PPI::Node> subclass, it will descend until it
461finds a L<PPI::Token>. If called on a L<PPI::Token> object, it will return
462the itself.
463
464Returns a L<PPI::Token> object, or dies on error (which should be extremely
465rare and only occur if an illegal empty L<PPI::Statement> exists below the
466current Element somewhere.
467
468=cut
469
470sub last_token {
471 my $cursor = shift;
472 while ( $cursor->isa('PPI::Node') ) {
473 $cursor = $cursor->last_element
474 or die "Found empty PPI::Node while getting first token";
475 }
476 $cursor;
477}
478
479=pod
480
481=head2 next_token
482
483As a support method for higher-order algorithms that deal specifically with
484tokens and actual Perl content, the C<next_token> method finds the
485L<PPI::Token> object that is immediately after the current Element, even if
486it is not within the same parent L<PPI::Node> as the one for which the
487method is being called.
488
489Note that this is B<not> defined as a L<PPI::Token>-specific method,
490because it can be useful to find the next token that is after, say, a
491L<PPI::Statement>, although obviously it would be useless to want the
492next token after a L<PPI::Document>.
493
494Returns a L<PPI::Token> object, or false if there are no more tokens after
495the Element.
496
497=cut
498
499sub next_token {
500 my $cursor = shift;
501
502 # Find the next element, going upwards as needed
503 while ( 1 ) {
504 my $element = $cursor->next_sibling;
505 if ( $element ) {
506 return $element if $element->isa('PPI::Token');
507 return $element->first_token;
508 }
509 $cursor = $cursor->parent or return '';
510 if ( $cursor->isa('PPI::Structure') and $cursor->finish ) {
511 return $cursor->finish;
512 }
513 }
514}
515
516=pod
517
518=head2 previous_token
519
520As a support method for higher-order algorithms that deal specifically with
521tokens and actual Perl content, the C<previous_token> method finds the
522L<PPI::Token> object that is immediately before the current Element, even
523if it is not within the same parent L<PPI::Node> as this one.
524
525Note that this is not defined as a L<PPI::Token>-only method, because it can
526be useful to find the token is before, say, a L<PPI::Statement>, although
527obviously it would be useless to want the next token before a
528L<PPI::Document>.
529
530Returns a L<PPI::Token> object, or false if there are no more tokens before
531the C<Element>.
532
533=cut
534
535sub previous_token {
536 my $cursor = shift;
537
538 # Find the previous element, going upwards as needed
539 while ( 1 ) {
540 my $element = $cursor->previous_sibling;
541 if ( $element ) {
542 return $element if $element->isa('PPI::Token');
543 return $element->last_token;
544 }
545 $cursor = $cursor->parent or return '';
546 if ( $cursor->isa('PPI::Structure') and $cursor->start ) {
547 return $cursor->start;
548 }
549 }
550}
551
- -
556#####################################################################
557# Manipulation
558
559=pod
560
561=head2 clone
562
563As per the L<Clone> module, the C<clone> method makes a perfect copy of
564an Element object. In the generic case, the implementation is done using
565the L<Clone> module's mechanism itself. In higher-order cases, such as for
566Nodes, there is more work involved to keep the parent-child links intact.
567
568=cut
569
570sub clone {
571 Clone::clone(shift);
572}
573
574=pod
575
576=head2 insert_before @Elements
577
578The C<insert_before> method allows you to insert lexical perl content, in
579the form of C<PPI::Element> objects, before the calling C<Element>. You
580need to be very careful when modifying perl code, as it's easy to break
581things.
582
583In its initial incarnation, this method allows you to insert a single
584Element, and will perform some basic checking to prevent you inserting
585something that would be structurally wrong (in PDOM terms).
586
587In future, this method may be enhanced to allow the insertion of multiple
588Elements, inline-parsed code strings or L<PPI::Document::Fragment> objects.
589
590Returns true if the Element was inserted, false if it can not be inserted,
591or C<undef> if you do not provide a L<PPI::Element> object as a parameter.
592
593=begin testing __insert_before 6
594
595my $Document = PPI::Document->new( \"print 'Hello World';" );
596isa_ok( $Document, 'PPI::Document' );
597my $semi = $Document->find_first('Token::Structure');
598isa_ok( $semi, 'PPI::Token::Structure' );
599is( $semi->content, ';', 'Got expected token' );
600my $foo = PPI::Token::Word->new('foo');
601isa_ok( $foo, 'PPI::Token::Word' );
602is( $foo->content, 'foo', 'Created Word token' );
603$semi->__insert_before( $foo );
604is( $Document->serialize, "print 'Hello World'foo;",
605 '__insert_before actually inserts' );
606
607=end testing
608
609=begin testing insert_before after __insert_before 6
610
611my $Document = PPI::Document->new( \"print 'Hello World';" );
612isa_ok( $Document, 'PPI::Document' );
613my $semi = $Document->find_first('Token::Structure');
614isa_ok( $semi, 'PPI::Token::Structure' );
615is( $semi->content, ';', 'Got expected token' );
616my $foo = PPI::Token::Word->new('foo');
617isa_ok( $foo, 'PPI::Token::Word' );
618is( $foo->content, 'foo', 'Created Word token' );
619$semi->insert_before( $foo );
620is( $Document->serialize, "print 'Hello World'foo;",
621 'insert_before actually inserts' );
622
623=end testing
624
625=cut
626
627sub __insert_before {
628 my $self = shift;
629 $self->parent->__insert_before_child( $self, @_ );
630}
631
632=pod
633
634=head2 insert_after @Elements
635
636The C<insert_after> method allows you to insert lexical perl content, in
637the form of C<PPI::Element> objects, after the calling C<Element>. You need
638to be very careful when modifying perl code, as it's easy to break things.
639
640In its initial incarnation, this method allows you to insert a single
641Element, and will perform some basic checking to prevent you inserting
642something that would be structurally wrong (in PDOM terms).
643
644In future, this method may be enhanced to allow the insertion of multiple
645Elements, inline-parsed code strings or L<PPI::Document::Fragment> objects.
646
647Returns true if the Element was inserted, false if it can not be inserted,
648or C<undef> if you do not provide a L<PPI::Element> object as a parameter.
649
650=begin testing __insert_after 6
651
652my $Document = PPI::Document->new( \"print 'Hello World';" );
653isa_ok( $Document, 'PPI::Document' );
654my $string = $Document->find_first('Token::Quote');
655isa_ok( $string, 'PPI::Token::Quote' );
656is( $string->content, "'Hello World'", 'Got expected token' );
657my $foo = PPI::Token::Word->new('foo');
658isa_ok( $foo, 'PPI::Token::Word' );
659is( $foo->content, 'foo', 'Created Word token' );
660$string->__insert_after( $foo );
661is( $Document->serialize, "print 'Hello World'foo;",
662 '__insert_after actually inserts' );
663
664=end testing
665
666=begin testing insert_after after __insert_after 6
667
668my $Document = PPI::Document->new( \"print 'Hello World';" );
669isa_ok( $Document, 'PPI::Document' );
670my $string = $Document->find_first('Token::Quote');
671isa_ok( $string, 'PPI::Token::Quote' );
672is( $string->content, "'Hello World'", 'Got expected token' );
673my $foo = PPI::Token::Word->new('foo');
674isa_ok( $foo, 'PPI::Token::Word' );
675is( $foo->content, 'foo', 'Created Word token' );
676$string->insert_after( $foo );
677is( $Document->serialize, "print 'Hello World'foo;",
678 'insert_after actually inserts' );
679
680=end testing
681
682=cut
683
684sub __insert_after {
685 my $self = shift;
686 $self->parent->__insert_after_child( $self, @_ );
687}
688
689=pod
690
691=head2 remove
692
693For a given C<PPI::Element>, the C<remove> method will remove it from its
694parent B<intact>, along with all of its children.
695
696Returns the C<Element> itself as a convenience, or C<undef> if an error
697occurs while trying to remove the C<Element>.
698
699=cut
700
701sub remove {
702 my $self = shift;
703 my $parent = $self->parent or return $self;
704 $parent->remove_child( $self );
705}
706
707=pod
708
709=head2 delete
710
711For a given C<PPI::Element>, the C<delete> method will remove it from its
712parent, immediately deleting the C<Element> and all of its children (if it
713has any).
714
715Returns true if the C<Element> was successfully deleted, or C<undef> if
716an error occurs while trying to remove the C<Element>.
717
718=cut
719
720sub delete {
721 $_[0]->remove or return undef;
722 $_[0]->DESTROY;
723 1;
724}
725
726=pod
727
728=head2 replace $Element
729
730Although some higher level class support more exotic forms of replace,
731at the basic level the C<replace> method takes a single C<Element> as
732an argument and replaces the current C<Element> with it.
733
734To prevent accidental damage to code, in this initial implementation the
735replacement element B<must> be of the same class (or a subclass) as the
736one being replaced.
737
738=cut
739
740sub replace {
741 my $self = ref $_[0] ? shift : return undef;
742 my $Element = _INSTANCE(shift, ref $self) or return undef;
743 die "The ->replace method has not yet been implemented";
744}
745
746=pod
747
748=head2 location
749
750If the Element exists within a L<PPI::Document> that has
751indexed the Element locations using C<PPI::Document::index_locations>, the
752C<location> method will return the location of the first character of the
753Element within the Document.
754
755Returns the location as a reference to a five-element array in the form C<[
756$line, $rowchar, $col, $logical_line, $logical_file_name ]>. The values are in
757a human format, with the first character of the file located at C<[ 1, 1, 1, ?,
758'something' ]>.
759
760The second and third numbers are similar, except that the second is the
761literal horizontal character, and the third is the visual column, taking
762into account tabbing (see L<PPI::Document/"tab_width [ $width ]">).
763
764The fourth number is the line number, taking into account any C<#line>
765directives. The fifth element is the name of the file that the element was
766found in, if available, taking into account any C<#line> directives.
767
768Returns C<undef> on error, or if the L<PPI::Document> object has not been
769indexed.
770
771=cut
772
773
# spent 61.3ms (47.2+14.1) within PPI::Element::location which was called 9763 times, avg 6┬Ás/call: # 9602 times (46.4ms+13.8ms) by PPI::Node::location at line 685 of PPI/Node.pm, avg 6┬Ás/call # 132 times (633┬Ás+256┬Ás) by PPI::Element::logical_line_number at line 932, avg 7┬Ás/call # 23 times (111┬Ás+34┬Ás) by PPI::Structure::location at line 265 of PPI/Structure.pm, avg 6┬Ás/call # 3 times (15┬Ás+6┬Ás) by PPI::Element::line_number at line 814, avg 7┬Ás/call # 3 times (11┬Ás+3┬Ás) by Perl::Critic::Violation::new at line 88 of Perl/Critic/Violation.pm, avg 5┬Ás/call
sub location {
77497631.24ms my $self = shift;
775
77697637.72ms976314.1ms $self->_ensure_location_present or return undef;
# spent 14.1ms making 9763 calls to PPI::Element::_ensure_location_present, avg 1┬Ás/call
777
778 # Return a copy, not the original
779976335.9ms return [ @{$self->{_location}} ];
780}
781
782=pod
783
784=head2 line_number
785
786If the Element exists within a L<PPI::Document> that has indexed the Element
787locations using C<PPI::Document::index_locations>, the C<line_number> method
788will return the line number of the first character of the Element within the
789Document.
790
791Returns C<undef> on error, or if the L<PPI::Document> object has not been
792indexed.
793
794=begin testing line_number 3
795
796my $document = PPI::Document->new(\<<'END_PERL');
797
798
799 foo
800END_PERL
801
802isa_ok( $document, 'PPI::Document' );
803my $words = $document->find('PPI::Token::Word');
804is( scalar @{$words}, 1, 'Found expected word token.' );
805is( $words->[0]->line_number, 3, 'Got correct line number.' );
806
807=end testing
808
809=cut
810
811
# spent 83┬Ás (28+55) within PPI::Element::line_number which was called 6 times, avg 14┬Ás/call: # 6 times (28┬Ás+55┬Ás) by Perl::Critic::Violation::_line_containing_violation at line 310 of Perl/Critic/Violation.pm, avg 14┬Ás/call
sub line_number {
81261┬Ás my $self = shift;
813
81468┬Ás655┬Ás my $location = $self->location() or return undef;
# spent 34┬Ás making 3 calls to PPI::Node::location, avg 11┬Ás/call # spent 21┬Ás making 3 calls to PPI::Element::location, avg 7┬Ás/call
815614┬Ás return $location->[0];
816}
817
818=pod
819
820=head2 column_number
821
822If the Element exists within a L<PPI::Document> that has indexed the Element
823locations using C<PPI::Document::index_locations>, the C<column_number> method
824will return the column number of the first character of the Element within the
825Document.
826
827Returns C<undef> on error, or if the L<PPI::Document> object has not been
828indexed.
829
830=begin testing column_number 3
831
832my $document = PPI::Document->new(\<<'END_PERL');
833
834
835 foo
836END_PERL
837
838isa_ok( $document, 'PPI::Document' );
839my $words = $document->find('PPI::Token::Word');
840is( scalar @{$words}, 1, 'Found expected word token.' );
841is( $words->[0]->column_number, 4, 'Got correct column number.' );
842
843=end testing
844
845=cut
846
847sub column_number {
848 my $self = shift;
849
850 my $location = $self->location() or return undef;
851 return $location->[1];
852}
853
854=pod
855
856=head2 visual_column_number
857
858If the Element exists within a L<PPI::Document> that has indexed the Element
859locations using C<PPI::Document::index_locations>, the C<visual_column_number>
860method will return the visual column number of the first character of the
861Element within the Document, according to the value of
862L<PPI::Document/"tab_width [ $width ]">.
863
864Returns C<undef> on error, or if the L<PPI::Document> object has not been
865indexed.
866
867=begin testing visual_column_number 3
868
869my $document = PPI::Document->new(\<<"END_PERL");
870
871
872\t foo
873END_PERL
874
875isa_ok( $document, 'PPI::Document' );
876my $tab_width = 5;
877$document->tab_width($tab_width); # don't use a "usual" value.
878my $words = $document->find('PPI::Token::Word');
879is( scalar @{$words}, 1, 'Found expected word token.' );
880is(
881 $words->[0]->visual_column_number,
882 $tab_width + 2,
883 'Got correct visual column number.',
884);
885
886=end testing
887
888=cut
889
890sub visual_column_number {
891 my $self = shift;
892
893 my $location = $self->location() or return undef;
894 return $location->[2];
895}
896
897=pod
898
899=head2 logical_line_number
900
901If the Element exists within a L<PPI::Document> that has indexed the Element
902locations using C<PPI::Document::index_locations>, the C<logical_line_number>
903method will return the line number of the first character of the Element within
904the Document, taking into account any C<#line> directives.
905
906Returns C<undef> on error, or if the L<PPI::Document> object has not been
907indexed.
908
909=begin testing logical_line_number 3
910
911# Double quoted so that we don't really have a "#line" at the beginning and
912# errors in this file itself aren't affected by this.
913my $document = PPI::Document->new(\<<"END_PERL");
914
915
916\#line 1 test-file
917 foo
918END_PERL
919
920isa_ok( $document, 'PPI::Document' );
921my $words = $document->find('PPI::Token::Word');
922is( scalar @{$words}, 1, 'Found expected word token.' );
923is( $words->[0]->logical_line_number, 1, 'Got correct logical line number.' );
924
925=end testing
926
927=cut
928
929
# spent 2.54ms (721┬Ás+1.82) within PPI::Element::logical_line_number which was called 198 times, avg 13┬Ás/call: # 51 times (251┬Ás+459┬Ás) by Perl::Critic::Annotation::_init at line 67 of Perl/Critic/Annotation.pm, avg 14┬Ás/call # 51 times (149┬Ás+261┬Ás) by Perl::Critic::Annotation::_is_single_line_annotation_on_simple_statement at line 184 of Perl/Critic/Annotation.pm, avg 8┬Ás/call # 41 times (135┬Ás+524┬Ás) by Perl::Critic::Annotation::_is_single_line_annotation_on_simple_statement at line 193 of Perl/Critic/Annotation.pm, avg 16┬Ás/call # 13 times (44┬Ás+76┬Ás) by Perl::Critic::Annotation::_init at line 127 of Perl/Critic/Annotation.pm, avg 9┬Ás/call # 12 times (51┬Ás+239┬Ás) by Perl::Critic::Annotation::_init at line 91 of Perl/Critic/Annotation.pm, avg 24┬Ás/call # 12 times (32┬Ás+118┬Ás) by Perl::Critic::Annotation::_is_single_line_annotation_on_simple_statement at line 201 of Perl/Critic/Annotation.pm, avg 12┬Ás/call # 12 times (37┬Ás+64┬Ás) by Perl::Critic::Annotation::_is_single_line_annotation_on_simple_statement at line 209 of Perl/Critic/Annotation.pm, avg 8┬Ás/call # 6 times (21┬Ás+82┬Ás) by Perl::Critic::Annotation::_init at line 92 of Perl/Critic/Annotation.pm, avg 17┬Ás/call
sub logical_line_number {
93019846┬Ás my $self = shift;
931
932198656┬Ás1981.82ms return $self->location()->[3];
# spent 888┬Ás making 132 calls to PPI::Element::location, avg 7┬Ás/call # spent 631┬Ás making 51 calls to PPI::Node::location, avg 12┬Ás/call # spent 304┬Ás making 15 calls to PPI::Structure::location, avg 20┬Ás/call
933}
934
935=pod
936
937=head2 logical_filename
938
939If the Element exists within a L<PPI::Document> that has indexed the Element
940locations using C<PPI::Document::index_locations>, the C<logical_filename>
941method will return the logical file name containing the first character of the
942Element within the Document, taking into account any C<#line> directives.
943
944Returns C<undef> on error, or if the L<PPI::Document> object has not been
945indexed.
946
947=begin testing logical_filename 3
948
949# Double quoted so that we don't really have a "#line" at the beginning and
950# errors in this file itself aren't affected by this.
951my $document = PPI::Document->new(\<<"END_PERL");
952
953
954\#line 1 test-file
955 foo
956END_PERL
957
958isa_ok( $document, 'PPI::Document' );
959my $words = $document->find('PPI::Token::Word');
960is( scalar @{$words}, 1, 'Found expected word token.' );
961is(
962 $words->[0]->logical_filename,
963 'test-file',
964 'Got correct logical line number.',
965);
966
967=end testing
968
969=cut
970
971
# spent 3.55ms (908┬Ás+2.64) within PPI::Element::logical_filename which was called 144 times, avg 25┬Ás/call: # 144 times (908┬Ás+2.64ms) by Perl::Critic::Policy::Modules::RequireFilenameMatchesPackage::violates at line 56 of Perl/Critic/Policy/Modules/RequireFilenameMatchesPackage.pm, avg 25┬Ás/call
sub logical_filename {
97214463┬Ás my $self = shift;
973
974144345┬Ás1442.64ms my $location = $self->location() or return undef;
# spent 2.64ms making 144 calls to PPI::Node::location, avg 18┬Ás/call
975144518┬Ás return $location->[4];
976}
977
978
# spent 14.1ms within PPI::Element::_ensure_location_present which was called 9763 times, avg 1┬Ás/call: # 9763 times (14.1ms+0s) by PPI::Element::location at line 776, avg 1┬Ás/call
sub _ensure_location_present {
97997631.08ms my $self = shift;
980
98197634.28ms unless ( exists $self->{_location} ) {
982 # Are we inside a normal document?
983 my $Document = $self->document or return undef;
984 if ( $Document->isa('PPI::Document::Fragment') ) {
985 # Because they can't be serialized, document fragments
986 # do not support the concept of location.
987 return undef;
988 }
989
990 # Generate the locations. If they need one location, then
991 # the chances are they'll want more, and it's better that
992 # everything is already pre-generated.
993 $Document->index_locations or return undef;
994 unless ( exists $self->{_location} ) {
995 # erm... something went very wrong here
996 return undef;
997 }
998 }
999
1000976321.0ms return 1;
1001}
1002
1003# Although flush_locations is only publically a Document-level method,
1004# we are able to implement it at an Element level, allowing us to
1005# selectively flush only the part of the document that occurs after the
1006# element for which the flush is called.
1007sub _flush_locations {
1008 my $self = shift;
1009 unless ( $self == $self->top ) {
1010 return $self->top->_flush_locations( $self );
1011 }
1012
1013 # Get the full list of all Tokens
1014 my @Tokens = $self->tokens;
1015
1016 # Optionally allow starting from an arbitrary element (or rather,
1017 # the first Token equal-to-or-within an arbitrary element)
1018 if ( _INSTANCE($_[0], 'PPI::Element') ) {
1019 my $start = shift->first_token;
1020 while ( my $Token = shift @Tokens ) {
1021 return 1 unless $Token->{_location};
1022 next unless refaddr($Token) == refaddr($start);
1023
1024 # Found the start. Flush it's location
1025 delete $$Token->{_location};
1026 last;
1027 }
1028 }
1029
1030 # Iterate over any remaining Tokens and flush their location
1031 foreach my $Token ( @Tokens ) {
1032 delete $Token->{_location};
1033 }
1034
1035 1;
1036}
1037
- -
1042#####################################################################
1043# XML Compatibility Methods
1044
1045sub _xml_name {
1046 my $class = ref $_[0] || $_[0];
1047 my $name = lc join( '_', split /::/, $class );
1048 substr($name, 4);
1049}
1050
1051sub _xml_attr {
1052 return {};
1053}
1054
1055sub _xml_content {
1056 defined $_[0]->{content} ? $_[0]->{content} : '';
1057}
1058
- -
1063#####################################################################
1064# Internals
1065
1066# Set the error string
1067sub _error {
1068 $errstr = $_[1];
1069 undef;
1070}
1071
1072# Clear the error string
1073sub _clear {
1074 $errstr = '';
1075 $_[0];
1076}
1077
1078# Being DESTROYed in this manner, rather than by an explicit
1079# ->delete means our reference count has probably fallen to zero.
1080# Therefore we don't need to remove ourselves from our parent,
1081# just the index ( just in case ).
1082### XS -> PPI/XS.xs:_PPI_Element__DESTROY 0.900+
108394372500ms9437251.4ms
# spent 389ms (338+51.4) within PPI::Element::DESTROY which was called 94372 times, avg 4┬Ás/call: # 82503 times (293ms+44.9ms) by PPI::Node::DESTROY at line 700 of PPI/Node.pm, avg 4┬Ás/call # 11578 times (43.2ms+6.05ms) by PPI::Node::DESTROY at line 704 of PPI/Node.pm, avg 4┬Ás/call # 144 times (994┬Ás+311┬Ás) by PPI::Token::Word::__TOKENIZER__commit at line 206 of PPI/Token/Whitespace.pm, avg 9┬Ás/call # 144 times (451┬Ás+77┬Ás) by PPI::Node::DESTROY at line 709 of PPI/Node.pm, avg 4┬Ás/call # 3 times (14┬Ás+3┬Ás) by PPI::Token::Magic::__TOKENIZER__on_char at line 176 of PPI/Token/Magic.pm, avg 6┬Ás/call
sub DESTROY { delete $_PARENT{refaddr $_[0]} }
# spent 51.4ms making 94372 calls to Scalar::Util::refaddr, avg 544ns/call
1084
1085# Operator overloads
1086sub __equals { ref $_[1] and refaddr($_[0]) == refaddr($_[1]) }
1087sub __nequals { !__equals(@_) }
1088
# spent 1.77s (1.08+684ms) within PPI::Element::__eq which was called 105472 times, avg 17┬Ás/call: # 104217 times (1.07s+675ms) by PPI::Element::__ne at line 1093, avg 17┬Ás/call # 904 times (12.4ms+6.41ms) by Perl::Critic::Utils::is_hash_key at line 724 of Perl/Critic/Utils.pm, avg 21┬Ás/call # 126 times (1.03ms+756┬Ás) by List::MoreUtils::any at line 209 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm, avg 14┬Ás/call # 83 times (817┬Ás+605┬Ás) by Perl::Critic::Policy::Variables::RequireLexicalLoopIterators::violates at line 61 of Perl/Critic/Policy/Variables/RequireLexicalLoopIterators.pm, avg 17┬Ás/call # 57 times (502┬Ás+377┬Ás) by Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions::_is_topic at line 48 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm, avg 15┬Ás/call # 41 times (444┬Ás+442┬Ás) by Perl::Critic::Utils::split_nodes_on_comma at line 989 of Perl/Critic/Utils.pm, avg 22┬Ás/call # 40 times (352┬Ás+265┬Ás) by Perl::Critic::Utils::_is_dereference_operator at line 800 of Perl/Critic/Utils.pm, avg 15┬Ás/call # 3 times (34┬Ás+39┬Ás) by Perl::Critic::Utils::parse_arg_list at line 971 of Perl/Critic/Utils.pm, avg 24┬Ás/call # once (8┬Ás+6┬Ás) by Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions::_is_topic_mutating_func at line 217 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm
sub __eq {
10891054721.07s421888687ms my $self = _INSTANCE($_[0], 'PPI::Element') ? $_[0]->content : $_[0];
# spent 428ms making 105472 calls to Params::Util::_INSTANCE, avg 4┬Ás/call # spent 141ms making 105472 calls to PPI::Token::content, avg 1┬Ás/call # spent 60.7ms making 105472 calls to UNIVERSAL::isa, avg 576ns/call # spent 57.6ms making 105472 calls to PPI::Util::TRUE, avg 546ns/call
1090105472287ms10556057.8ms my $other = _INSTANCE($_[1], 'PPI::Element') ? $_[1]->content : $_[1];
# spent 57.7ms making 105472 calls to Params::Util::_INSTANCE, avg 547ns/call # spent 96┬Ás making 88 calls to Readonly::Scalar::FETCH, avg 1┬Ás/call
1091105472225ms $self eq $other;
1092}
1093104217274ms1042171.74s
# spent 2.04s (301ms+1.74) within PPI::Element::__ne which was called 104217 times, avg 20┬Ás/call: # 13481 times (37.5ms+251ms) by Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen::violates at line 44 of Perl/Critic/Policy/InputOutput/ProhibitTwoArgOpen.pm, avg 21┬Ás/call # 13481 times (36.7ms+233ms) by Perl::Critic::Policy::ClassHierarchies::ProhibitOneArgBless::violates at line 37 of Perl/Critic/Policy/ClassHierarchies/ProhibitOneArgBless.pm, avg 20┬Ás/call # 13481 times (42.0ms+227ms) by Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles::violates at line 37 of Perl/Critic/Policy/InputOutput/ProhibitBarewordFileHandles.pm, avg 20┬Ás/call # 13481 times (41.4ms+225ms) by Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef::violates at line 36 of Perl/Critic/Policy/Subroutines/ProhibitExplicitReturnUndef.pm, avg 20┬Ás/call # 13481 times (38.5ms+218ms) by Perl::Critic::Policy::Subroutines::ProhibitReturnSort::violates at line 36 of Perl/Critic/Policy/Subroutines/ProhibitReturnSort.pm, avg 19┬Ás/call # 13481 times (36.9ms+218ms) by Perl::Critic::Policy::BuiltinFunctions::ProhibitSleepViaSelect::violates at line 38 of Perl/Critic/Policy/BuiltinFunctions/ProhibitSleepViaSelect.pm, avg 19┬Ás/call # 13481 times (35.7ms+209ms) by Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval::violates at line 49 of Perl/Critic/Policy/BuiltinFunctions/ProhibitStringyEval.pm, avg 18┬Ás/call # 8379 times (28.3ms+139ms) by Perl::Critic::Policy::InputOutput::ProhibitInteractiveTest::violates at line 36 of Perl/Critic/Policy/InputOutput/ProhibitInteractiveTest.pm, avg 20┬Ás/call # 573 times (1.45ms+9.83ms) by Perl::Critic::Policy::Subroutines::ProhibitReturnSort::violates at line 42 of Perl/Critic/Policy/Subroutines/ProhibitReturnSort.pm, avg 20┬Ás/call # 573 times (1.45ms+8.15ms) by Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef::violates at line 42 of Perl/Critic/Policy/Subroutines/ProhibitExplicitReturnUndef.pm, avg 17┬Ás/call # 321 times (781┬Ás+4.59ms) by Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions::_is_topic_mutating_substr at line 229 of Perl/Critic/Policy/ControlStructures/ProhibitMutatingListFunctions.pm, avg 17┬Ás/call # 4 times (10┬Ás+54┬Ás) by Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles::violates at line 46 of Perl/Critic/Policy/InputOutput/ProhibitBarewordFileHandles.pm, avg 16┬Ás/call
sub __ne { !__eq(@_) }
# spent 1.74s making 104217 calls to PPI::Element::__eq, avg 17┬Ás/call
1094
109512┬Ás1;
1096
1097=pod
1098
1099=head1 TO DO
1100
1101It would be nice if C<location> could be used in an ad-hoc manner. That is,
1102if called on an Element within a Document that has not been indexed, it will
1103do a one-off calculation to find the location. It might be very painful if
1104someone started using it a lot, without remembering to index the document,
1105but it would be handy for things that are only likely to use it once, such
1106as error handlers.
1107
1108=head1 SUPPORT
1109
1110See the L<support section|PPI/SUPPORT> in the main module.
1111
1112=head1 AUTHOR
1113
1114Adam Kennedy E<lt>adamk@cpan.orgE<gt>
1115
1116=head1 COPYRIGHT
1117
1118Copyright 2001 - 2011 Adam Kennedy.
1119
1120This program is free software; you can redistribute
1121it and/or modify it under the same terms as Perl itself.
1122
1123The full text of the license can be found in the
1124LICENSE file included with this module.
1125
1126=cut