← 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