Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Element.pm |
Statements | Executed 1237739 statements in 4.31s |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
105472 | 9 | 4 | 1.08s | 1.77s | __eq | PPI::Element::
30261 | 10 | 4 | 519ms | 916ms | snext_sibling | PPI::Element::
94372 | 5 | 3 | 338ms | 389ms | DESTROY | PPI::Element::
104217 | 12 | 9 | 301ms | 2.04s | __ne | PPI::Element::
184039 | 17 | 6 | 163ms | 163ms | significant | PPI::Element::
165294 | 1 | 1 | 133ms | 133ms | tokens | PPI::Element::
23725 | 7 | 4 | 85.9ms | 98.7ms | parent | PPI::Element::
9763 | 5 | 4 | 47.2ms | 61.3ms | location | PPI::Element::
9763 | 1 | 1 | 14.1ms | 14.1ms | _ensure_location_present | PPI::Element::
286 | 5 | 2 | 5.54ms | 8.20ms | statement | PPI::Element::
339 | 5 | 3 | 5.42ms | 15.3ms | sprevious_sibling | PPI::Element::
226 | 2 | 1 | 2.79ms | 17.6ms | next_sibling | PPI::Element::
1 | 1 | 1 | 1.90ms | 2.06ms | BEGIN@30 | PPI::Element::
1 | 1 | 1 | 1.12ms | 1.57ms | BEGIN@25 | PPI::Element::
144 | 1 | 1 | 908µs | 3.55ms | logical_filename | PPI::Element::
1 | 1 | 1 | 736µs | 6.30ms | BEGIN@28 | PPI::Element::
198 | 8 | 1 | 721µs | 2.54ms | logical_line_number | PPI::Element::
1 | 1 | 1 | 462µs | 1.59ms | BEGIN@29 | PPI::Element::
3 | 1 | 1 | 102µs | 127µs | top | PPI::Element::
6 | 1 | 1 | 28µs | 83µs | line_number | PPI::Element::
1 | 1 | 1 | 15µs | 30µs | BEGIN@46 | PPI::Element::
1 | 1 | 1 | 11µs | 23µs | BEGIN@24 | PPI::Element::
1 | 1 | 1 | 8µs | 32µs | BEGIN@26 | PPI::Element::
1 | 1 | 1 | 8µs | 30µs | BEGIN@41 | PPI::Element::
1 | 1 | 1 | 7µs | 31µs | BEGIN@27 | PPI::Element::
1 | 1 | 1 | 7µs | 45µs | BEGIN@32 | PPI::Element::
1 | 1 | 1 | 6µs | 21µs | BEGIN@44 | PPI::Element::
1 | 1 | 1 | 6µs | 19µs | BEGIN@43 | PPI::Element::
1 | 1 | 1 | 5µs | 21µs | BEGIN@42 | PPI::Element::
1 | 1 | 1 | 5µs | 19µs | BEGIN@45 | PPI::Element::
1 | 1 | 1 | 4µs | 4µs | BEGIN@33 | PPI::Element::
0 | 0 | 0 | 0s | 0s | __ANON__[:346] | PPI::Element::
0 | 0 | 0 | 0s | 0s | __ANON__[:369] | PPI::Element::
0 | 0 | 0 | 0s | 0s | __ANON__[:394] | PPI::Element::
0 | 0 | 0 | 0s | 0s | __ANON__[:417] | PPI::Element::
0 | 0 | 0 | 0s | 0s | __equals | PPI::Element::
0 | 0 | 0 | 0s | 0s | __insert_after | PPI::Element::
0 | 0 | 0 | 0s | 0s | __insert_before | PPI::Element::
0 | 0 | 0 | 0s | 0s | __nequals | PPI::Element::
0 | 0 | 0 | 0s | 0s | _clear | PPI::Element::
0 | 0 | 0 | 0s | 0s | _error | PPI::Element::
0 | 0 | 0 | 0s | 0s | _flush_locations | PPI::Element::
0 | 0 | 0 | 0s | 0s | _xml_attr | PPI::Element::
0 | 0 | 0 | 0s | 0s | _xml_content | PPI::Element::
0 | 0 | 0 | 0s | 0s | _xml_name | PPI::Element::
0 | 0 | 0 | 0s | 0s | ancestor_of | PPI::Element::
0 | 0 | 0 | 0s | 0s | class | PPI::Element::
0 | 0 | 0 | 0s | 0s | clone | PPI::Element::
0 | 0 | 0 | 0s | 0s | column_number | PPI::Element::
0 | 0 | 0 | 0s | 0s | content | PPI::Element::
0 | 0 | 0 | 0s | 0s | delete | PPI::Element::
0 | 0 | 0 | 0s | 0s | descendant_of | PPI::Element::
0 | 0 | 0 | 0s | 0s | document | PPI::Element::
0 | 0 | 0 | 0s | 0s | first_token | PPI::Element::
0 | 0 | 0 | 0s | 0s | last_token | PPI::Element::
0 | 0 | 0 | 0s | 0s | next_token | PPI::Element::
0 | 0 | 0 | 0s | 0s | previous_sibling | PPI::Element::
0 | 0 | 0 | 0s | 0s | previous_token | PPI::Element::
0 | 0 | 0 | 0s | 0s | remove | PPI::Element::
0 | 0 | 0 | 0s | 0s | replace | PPI::Element::
0 | 0 | 0 | 0s | 0s | visual_column_number | PPI::Element::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package PPI::Element; | ||||
2 | |||||
3 | =pod | ||||
4 | |||||
5 | =head1 NAME | ||||
6 | |||||
7 | PPI::Element - The abstract Element class, a base for all source objects | ||||
8 | |||||
9 | =head1 INHERITANCE | ||||
10 | |||||
11 | PPI::Element is the root of the PDOM tree | ||||
12 | |||||
13 | =head1 DESCRIPTION | ||||
14 | |||||
15 | The abstract C<PPI::Element> serves as a base class for all source-related | ||||
16 | objects, from a single whitespace token to an entire document. It provides | ||||
17 | a basic set of methods to provide a common interface and basic | ||||
18 | implementations. | ||||
19 | |||||
20 | =head1 METHODS | ||||
21 | |||||
22 | =cut | ||||
23 | |||||
24 | 2 | 19µs | 2 | 35µ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 # spent 23µs making 1 call to PPI::Element::BEGIN@24
# spent 12µs making 1 call to strict::import |
25 | 2 | 79µs | 1 | 1.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 # spent 1.57ms making 1 call to PPI::Element::BEGIN@25 |
26 | 2 | 24µs | 2 | 56µ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 # spent 32µs making 1 call to PPI::Element::BEGIN@26
# spent 24µs making 1 call to Exporter::import |
27 | 2 | 20µs | 2 | 55µ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 # spent 31µs making 1 call to PPI::Element::BEGIN@27
# spent 24µs making 1 call to Exporter::import |
28 | 2 | 99µs | 1 | 6.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 # spent 6.30ms making 1 call to PPI::Element::BEGIN@28 |
29 | 2 | 78µs | 1 | 1.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 # spent 1.59ms making 1 call to PPI::Element::BEGIN@29 |
30 | 2 | 99µs | 1 | 2.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 # spent 2.06ms making 1 call to PPI::Element::BEGIN@30 |
31 | |||||
32 | 2 | 32µs | 2 | 82µ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 # 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 | ||||
34 | 1 | 400ns | $VERSION = '1.215'; | ||
35 | 1 | 200ns | $errstr = ''; | ||
36 | |||||
37 | # Master Child -> Parent index | ||||
38 | 1 | 4µs | %_PARENT = (); | ||
39 | 1 | 20µs | 1 | 4µs | } # spent 4µs making 1 call to PPI::Element::BEGIN@33 |
40 | |||||
41 | 2 | 24µs | 2 | 53µ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 # spent 30µs making 1 call to PPI::Element::BEGIN@41
# spent 23µs making 1 call to overload::import |
42 | 2 | 20µs | 2 | 37µ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 # spent 21µs making 1 call to PPI::Element::BEGIN@42
# spent 16µs making 1 call to overload::import |
43 | 2 | 29µs | 2 | 33µ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 # spent 19µs making 1 call to PPI::Element::BEGIN@43
# spent 14µs making 1 call to overload::import |
44 | 2 | 19µs | 2 | 36µ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 # spent 21µs making 1 call to PPI::Element::BEGIN@44
# spent 15µs making 1 call to overload::import |
45 | 2 | 28µs | 2 | 33µ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 # spent 19µs making 1 call to PPI::Element::BEGIN@45
# spent 14µs making 1 call to overload::import |
46 | 2 | 1.59ms | 2 | 44µ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 # 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 | |||||
59 | Because we treat whitespace and other non-code items as Tokens (in order to | ||||
60 | be able to "round trip" the L<PPI::Document> back to a file) the | ||||
61 | C<significant> method allows us to distinguish between tokens that form a | ||||
62 | part of the code, and tokens that aren't significant, such as whitespace, | ||||
63 | POD, or the portion of a file after (and including) the C<__END__> token. | ||||
64 | |||||
65 | Returns true if the Element is significant, or false it not. | ||||
66 | |||||
67 | =cut | ||||
68 | |||||
69 | ### XS -> PPI/XS.xs:_PPI_Element__significant 0.845+ | ||||
70 | 184039 | 549ms | # 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 | ||
71 | |||||
72 | =pod | ||||
73 | |||||
74 | =head2 class | ||||
75 | |||||
76 | The C<class> method is provided as a convenience, and really does nothing | ||||
77 | more than returning C<ref($self)>. However, some people have found that | ||||
78 | they appreciate the laziness of C<$Foo-E<gt>class eq 'whatever'>, so I | ||||
79 | have caved to popular demand and included it. | ||||
80 | |||||
81 | Returns the class of the Element as a string | ||||
82 | |||||
83 | =cut | ||||
84 | |||||
85 | sub class { ref($_[0]) } | ||||
86 | |||||
87 | =pod | ||||
88 | |||||
89 | =head2 tokens | ||||
90 | |||||
91 | The C<tokens> method returns a list of L<PPI::Token> objects for the | ||||
92 | Element, essentially getting back that part of the document as if it had | ||||
93 | not been lexed. | ||||
94 | |||||
95 | This also means there are no Statements and no Structures in the list, | ||||
96 | just the Token classes. | ||||
97 | |||||
98 | =cut | ||||
99 | |||||
100 | 165294 | 372ms | # 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 | ||
101 | |||||
102 | =pod | ||||
103 | |||||
104 | =head2 content | ||||
105 | |||||
106 | For B<any> C<PPI::Element>, the C<content> method will reconstitute the | ||||
107 | base code for it as a single string. This method is also the method used | ||||
108 | for overloading stringification. When an Element is used in a double-quoted | ||||
109 | string for example, this is the method that is called. | ||||
110 | |||||
111 | B<WARNING:> | ||||
112 | |||||
113 | You should be aware that because of the way that here-docs are handled, any | ||||
114 | here-doc content is not included in C<content>, and as such you should | ||||
115 | B<not> eval or execute the result if it contains any L<PPI::Token::HereDoc>. | ||||
116 | |||||
117 | The L<PPI::Document> method C<serialize> should be used to stringify a PDOM | ||||
118 | document into something that can be executed as expected. | ||||
119 | |||||
120 | Returns the basic code as a string (excluding here-doc content). | ||||
121 | |||||
122 | =cut | ||||
123 | |||||
124 | ### XS -> PPI/XS.xs:_PPI_Element__content 0.900+ | ||||
125 | sub content { '' } | ||||
126 | |||||
- - | |||||
131 | ##################################################################### | ||||
132 | # Naigation Methods | ||||
133 | |||||
134 | =pod | ||||
135 | |||||
136 | =head2 parent | ||||
137 | |||||
138 | Elements themselves are not intended to contain other Elements, that is | ||||
139 | left to the L<PPI::Node> abstract class, a subclass of C<PPI::Element>. | ||||
140 | However, all Elements can be contained B<within> a parent Node. | ||||
141 | |||||
142 | If an Element is within a parent Node, the C<parent> method returns the | ||||
143 | Node. | ||||
144 | |||||
145 | =cut | ||||
146 | |||||
147 | 23725 | 120ms | 23725 | 12.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 # spent 12.8ms making 23725 calls to Scalar::Util::refaddr, avg 539ns/call |
148 | |||||
149 | =pod | ||||
150 | |||||
151 | =head2 descendant_of $element | ||||
152 | |||||
153 | Answers whether a C<PPI::Element> is contained within another one. | ||||
154 | |||||
155 | C<PPI::Element>s are considered to be descendants of themselves. | ||||
156 | |||||
157 | =begin testing descendant_of 9 | ||||
158 | |||||
159 | my $Document = PPI::Document->new( \'( [ thingy ] ); $blarg = 1' ); | ||||
160 | isa_ok( $Document, 'PPI::Document' ); | ||||
161 | ok( | ||||
162 | $Document->descendant_of($Document), | ||||
163 | 'Document is a descendant of itself.', | ||||
164 | ); | ||||
165 | |||||
166 | my $words = $Document->find('Token::Word'); | ||||
167 | is(scalar @{$words}, 1, 'Document contains 1 Word.'); | ||||
168 | my $word = $words->[0]; | ||||
169 | ok( | ||||
170 | $word->descendant_of($word), | ||||
171 | 'Word is a descendant of itself.', | ||||
172 | ); | ||||
173 | ok( | ||||
174 | $word->descendant_of($Document), | ||||
175 | 'Word is a descendant of the Document.', | ||||
176 | ); | ||||
177 | ok( | ||||
178 | ! $Document->descendant_of($word), | ||||
179 | 'Document is not a descendant of the Word.', | ||||
180 | ); | ||||
181 | |||||
182 | my $symbols = $Document->find('Token::Symbol'); | ||||
183 | is(scalar @{$symbols}, 1, 'Document contains 1 Symbol.'); | ||||
184 | my $symbol = $symbols->[0]; | ||||
185 | ok( | ||||
186 | ! $word->descendant_of($symbol), | ||||
187 | 'Word is not a descendant the Symbol.', | ||||
188 | ); | ||||
189 | ok( | ||||
190 | ! $symbol->descendant_of($word), | ||||
191 | 'Symbol is not a descendant the Word.', | ||||
192 | ); | ||||
193 | |||||
194 | =end testing | ||||
195 | |||||
196 | =cut | ||||
197 | |||||
198 | sub 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 | |||||
211 | Answers whether a C<PPI::Element> is contains another one. | ||||
212 | |||||
213 | C<PPI::Element>s are considered to be ancestors of themselves. | ||||
214 | |||||
215 | =begin testing ancestor_of 9 | ||||
216 | |||||
217 | my $Document = PPI::Document->new( \'( [ thingy ] ); $blarg = 1' ); | ||||
218 | isa_ok( $Document, 'PPI::Document' ); | ||||
219 | ok( | ||||
220 | $Document->ancestor_of($Document), | ||||
221 | 'Document is an ancestor of itself.', | ||||
222 | ); | ||||
223 | |||||
224 | my $words = $Document->find('Token::Word'); | ||||
225 | is(scalar @{$words}, 1, 'Document contains 1 Word.'); | ||||
226 | my $word = $words->[0]; | ||||
227 | ok( | ||||
228 | $word->ancestor_of($word), | ||||
229 | 'Word is an ancestor of itself.', | ||||
230 | ); | ||||
231 | ok( | ||||
232 | ! $word->ancestor_of($Document), | ||||
233 | 'Word is not an ancestor of the Document.', | ||||
234 | ); | ||||
235 | ok( | ||||
236 | $Document->ancestor_of($word), | ||||
237 | 'Document is an ancestor of the Word.', | ||||
238 | ); | ||||
239 | |||||
240 | my $symbols = $Document->find('Token::Symbol'); | ||||
241 | is(scalar @{$symbols}, 1, 'Document contains 1 Symbol.'); | ||||
242 | my $symbol = $symbols->[0]; | ||||
243 | ok( | ||||
244 | ! $word->ancestor_of($symbol), | ||||
245 | 'Word is not an ancestor the Symbol.', | ||||
246 | ); | ||||
247 | ok( | ||||
248 | ! $symbol->ancestor_of($word), | ||||
249 | 'Symbol is not an ancestor the Word.', | ||||
250 | ); | ||||
251 | |||||
252 | =end testing | ||||
253 | |||||
254 | =cut | ||||
255 | |||||
256 | sub 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 | |||||
269 | For a C<PPI::Element> that is contained (at some depth) within a | ||||
270 | L<PPI::Statment>, the C<statement> method will return the first parent | ||||
271 | Statement object lexically 'above' the Element. | ||||
272 | |||||
273 | Returns a L<PPI::Statement> object, which may be the same Element if the | ||||
274 | Element is itself a L<PPI::Statement> object. | ||||
275 | |||||
276 | Returns false if the Element is not within a Statement and is not itself | ||||
277 | a 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 | ||||
282 | 286 | 50µs | my $cursor = shift; | ||
283 | 286 | 1.64ms | 572 | 1.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 |
284 | 286 | 6.09ms | 1430 | 1.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 | } | ||||
286 | 286 | 537µs | $cursor; | ||
287 | } | ||||
288 | |||||
289 | =pod | ||||
290 | |||||
291 | =head2 top | ||||
292 | |||||
293 | For a C<PPI::Element> that is contained within a PDOM tree, the C<top> method | ||||
294 | will return the top-level Node in the tree. Most of the time this should be | ||||
295 | a L<PPI::Document> object, however this will not always be so. For example, | ||||
296 | if a subroutine has been removed from its Document, to be moved to another | ||||
297 | Document. | ||||
298 | |||||
299 | Returns the top-most PDOM object, which may be the same Element, if it is | ||||
300 | not 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 | ||||
305 | 3 | 1µs | my $cursor = shift; | ||
306 | 3 | 119µs | 51 | 25µ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 | } | ||||
309 | 3 | 7µs | $cursor; | ||
310 | } | ||||
311 | |||||
312 | =pod | ||||
313 | |||||
314 | =head2 document | ||||
315 | |||||
316 | For an Element that is contained within a L<PPI::Document> object, | ||||
317 | the C<document> method will return the top-level Document for the Element. | ||||
318 | |||||
319 | Returns the L<PPI::Document> for this Element, or false if the Element is not | ||||
320 | contained within a Document. | ||||
321 | |||||
322 | =cut | ||||
323 | |||||
324 | sub document { | ||||
325 | my $top = shift->top; | ||||
326 | _INSTANCE($top, 'PPI::Document') and $top; | ||||
327 | } | ||||
328 | |||||
329 | =pod | ||||
330 | |||||
331 | =head2 next_sibling | ||||
332 | |||||
333 | All L<PPI::Node> objects (specifically, our parent Node) contain a number of | ||||
334 | C<PPI::Element> objects. The C<next_sibling> method returns the C<PPI::Element> | ||||
335 | immediately 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 | ||||
340 | 226 | 42µs | my $self = shift; | ||
341 | 226 | 1.11ms | 452 | 241µ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 |
342 | 226 | 460µs | 226 | 123µs | my $key = refaddr $self; # spent 123µs making 226 calls to Scalar::Util::refaddr, avg 545ns/call |
343 | 226 | 74µs | my $elements = $parent->{children}; | ||
344 | my $position = List::MoreUtils::firstidx { | ||||
345 | 5789 | 13.6ms | 5789 | 2.49ms | refaddr $_ == $key # spent 2.49ms making 5789 calls to Scalar::Util::refaddr, avg 430ns/call |
346 | 226 | 387µs | 226 | 14.3ms | } @$elements; # spent 14.3ms making 226 calls to List::MoreUtils::firstidx, avg 63µs/call |
347 | 226 | 2.64ms | 216 | 132µ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 | |||||
354 | As per the other 's' methods, the C<snext_sibling> method returns the next | ||||
355 | B<significant> sibling of the C<PPI::Element> object. | ||||
356 | |||||
357 | Returns a C<PPI::Element> object, or false if there is no 'next' significant | ||||
358 | sibling. | ||||
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 | ||||
363 | 30261 | 5.35ms | my $self = shift; | ||
364 | 30261 | 167ms | 60522 | 33.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 |
365 | 30261 | 77.2ms | 30261 | 17.3ms | my $key = refaddr $self; # spent 17.3ms making 30261 calls to Scalar::Util::refaddr, avg 570ns/call |
366 | 30261 | 10.6ms | my $elements = $parent->{children}; | ||
367 | my $position = List::MoreUtils::firstidx { | ||||
368 | 95278 | 324ms | 95278 | 47.5ms | refaddr $_ == $key # spent 47.5ms making 95278 calls to Scalar::Util::refaddr, avg 498ns/call |
369 | 30261 | 56.8ms | 30261 | 294ms | } @$elements; # spent 294ms making 30261 calls to List::MoreUtils::firstidx, avg 10µs/call |
370 | 30261 | 151ms | 55005 | 51.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 | } | ||||
373 | 486 | 1.07ms | ''; | ||
374 | } | ||||
375 | |||||
376 | =pod | ||||
377 | |||||
378 | =head2 previous_sibling | ||||
379 | |||||
380 | All L<PPI::Node> objects (specifically, our parent Node) contain a number of | ||||
381 | C<PPI::Element> objects. The C<previous_sibling> method returns the Element | ||||
382 | immediately before the current one, or false if there is no 'previous' | ||||
383 | C<PPI::Element> object. | ||||
384 | |||||
385 | =cut | ||||
386 | |||||
387 | sub 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 | |||||
402 | As per the other 's' methods, the C<sprevious_sibling> method returns | ||||
403 | the previous B<significant> sibling of the C<PPI::Element> object. | ||||
404 | |||||
405 | Returns a C<PPI::Element> object, or false if there is no 'previous' significant | ||||
406 | sibling. | ||||
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 | ||||
411 | 339 | 72µs | my $self = shift; | ||
412 | 339 | 1.64ms | 678 | 368µ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 |
413 | 339 | 731µs | 339 | 192µs | my $key = refaddr $self; # spent 192µs making 339 calls to Scalar::Util::refaddr, avg 567ns/call |
414 | 339 | 130µs | my $elements = $parent->{children}; | ||
415 | my $position = List::MoreUtils::firstidx { | ||||
416 | 2437 | 8.90ms | 2437 | 1.13ms | refaddr $_ == $key # spent 1.13ms making 2437 calls to Scalar::Util::refaddr, avg 464ns/call |
417 | 339 | 789µs | 339 | 8.81ms | } @$elements; # spent 8.81ms making 339 calls to List::MoreUtils::firstidx, avg 26µs/call |
418 | 339 | 1.43ms | 498 | 513µ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 | } | ||||
421 | 121 | 290µs | ''; | ||
422 | } | ||||
423 | |||||
424 | =pod | ||||
425 | |||||
426 | =head2 first_token | ||||
427 | |||||
428 | As a support method for higher-order algorithms that deal specifically with | ||||
429 | tokens and actual Perl content, the C<first_token> method finds the first | ||||
430 | PPI::Token object within or equal to this one. | ||||
431 | |||||
432 | That is, if called on a L<PPI::Node> subclass, it will descend until it | ||||
433 | finds a L<PPI::Token>. If called on a L<PPI::Token> object, it will return | ||||
434 | the same object. | ||||
435 | |||||
436 | Returns a L<PPI::Token> object, or dies on error (which should be extremely | ||||
437 | rare and only occur if an illegal empty L<PPI::Statement> exists below the | ||||
438 | current Element somewhere. | ||||
439 | |||||
440 | =cut | ||||
441 | |||||
442 | sub 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 | |||||
456 | As a support method for higher-order algorithms that deal specifically with | ||||
457 | tokens and actual Perl content, the C<last_token> method finds the last | ||||
458 | PPI::Token object within or equal to this one. | ||||
459 | |||||
460 | That is, if called on a L<PPI::Node> subclass, it will descend until it | ||||
461 | finds a L<PPI::Token>. If called on a L<PPI::Token> object, it will return | ||||
462 | the itself. | ||||
463 | |||||
464 | Returns a L<PPI::Token> object, or dies on error (which should be extremely | ||||
465 | rare and only occur if an illegal empty L<PPI::Statement> exists below the | ||||
466 | current Element somewhere. | ||||
467 | |||||
468 | =cut | ||||
469 | |||||
470 | sub 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 | |||||
483 | As a support method for higher-order algorithms that deal specifically with | ||||
484 | tokens and actual Perl content, the C<next_token> method finds the | ||||
485 | L<PPI::Token> object that is immediately after the current Element, even if | ||||
486 | it is not within the same parent L<PPI::Node> as the one for which the | ||||
487 | method is being called. | ||||
488 | |||||
489 | Note that this is B<not> defined as a L<PPI::Token>-specific method, | ||||
490 | because it can be useful to find the next token that is after, say, a | ||||
491 | L<PPI::Statement>, although obviously it would be useless to want the | ||||
492 | next token after a L<PPI::Document>. | ||||
493 | |||||
494 | Returns a L<PPI::Token> object, or false if there are no more tokens after | ||||
495 | the Element. | ||||
496 | |||||
497 | =cut | ||||
498 | |||||
499 | sub 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 | |||||
520 | As a support method for higher-order algorithms that deal specifically with | ||||
521 | tokens and actual Perl content, the C<previous_token> method finds the | ||||
522 | L<PPI::Token> object that is immediately before the current Element, even | ||||
523 | if it is not within the same parent L<PPI::Node> as this one. | ||||
524 | |||||
525 | Note that this is not defined as a L<PPI::Token>-only method, because it can | ||||
526 | be useful to find the token is before, say, a L<PPI::Statement>, although | ||||
527 | obviously it would be useless to want the next token before a | ||||
528 | L<PPI::Document>. | ||||
529 | |||||
530 | Returns a L<PPI::Token> object, or false if there are no more tokens before | ||||
531 | the C<Element>. | ||||
532 | |||||
533 | =cut | ||||
534 | |||||
535 | sub 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 | |||||
563 | As per the L<Clone> module, the C<clone> method makes a perfect copy of | ||||
564 | an Element object. In the generic case, the implementation is done using | ||||
565 | the L<Clone> module's mechanism itself. In higher-order cases, such as for | ||||
566 | Nodes, there is more work involved to keep the parent-child links intact. | ||||
567 | |||||
568 | =cut | ||||
569 | |||||
570 | sub clone { | ||||
571 | Clone::clone(shift); | ||||
572 | } | ||||
573 | |||||
574 | =pod | ||||
575 | |||||
576 | =head2 insert_before @Elements | ||||
577 | |||||
578 | The C<insert_before> method allows you to insert lexical perl content, in | ||||
579 | the form of C<PPI::Element> objects, before the calling C<Element>. You | ||||
580 | need to be very careful when modifying perl code, as it's easy to break | ||||
581 | things. | ||||
582 | |||||
583 | In its initial incarnation, this method allows you to insert a single | ||||
584 | Element, and will perform some basic checking to prevent you inserting | ||||
585 | something that would be structurally wrong (in PDOM terms). | ||||
586 | |||||
587 | In future, this method may be enhanced to allow the insertion of multiple | ||||
588 | Elements, inline-parsed code strings or L<PPI::Document::Fragment> objects. | ||||
589 | |||||
590 | Returns true if the Element was inserted, false if it can not be inserted, | ||||
591 | or C<undef> if you do not provide a L<PPI::Element> object as a parameter. | ||||
592 | |||||
593 | =begin testing __insert_before 6 | ||||
594 | |||||
595 | my $Document = PPI::Document->new( \"print 'Hello World';" ); | ||||
596 | isa_ok( $Document, 'PPI::Document' ); | ||||
597 | my $semi = $Document->find_first('Token::Structure'); | ||||
598 | isa_ok( $semi, 'PPI::Token::Structure' ); | ||||
599 | is( $semi->content, ';', 'Got expected token' ); | ||||
600 | my $foo = PPI::Token::Word->new('foo'); | ||||
601 | isa_ok( $foo, 'PPI::Token::Word' ); | ||||
602 | is( $foo->content, 'foo', 'Created Word token' ); | ||||
603 | $semi->__insert_before( $foo ); | ||||
604 | is( $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 | |||||
611 | my $Document = PPI::Document->new( \"print 'Hello World';" ); | ||||
612 | isa_ok( $Document, 'PPI::Document' ); | ||||
613 | my $semi = $Document->find_first('Token::Structure'); | ||||
614 | isa_ok( $semi, 'PPI::Token::Structure' ); | ||||
615 | is( $semi->content, ';', 'Got expected token' ); | ||||
616 | my $foo = PPI::Token::Word->new('foo'); | ||||
617 | isa_ok( $foo, 'PPI::Token::Word' ); | ||||
618 | is( $foo->content, 'foo', 'Created Word token' ); | ||||
619 | $semi->insert_before( $foo ); | ||||
620 | is( $Document->serialize, "print 'Hello World'foo;", | ||||
621 | 'insert_before actually inserts' ); | ||||
622 | |||||
623 | =end testing | ||||
624 | |||||
625 | =cut | ||||
626 | |||||
627 | sub __insert_before { | ||||
628 | my $self = shift; | ||||
629 | $self->parent->__insert_before_child( $self, @_ ); | ||||
630 | } | ||||
631 | |||||
632 | =pod | ||||
633 | |||||
634 | =head2 insert_after @Elements | ||||
635 | |||||
636 | The C<insert_after> method allows you to insert lexical perl content, in | ||||
637 | the form of C<PPI::Element> objects, after the calling C<Element>. You need | ||||
638 | to be very careful when modifying perl code, as it's easy to break things. | ||||
639 | |||||
640 | In its initial incarnation, this method allows you to insert a single | ||||
641 | Element, and will perform some basic checking to prevent you inserting | ||||
642 | something that would be structurally wrong (in PDOM terms). | ||||
643 | |||||
644 | In future, this method may be enhanced to allow the insertion of multiple | ||||
645 | Elements, inline-parsed code strings or L<PPI::Document::Fragment> objects. | ||||
646 | |||||
647 | Returns true if the Element was inserted, false if it can not be inserted, | ||||
648 | or C<undef> if you do not provide a L<PPI::Element> object as a parameter. | ||||
649 | |||||
650 | =begin testing __insert_after 6 | ||||
651 | |||||
652 | my $Document = PPI::Document->new( \"print 'Hello World';" ); | ||||
653 | isa_ok( $Document, 'PPI::Document' ); | ||||
654 | my $string = $Document->find_first('Token::Quote'); | ||||
655 | isa_ok( $string, 'PPI::Token::Quote' ); | ||||
656 | is( $string->content, "'Hello World'", 'Got expected token' ); | ||||
657 | my $foo = PPI::Token::Word->new('foo'); | ||||
658 | isa_ok( $foo, 'PPI::Token::Word' ); | ||||
659 | is( $foo->content, 'foo', 'Created Word token' ); | ||||
660 | $string->__insert_after( $foo ); | ||||
661 | is( $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 | |||||
668 | my $Document = PPI::Document->new( \"print 'Hello World';" ); | ||||
669 | isa_ok( $Document, 'PPI::Document' ); | ||||
670 | my $string = $Document->find_first('Token::Quote'); | ||||
671 | isa_ok( $string, 'PPI::Token::Quote' ); | ||||
672 | is( $string->content, "'Hello World'", 'Got expected token' ); | ||||
673 | my $foo = PPI::Token::Word->new('foo'); | ||||
674 | isa_ok( $foo, 'PPI::Token::Word' ); | ||||
675 | is( $foo->content, 'foo', 'Created Word token' ); | ||||
676 | $string->insert_after( $foo ); | ||||
677 | is( $Document->serialize, "print 'Hello World'foo;", | ||||
678 | 'insert_after actually inserts' ); | ||||
679 | |||||
680 | =end testing | ||||
681 | |||||
682 | =cut | ||||
683 | |||||
684 | sub __insert_after { | ||||
685 | my $self = shift; | ||||
686 | $self->parent->__insert_after_child( $self, @_ ); | ||||
687 | } | ||||
688 | |||||
689 | =pod | ||||
690 | |||||
691 | =head2 remove | ||||
692 | |||||
693 | For a given C<PPI::Element>, the C<remove> method will remove it from its | ||||
694 | parent B<intact>, along with all of its children. | ||||
695 | |||||
696 | Returns the C<Element> itself as a convenience, or C<undef> if an error | ||||
697 | occurs while trying to remove the C<Element>. | ||||
698 | |||||
699 | =cut | ||||
700 | |||||
701 | sub 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 | |||||
711 | For a given C<PPI::Element>, the C<delete> method will remove it from its | ||||
712 | parent, immediately deleting the C<Element> and all of its children (if it | ||||
713 | has any). | ||||
714 | |||||
715 | Returns true if the C<Element> was successfully deleted, or C<undef> if | ||||
716 | an error occurs while trying to remove the C<Element>. | ||||
717 | |||||
718 | =cut | ||||
719 | |||||
720 | sub delete { | ||||
721 | $_[0]->remove or return undef; | ||||
722 | $_[0]->DESTROY; | ||||
723 | 1; | ||||
724 | } | ||||
725 | |||||
726 | =pod | ||||
727 | |||||
728 | =head2 replace $Element | ||||
729 | |||||
730 | Although some higher level class support more exotic forms of replace, | ||||
731 | at the basic level the C<replace> method takes a single C<Element> as | ||||
732 | an argument and replaces the current C<Element> with it. | ||||
733 | |||||
734 | To prevent accidental damage to code, in this initial implementation the | ||||
735 | replacement element B<must> be of the same class (or a subclass) as the | ||||
736 | one being replaced. | ||||
737 | |||||
738 | =cut | ||||
739 | |||||
740 | sub 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 | |||||
750 | If the Element exists within a L<PPI::Document> that has | ||||
751 | indexed the Element locations using C<PPI::Document::index_locations>, the | ||||
752 | C<location> method will return the location of the first character of the | ||||
753 | Element within the Document. | ||||
754 | |||||
755 | Returns 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 | ||||
757 | a human format, with the first character of the file located at C<[ 1, 1, 1, ?, | ||||
758 | 'something' ]>. | ||||
759 | |||||
760 | The second and third numbers are similar, except that the second is the | ||||
761 | literal horizontal character, and the third is the visual column, taking | ||||
762 | into account tabbing (see L<PPI::Document/"tab_width [ $width ]">). | ||||
763 | |||||
764 | The fourth number is the line number, taking into account any C<#line> | ||||
765 | directives. The fifth element is the name of the file that the element was | ||||
766 | found in, if available, taking into account any C<#line> directives. | ||||
767 | |||||
768 | Returns C<undef> on error, or if the L<PPI::Document> object has not been | ||||
769 | indexed. | ||||
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 | ||||
774 | 9763 | 1.24ms | my $self = shift; | ||
775 | |||||
776 | 9763 | 7.72ms | 9763 | 14.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 | ||||
779 | 9763 | 35.9ms | return [ @{$self->{_location}} ]; | ||
780 | } | ||||
781 | |||||
782 | =pod | ||||
783 | |||||
784 | =head2 line_number | ||||
785 | |||||
786 | If the Element exists within a L<PPI::Document> that has indexed the Element | ||||
787 | locations using C<PPI::Document::index_locations>, the C<line_number> method | ||||
788 | will return the line number of the first character of the Element within the | ||||
789 | Document. | ||||
790 | |||||
791 | Returns C<undef> on error, or if the L<PPI::Document> object has not been | ||||
792 | indexed. | ||||
793 | |||||
794 | =begin testing line_number 3 | ||||
795 | |||||
796 | my $document = PPI::Document->new(\<<'END_PERL'); | ||||
797 | |||||
798 | |||||
799 | foo | ||||
800 | END_PERL | ||||
801 | |||||
802 | isa_ok( $document, 'PPI::Document' ); | ||||
803 | my $words = $document->find('PPI::Token::Word'); | ||||
804 | is( scalar @{$words}, 1, 'Found expected word token.' ); | ||||
805 | is( $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 | ||||
812 | 6 | 1µs | my $self = shift; | ||
813 | |||||
814 | 6 | 8µs | 6 | 55µ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 |
815 | 6 | 14µs | return $location->[0]; | ||
816 | } | ||||
817 | |||||
818 | =pod | ||||
819 | |||||
820 | =head2 column_number | ||||
821 | |||||
822 | If the Element exists within a L<PPI::Document> that has indexed the Element | ||||
823 | locations using C<PPI::Document::index_locations>, the C<column_number> method | ||||
824 | will return the column number of the first character of the Element within the | ||||
825 | Document. | ||||
826 | |||||
827 | Returns C<undef> on error, or if the L<PPI::Document> object has not been | ||||
828 | indexed. | ||||
829 | |||||
830 | =begin testing column_number 3 | ||||
831 | |||||
832 | my $document = PPI::Document->new(\<<'END_PERL'); | ||||
833 | |||||
834 | |||||
835 | foo | ||||
836 | END_PERL | ||||
837 | |||||
838 | isa_ok( $document, 'PPI::Document' ); | ||||
839 | my $words = $document->find('PPI::Token::Word'); | ||||
840 | is( scalar @{$words}, 1, 'Found expected word token.' ); | ||||
841 | is( $words->[0]->column_number, 4, 'Got correct column number.' ); | ||||
842 | |||||
843 | =end testing | ||||
844 | |||||
845 | =cut | ||||
846 | |||||
847 | sub 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 | |||||
858 | If the Element exists within a L<PPI::Document> that has indexed the Element | ||||
859 | locations using C<PPI::Document::index_locations>, the C<visual_column_number> | ||||
860 | method will return the visual column number of the first character of the | ||||
861 | Element within the Document, according to the value of | ||||
862 | L<PPI::Document/"tab_width [ $width ]">. | ||||
863 | |||||
864 | Returns C<undef> on error, or if the L<PPI::Document> object has not been | ||||
865 | indexed. | ||||
866 | |||||
867 | =begin testing visual_column_number 3 | ||||
868 | |||||
869 | my $document = PPI::Document->new(\<<"END_PERL"); | ||||
870 | |||||
871 | |||||
872 | \t foo | ||||
873 | END_PERL | ||||
874 | |||||
875 | isa_ok( $document, 'PPI::Document' ); | ||||
876 | my $tab_width = 5; | ||||
877 | $document->tab_width($tab_width); # don't use a "usual" value. | ||||
878 | my $words = $document->find('PPI::Token::Word'); | ||||
879 | is( scalar @{$words}, 1, 'Found expected word token.' ); | ||||
880 | is( | ||||
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 | |||||
890 | sub 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 | |||||
901 | If the Element exists within a L<PPI::Document> that has indexed the Element | ||||
902 | locations using C<PPI::Document::index_locations>, the C<logical_line_number> | ||||
903 | method will return the line number of the first character of the Element within | ||||
904 | the Document, taking into account any C<#line> directives. | ||||
905 | |||||
906 | Returns C<undef> on error, or if the L<PPI::Document> object has not been | ||||
907 | indexed. | ||||
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. | ||||
913 | my $document = PPI::Document->new(\<<"END_PERL"); | ||||
914 | |||||
915 | |||||
916 | \#line 1 test-file | ||||
917 | foo | ||||
918 | END_PERL | ||||
919 | |||||
920 | isa_ok( $document, 'PPI::Document' ); | ||||
921 | my $words = $document->find('PPI::Token::Word'); | ||||
922 | is( scalar @{$words}, 1, 'Found expected word token.' ); | ||||
923 | is( $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 | ||||
930 | 198 | 46µs | my $self = shift; | ||
931 | |||||
932 | 198 | 656µs | 198 | 1.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 | |||||
939 | If the Element exists within a L<PPI::Document> that has indexed the Element | ||||
940 | locations using C<PPI::Document::index_locations>, the C<logical_filename> | ||||
941 | method will return the logical file name containing the first character of the | ||||
942 | Element within the Document, taking into account any C<#line> directives. | ||||
943 | |||||
944 | Returns C<undef> on error, or if the L<PPI::Document> object has not been | ||||
945 | indexed. | ||||
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. | ||||
951 | my $document = PPI::Document->new(\<<"END_PERL"); | ||||
952 | |||||
953 | |||||
954 | \#line 1 test-file | ||||
955 | foo | ||||
956 | END_PERL | ||||
957 | |||||
958 | isa_ok( $document, 'PPI::Document' ); | ||||
959 | my $words = $document->find('PPI::Token::Word'); | ||||
960 | is( scalar @{$words}, 1, 'Found expected word token.' ); | ||||
961 | is( | ||||
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 | ||||
972 | 144 | 63µs | my $self = shift; | ||
973 | |||||
974 | 144 | 345µs | 144 | 2.64ms | my $location = $self->location() or return undef; # spent 2.64ms making 144 calls to PPI::Node::location, avg 18µs/call |
975 | 144 | 518µ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 | ||||
979 | 9763 | 1.08ms | my $self = shift; | ||
980 | |||||
981 | 9763 | 4.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 | |||||
1000 | 9763 | 21.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. | ||||
1007 | sub _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 | |||||
1045 | sub _xml_name { | ||||
1046 | my $class = ref $_[0] || $_[0]; | ||||
1047 | my $name = lc join( '_', split /::/, $class ); | ||||
1048 | substr($name, 4); | ||||
1049 | } | ||||
1050 | |||||
1051 | sub _xml_attr { | ||||
1052 | return {}; | ||||
1053 | } | ||||
1054 | |||||
1055 | sub _xml_content { | ||||
1056 | defined $_[0]->{content} ? $_[0]->{content} : ''; | ||||
1057 | } | ||||
1058 | |||||
- - | |||||
1063 | ##################################################################### | ||||
1064 | # Internals | ||||
1065 | |||||
1066 | # Set the error string | ||||
1067 | sub _error { | ||||
1068 | $errstr = $_[1]; | ||||
1069 | undef; | ||||
1070 | } | ||||
1071 | |||||
1072 | # Clear the error string | ||||
1073 | sub _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+ | ||||
1083 | 94372 | 500ms | 94372 | 51.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 # spent 51.4ms making 94372 calls to Scalar::Util::refaddr, avg 544ns/call |
1084 | |||||
1085 | # Operator overloads | ||||
1086 | sub __equals { ref $_[1] and refaddr($_[0]) == refaddr($_[1]) } | ||||
1087 | sub __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 | ||||
1089 | 105472 | 1.07s | 421888 | 687ms | 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 |
1090 | 105472 | 287ms | 105560 | 57.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 |
1091 | 105472 | 225ms | $self eq $other; | ||
1092 | } | ||||
1093 | 104217 | 274ms | 104217 | 1.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 # spent 1.74s making 104217 calls to PPI::Element::__eq, avg 17µs/call |
1094 | |||||
1095 | 1 | 2µs | 1; | ||
1096 | |||||
1097 | =pod | ||||
1098 | |||||
1099 | =head1 TO DO | ||||
1100 | |||||
1101 | It would be nice if C<location> could be used in an ad-hoc manner. That is, | ||||
1102 | if called on an Element within a Document that has not been indexed, it will | ||||
1103 | do a one-off calculation to find the location. It might be very painful if | ||||
1104 | someone started using it a lot, without remembering to index the document, | ||||
1105 | but it would be handy for things that are only likely to use it once, such | ||||
1106 | as error handlers. | ||||
1107 | |||||
1108 | =head1 SUPPORT | ||||
1109 | |||||
1110 | See the L<support section|PPI/SUPPORT> in the main module. | ||||
1111 | |||||
1112 | =head1 AUTHOR | ||||
1113 | |||||
1114 | Adam Kennedy E<lt>adamk@cpan.orgE<gt> | ||||
1115 | |||||
1116 | =head1 COPYRIGHT | ||||
1117 | |||||
1118 | Copyright 2001 - 2011 Adam Kennedy. | ||||
1119 | |||||
1120 | This program is free software; you can redistribute | ||||
1121 | it and/or modify it under the same terms as Perl itself. | ||||
1122 | |||||
1123 | The full text of the license can be found in the | ||||
1124 | LICENSE file included with this module. | ||||
1125 | |||||
1126 | =cut |