← 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/Token/_QuoteEngine.pm
StatementsExecuted 54733 statements in 137ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
27432239.2ms229msPPI::Token::_QuoteEngine::::__TOKENIZER__on_charPPI::Token::_QuoteEngine::__TOKENIZER__on_char
9762129.5ms59.6msPPI::Token::_QuoteEngine::::_scan_for_brace_characterPPI::Token::_QuoteEngine::_scan_for_brace_character
18003228.6ms49.3msPPI::Token::_QuoteEngine::::_scan_for_unescaped_characterPPI::Token::_QuoteEngine::_scan_for_unescaped_character
69335126.7ms26.7msPPI::Token::_QuoteEngine::::CORE:regcompPPI::Token::_QuoteEngine::CORE:regcomp (opcode)
51334116.5ms16.5msPPI::Token::_QuoteEngine::::CORE:matchPPI::Token::_QuoteEngine::CORE:match (opcode)
2776214.82ms4.82msPPI::Token::_QuoteEngine::::CORE:qrPPI::Token::_QuoteEngine::CORE:qr (opcode)
11111µs23µsPPI::Token::_QuoteEngine::::BEGIN@33PPI::Token::_QuoteEngine::BEGIN@33
1116µs24µsPPI::Token::_QuoteEngine::::BEGIN@36PPI::Token::_QuoteEngine::BEGIN@36
1113µs3µsPPI::Token::_QuoteEngine::::BEGIN@37PPI::Token::_QuoteEngine::BEGIN@37
1113µs3µsPPI::Token::_QuoteEngine::::BEGIN@34PPI::Token::_QuoteEngine::BEGIN@34
0000s0sPPI::Token::_QuoteEngine::::_scan_for_characterPPI::Token::_QuoteEngine::_scan_for_character
0000s0sPPI::Token::_QuoteEngine::::_scan_quote_like_operator_gapPPI::Token::_QuoteEngine::_scan_quote_like_operator_gap
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package PPI::Token::_QuoteEngine;
2
3=pod
4
5=head1 NAME
6
7PPI::Token::_QuoteEngine - The PPI Quote Engine
8
9=head1 DESCRIPTION
10
11The C<PPI::Token::_QuoteEngine> package is designed hold functionality
12for processing quotes and quote like operators, including regexes.
13These have special requirements in parsing.
14
15The C<PPI::Token::_QuoteEngine> package itself provides various parsing
16methods, which the L<PPI::Token::Quote>, L<PPI::Token::QuoteLike> and
17L<PPI::Token::Regexp> can inherit from. In this sense, it serves
18as a base class.
19
20=head2 Using this class
21
22I<(Refers only to internal uses. This class does not provide a
23public interface)>
24
25To use these, you should initialize them as normal C<'$Class-E<gt>new'>,
26and then call the 'fill' method, which will cause the specialised
27parser to scan forwards and parse the quote to its end point.
28
29If -E<gt>fill returns true, finalise the token.
30
31=cut
32
33218µs234µs
# spent 23µs (11+12) within PPI::Token::_QuoteEngine::BEGIN@33 which was called: # once (11µs+12µs) by PPI::Token::_QuoteEngine::Simple::BEGIN@6 at line 33
use strict;
# spent 23µs making 1 call to PPI::Token::_QuoteEngine::BEGIN@33 # spent 12µs making 1 call to strict::import
34222µs13µs
# spent 3µs within PPI::Token::_QuoteEngine::BEGIN@34 which was called: # once (3µs+0s) by PPI::Token::_QuoteEngine::Simple::BEGIN@6 at line 34
use Carp ();
# spent 3µs making 1 call to PPI::Token::_QuoteEngine::BEGIN@34
35
36223µs241µs
# spent 24µs (6+18) within PPI::Token::_QuoteEngine::BEGIN@36 which was called: # once (6µs+18µs) by PPI::Token::_QuoteEngine::Simple::BEGIN@6 at line 36
use vars qw{$VERSION};
# spent 24µs making 1 call to PPI::Token::_QuoteEngine::BEGIN@36 # spent 18µs making 1 call to vars::import
37
# spent 3µs within PPI::Token::_QuoteEngine::BEGIN@37 which was called: # once (3µs+0s) by PPI::Token::_QuoteEngine::Simple::BEGIN@6 at line 39
BEGIN {
3814µs $VERSION = '1.215';
391562µs13µs}
# spent 3µs making 1 call to PPI::Token::_QuoteEngine::BEGIN@37
40
- -
45# Hook for the __TOKENIZER__on_char token call
46
# spent 229ms (39.2+190) within PPI::Token::_QuoteEngine::__TOKENIZER__on_char which was called 2743 times, avg 83µs/call: # 1688 times (23.7ms+67.2ms) by PPI::Tokenizer::_process_next_char at line 554 of PPI/Tokenizer.pm, avg 54µs/call # 1055 times (15.5ms+122ms) by PPI::Token::Word::__TOKENIZER__commit at line 498 of PPI/Token/Word.pm, avg 131µs/call
sub __TOKENIZER__on_char {
472743811µs my $class = shift;
4827439.08ms27431.53ms my $t = $_[0]->{token} ? shift : return undef;
# spent 1.53ms making 2743 calls to PPI::Util::TRUE, avg 558ns/call
49
50 # Call the fill method to process the quote
5127434.59ms2743180ms my $rv = $t->{token}->_fill( $t );
# spent 119ms making 1061 calls to PPI::Token::_QuoteEngine::Full::_fill, avg 112µs/call # spent 61.4ms making 1682 calls to PPI::Token::_QuoteEngine::Simple::_fill, avg 37µs/call
522743416µs return undef unless defined $rv;
53
54 ## Doesn't support "end of file" indicator
55
56 # Finalize the token and return 0 to tell the tokenizer
57 # to go to the next character.
5827433.86ms27437.54ms $t->_finalize_token;
# spent 7.54ms making 2743 calls to PPI::Tokenizer::_finalize_token, avg 3µs/call
59
60274310.9ms 0;
61}
62
- -
67#####################################################################
68# Optimised character processors, used for quotes
69# and quote like stuff, and accessible to the child classes
70
71# An outright scan, raw and fast.
72# Searches for a particular character, loading in new
73# lines as needed.
74# When called, we start at the current position.
75# When leaving, the position should be set to the position
76# of the character, NOT the one after it.
77sub _scan_for_character {
78 my $class = shift;
79 my $t = shift;
80 my $char = (length $_[0] == 1) ? quotemeta shift : return undef;
81
82 # Create the search regex
83 my $search = qr/^(.*?$char)/;
84
85 my $string = '';
86 while ( exists $t->{line} ) {
87 # Get the search area for the current line
88 my $search_area
89 = $t->{line_cursor}
90 ? substr( $t->{line}, $t->{line_cursor} )
91 : $t->{line};
92
93 # Can we find a match on this line
94 if ( $search_area =~ /$search/ ) {
95 # Found the character on this line
96 $t->{line_cursor} += length($1) - 1;
97 return $string . $1;
98 }
99
100 # Load in the next line
101 $string .= $search_area;
102 return undef unless defined $t->_fill_line;
103 $t->{line_cursor} = 0;
104 }
105
106 # Returning the string as a reference indicates EOF
107 \$string;
108}
109
110# Scan for a character, but not if it is escaped
111
# spent 49.3ms (28.6+20.7) within PPI::Token::_QuoteEngine::_scan_for_unescaped_character which was called 1800 times, avg 27µs/call: # 1682 times (26.6ms+18.3ms) by PPI::Token::_QuoteEngine::Simple::_fill at line 34 of PPI/Token/_QuoteEngine/Simple.pm, avg 27µs/call # 105 times (1.79ms+2.32ms) by PPI::Token::_QuoteEngine::Full::_fill_normal at line 233 of PPI/Token/_QuoteEngine/Full.pm, avg 39µs/call # 13 times (174µs+76µs) by PPI::Token::_QuoteEngine::Full::_fill_normal at line 271 of PPI/Token/_QuoteEngine/Full.pm, avg 19µs/call
sub _scan_for_unescaped_character {
1121800501µs my $class = shift;
1131800210µs my $t = shift;
11418001.32ms my $char = (length $_[0] == 1) ? quotemeta shift : return undef;
115
116 # Create the search regex.
117 # Same as above but with a negative look-behind assertion.
118180017.1ms36009.45ms my $search = qr/^(.*?(?<!\\)(?:\\\\)*$char)/;
# spent 6.33ms making 1800 calls to PPI::Token::_QuoteEngine::CORE:regcomp, avg 4µs/call # spent 3.12ms making 1800 calls to PPI::Token::_QuoteEngine::CORE:qr, avg 2µs/call
119
1201800380µs my $string = '';
1211800896µs while ( exists $t->{line} ) {
122 # Get the search area for the current line
12318051.55ms my $search_area
124 = $t->{line_cursor}
125 ? substr( $t->{line}, $t->{line_cursor} )
126 : $t->{line};
127
128 # Can we find a match on this line
129180517.8ms361011.2ms if ( $search_area =~ /$search/ ) {
# spent 8.17ms making 1805 calls to PPI::Token::_QuoteEngine::CORE:match, avg 5µs/call # spent 3.07ms making 1805 calls to PPI::Token::_QuoteEngine::CORE:regcomp, avg 2µs/call
130 # Found the character on this line
13118002.19ms $t->{line_cursor} += length($1) - 1;
13218008.21ms return $string . $1;
133 }
134
135 # Load in the next line
13654µs $string .= $search_area;
13759µs554µs my $rv = $t->_fill_line('inscan');
# spent 54µs making 5 calls to PPI::Tokenizer::_fill_line, avg 11µs/call
13855µs if ( $rv ) {
139 # Push to first character
140 $t->{line_cursor} = 0;
141 } elsif ( defined $rv ) {
142 # We hit the End of File
143 return \$string;
144 } else {
145 # Unexpected error
146 return undef;
147 }
148 }
149
150 # We shouldn't be able to get here
151 return undef;
152}
153
154# Scan for a close braced, and take into account both escaping,
155# and open close bracket pairs in the string. When complete, the
156# method leaves the line cursor on the LAST character found.
157
# spent 59.6ms (29.5+30.1) within PPI::Token::_QuoteEngine::_scan_for_brace_character which was called 976 times, avg 61µs/call: # 956 times (29.1ms+30.0ms) by PPI::Token::_QuoteEngine::Full::_fill_braced at line 296 of PPI/Token/_QuoteEngine/Full.pm, avg 62µs/call # 20 times (392µs+150µs) by PPI::Token::_QuoteEngine::Full::_fill_braced at line 345 of PPI/Token/_QuoteEngine/Full.pm, avg 27µs/call
sub _scan_for_brace_character {
158976198µs my $class = shift;
159976137µs my $t = shift;
1609766.33ms9761.13ms my $close_brace = $_[0] =~ /^(?:\>|\)|\}|\])$/ ? shift : Carp::confess(''); # return undef;
# spent 1.13ms making 976 calls to PPI::Token::_QuoteEngine::CORE:match, avg 1µs/call
161976203µs my $open_brace = $close_brace;
162976719µs $open_brace =~ tr/\>\)\}\]/\<\(\{\[/;
163
164 # Create the search string
165976343µs $close_brace = quotemeta $close_brace;
166976165µs $open_brace = quotemeta $open_brace;
16797617.5ms195212.9ms my $search = qr/^(.*?(?<!\\)(?:\\\\)*(?:$open_brace|$close_brace))/;
# spent 11.2ms making 976 calls to PPI::Token::_QuoteEngine::CORE:regcomp, avg 11µs/call # spent 1.71ms making 976 calls to PPI::Token::_QuoteEngine::CORE:qr, avg 2µs/call
168
169 # Loop as long as we can get new lines
170976233µs my $string = '';
171976137µs my $depth = 1;
172976659µs while ( exists $t->{line} ) {
173 # Get the search area
1741362942µs my $search_area
175 = $t->{line_cursor}
176 ? substr( $t->{line}, $t->{line_cursor} )
177 : $t->{line};
178
179 # Look for a match
180136214.1ms27249.52ms unless ( $search_area =~ /$search/ ) {
# spent 6.57ms making 1362 calls to PPI::Token::_QuoteEngine::CORE:match, avg 5µs/call # spent 2.96ms making 1362 calls to PPI::Token::_QuoteEngine::CORE:regcomp, avg 2µs/call
181 # Load in the next line
18237260µs $string .= $search_area;
183372509µs3722.77ms my $rv = $t->_fill_line('inscan');
# spent 2.77ms making 372 calls to PPI::Tokenizer::_fill_line, avg 7µs/call
18437264µs if ( $rv ) {
185 # Push to first character
18637271µs $t->{line_cursor} = 0;
187372126µs next;
188 }
189 if ( defined $rv ) {
190 # We hit the End of File
191 return \$string;
192 }
193
194 # Unexpected error
195 return undef;
196 }
197
198 # Add to the string
199990831µs $string .= $1;
200990718µs $t->{line_cursor} += length $1;
201
202 # Alter the depth and continue if we arn't at the end
2039907.39ms19803.79ms $depth += ($1 =~ /$open_brace$/) ? 1 : -1 and next;
# spent 3.14ms making 990 calls to PPI::Token::_QuoteEngine::CORE:regcomp, avg 3µs/call # spent 654µs making 990 calls to PPI::Token::_QuoteEngine::CORE:match, avg 660ns/call
204
205 # Rewind the cursor by one character ( cludgy hack )
206976407µs $t->{line_cursor} -= 1;
2079764.37ms return $string;
208 }
209
210 # Returning the string as a reference indicates EOF
211 \$string;
212}
213
214# Find all spaces and comments, up to, but not including
215# the first non-whitespace character.
216#
217# Although it doesn't return it, it leaves the cursor
218# on the character following the gap
219sub _scan_quote_like_operator_gap {
220 my $t = $_[1];
221
222 my $string = '';
223 while ( exists $t->{line} ) {
224 # Get the search area for the current line
225 my $search_area
226 = $t->{line_cursor}
227 ? substr( $t->{line}, $t->{line_cursor} )
228 : $t->{line};
229
230 # Since this regex can match zero characters, it should always match
231 $search_area =~ /^(\s*(?:\#.*)?)/s or return undef;
232
233 # Add the chars found to the string
234 $string .= $1;
235
236 # Did we match the entire line?
237 unless ( length $1 == length $search_area ) {
238 # Partial line match, which means we are at
239 # the end of the gap. Fix the cursor and return
240 # the string.
241 $t->{line_cursor} += length $1;
242 return $string;
243 }
244
245 # Load in the next line.
246 # If we reach the EOF, $t->{line} gets deleted,
247 # which is caught by the while.
248 my $rv = $t->_fill_line('inscan');
249 if ( $rv ) {
250 # Set the cursor to the first character
251 $t->{line_cursor} = 0;
252 } elsif ( defined $rv ) {
253 # Returning the string as a reference indicates EOF
254 return \$string;
255 } else {
256 return undef;
257 }
258 }
259
260 # Shouldn't be able to get here
261 return undef;
262}
263
26412µs1;
265
266=pod
267
268=head1 SUPPORT
269
270See the L<support section|PPI/SUPPORT> in the main module.
271
272=head1 AUTHOR
273
274Adam Kennedy E<lt>adamk@cpan.orgE<gt>
275
276=head1 COPYRIGHT
277
278Copyright 2001 - 2011 Adam Kennedy.
279
280This program is free software; you can redistribute
281it and/or modify it under the same terms as Perl itself.
282
283The full text of the license can be found in the
284LICENSE file included with this module.
285
286=cut
 
# spent 16.5ms within PPI::Token::_QuoteEngine::CORE:match which was called 5133 times, avg 3µs/call: # 1805 times (8.17ms+0s) by PPI::Token::_QuoteEngine::_scan_for_unescaped_character at line 129, avg 5µs/call # 1362 times (6.57ms+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 180, avg 5µs/call # 990 times (654µs+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 203, avg 660ns/call # 976 times (1.13ms+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 160, avg 1µs/call
sub PPI::Token::_QuoteEngine::CORE:match; # opcode
# spent 4.82ms within PPI::Token::_QuoteEngine::CORE:qr which was called 2776 times, avg 2µs/call: # 1800 times (3.12ms+0s) by PPI::Token::_QuoteEngine::_scan_for_unescaped_character at line 118, avg 2µs/call # 976 times (1.71ms+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 167, avg 2µs/call
sub PPI::Token::_QuoteEngine::CORE:qr; # opcode
# spent 26.7ms within PPI::Token::_QuoteEngine::CORE:regcomp which was called 6933 times, avg 4µs/call: # 1805 times (3.07ms+0s) by PPI::Token::_QuoteEngine::_scan_for_unescaped_character at line 129, avg 2µs/call # 1800 times (6.33ms+0s) by PPI::Token::_QuoteEngine::_scan_for_unescaped_character at line 118, avg 4µs/call # 1362 times (2.96ms+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 180, avg 2µs/call # 990 times (3.14ms+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 203, avg 3µs/call # 976 times (11.2ms+0s) by PPI::Token::_QuoteEngine::_scan_for_brace_character at line 167, avg 11µs/call
sub PPI::Token::_QuoteEngine::CORE:regcomp; # opcode