← 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:12 2016

Filename/Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Lexer.pm
StatementsExecuted 1375127 statements in 3.35s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
10537411.31s11.1sPPI::Lexer::::_lex_statementPPI::Lexer::_lex_statement (recurses: max depth 7, inclusive time 11.9s)
5056591676ms944msPPI::Lexer::::_add_elementPPI::Lexer::_add_element
578911655ms9.04sPPI::Lexer::::_lex_structurePPI::Lexer::_lex_structure (recurses: max depth 6, inclusive time 7.76s)
111133121459ms7.26sPPI::Lexer::::_get_tokenPPI::Lexer::_get_token
1045021284ms476msPPI::Lexer::::_statementPPI::Lexer::_statement
2217251202ms231msPPI::Lexer::::_add_delayedPPI::Lexer::_add_delayed
14411146ms12.7sPPI::Lexer::::_lex_documentPPI::Lexer::_lex_document
481711144ms444msPPI::Lexer::::_continuesPPI::Lexer::_continues
31571195.9ms168msPPI::Lexer::::_roundPPI::Lexer::_round
22731179.5ms222msPPI::Lexer::::_curlyPPI::Lexer::_curly
788710124.0ms24.0msPPI::Lexer::::_rollbackPPI::Lexer::_rollback
1441113.1ms337msPPI::Lexer::::_lex_endPPI::Lexer::_lex_end
71818110.9ms10.9msPPI::Lexer::::CORE:matchPPI::Lexer::CORE:match (opcode)
144119.07ms13.2sPPI::Lexer::::lex_filePPI::Lexer::lex_file
359116.18ms10.6msPPI::Lexer::::_squarePPI::Lexer::_square
144113.50ms12.7sPPI::Lexer::::lex_tokenizerPPI::Lexer::lex_tokenizer
144111.32ms1.70msPPI::Lexer::::newPPI::Lexer::new
14411373µs373µsPPI::Lexer::::_clearPPI::Lexer::_clear
6831282µs282µsPPI::Lexer::::_bufferPPI::Lexer::_buffer
11115µs15µsPPI::Lexer::::BEGIN@1052PPI::Lexer::BEGIN@1052
11113µs13µsPPI::Lexer::::BEGIN@361PPI::Lexer::BEGIN@361
11112µs25µsPPI::Lexer::::BEGIN@56PPI::Lexer::BEGIN@56
11112µs12µsPPI::Lexer::::BEGIN@97PPI::Lexer::BEGIN@97
11112µs12µsPPI::Lexer::::BEGIN@64PPI::Lexer::BEGIN@64
1118µs38µsPPI::Lexer::::BEGIN@1051PPI::Lexer::BEGIN@1051
1117µs26µsPPI::Lexer::::BEGIN@360PPI::Lexer::BEGIN@360
1117µs42µsPPI::Lexer::::BEGIN@100PPI::Lexer::BEGIN@100
1117µs32µsPPI::Lexer::::BEGIN@58PPI::Lexer::BEGIN@58
1117µs23µsPPI::Lexer::::BEGIN@96PPI::Lexer::BEGIN@96
1116µs76µsPPI::Lexer::::BEGIN@63PPI::Lexer::BEGIN@63
1113µs3µsPPI::Lexer::::BEGIN@59PPI::Lexer::BEGIN@59
1113µs3µsPPI::Lexer::::BEGIN@57PPI::Lexer::BEGIN@57
1113µs3µsPPI::Lexer::::BEGIN@61PPI::Lexer::BEGIN@61
1113µs3µsPPI::Lexer::::BEGIN@60PPI::Lexer::BEGIN@60
0000s0sPPI::Lexer::::_errorPPI::Lexer::_error
0000s0sPPI::Lexer::::errstrPPI::Lexer::errstr
0000s0sPPI::Lexer::::lex_sourcePPI::Lexer::lex_source
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package PPI::Lexer;
2
3=pod
4
5=head1 NAME
6
7PPI::Lexer - The PPI Lexer
8
9=head1 SYNOPSIS
10
11 use PPI;
12
13 # Create a new Lexer
14 my $Lexer = PPI::Lexer->new;
15
16 # Build a PPI::Document object from a Token stream
17 my $Tokenizer = PPI::Tokenizer->load('My/Module.pm');
18 my $Document = $Lexer->lex_tokenizer($Tokenizer);
19
20 # Build a PPI::Document object for some raw source
21 my $source = "print 'Hello World!'; kill(Humans->all);";
22 $Document = $Lexer->lex_source($source);
23
24 # Build a PPI::Document object for a particular file name
25 $Document = $Lexer->lex_file('My/Module.pm');
26
27=head1 DESCRIPTION
28
29The is the L<PPI> Lexer. In the larger scheme of things, its job is to take
30token streams, in a variety of forms, and "lex" them into nested structures.
31
32Pretty much everything in this module happens behind the scenes at this
33point. In fact, at the moment you don't really need to instantiate the lexer
34at all, the three main methods will auto-instantiate themselves a
35C<PPI::Lexer> object as needed.
36
37All methods do a one-shot "lex this and give me a L<PPI::Document> object".
38
39In fact, if you are reading this, what you B<probably> want to do is to
40just "load a document", in which case you can do this in a much more
41direct and concise manner with one of the following.
42
43 use PPI;
44
45 $Document = PPI::Document->load( $filename );
46 $Document = PPI::Document->new( $string );
47
48See L<PPI::Document> for more details.
49
50For more unusual tasks, by all means forge onwards.
51
52=head1 METHODS
53
54=cut
55
56220µs238µs
# spent 25µs (12+13) within PPI::Lexer::BEGIN@56 which was called: # once (12µs+13µs) by PPI::BEGIN@29 at line 56
use strict;
# spent 25µs making 1 call to PPI::Lexer::BEGIN@56 # spent 13µs making 1 call to strict::import
57222µs13µs
# spent 3µs within PPI::Lexer::BEGIN@57 which was called: # once (3µs+0s) by PPI::BEGIN@29 at line 57
use Scalar::Util ();
# spent 3µs making 1 call to PPI::Lexer::BEGIN@57
58219µs256µs
# spent 32µs (7+25) within PPI::Lexer::BEGIN@58 which was called: # once (7µs+25µs) by PPI::BEGIN@29 at line 58
use Params::Util qw{_STRING _INSTANCE};
# spent 32µs making 1 call to PPI::Lexer::BEGIN@58 # spent 25µs making 1 call to Exporter::import
59225µs13µs
# spent 3µs within PPI::Lexer::BEGIN@59 which was called: # once (3µs+0s) by PPI::BEGIN@29 at line 59
use List::MoreUtils ();
# spent 3µs making 1 call to PPI::Lexer::BEGIN@59
60215µs13µs
# spent 3µs within PPI::Lexer::BEGIN@60 which was called: # once (3µs+0s) by PPI::BEGIN@29 at line 60
use PPI ();
# spent 3µs making 1 call to PPI::Lexer::BEGIN@60
61218µs13µs
# spent 3µs within PPI::Lexer::BEGIN@61 which was called: # once (3µs+0s) by PPI::BEGIN@29 at line 61
use PPI::Exception ();
# spent 3µs making 1 call to PPI::Lexer::BEGIN@61
62
63279µs2146µs
# spent 76µs (6+70) within PPI::Lexer::BEGIN@63 which was called: # once (6µs+70µs) by PPI::BEGIN@29 at line 63
use vars qw{$VERSION $errstr *_PARENT %ROUND %RESOLVE};
# spent 76µs making 1 call to PPI::Lexer::BEGIN@63 # spent 70µs making 1 call to vars::import
64
# spent 12µs within PPI::Lexer::BEGIN@64 which was called: # once (12µs+0s) by PPI::BEGIN@29 at line 93
BEGIN {
651400ns $VERSION = '1.215';
661200ns $errstr = '';
67
68 # Faster than having another method call just
69 # to set the structure finish token.
701700ns *_PARENT = *PPI::Element::_PARENT;
71
72 # Keyword -> Structure class maps
7316µs %ROUND = (
74 # Conditions
75 'if' => 'PPI::Structure::Condition',
76 'elsif' => 'PPI::Structure::Condition',
77 'unless' => 'PPI::Structure::Condition',
78 'while' => 'PPI::Structure::Condition',
79 'until' => 'PPI::Structure::Condition',
80
81 # For(each)
82 'for' => 'PPI::Structure::For',
83 'foreach' => 'PPI::Structure::For',
84 );
85
86 # Opening brace to refining method
8715µs %RESOLVE = (
88 '(' => '_round',
89 '[' => '_square',
90 '{' => '_curly',
91 );
92
93121µs112µs}
# spent 12µs making 1 call to PPI::Lexer::BEGIN@64
94
95# Allows for experimental overriding of the tokenizer
96232µs240µs
# spent 23µs (7+17) within PPI::Lexer::BEGIN@96 which was called: # once (7µs+17µs) by PPI::BEGIN@29 at line 96
use vars qw{ $X_TOKENIZER };
# spent 23µs making 1 call to PPI::Lexer::BEGIN@96 # spent 17µs making 1 call to vars::import
97
# spent 12µs within PPI::Lexer::BEGIN@97 which was called: # once (12µs+0s) by PPI::BEGIN@29 at line 99
BEGIN {
9814µs $X_TOKENIZER ||= 'PPI::Tokenizer';
99115µs112µs}
# spent 12µs making 1 call to PPI::Lexer::BEGIN@97
1002527µs277µs
# spent 42µs (7+35) within PPI::Lexer::BEGIN@100 which was called: # once (7µs+35µs) by PPI::BEGIN@29 at line 100
use constant X_TOKENIZER => $X_TOKENIZER;
# spent 42µs making 1 call to PPI::Lexer::BEGIN@100 # spent 35µs making 1 call to constant::import
101
- -
106#####################################################################
107# Constructor
108
109=pod
110
111=head2 new
112
113The C<new> constructor creates a new C<PPI::Lexer> object. The object itself
114is merely used to hold various buffers and state data during the lexing
115process, and holds no significant data between -E<gt>lex_xxxxx calls.
116
117Returns a new C<PPI::Lexer> object
118
119=cut
120
121
# spent 1.70ms (1.32+373µs) within PPI::Lexer::new which was called 144 times, avg 12µs/call: # 144 times (1.32ms+373µs) by PPI::Lexer::lex_file at line 151, avg 12µs/call
sub new {
122144401µs144373µs my $class = shift->_clear;
# spent 373µs making 144 calls to PPI::Lexer::_clear, avg 3µs/call
123144892µs bless {
124 Tokenizer => undef, # Where we store the tokenizer for a run
125 buffer => [], # The input token buffer
126 delayed => [], # The "delayed insignificant tokens" buffer
127 }, $class;
128}
129
- -
134#####################################################################
135# Main Lexing Methods
136
137=pod
138
139=head2 lex_file $filename
140
141The C<lex_file> method takes a filename as argument. It then loads the file,
142creates a L<PPI::Tokenizer> for the content and lexes the token stream
143produced by the tokenizer. Basically, a sort of all-in-one method for
144getting a L<PPI::Document> object from a file name.
145
146Returns a L<PPI::Document> object, or C<undef> on error.
147
148=cut
149
150
# spent 13.2s (9.07ms+13.2) within PPI::Lexer::lex_file which was called 144 times, avg 92.0ms/call: # 144 times (9.07ms+13.2s) by PPI::Document::new at line 215 of PPI/Document.pm, avg 92.0ms/call
sub lex_file {
151144421µs1441.70ms my $self = ref $_[0] ? shift : shift->new;
# spent 1.70ms making 144 calls to PPI::Lexer::new, avg 12µs/call
152144527µs144128µs my $file = _STRING(shift);
# spent 128µs making 144 calls to Params::Util::_STRING, avg 891ns/call
15314446µs unless ( defined $file ) {
154 return $self->_error("Did not pass a filename to PPI::Lexer::lex_file");
155 }
156
157 # Create the Tokenizer
158144126µs my $Tokenizer = eval {
159144786µs144503ms X_TOKENIZER->new($file);
# spent 503ms making 144 calls to PPI::Tokenizer::new, avg 3.49ms/call
160 };
161144976µs144320µs if ( _INSTANCE($@, 'PPI::Exception') ) {
# spent 320µs making 144 calls to Params::Util::_INSTANCE, avg 2µs/call
162 return $self->_error( $@->message );
163 } elsif ( $@ ) {
164 return $self->_error( $errstr );
165 }
166
1671445.99ms14412.7s $self->lex_tokenizer( $Tokenizer );
# spent 12.7s making 144 calls to PPI::Lexer::lex_tokenizer, avg 88.4ms/call
168}
169
170=pod
171
172=head2 lex_source $string
173
174The C<lex_source> method takes a normal scalar string as argument. It
175creates a L<PPI::Tokenizer> object for the string, and then lexes the
176resulting token stream.
177
178Returns a L<PPI::Document> object, or C<undef> on error.
179
180=cut
181
182sub lex_source {
183 my $self = ref $_[0] ? shift : shift->new;
184 my $source = shift;
185 unless ( defined $source and not ref $source ) {
186 return $self->_error("Did not pass a string to PPI::Lexer::lex_source");
187 }
188
189 # Create the Tokenizer and hand off to the next method
190 my $Tokenizer = eval {
191 X_TOKENIZER->new(\$source);
192 };
193 if ( _INSTANCE($@, 'PPI::Exception') ) {
194 return $self->_error( $@->message );
195 } elsif ( $@ ) {
196 return $self->_error( $errstr );
197 }
198
199 $self->lex_tokenizer( $Tokenizer );
200}
201
202=pod
203
204=head2 lex_tokenizer $Tokenizer
205
206The C<lex_tokenizer> takes as argument a L<PPI::Tokenizer> object. It
207lexes the token stream from the tokenizer into a L<PPI::Document> object.
208
209Returns a L<PPI::Document> object, or C<undef> on error.
210
211=cut
212
213
# spent 12.7s (3.50ms+12.7) within PPI::Lexer::lex_tokenizer which was called 144 times, avg 88.4ms/call: # 144 times (3.50ms+12.7s) by PPI::Lexer::lex_file at line 167, avg 88.4ms/call
sub lex_tokenizer {
214144271µs my $self = ref $_[0] ? shift : shift->new;
2151442.21ms2882.01ms my $Tokenizer = _INSTANCE(shift, 'PPI::Tokenizer');
# spent 1.68ms making 144 calls to Params::Util::_INSTANCE, avg 12µs/call # spent 334µs making 144 calls to UNIVERSAL::isa, avg 2µs/call
21614483µs return $self->_error(
217 "Did not pass a PPI::Tokenizer object to PPI::Lexer::lex_tokenizer"
218 ) unless $Tokenizer;
219
220 # Create the empty document
2211441.06ms1440s my $Document = PPI::Document->new;
# spent 3.10ms making 144 calls to PPI::Document::new, avg 22µs/call, recursion: max depth 1, sum of overlapping time 3.10ms
222
223 # Lex the token stream into the document
224144118µs $self->{Tokenizer} = $Tokenizer;
225144115µs eval {
226144401µs14412.7s $self->_lex_document($Document);
# spent 12.7s making 144 calls to PPI::Lexer::_lex_document, avg 88.3ms/call
227 };
22814440µs if ( $@ ) {
229 # If an error occurs DESTROY the partially built document.
230 undef $Document;
231 if ( _INSTANCE($@, 'PPI::Exception') ) {
232 return $self->_error( $@->message );
233 } else {
234 return $self->_error( $errstr );
235 }
236 }
237
238144453µs return $Document;
239}
240
- -
245#####################################################################
246# Lex Methods - Document Object
247
248=pod
249
250=begin testing _lex_document 3
251
252# Validate the creation of a null statement
253SCOPE: {
254 my $token = new_ok( 'PPI::Token::Structure' => [ ')' ] );
255 my $brace = new_ok( 'PPI::Statement::UnmatchedBrace' => [ $token ] );
256 is( $brace->content, ')', '->content ok' );
257}
258
259=end testing
260
261=cut
262
263
# spent 12.7s (146ms+12.6) within PPI::Lexer::_lex_document which was called 144 times, avg 88.3ms/call: # 144 times (146ms+12.6s) by PPI::Lexer::lex_tokenizer at line 226, avg 88.3ms/call
sub _lex_document {
264144128µs my ($self, $Document) = @_;
265 # my $self = shift;
266 # my $Document = _INSTANCE(shift, 'PPI::Document') or return undef;
267
268 # Start the processing loop
26914444µs my $Token;
27014413.5ms93561.09s while ( ref($Token = $self->_get_token) ) {
# spent 1.09s making 9356 calls to PPI::Lexer::_get_token, avg 117µs/call
271 # Add insignificant tokens directly beneath us
272921210.4ms92129.55ms unless ( $Token->significant ) {
# spent 5.48ms making 5248 calls to PPI::Token::Whitespace::significant, avg 1µs/call # spent 2.95ms making 3024 calls to PPI::Element::significant, avg 977ns/call # spent 1.11ms making 940 calls to PPI::Token::Comment::significant, avg 1µs/call
27361886.51ms618877.8ms $self->_add_element( $Document, $Token );
# spent 77.8ms making 6188 calls to PPI::Lexer::_add_element, avg 13µs/call
27461882.41ms next;
275 }
276
27730244.11ms30244.79ms if ( $Token->content eq ';' ) {
# spent 4.79ms making 3024 calls to PPI::Token::content, avg 2µs/call
278 # It's a semi-colon on it's own.
279 # We call this a null statement.
280 $self->_add_element(
281 $Document,
282 PPI::Statement::Null->new($Token),
283 );
284 next;
285 }
286
287 # Handle anything other than a structural element
28830241.35ms unless ( ref $Token eq 'PPI::Token::Structure' ) {
289 # Determine the class for the Statement, and create it
290301810.9ms6036296ms my $Statement = $self->_statement($Document, $Token)->new($Token);
# spent 217ms making 3018 calls to PPI::Lexer::_statement, avg 72µs/call # spent 78.9ms making 3018 calls to PPI::Statement::new, avg 26µs/call
291
292 # Move the lexing down into the statement
29330184.26ms30189.82ms $self->_add_delayed( $Document );
# spent 9.82ms making 3018 calls to PPI::Lexer::_add_delayed, avg 3µs/call
29430183.62ms301827.5ms $self->_add_element( $Document, $Statement );
# spent 27.5ms making 3018 calls to PPI::Lexer::_add_element, avg 9µs/call
29530184.01ms301810.9s $self->_lex_statement( $Statement );
# spent 10.9s making 3018 calls to PPI::Lexer::_lex_statement, avg 3.60ms/call
296
29730181.85ms next;
298 }
299
300 # Is this the opening of a structure?
301610µs639µs if ( $Token->__LEXER__opens ) {
# spent 39µs making 6 calls to PPI::Token::__LEXER__opens, avg 6µs/call
302 # This should actually have a Statement instead
303610µs617µs $self->_rollback( $Token );
# spent 17µs making 6 calls to PPI::Lexer::_rollback, avg 3µs/call
304614µs652µs my $Statement = PPI::Statement->new;
# spent 52µs making 6 calls to PPI::Statement::new, avg 9µs/call
305620µs682µs $self->_add_element( $Document, $Statement );
# spent 82µs making 6 calls to PPI::Lexer::_add_element, avg 14µs/call
306678µs6180ms $self->_lex_statement( $Statement );
# spent 180ms making 6 calls to PPI::Lexer::_lex_statement, avg 30.0ms/call
30767µs next;
308 }
309
310 # Is this the close of a structure.
311 if ( $Token->__LEXER__closes ) {
312 # Because we are at the top of the tree, this is an error.
313 # This means either a mis-parsing, or an mistake in the code.
314 # To handle this, we create a "Naked Close" statement
315 $self->_add_element( $Document,
316 PPI::Statement::UnmatchedBrace->new($Token)
317 );
318 next;
319 }
320
321 # Shouldn't be able to get here
322 PPI::Exception->throw('Lexer reached an illegal state');
323 }
324
325 # Did we leave the main loop because of a Tokenizer error?
32614457µs unless ( defined $Token ) {
327 my $errstr = $self->{Tokenizer} ? $self->{Tokenizer}->errstr : '';
328 $errstr ||= 'Unknown Tokenizer Error';
329 PPI::Exception->throw($errstr);
330 }
331
332 # No error, it's just the end of file.
333 # Add any insignificant trailing tokens.
334144243µs144528µs $self->_add_delayed( $Document );
# spent 528µs making 144 calls to PPI::Lexer::_add_delayed, avg 4µs/call
335
336 # If the Tokenizer has any v6 blocks to attach, do so now.
337 # Checking once at the end is faster than adding a special
338 # case check for every statement parsed.
339144122µs my $perl6 = $self->{Tokenizer}->{'perl6'};
34014461µs if ( @$perl6 ) {
341 my $includes = $Document->find( 'PPI::Statement::Include::Perl6' );
342 foreach my $include ( @$includes ) {
343 unless ( @$perl6 ) {
344 PPI::Exception->throw('Failed to find a perl6 section');
345 }
346 $include->{perl6} = shift @$perl6;
347 }
348 }
349
350144352µs return 1;
351}
352
- -
357#####################################################################
358# Lex Methods - Statement Object
359
360290µs245µs
# spent 26µs (7+19) within PPI::Lexer::BEGIN@360 which was called: # once (7µs+19µs) by PPI::BEGIN@29 at line 360
use vars qw{%STATEMENT_CLASSES};
# spent 26µs making 1 call to PPI::Lexer::BEGIN@360 # spent 19µs making 1 call to vars::import
361
# spent 13µs within PPI::Lexer::BEGIN@361 which was called: # once (13µs+0s) by PPI::BEGIN@29 at line 411
BEGIN {
362 # Keyword -> Statement Subclass
363116µs %STATEMENT_CLASSES = (
364 # Things that affect the timing of execution
365 'BEGIN' => 'PPI::Statement::Scheduled',
366 'CHECK' => 'PPI::Statement::Scheduled',
367 'UNITCHECK' => 'PPI::Statement::Scheduled',
368 'INIT' => 'PPI::Statement::Scheduled',
369 'END' => 'PPI::Statement::Scheduled',
370
371 # Loading and context statement
372 'package' => 'PPI::Statement::Package',
373 # 'use' => 'PPI::Statement::Include',
374 'no' => 'PPI::Statement::Include',
375 'require' => 'PPI::Statement::Include',
376
377 # Various declarations
378 'my' => 'PPI::Statement::Variable',
379 'local' => 'PPI::Statement::Variable',
380 'our' => 'PPI::Statement::Variable',
381 'state' => 'PPI::Statement::Variable',
382 # Statements starting with 'sub' could be any one of...
383 # 'sub' => 'PPI::Statement::Sub',
384 # 'sub' => 'PPI::Statement::Scheduled',
385 # 'sub' => 'PPI::Statement',
386
387 # Compound statement
388 'if' => 'PPI::Statement::Compound',
389 'unless' => 'PPI::Statement::Compound',
390 'for' => 'PPI::Statement::Compound',
391 'foreach' => 'PPI::Statement::Compound',
392 'while' => 'PPI::Statement::Compound',
393 'until' => 'PPI::Statement::Compound',
394
395 # Switch statement
396 'given' => 'PPI::Statement::Given',
397 'when' => 'PPI::Statement::When',
398 'default' => 'PPI::Statement::When',
399
400 # Various ways of breaking out of scope
401 'redo' => 'PPI::Statement::Break',
402 'next' => 'PPI::Statement::Break',
403 'last' => 'PPI::Statement::Break',
404 'return' => 'PPI::Statement::Break',
405 'goto' => 'PPI::Statement::Break',
406
407 # Special sections of the file
408 '__DATA__' => 'PPI::Statement::Data',
409 '__END__' => 'PPI::Statement::End',
410 );
41111.34ms113µs}
# spent 13µs making 1 call to PPI::Lexer::BEGIN@361
412
413
# spent 476ms (284+192) within PPI::Lexer::_statement which was called 10450 times, avg 46µs/call: # 7432 times (154ms+106ms) by PPI::Lexer::_lex_structure at line 1334, avg 35µs/call # 3018 times (131ms+86.3ms) by PPI::Lexer::_lex_document at line 290, avg 72µs/call
sub _statement {
414104502.86ms my ($self, $Parent, $Token) = @_;
415 # my $self = shift;
416 # my $Parent = _INSTANCE(shift, 'PPI::Node') or die "Bad param 1";
417 # my $Token = _INSTANCE(shift, 'PPI::Token') or die "Bad param 2";
418
419 # Check for things like ( parent => ... )
4201045057.9ms1909633.1ms if (
# spent 23.0ms making 17102 calls to UNIVERSAL::isa, avg 1µs/call # spent 9.04ms making 1804 calls to PPI::Structure::List::isa, avg 5µs/call # spent 1.05ms making 190 calls to PPI::Structure::For::isa, avg 6µs/call
421 $Parent->isa('PPI::Structure::List')
422 or
423 $Parent->isa('PPI::Structure::Constructor')
424 ) {
42520786.78ms20782.31ms if ( $Token->isa('PPI::Token::Word') ) {
# spent 2.31ms making 2078 calls to UNIVERSAL::isa, avg 1µs/call
426 # Is the next significant token a =>
427 # Read ahead to the next significant token
42820337µs my $Next;
4292031.34ms7247.69ms while ( $Next = $self->_get_token ) {
# spent 7.48ms making 362 calls to PPI::Lexer::_get_token, avg 21µs/call # spent 206µs making 362 calls to PPI::Util::TRUE, avg 568ns/call
430362428µs362331µs unless ( $Next->significant ) {
# spent 169µs making 203 calls to PPI::Element::significant, avg 834ns/call # spent 161µs making 159 calls to PPI::Token::Whitespace::significant, avg 1µs/call
431159132µs push @{$self->{delayed}}, $Next;
432 # $self->_delay_element( $Next );
43315974µs next;
434 }
435
436 # Got the next token
437203868µs343413µs if (
# spent 210µs making 140 calls to PPI::Token::content, avg 2µs/call # spent 203µs making 203 calls to UNIVERSAL::isa, avg 1µs/call
438 $Next->isa('PPI::Token::Operator')
439 and
440 $Next->content eq '=>'
441 ) {
442 # Is an ordinary expression
443119144µs119364µs $self->_rollback( $Next );
# spent 364µs making 119 calls to PPI::Lexer::_rollback, avg 3µs/call
444119318µs return 'PPI::Statement::Expression';
445 } else {
4468444µs last;
447 }
448 }
449
450 # Rollback and continue
45184111µs84240µs $self->_rollback( $Next );
# spent 240µs making 84 calls to PPI::Lexer::_rollback, avg 3µs/call
452 }
453 }
454
455 # Is it a token in our known classes list
4561033116.6ms1033114.6ms my $class = $STATEMENT_CLASSES{$Token->content};
# spent 14.6ms making 10331 calls to PPI::Token::content, avg 1µs/call
457
458 # Handle potential barewords for subscripts
4591033133.0ms1033125.3ms if ( $Parent->isa('PPI::Structure::Subscript') ) {
# spent 14.6ms making 1791 calls to PPI::Structure::List::isa, avg 8µs/call # spent 10.3ms making 8445 calls to UNIVERSAL::isa, avg 1µs/call # spent 413µs making 95 calls to PPI::Structure::For::isa, avg 4µs/call
460 # Fast obvious case, just an expression
4614981.27ms unless ( $class and $class->isa('PPI::Statement::Expression') ) {
462 return 'PPI::Statement::Expression';
463 }
464
465 # This is something like "my" or "our" etc... more subtle.
466 # Check if the next token is a closing curly brace.
467 # This means we are something like $h{my}
468 my $Next;
469 while ( $Next = $self->_get_token ) {
470 unless ( $Next->significant ) {
471 push @{$self->{delayed}}, $Next;
472 # $self->_delay_element( $Next );
473 next;
474 }
475
476 # Found the next significant token.
477 # Is it a closing curly brace?
478 if ( $Next->content eq '}' ) {
479 $self->_rollback( $Next );
480 return 'PPI::Statement::Expression';
481 } else {
482 $self->_rollback( $Next );
483 return $class;
484 }
485 }
486
487 # End of file... this means it is something like $h{our
488 # which is probably going to be $h{our} ... I think
489 $self->_rollback( $Next );
490 return 'PPI::Statement::Expression';
491 }
492
493 # If it's a token in our list, use that class
494983314.6ms return $class if $class;
495
496 # Handle the more in-depth sub detection
49758189.98ms58187.37ms if ( $Token->content eq 'sub' ) {
# spent 7.37ms making 5818 calls to PPI::Token::content, avg 1µs/call
498 # Read ahead to the next significant token
4991022145µs my $Next;
500102211.5ms408824.8ms while ( $Next = $self->_get_token ) {
# spent 23.7ms making 2044 calls to PPI::Lexer::_get_token, avg 12µs/call # spent 1.16ms making 2044 calls to PPI::Util::TRUE, avg 567ns/call
50120442.05ms20441.81ms unless ( $Next->significant ) {
# spent 969µs making 1022 calls to PPI::Token::Whitespace::significant, avg 948ns/call # spent 844µs making 1022 calls to PPI::Element::significant, avg 826ns/call
5021022762µs push @{$self->{delayed}}, $Next;
503 # $self->_delay_element( $Next );
5041022409µs next;
505 }
506
507 # Got the next significant token
50810221.65ms10221.36ms my $sclass = $STATEMENT_CLASSES{$Next->content};
# spent 1.36ms making 1022 calls to PPI::Token::content, avg 1µs/call
5091022103µs if ( $sclass and $sclass eq 'PPI::Statement::Scheduled' ) {
510 $self->_rollback( $Next );
511 return 'PPI::Statement::Scheduled';
512 }
51310223.04ms1022832µs if ( $Next->isa('PPI::Token::Word') ) {
# spent 832µs making 1022 calls to UNIVERSAL::isa, avg 814ns/call
5141016954µs10162.56ms $self->_rollback( $Next );
# spent 2.56ms making 1016 calls to PPI::Lexer::_rollback, avg 3µs/call
51510162.74ms return 'PPI::Statement::Sub';
516 }
517
518 ### Comment out these two, as they would return PPI::Statement anyway
519 # if ( $content eq '{' ) {
520 # Anonymous sub at start of statement
521 # return 'PPI::Statement';
522 # }
523 #
524 # if ( $Next->isa('PPI::Token::Prototype') ) {
525 # Anonymous sub at start of statement
526 # return 'PPI::Statement';
527 # }
528
529 # PPI::Statement is the safest fall-through
53066µs614µs $self->_rollback( $Next );
# spent 14µs making 6 calls to PPI::Lexer::_rollback, avg 2µs/call
531615µs return 'PPI::Statement';
532 }
533
534 # End of file... PPI::Statement::Sub is the most likely
535 $self->_rollback( $Next );
536 return 'PPI::Statement::Sub';
537 }
538
53947965.65ms47966.04ms if ( $Token->content eq 'use' ) {
# spent 6.04ms making 4796 calls to PPI::Token::content, avg 1µs/call
540 # Add a special case for "use v6" lines.
54198198µs my $Next;
5429817.37ms392420.2ms while ( $Next = $self->_get_token ) {
# spent 19.0ms making 1962 calls to PPI::Lexer::_get_token, avg 10µs/call # spent 1.20ms making 1962 calls to PPI::Util::TRUE, avg 613ns/call
54319622.19ms19621.99ms unless ( $Next->significant ) {
# spent 1.10ms making 981 calls to PPI::Token::Whitespace::significant, avg 1µs/call # spent 886µs making 981 calls to PPI::Element::significant, avg 903ns/call
544981704µs push @{$self->{delayed}}, $Next;
545 # $self->_delay_element( $Next );
546981470µs next;
547 }
548
549 # Found the next significant token.
550 # Is it a v6 use?
5519811.20ms9811.45ms if ( $Next->content eq 'v6' ) {
# spent 1.45ms making 981 calls to PPI::Token::content, avg 1µs/call
552 $self->_rollback( $Next );
553 return 'PPI::Statement::Include::Perl6';
554 } else {
5559811.16ms9813.41ms $self->_rollback( $Next );
# spent 3.41ms making 981 calls to PPI::Lexer::_rollback, avg 3µs/call
5569812.52ms return 'PPI::Statement::Include';
557 }
558 }
559
560 # End of file... this means it is an incomplete use
561 # line, just treat it as a normal include.
562 $self->_rollback( $Next );
563 return 'PPI::Statement::Include';
564 }
565
566 # If our parent is a Condition, we are an Expression
56738159.55ms381510.3ms if ( $Parent->isa('PPI::Structure::Condition') ) {
# spent 7.60ms making 1777 calls to PPI::Structure::List::isa, avg 4µs/call # spent 2.27ms making 1946 calls to UNIVERSAL::isa, avg 1µs/call # spent 385µs making 92 calls to PPI::Structure::For::isa, avg 4µs/call
568 return 'PPI::Statement::Expression';
569 }
570
571 # If our parent is a List, we are also an expression
572339020.2ms339012.5ms if ( $Parent->isa('PPI::Structure::List') ) {
# spent 10.6ms making 1777 calls to PPI::Structure::List::isa, avg 6µs/call # spent 1.53ms making 1521 calls to UNIVERSAL::isa, avg 1µs/call # spent 349µs making 92 calls to PPI::Structure::For::isa, avg 4µs/call
573 return 'PPI::Statement::Expression';
574 }
575
576 # Switch statements use expressions, as well.
57716138.85ms32264.11ms if (
# spent 3.37ms making 3042 calls to UNIVERSAL::isa, avg 1µs/call # spent 737µs making 184 calls to PPI::Structure::For::isa, avg 4µs/call
578 $Parent->isa('PPI::Structure::Given')
579 or
580 $Parent->isa('PPI::Structure::When')
581 ) {
582 return 'PPI::Statement::Expression';
583 }
584
585161311.8ms324010.7ms if ( _INSTANCE($Token, 'PPI::Token::Label') ) {
# spent 8.82ms making 1613 calls to Params::Util::_INSTANCE, avg 5µs/call # spent 1.86ms making 1613 calls to UNIVERSAL::isa, avg 1µs/call # spent 8µs making 14 calls to PPI::Util::TRUE, avg 564ns/call
586 return 'PPI::Statement::Compound';
587 }
588
589 # Beyond that, I have no idea for the moment.
590 # Just keep adding more conditions above this.
59115993.93ms return 'PPI::Statement';
592}
593
594
# spent 11.1s (1.31+9.75) within PPI::Lexer::_lex_statement which was called 10537 times, avg 1.05ms/call: # 7432 times (954ms+-954ms) by PPI::Lexer::_lex_structure at line 1338, avg 0s/call # 3018 times (338ms+10.5s) by PPI::Lexer::_lex_document at line 295, avg 3.60ms/call # 81 times (15.8ms+-15.8ms) by PPI::Lexer::_lex_structure at line 1349, avg 0s/call # 6 times (680µs+180ms) by PPI::Lexer::_lex_document at line 306, avg 30.0ms/call
sub _lex_statement {
595105372.52ms my ($self, $Statement) = @_;
596 # my $self = shift;
597 # my $Statement = _INSTANCE(shift, 'PPI::Statement') or die "Bad param 1";
598
599 # Handle some special statements
6001053739.5ms10681351ms if ( $Statement->isa('PPI::Statement::End') ) {
# spent 337ms making 144 calls to PPI::Lexer::_lex_end, avg 2.34ms/call # spent 14.1ms making 10537 calls to UNIVERSAL::isa, avg 1µs/call
601 return $self->_lex_end( $Statement );
602 }
603
604 # Begin processing tokens
605103931.28ms my $Token;
6061039385.2ms618032.32s while ( ref( $Token = $self->_get_token ) ) {
# spent 2.32s making 61803 calls to PPI::Lexer::_get_token, avg 38µs/call
607 # Delay whitespace and comment tokens
6086759277.7ms6759266.6ms unless ( $Token->significant ) {
# spent 36.3ms making 39289 calls to PPI::Element::significant, avg 925ns/call # spent 29.5ms making 27638 calls to PPI::Token::Whitespace::significant, avg 1µs/call # spent 813µs making 665 calls to PPI::Token::Comment::significant, avg 1µs/call
6092830315.7ms push @{$self->{delayed}}, $Token;
610 # $self->_delay_element( $Token );
6112830311.5ms next;
612 }
613
614 # Structual closes, and __DATA__ and __END__ tags implicitly
615 # end every type of statement
61639289220ms78578173ms if (
# spent 116ms making 39289 calls to PPI::Token::__LEXER__closes, avg 3µs/call # spent 44.7ms making 35232 calls to UNIVERSAL::isa, avg 1µs/call # spent 12.3ms making 4057 calls to PPI::Lexer::_rollback, avg 3µs/call
617 $Token->__LEXER__closes
618 or
619 $Token->isa('PPI::Token::Separator')
620 ) {
621 # Rollback and end the statement
622 return $self->_rollback( $Token );
623 }
624
625 # Normal statements never implicitly end
6263523247.7ms41442481ms unless ( $Statement->__LEXER__normal ) {
# spent 444ms making 4817 calls to PPI::Lexer::_continues, avg 92µs/call # spent 26.7ms making 30415 calls to PPI::Statement::__LEXER__normal, avg 879ns/call # spent 4.56ms making 1393 calls to PPI::Lexer::_rollback, avg 3µs/call # spent 3.39ms making 3042 calls to PPI::Statement::Sub::__LEXER__normal, avg 1µs/call # spent 2.24ms making 1775 calls to PPI::Statement::Compound::__LEXER__normal, avg 1µs/call
627 # Have we hit an implicit end to the statement
628 unless ( $self->_continues( $Statement, $Token ) ) {
629 # Rollback and finish the statement
630 return $self->_rollback( $Token );
631 }
632 }
633
634 # Any normal character just gets added
63533839107ms3383931.4ms unless ( $Token->isa('PPI::Token::Structure') ) {
# spent 31.4ms making 33839 calls to UNIVERSAL::isa, avg 928ns/call
6362310723.7ms23107571ms $self->_add_element( $Statement, $Token );
# spent 571ms making 23107 calls to PPI::Lexer::_add_element, avg 25µs/call
637231079.28ms next;
638 }
639
640 # Handle normal statement terminators
6411073212.0ms1073214.8ms if ( $Token->content eq ';' ) {
# spent 14.8ms making 10732 calls to PPI::Token::content, avg 1µs/call
64249435.21ms494385.8ms $self->_add_element( $Statement, $Token );
# spent 85.8ms making 4943 calls to PPI::Lexer::_add_element, avg 17µs/call
643494310.7ms return 1;
644 }
645
646 # Which leaves us with a new structure
647
648 # Determine the class for the structure and create it
64957899.02ms57897.12ms my $method = $RESOLVE{$Token->content};
# spent 7.12ms making 5789 calls to PPI::Token::content, avg 1µs/call
650578920.0ms11578540ms my $Structure = $self->$method($Statement)->new($Token);
# spent 222ms making 2273 calls to PPI::Lexer::_curly, avg 98µs/call # spent 168ms making 3157 calls to PPI::Lexer::_round, avg 53µs/call # spent 139ms making 5789 calls to PPI::Structure::new, avg 24µs/call # spent 10.6ms making 359 calls to PPI::Lexer::_square, avg 30µs/call
651
652 # Move the lexing down into the Structure
65357897.75ms578944.0ms $self->_add_delayed( $Statement );
# spent 44.0ms making 5789 calls to PPI::Lexer::_add_delayed, avg 8µs/call
65457896.60ms578999.5ms $self->_add_element( $Statement, $Structure );
# spent 99.5ms making 5789 calls to PPI::Lexer::_add_element, avg 17µs/call
655578921.2ms115789.10s $self->_lex_structure( $Structure );
# spent 16.8s making 5789 calls to PPI::Lexer::_lex_structure, avg 2.90ms/call, recursion: max depth 6, sum of overlapping time 7.76s # spent 55.9ms making 5789 calls to PPI::Lexer::_get_token, avg 10µs/call
656 }
657
658 # Was it an error in the tokenizer?
659 unless ( defined $Token ) {
660 PPI::Exception->throw;
661 }
662
663 # No, it's just the end of the file...
664 # Roll back any insignificant tokens, they'll get added at the Document level
665 $self->_rollback;
666}
667
668
# spent 337ms (13.1+324) within PPI::Lexer::_lex_end which was called 144 times, avg 2.34ms/call: # 144 times (13.1ms+324ms) by PPI::Lexer::_lex_statement at line 600, avg 2.34ms/call
sub _lex_end {
66914456µs my ($self, $Statement) = @_;
670 # my $self = shift;
671 # my $Statement = _INSTANCE(shift, 'PPI::Statement::End') or die "Bad param 1";
672
673 # End of the file, EVERYTHING is ours
67414428µs my $Token;
675144622µs2881.20ms while ( $Token = $self->_get_token ) {
# spent 1.11ms making 144 calls to PPI::Lexer::_get_token, avg 8µs/call # spent 88µs making 144 calls to PPI::Util::TRUE, avg 608ns/call
676 # Inlined $Statement->__add_element($Token);
6775763.29ms1152956µs Scalar::Util::weaken(
# spent 497µs making 576 calls to Scalar::Util::weaken, avg 863ns/call # spent 459µs making 576 calls to Scalar::Util::refaddr, avg 796ns/call
678 $_PARENT{Scalar::Util::refaddr $Token} = $Statement
679 );
6805762.28ms1008321ms push @{$Statement->{children}}, $Token;
# spent 321ms making 576 calls to PPI::Lexer::_get_token, avg 557µs/call # spent 262µs making 432 calls to PPI::Util::TRUE, avg 607ns/call
681 }
682
683 # Was it an error in the tokenizer?
68414442µs unless ( defined $Token ) {
685 PPI::Exception->throw;
686 }
687
688 # No, it's just the end of the file...
689 # Roll back any insignificant tokens, they get added at the Document level
690144489µs144276µs $self->_rollback;
# spent 276µs making 144 calls to PPI::Lexer::_rollback, avg 2µs/call
691}
692
693# For many statements, it can be dificult to determine the end-point.
694# This method takes a statement and the next significant token, and attempts
695# to determine if the there is a statement boundary between the two, or if
696# the statement can continue with the token.
697
# spent 444ms (144+300) within PPI::Lexer::_continues which was called 4817 times, avg 92µs/call: # 4817 times (144ms+300ms) by PPI::Lexer::_lex_statement at line 626, avg 92µs/call
sub _continues {
69848171.46ms my ($self, $Statement, $Token) = @_;
699 # my $self = shift;
700 # my $Statement = _INSTANCE(shift, 'PPI::Statement') or die "Bad param 1";
701 # my $Token = _INSTANCE(shift, 'PPI::Token') or die "Bad param 2";
702
703 # Handle the simple block case
704 # { print 1; }
705481717.6ms785787.4ms if (
# spent 75.1ms making 4817 calls to PPI::Node::schildren, avg 16µs/call # spent 10.2ms making 1520 calls to PPI::Node::schild, avg 7µs/call # spent 2.11ms making 1520 calls to UNIVERSAL::isa, avg 1µs/call
706 $Statement->schildren == 1
707 and
708 $Statement->schild(0)->isa('PPI::Structure::Block')
709 ) {
710 return '';
711 }
712
713 # Alrighty then, there are only five implied end statement types,
714 # ::Scheduled blocks, ::Sub declarations, ::Compound, ::Given, and ::When
715 # statements.
716481018.0ms48108.76ms unless ( ref($Statement) =~ /\b(?:Scheduled|Sub|Compound|Given|When)$/ ) {
# spent 8.76ms making 4810 calls to PPI::Lexer::CORE:match, avg 2µs/call
717 return 1;
718 }
719
720 # Of these five, ::Scheduled, ::Sub, ::Given, and ::When follow the same
721 # simple rule and can be handled first.
72248108.53ms4810103ms my @part = $Statement->schildren;
# spent 103ms making 4810 calls to PPI::Node::schildren, avg 21µs/call
72348101.36ms my $LastChild = $part[-1];
724481054.1ms78528.75ms unless ( $Statement->isa('PPI::Statement::Compound') ) {
# spent 8.75ms making 7852 calls to UNIVERSAL::isa, avg 1µs/call
725 # If the last significant element of the statement is a block,
726 # then a scheduled statement is done, no questions asked.
727 return ! $LastChild->isa('PPI::Structure::Block');
728 }
729
730 # Now we get to compound statements, which kind of suck (to lex).
731 # However, of them all, the 'if' type, which includes unless, are
732 # relatively easy to handle compared to the others.
73317682.62ms176877.3ms my $type = $Statement->type;
# spent 77.3ms making 1768 calls to PPI::Statement::Compound::type, avg 44µs/call
7341768569µs if ( $type eq 'if' ) {
735 # This should be one of the following
736 # if (EXPR) BLOCK
737 # if (EXPR) BLOCK else BLOCK
738 # if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
739
740 # We only implicitly end on a block
74111515.56ms11511.26ms unless ( $LastChild->isa('PPI::Structure::Block') ) {
# spent 1.26ms making 1151 calls to UNIVERSAL::isa, avg 1µs/call
742 # if (EXPR) ...
743 # if (EXPR) BLOCK else ...
744 # if (EXPR) BLOCK elsif (EXPR) BLOCK ...
745 return 1;
746 }
747
748 # If the token before the block is an 'else',
749 # it's over, no matter what.
750329475µs3294.42ms my $NextLast = $Statement->schild(-2);
# spent 4.42ms making 329 calls to PPI::Node::schild, avg 13µs/call
7513296.18ms694628µs if (
# spent 376µs making 347 calls to UNIVERSAL::isa, avg 1µs/call # spent 227µs making 329 calls to PPI::Util::TRUE, avg 689ns/call # spent 25µs making 18 calls to PPI::Token::content, avg 1µs/call
752 $NextLast
753 and
754 $NextLast->isa('PPI::Token')
755 and
756 $NextLast->isa('PPI::Token::Word')
757 and
758 $NextLast->content eq 'else'
759 ) {
760 return '';
761 }
762
763 # Otherwise, we continue for 'elsif' or 'else' only.
7643111.72ms847930µs if (
# spent 693µs making 536 calls to PPI::Token::content, avg 1µs/call # spent 237µs making 311 calls to UNIVERSAL::isa, avg 762ns/call
765 $Token->isa('PPI::Token::Word')
766 and (
767 $Token->content eq 'else'
768 or
769 $Token->content eq 'elsif'
770 )
771 ) {
772 return 1;
773 }
774
775227626µs return '';
776 }
777
778617107µs if ( $type eq 'label' ) {
779 # We only have the label so far, could be any of
780 # LABEL while (EXPR) BLOCK
781 # LABEL while (EXPR) BLOCK continue BLOCK
782 # LABEL for (EXPR; EXPR; EXPR) BLOCK
783 # LABEL foreach VAR (LIST) BLOCK
784 # LABEL foreach VAR (LIST) BLOCK continue BLOCK
785 # LABEL BLOCK continue BLOCK
786
787 # Handle cases with a word after the label
78814151µs4255µs if (
# spent 24µs making 14 calls to PPI::Lexer::CORE:match, avg 2µs/call # spent 20µs making 14 calls to PPI::Token::content, avg 1µs/call # spent 11µs making 14 calls to UNIVERSAL::isa, avg 793ns/call
789 $Token->isa('PPI::Token::Word')
790 and
791 $Token->content =~ /^(?:while|until|for|foreach)$/
792 ) {
793 return 1;
794 }
795
796 # Handle labelled blocks
797 if ( $Token->isa('PPI::Token::Structure') && $Token->content eq '{' ) {
798 return 1;
799 }
800
801 return '';
802 }
803
804 # Handle the common "after round braces" case
8056033.29ms11893.68ms if ( $LastChild->isa('PPI::Structure') and $LastChild->braces eq '()' ) {
# spent 2.43ms making 284 calls to PPI::Structure::braces, avg 9µs/call # spent 651µs making 665 calls to UNIVERSAL::isa, avg 979ns/call # spent 382µs making 86 calls to PPI::Structure::List::isa, avg 4µs/call # spent 209µs making 151 calls to PPI::Token::content, avg 1µs/call # spent 10µs making 3 calls to PPI::Structure::For::isa, avg 4µs/call
806 # LABEL while (EXPR) ...
807 # LABEL while (EXPR) ...
808 # LABEL for (EXPR; EXPR; EXPR) ...
809 # LABEL for VAR (LIST) ...
810 # LABEL foreach VAR (LIST) ...
811 # Only a block will do
812 return $Token->isa('PPI::Token::Structure') && $Token->content eq '{';
813 }
814
81545299µs if ( $type eq 'for' ) {
816 # LABEL for (EXPR; EXPR; EXPR) BLOCK
81735230µs103102µs if (
# spent 42µs making 33 calls to PPI::Token::content, avg 1µs/call # spent 32µs making 33 calls to PPI::Lexer::CORE:match, avg 970ns/call # spent 27µs making 37 calls to UNIVERSAL::isa, avg 735ns/call
818 $LastChild->isa('PPI::Token::Word')
819 and
820 $LastChild->content =~ /^for(?:each)?\z/
821 ) {
822 # LABEL for ...
82333242µs6696µs if (
# spent 89µs making 60 calls to UNIVERSAL::isa, avg 1µs/call # spent 7µs making 6 calls to PPI::Token::content, avg 1µs/call
824 (
825 $Token->isa('PPI::Token::Structure')
826 and
827 $Token->content eq '('
828 )
829 or
830 $Token->isa('PPI::Token::QuoteLike::Words')
831 ) {
832 return 1;
833 }
834
8352795µs2726µs if ( $LastChild->isa('PPI::Token::QuoteLike::Words') ) {
# spent 26µs making 27 calls to UNIVERSAL::isa, avg 956ns/call
836 # LABEL for VAR QW{} ...
837 # LABEL foreach VAR QW{} ...
838 # Only a block will do
839 return $Token->isa('PPI::Token::Structure') && $Token->content eq '{';
840 }
841
842 # In this case, we can also behave like a foreach
8432716µs $type = 'foreach';
844
845 } elsif ( $LastChild->isa('PPI::Structure::Block') ) {
846 # LABEL for (EXPR; EXPR; EXPR) BLOCK
847 # That's it, nothing can continue
848 return '';
849
850 } elsif ( $LastChild->isa('PPI::Token::QuoteLike::Words') ) {
851 # LABEL for VAR QW{} ...
852 # LABEL foreach VAR QW{} ...
853 # Only a block will do
854 return $Token->isa('PPI::Token::Structure') && $Token->content eq '{';
855 }
856 }
857
858 # Handle the common continue case
8594446.21ms678736µs if ( $LastChild->isa('PPI::Token::Word') and $LastChild->content eq 'continue' ) {
# spent 430µs making 446 calls to UNIVERSAL::isa, avg 964ns/call # spent 307µs making 232 calls to PPI::Token::content, avg 1µs/call
860 # LABEL while (EXPR) BLOCK continue ...
861 # LABEL foreach VAR (LIST) BLOCK continue ...
862 # LABEL BLOCK continue ...
863 # Only a block will do
864 return $Token->isa('PPI::Token::Structure') && $Token->content eq '{';
865 }
866
867 # Handle the common continuable block case
8684421.36ms442458µs if ( $LastChild->isa('PPI::Structure::Block') ) {
# spent 458µs making 442 calls to UNIVERSAL::isa, avg 1µs/call
869 # LABEL while (EXPR) BLOCK
870 # LABEL while (EXPR) BLOCK ...
871 # LABEL for (EXPR; EXPR; EXPR) BLOCK
872 # LABEL foreach VAR (LIST) BLOCK
873 # LABEL foreach VAR (LIST) BLOCK ...
874 # LABEL BLOCK ...
875 # Is this the block for a continue?
8761311.01ms2661.49ms if ( _INSTANCE($part[-2], 'PPI::Token::Word') and $part[-2]->content eq 'continue' ) {
# spent 1.09ms making 131 calls to Params::Util::_INSTANCE, avg 8µs/call # spent 332µs making 69 calls to PPI::Structure::List::isa, avg 5µs/call # spent 67µs making 62 calls to UNIVERSAL::isa, avg 1µs/call # spent 3µs making 2 calls to PPI::Token::content, avg 1µs/call # spent 1µs making 2 calls to PPI::Util::TRUE, avg 500ns/call
877 # LABEL while (EXPR) BLOCK continue BLOCK
878 # LABEL foreach VAR (LIST) BLOCK continue BLOCK
879 # LABEL BLOCK continue BLOCK
880 # That's it, nothing can continue this
881 return '';
882 }
883
884 # Only a continue will do
885129940µs248288µs return $Token->isa('PPI::Token::Word') && $Token->content eq 'continue';
# spent 185µs making 119 calls to PPI::Token::content, avg 2µs/call # spent 103µs making 129 calls to UNIVERSAL::isa, avg 797ns/call
886 }
887
88831176µs if ( $type eq 'block' ) {
889 # LABEL BLOCK continue BLOCK
890 # Every possible case is covered in the common cases above
891 }
892
893311697µs248242µs if ( $type eq 'while' ) {
# spent 151µs making 124 calls to PPI::Token::content, avg 1µs/call # spent 91µs making 124 calls to UNIVERSAL::isa, avg 736ns/call
894 # LABEL while (EXPR) BLOCK
895 # LABEL while (EXPR) BLOCK continue BLOCK
896 # LABEL until (EXPR) BLOCK
897 # LABEL until (EXPR) BLOCK continue BLOCK
898 # The only case not covered is the while ...
899 if (
900 $LastChild->isa('PPI::Token::Word')
901 and (
902 $LastChild->content eq 'while'
903 or
904 $LastChild->content eq 'until'
905 )
906 ) {
907 # LABEL while ...
908 # LABEL until ...
909 # Only a condition structure will do
910 return $Token->isa('PPI::Token::Structure') && $Token->content eq '(';
911 }
912 }
913
91424970µs if ( $type eq 'foreach' ) {
915 # LABEL foreach VAR (LIST) BLOCK
916 # LABEL foreach VAR (LIST) BLOCK continue BLOCK
917 # The only two cases that have not been covered already are
918 # 'foreach ...' and 'foreach VAR ...'
919
920249712µs249230µs if ( $LastChild->isa('PPI::Token::Symbol') ) {
# spent 230µs making 249 calls to UNIVERSAL::isa, avg 925ns/call
921 # LABEL foreach my $scalar ...
922 # Open round brace, or a quotewords
92383516µs166157µs return 1 if $Token->isa('PPI::Token::Structure') && $Token->content eq '(';
# spent 104µs making 83 calls to PPI::Token::content, avg 1µs/call # spent 53µs making 83 calls to UNIVERSAL::isa, avg 637ns/call
924 return 1 if $Token->isa('PPI::Token::QuoteLike::Words');
925 return '';
926 }
927
928166332µs276340µs if ( $LastChild->content eq 'foreach' or $LastChild->content eq 'for' ) {
# spent 340µs making 276 calls to PPI::Token::content, avg 1µs/call
929 # There are three possibilities here
93083601µs166163µs if (
# spent 99µs making 83 calls to PPI::Token::content, avg 1µs/call # spent 64µs making 83 calls to UNIVERSAL::isa, avg 772ns/call
931 $Token->isa('PPI::Token::Word')
932 and (
933 ($STATEMENT_CLASSES{ $Token->content } || '')
934 eq
935 'PPI::Statement::Variable'
936 )
937 ) {
938 # VAR == 'my ...'
939 return 1;
940 } elsif ( $Token->content =~ /^\$/ ) {
941 # VAR == '$scalar'
942 return 1;
943 } elsif ( $Token->isa('PPI::Token::Structure') and $Token->content eq '(' ) {
944 return 1;
945 } elsif ( $Token->isa('PPI::Token::QuoteLike::Words') ) {
946 return 1;
947 } else {
948 return '';
949 }
950 }
951
95283165µs8396µs if (
# spent 96µs making 83 calls to PPI::Token::content, avg 1µs/call
953 ($STATEMENT_CLASSES{ $LastChild->content } || '')
954 eq
955 'PPI::Statement::Variable'
956 ) {
957 # LABEL foreach my ...
958 # Only a scalar will do
95983514µs166179µs return $Token->content =~ /^\$/;
# spent 99µs making 83 calls to PPI::Token::content, avg 1µs/call # spent 81µs making 83 calls to PPI::Lexer::CORE:match, avg 973ns/call
960 }
961
962 # Handle the rare for my $foo qw{bar} ... case
963 if ( $LastChild->isa('PPI::Token::QuoteLike::Words') ) {
964 # LABEL for VAR QW ...
965 # LABEL foreach VAR QW ...
966 # Only a block will do
967 return $Token->isa('PPI::Token::Structure') && $Token->content eq '{';
968 }
969 }
970
971 # Something we don't know about... what could it be
972 PPI::Exception->throw("Illegal state in '$type' compound statement");
973}
974
- -
979#####################################################################
980# Lex Methods - Structure Object
981
982# Given a parent element, and a ( token to open a structure, determine
983# the class that the structure should be.
984
# spent 168ms (95.9+72.0) within PPI::Lexer::_round which was called 3157 times, avg 53µs/call: # 3157 times (95.9ms+72.0ms) by PPI::Lexer::_lex_statement at line 650, avg 53µs/call
sub _round {
9853157952µs my ($self, $Parent) = @_;
986 # my $self = shift;
987 # my $Parent = _INSTANCE(shift, 'PPI::Node') or die "Bad param 1";
988
989 # Get the last significant element in the parent
99031574.22ms315721.1ms my $Element = $Parent->schild(-1);
# spent 21.1ms making 3157 calls to PPI::Node::schild, avg 7µs/call
991315747.1ms924419.3ms if ( _INSTANCE($Element, 'PPI::Token::Word') ) {
# spent 15.0ms making 3157 calls to Params::Util::_INSTANCE, avg 5µs/call # spent 2.40ms making 3134 calls to UNIVERSAL::isa, avg 765ns/call # spent 1.89ms making 2953 calls to PPI::Util::TRUE, avg 641ns/call
992 # Can it be determined because it is a keyword?
99329534.74ms29533.91ms my $rclass = $ROUND{$Element->content};
# spent 3.91ms making 2953 calls to PPI::Token::content, avg 1µs/call
99429531.98ms return $rclass if $rclass;
995 }
996
997 # If we are part of a for or foreach statement, we are a ForLoop
998268027.4ms78749.93ms if ( $Parent->isa('PPI::Statement::Compound') ) {
# spent 9.93ms making 7874 calls to UNIVERSAL::isa, avg 1µs/call
99983524µs1668.88ms if ( $Parent->type =~ /^for(?:each)?$/ ) {
# spent 8.80ms making 83 calls to PPI::Statement::Compound::type, avg 106µs/call # spent 79µs making 83 calls to PPI::Lexer::CORE:match, avg 949ns/call
1000 return 'PPI::Structure::For';
1001 }
1002 } elsif ( $Parent->isa('PPI::Statement::Given') ) {
1003 return 'PPI::Structure::Given';
1004 } elsif ( $Parent->isa('PPI::Statement::When') ) {
1005 return 'PPI::Structure::When';
1006 }
1007
1008 # Otherwise, it must be a list
1009
1010 # If the previous element is -> then we mark it as a dereference
1011259725.3ms536313.8ms if ( _INSTANCE($Element, 'PPI::Token::Operator') and $Element->content eq '->' ) {
# spent 11.1ms making 2597 calls to Params::Util::_INSTANCE, avg 4µs/call # spent 2.50ms making 2574 calls to UNIVERSAL::isa, avg 972ns/call # spent 130µs making 96 calls to PPI::Token::content, avg 1µs/call # spent 57µs making 96 calls to PPI::Util::TRUE, avg 598ns/call
1012 $Element->{_dereference} = 1;
1013 }
1014
1015 'PPI::Structure::List'
101625976.21ms}
1017
1018# Given a parent element, and a [ token to open a structure, determine
1019# the class that the structure should be.
1020
# spent 10.6ms (6.18+4.44) within PPI::Lexer::_square which was called 359 times, avg 30µs/call: # 359 times (6.18ms+4.44ms) by PPI::Lexer::_lex_statement at line 650, avg 30µs/call
sub _square {
1021359142µs my ($self, $Parent) = @_;
1022 # my $self = shift;
1023 # my $Parent = _INSTANCE(shift, 'PPI::Node') or die "Bad param 1";
1024
1025 # Get the last significant element in the parent
1026359531µs3592.51ms my $Element = $Parent->schild(-1);
# spent 2.51ms making 359 calls to PPI::Node::schild, avg 7µs/call
1027
1028 # Is this a subscript, like $foo[1] or $foo{expr}
1029
10303591.14ms356242µs if ( $Element ) {
# spent 242µs making 356 calls to PPI::Util::TRUE, avg 681ns/call
10313561.52ms596674µs if ( $Element->isa('PPI::Token::Operator') and $Element->content eq '->' ) {
# spent 334µs making 354 calls to UNIVERSAL::isa, avg 944ns/call # spent 332µs making 240 calls to PPI::Token::content, avg 1µs/call # spent 8µs making 2 calls to PPI::Structure::List::isa, avg 4µs/call
1032 # $foo->[]
10336247µs $Element->{_dereference} = 1;
103462155µs return 'PPI::Structure::Subscript';
1035 }
10362941.05ms294415µs if ( $Element->isa('PPI::Structure::Subscript') ) {
# spent 407µs making 292 calls to UNIVERSAL::isa, avg 1µs/call # spent 8µs making 2 calls to PPI::Structure::List::isa, avg 4µs/call
1037 # $foo{}[]
1038 return 'PPI::Structure::Subscript';
1039 }
10402941.68ms516590µs if ( $Element->isa('PPI::Token::Symbol') and $Element->content =~ /^(?:\$|\@)/ ) {
# spent 298µs making 292 calls to UNIVERSAL::isa, avg 1µs/call # spent 152µs making 111 calls to PPI::Token::content, avg 1µs/call # spent 133µs making 111 calls to PPI::Lexer::CORE:match, avg 1µs/call # spent 8µs making 2 calls to PPI::Structure::List::isa, avg 4µs/call
1041 # $foo[], @foo[]
1042 return 'PPI::Structure::Subscript';
1043 }
1044 # FIXME - More cases to catch
1045 }
1046
1047 # Otherwise, we assume that it's an anonymous arrayref constructor
1048186464µs 'PPI::Structure::Constructor';
1049}
1050
1051267µs269µs
# spent 38µs (8+30) within PPI::Lexer::BEGIN@1051 which was called: # once (8µs+30µs) by PPI::BEGIN@29 at line 1051
use vars qw{%CURLY_CLASSES @CURLY_LOOKAHEAD_CLASSES};
# spent 38µs making 1 call to PPI::Lexer::BEGIN@1051 # spent 30µs making 1 call to vars::import
1052
# spent 15µs within PPI::Lexer::BEGIN@1052 which was called: # once (15µs+0s) by PPI::BEGIN@29 at line 1085
BEGIN {
1053 # Keyword -> Structure class maps
1054110µs %CURLY_CLASSES = (
1055 # Blocks
1056 'sub' => 'PPI::Structure::Block',
1057 'grep' => 'PPI::Structure::Block',
1058 'map' => 'PPI::Structure::Block',
1059 'sort' => 'PPI::Structure::Block',
1060 'do' => 'PPI::Structure::Block',
1061
1062 # Hash constructors
1063 'scalar' => 'PPI::Structure::Constructor',
1064 '=' => 'PPI::Structure::Constructor',
1065 '||=' => 'PPI::Structure::Constructor',
1066 ',' => 'PPI::Structure::Constructor',
1067 '=>' => 'PPI::Structure::Constructor',
1068 '+' => 'PPI::Structure::Constructor', # per perlref
1069 'return' => 'PPI::Structure::Constructor', # per perlref
1070 'bless' => 'PPI::Structure::Constructor', # pragmatic --
1071 # perlfunc says first arg is a reference, and
1072 # bless {; ... } fails to compile.
1073 );
1074
107516µs @CURLY_LOOKAHEAD_CLASSES = (
1076 {}, # not used
1077 {
1078 ';' => 'PPI::Structure::Block', # per perlref
1079 '}' => 'PPI::Structure::Constructor',
1080 },
1081 {
1082 '=>' => 'PPI::Structure::Constructor',
1083 },
1084 );
10851890µs115µs}
# spent 15µs making 1 call to PPI::Lexer::BEGIN@1052
1086
1087=pod
1088
1089=begin testing _curly 26
1090
1091my $document = PPI::Document->new(\<<'END_PERL');
1092use constant { One => 1 };
1093use constant 1 { One => 1 };
1094$foo->{bar};
1095$foo[1]{bar};
1096$foo{bar};
1097sub {1};
1098grep { $_ } 0 .. 2;
1099map { $_ => 1 } 0 .. 2;
1100sort { $b <=> $a } 0 .. 2;
1101do {foo};
1102$foo = { One => 1 };
1103$foo ||= { One => 1 };
11041, { One => 1 };
1105One => { Two => 2 };
1106{foo, bar};
1107{foo => bar};
1108{};
1109+{foo, bar};
1110{; => bar};
1111@foo{'bar', 'baz'};
1112@{$foo}{'bar', 'baz'};
1113${$foo}{bar};
1114return { foo => 'bar' };
1115bless { foo => 'bar' };
1116END_PERL
1117
1118isa_ok( $document, 'PPI::Document' );
1119$document->index_locations();
1120
1121my @statements;
1122foreach my $elem ( @{ $document->find( 'PPI::Statement' ) || [] } ) {
1123 $statements[ $elem->line_number() - 1 ] ||= $elem;
1124}
1125
1126is( scalar(@statements), 24, 'Found 24 statements' );
1127
1128isa_ok( $statements[0]->schild(2), 'PPI::Structure::Constructor',
1129 'The curly in ' . $statements[0]);
1130isa_ok( $statements[1]->schild(3), 'PPI::Structure::Constructor',
1131 'The curly in ' . $statements[1]);
1132isa_ok( $statements[2]->schild(2), 'PPI::Structure::Subscript',
1133 'The curly in ' . $statements[2]);
1134isa_ok( $statements[3]->schild(2), 'PPI::Structure::Subscript',
1135 'The curly in ' . $statements[3]);
1136isa_ok( $statements[4]->schild(1), 'PPI::Structure::Subscript',
1137 'The curly in ' . $statements[4]);
1138isa_ok( $statements[5]->schild(1), 'PPI::Structure::Block',
1139 'The curly in ' . $statements[5]);
1140isa_ok( $statements[6]->schild(1), 'PPI::Structure::Block',
1141 'The curly in ' . $statements[6]);
1142isa_ok( $statements[7]->schild(1), 'PPI::Structure::Block',
1143 'The curly in ' . $statements[7]);
1144isa_ok( $statements[8]->schild(1), 'PPI::Structure::Block',
1145 'The curly in ' . $statements[8]);
1146isa_ok( $statements[9]->schild(1), 'PPI::Structure::Block',
1147 'The curly in ' . $statements[9]);
1148isa_ok( $statements[10]->schild(2), 'PPI::Structure::Constructor',
1149 'The curly in ' . $statements[10]);
1150isa_ok( $statements[11]->schild(3), 'PPI::Structure::Constructor',
1151 'The curly in ' . $statements[11]);
1152isa_ok( $statements[12]->schild(2), 'PPI::Structure::Constructor',
1153 'The curly in ' . $statements[12]);
1154isa_ok( $statements[13]->schild(2), 'PPI::Structure::Constructor',
1155 'The curly in ' . $statements[13]);
1156isa_ok( $statements[14]->schild(0), 'PPI::Structure::Block',
1157 'The curly in ' . $statements[14]);
1158isa_ok( $statements[15]->schild(0), 'PPI::Structure::Constructor',
1159 'The curly in ' . $statements[15]);
1160isa_ok( $statements[16]->schild(0), 'PPI::Structure::Constructor',
1161 'The curly in ' . $statements[16]);
1162isa_ok( $statements[17]->schild(1), 'PPI::Structure::Constructor',
1163 'The curly in ' . $statements[17]);
1164isa_ok( $statements[18]->schild(0), 'PPI::Structure::Block',
1165 'The curly in ' . $statements[18]);
1166isa_ok( $statements[19]->schild(1), 'PPI::Structure::Subscript',
1167 'The curly in ' . $statements[19]);
1168isa_ok( $statements[20]->schild(2), 'PPI::Structure::Subscript',
1169 'The curly in ' . $statements[20]);
1170isa_ok( $statements[21]->schild(2), 'PPI::Structure::Subscript',
1171 'The curly in ' . $statements[21]);
1172isa_ok( $statements[22]->schild(1), 'PPI::Structure::Constructor',
1173 'The curly in ' . $statements[22]);
1174isa_ok( $statements[23]->schild(1), 'PPI::Structure::Constructor',
1175 'The curly in ' . $statements[23]);
1176
1177=end testing
1178
1179=cut
1180
1181# Given a parent element, and a { token to open a structure, determine
1182# the class that the structure should be.
1183
# spent 222ms (79.5+142) within PPI::Lexer::_curly which was called 2273 times, avg 98µs/call: # 2273 times (79.5ms+142ms) by PPI::Lexer::_lex_statement at line 650, avg 98µs/call
sub _curly {
11842273654µs my ($self, $Parent) = @_;
1185 # my $self = shift;
1186 # my $Parent = _INSTANCE(shift, 'PPI::Node') or die "Bad param 1";
1187
1188 # Get the last significant element in the parent
118922732.68ms227314.4ms my $Element = $Parent->schild(-1);
# spent 14.4ms making 2273 calls to PPI::Node::schild, avg 6µs/call
119022739.62ms442473.9ms my $content = $Element ? $Element->content : '';
# spent 70.2ms making 568 calls to PPI::Structure::content, avg 124µs/call # spent 2.17ms making 1644 calls to PPI::Token::content, avg 1µs/call # spent 1.49ms making 2212 calls to PPI::Util::TRUE, avg 674ns/call
1191
1192 # Is this a subscript, like $foo[1] or $foo{expr}
119322736.03ms22121.28ms if ( $Element ) {
# spent 1.28ms making 2212 calls to PPI::Util::TRUE, avg 581ns/call
119422121.08ms195152µs if ( $content eq '->' and $Element->isa('PPI::Token::Operator') ) {
# spent 152µs making 195 calls to UNIVERSAL::isa, avg 778ns/call
1195 # $foo->{}
1196195152µs $Element->{_dereference} = 1;
1197195472µs return 'PPI::Structure::Subscript';
1198 }
119920176.43ms20172.99ms if ( $Element->isa('PPI::Structure::Subscript') ) {
# spent 2.56ms making 1928 calls to UNIVERSAL::isa, avg 1µs/call # spent 414µs making 86 calls to PPI::Structure::List::isa, avg 5µs/call # spent 13µs making 3 calls to PPI::Structure::For::isa, avg 4µs/call
1200 # $foo[]{}
1201 return 'PPI::Structure::Subscript';
1202 }
120319935.62ms21851.94ms if ( $content =~ /^(?:\$|\@)/ and $Element->isa('PPI::Token::Symbol') ) {
# spent 1.74ms making 1993 calls to PPI::Lexer::CORE:match, avg 873ns/call # spent 196µs making 192 calls to UNIVERSAL::isa, avg 1µs/call
1204 # $foo{}, @foo{}
1205 return 'PPI::Structure::Subscript';
1206 }
120718885.41ms18882.41ms if ( $Element->isa('PPI::Structure::Block') ) {
# spent 2.03ms making 1799 calls to UNIVERSAL::isa, avg 1µs/call # spent 367µs making 86 calls to PPI::Structure::List::isa, avg 4µs/call # spent 12µs making 3 calls to PPI::Structure::For::isa, avg 4µs/call
1208 # deference - ${$hash_ref}{foo}
1209 # or even ${burfle}{foo}
1210 # hash slice - @{$hash_ref}{'foo', 'bar'}
121115µs29µs if ( my $prior = $Parent->schild(-2) ) {
# spent 8µs making 1 call to PPI::Node::schild # spent 500ns making 1 call to PPI::Util::TRUE
121212µs11µs my $prior_content = $prior->content();
# spent 1µs making 1 call to PPI::Token::content
121317µs1700ns $prior->isa( 'PPI::Token::Cast' )
# spent 700ns making 1 call to UNIVERSAL::isa
1214 and ( $prior_content eq '@' ||
1215 $prior_content eq '$' )
1216 and return 'PPI::Structure::Subscript';
1217 }
1218 }
121918871.90ms if ( $CURLY_CLASSES{$content} ) {
1220 # Known type
1221 return $CURLY_CLASSES{$content};
1222 }
1223 }
1224
1225 # Are we in a compound statement
1226180311.7ms18031.79ms if ( $Parent->isa('PPI::Statement::Compound') ) {
# spent 1.79ms making 1803 calls to UNIVERSAL::isa, avg 994ns/call
1227 # We will only encounter blocks in compound statements
1228 return 'PPI::Structure::Block';
1229 }
1230
1231 # Are we the second or third argument of use
123212209.48ms12201.55ms if ( $Parent->isa('PPI::Statement::Include') ) {
# spent 1.55ms making 1220 calls to UNIVERSAL::isa, avg 1µs/call
1233 if ( $Parent->schildren == 2 ||
1234 $Parent->schildren == 3 &&
1235 $Parent->schild(2)->isa('PPI::Token::Number')
1236 ) {
1237 # This is something like use constant { ... };
1238 return 'PPI::Structure::Constructor';
1239 }
1240 }
1241
1242 # Unless we are at the start of the statement, everything else should be a block
1243 ### FIXME This is possibly a bad choice, but will have to do for now.
124412205.37ms1159614µs return 'PPI::Structure::Block' if $Element;
# spent 614µs making 1159 calls to PPI::Util::TRUE, avg 530ns/call
1245
1246 # Special case: Are we the param of a core function
1247 # i.e. map({ $_ => 1 } @foo)
124861891µs2981.48ms if (
# spent 669µs making 61 calls to Params::Util::_INSTANCE, avg 11µs/call # spent 366µs making 61 calls to PPI::Element::parent, avg 6µs/call # spent 346µs making 54 calls to PPI::Structure::List::isa, avg 6µs/call # spent 68µs making 68 calls to UNIVERSAL::isa, avg 994ns/call # spent 34µs making 54 calls to PPI::Util::TRUE, avg 626ns/call
1249 $Parent->isa('PPI::Statement')
1250 and
1251 _INSTANCE($Parent->parent, 'PPI::Structure::List')
1252 ) {
125354214µs1621.10ms my $function = $Parent->parent->parent->schild(-2);
# spent 741µs making 54 calls to PPI::Node::schild, avg 14µs/call # spent 356µs making 108 calls to PPI::Element::parent, avg 3µs/call
125454399µs162188µs if ( $function and $function->content =~ /^(?:map|grep|sort)$/ ) {
# spent 81µs making 54 calls to PPI::Lexer::CORE:match, avg 1µs/call # spent 74µs making 54 calls to PPI::Token::content, avg 1µs/call # spent 33µs making 54 calls to PPI::Util::TRUE, avg 611ns/call
1255 return 'PPI::Structure::Block';
1256 }
1257 }
1258
1259 # We need to scan ahead.
12606113µs my $Next;
12616122µs my $position = 0;
12626133µs my @delayed = ();
126361950µs51237.3ms while ( $Next = $self->_get_token ) {
# spent 37.2ms making 256 calls to PPI::Lexer::_get_token, avg 145µs/call # spent 153µs making 256 calls to PPI::Util::TRUE, avg 599ns/call
1264324371µs324328µs unless ( $Next->significant ) {
# spent 202µs making 190 calls to PPI::Token::Whitespace::significant, avg 1µs/call # spent 120µs making 129 calls to PPI::Element::significant, avg 926ns/call # spent 7µs making 5 calls to PPI::Token::Comment::significant, avg 1µs/call
126519564µs push @delayed, $Next;
126619588µs next;
1267 }
1268
1269 # If we are off the end of the lookahead array,
1270129305µs122178µs if ( ++$position >= @CURLY_LOOKAHEAD_CLASSES ) {
# spent 178µs making 122 calls to PPI::Token::content, avg 1µs/call
1271 # default to block.
1272718µs728µs $self->_buffer( splice(@delayed), $Next );
# spent 28µs making 7 calls to PPI::Lexer::_buffer, avg 4µs/call
127374µs last;
1274 # If the content at this position is known
1275 } elsif ( my $class = $CURLY_LOOKAHEAD_CLASSES[$position]
1276 {$Next->content} ) {
1277 # return the associated class.
127854148µs54245µs $self->_buffer( splice(@delayed), $Next );
# spent 245µs making 54 calls to PPI::Lexer::_buffer, avg 5µs/call
127954178µs return $class;
1280 }
1281
1282 # Delay and continue
1283686.05ms136628µs push @delayed, $Next;
# spent 564µs making 68 calls to PPI::Lexer::_get_token, avg 8µs/call # spent 64µs making 68 calls to PPI::Util::TRUE, avg 940ns/call
1284 }
1285
1286 # Hit the end of the document, or bailed out, go with block
1287710µs79µs $self->_buffer( splice(@delayed) );
# spent 9µs making 7 calls to PPI::Lexer::_buffer, avg 1µs/call
1288715µs if ( ref $Parent eq 'PPI::Statement' ) {
1289 bless $Parent, 'PPI::Statement::Compound';
1290 }
1291723µs return 'PPI::Structure::Block';
1292}
1293
1294=pod
1295
1296=begin testing _lex_structure 4
1297
1298# Validate the creation of a null statement
1299SCOPE: {
1300 my $token = new_ok( 'PPI::Token::Structure' => [ ';' ] );
1301 my $null = new_ok( 'PPI::Statement::Null' => [ $token ] );
1302 is( $null->content, ';', '->content ok' );
1303}
1304
1305# Validate the creation of an empty statement
1306new_ok( 'PPI::Statement' => [ ] );
1307
1308=end testing
1309
1310=cut
1311
1312
# spent 9.04s (655ms+8.39) within PPI::Lexer::_lex_structure which was called 5789 times, avg 1.56ms/call: # 5789 times (655ms+8.39s) by PPI::Lexer::_lex_statement at line 655, avg 1.56ms/call
sub _lex_structure {
131357891.34ms my ($self, $Structure) = @_;
1314 # my $self = shift;
1315 # my $Structure = _INSTANCE(shift, 'PPI::Structure') or die "Bad param 1";
1316
1317 # Start the processing loop
13185789686µs my $Token;
1319578938.0ms287723.38s while ( ref($Token = $self->_get_token) ) {
# spent 3.38s making 28772 calls to PPI::Lexer::_get_token, avg 117µs/call
1320 # Is this a direct type token
13212877331.2ms2877328.9ms unless ( $Token->significant ) {
# spent 15.5ms making 14524 calls to PPI::Token::Whitespace::significant, avg 1µs/call # spent 12.3ms making 13303 calls to PPI::Element::significant, avg 923ns/call # spent 1.19ms making 944 calls to PPI::Token::Comment::significant, avg 1µs/call # spent 3µs making 2 calls to PPI::Token::Pod::significant, avg 1µs/call
1322154708.22ms push @{$self->{delayed}}, $Token;
1323 # $self->_delay_element( $Token );
1324154706.15ms next;
1325 }
1326
1327 # Anything other than a Structure starts a Statement
13281330390.4ms1330314.9ms unless ( $Token->isa('PPI::Token::Structure') ) {
# spent 14.9ms making 13303 calls to UNIVERSAL::isa, avg 1µs/call
1329 # Because _statement may well delay and rollback itself,
1330 # we need to add the delayed tokens early
133174328.37ms7432117ms $self->_add_delayed( $Structure );
# spent 117ms making 7432 calls to PPI::Lexer::_add_delayed, avg 16µs/call
1332
1333 # Determine the class for the Statement and create it
1334743223.0ms14864445ms my $Statement = $self->_statement($Structure, $Token)->new($Token);
# spent 259ms making 7432 calls to PPI::Lexer::_statement, avg 35µs/call # spent 186ms making 7432 calls to PPI::Statement::new, avg 25µs/call
1335
1336 # Move the lexing down into the Statement
133774329.27ms743281.2ms $self->_add_element( $Structure, $Statement );
# spent 81.2ms making 7432 calls to PPI::Lexer::_add_element, avg 11µs/call
1338743210.1ms74320s $self->_lex_statement( $Statement );
# spent 11.2s making 7432 calls to PPI::Lexer::_lex_statement, avg 1.51ms/call, recursion: max depth 7, sum of overlapping time 11.2s
1339
134074324.10ms next;
1341 }
1342
1343 # Is this the opening of another structure directly inside us?
134458716.59ms587129.3ms if ( $Token->__LEXER__opens ) {
# spent 29.3ms making 5871 calls to PPI::Token::__LEXER__opens, avg 5µs/call
1345 # Rollback the Token, and recurse into the statement
134681113µs81277µs $self->_rollback( $Token );
# spent 277µs making 81 calls to PPI::Lexer::_rollback, avg 3µs/call
134781150µs81515µs my $Statement = PPI::Statement->new;
# spent 515µs making 81 calls to PPI::Statement::new, avg 6µs/call
134881125µs81811µs $self->_add_element( $Structure, $Statement );
# spent 811µs making 81 calls to PPI::Lexer::_add_element, avg 10µs/call
134981144µs810s $self->_lex_statement( $Statement );
# spent 660ms making 81 calls to PPI::Lexer::_lex_statement, avg 8.14ms/call, recursion: max depth 5, sum of overlapping time 660ms
13508173µs next;
1351 }
1352
1353 # Is this the close of a structure ( which would be an error )
135457906.46ms579036.1ms if ( $Token->__LEXER__closes ) {
# spent 36.1ms making 5790 calls to PPI::Token::__LEXER__closes, avg 6µs/call
1355 # Is this OUR closing structure
1356578920.0ms1736726.3ms if ( $Token->content eq $Structure->start->__LEXER__opposite ) {
# spent 10.0ms making 5789 calls to PPI::Token::Structure::__LEXER__opposite, avg 2µs/call # spent 8.13ms making 5789 calls to PPI::Structure::start, avg 1µs/call # spent 8.10ms making 5789 calls to PPI::Token::content, avg 1µs/call
1357 # Add any delayed tokens, and the finishing token (the ugly way)
135857897.31ms578959.4ms $self->_add_delayed( $Structure );
# spent 59.4ms making 5789 calls to PPI::Lexer::_add_delayed, avg 10µs/call
135957893.25ms $Structure->{finish} = $Token;
1360578941.5ms115789.36ms Scalar::Util::weaken(
# spent 4.99ms making 5789 calls to Scalar::Util::weaken, avg 862ns/call # spent 4.38ms making 5789 calls to Scalar::Util::refaddr, avg 756ns/call
1361 $_PARENT{Scalar::Util::refaddr $Token} = $Structure
1362 );
1363
1364 # Confirm that ForLoop structures are actually so, and
1365 # aren't really a list.
1366578917.6ms578918.8ms if ( $Structure->isa('PPI::Structure::For') ) {
# spent 13.8ms making 2597 calls to PPI::Structure::List::isa, avg 5µs/call # spent 4.59ms making 3103 calls to UNIVERSAL::isa, avg 1µs/call # spent 394µs making 89 calls to PPI::Structure::For::isa, avg 4µs/call
13673294.84ms329457µs if ( 2 > scalar grep {
# spent 245µs making 89 calls to PPI::Node::children, avg 3µs/call # spent 212µs making 240 calls to UNIVERSAL::isa, avg 883ns/call
1368 $_->isa('PPI::Statement')
1369 } $Structure->children ) {
1370 bless($Structure, 'PPI::Structure::List');
1371 }
1372 }
1373578922.5ms return 1;
1374 }
1375
1376 # Unmatched closing brace.
1377 # Either they typed the wrong thing, or haven't put
1378 # one at all. Either way it's an error we need to
1379 # somehow handle gracefully. For now, we'll treat it
1380 # as implicitly ending the structure. This causes the
1381 # least damage across the various reasons why this
1382 # might have happened.
1383 return $self->_rollback( $Token );
1384 }
1385
1386 # It's a semi-colon on it's own, just inside the block.
1387 # This is a null statement.
1388 $self->_add_element(
1389133µs3120µs $Structure,
# spent 103µs making 1 call to PPI::Statement::new # spent 9µs making 1 call to PPI::Lexer::_add_element # spent 8µs making 1 call to PPI::Lexer::_get_token
1390 PPI::Statement::Null->new($Token),
1391 );
1392 }
1393
1394 # Is this an error
1395 unless ( defined $Token ) {
1396 PPI::Exception->throw;
1397 }
1398
1399 # No, it's just the end of file.
1400 # Add any insignificant trailing tokens.
1401 $self->_add_delayed( $Structure );
1402}
1403
- -
1408#####################################################################
1409# Support Methods
1410
1411# Get the next token for processing, handling buffering
1412
# spent 7.26s (459ms+6.80) within PPI::Lexer::_get_token which was called 111133 times, avg 65µs/call: # 61803 times (263ms+2.06s) by PPI::Lexer::_lex_statement at line 606, avg 38µs/call # 28772 times (111ms+3.27s) by PPI::Lexer::_lex_structure at line 1319, avg 117µs/call # 9356 times (40.7ms+1.05s) by PPI::Lexer::_lex_document at line 270, avg 117µs/call # 5789 times (23.0ms+32.9ms) by PPI::Lexer::_lex_statement at line 655, avg 10µs/call # 2044 times (9.93ms+13.7ms) by PPI::Lexer::_statement at line 500, avg 12µs/call # 1962 times (6.26ms+12.7ms) by PPI::Lexer::_statement at line 542, avg 10µs/call # 576 times (1.81ms+319ms) by PPI::Lexer::_lex_end at line 680, avg 557µs/call # 362 times (1.07ms+6.41ms) by PPI::Lexer::_statement at line 429, avg 21µs/call # 256 times (880µs+36.3ms) by PPI::Lexer::_curly at line 1263, avg 145µs/call # 144 times (431µs+684µs) by PPI::Lexer::_lex_end at line 675, avg 8µs/call # 68 times (232µs+333µs) by PPI::Lexer::_curly at line 1283, avg 8µs/call # once (3µs+5µs) by PPI::Lexer::_lex_structure at line 1389
sub _get_token {
1413111133476ms1111336.80s shift(@{$_[0]->{buffer}}) or $_[0]->{Tokenizer}->get_token;
# spent 6.79s making 94513 calls to PPI::Tokenizer::get_token, avg 72µs/call # spent 9.35ms making 16620 calls to PPI::Util::TRUE, avg 563ns/call
1414}
1415
1416# Old long version of the above
1417# my $self = shift;
1418# # First from the buffer
1419# if ( @{$self->{buffer}} ) {
1420# return shift @{$self->{buffer}};
1421# }
1422#
1423# # Then from the Tokenizer
1424# $self->{Tokenizer}->get_token;
1425# }
1426
1427# Delay the addition of a insignificant elements.
1428# This ended up being inlined.
1429# sub _delay_element {
1430# my $self = shift;
1431# my $Element = _INSTANCE(shift, 'PPI::Element') or die "Bad param 1";
1432# push @{ $_[0]->{delayed} }, $_[1];
1433# }
1434
1435# Add an Element to a Node, including any delayed Elements
1436
# spent 944ms (676+268) within PPI::Lexer::_add_element which was called 50565 times, avg 19µs/call: # 23107 times (389ms+182ms) by PPI::Lexer::_lex_statement at line 636, avg 25µs/call # 7432 times (71.0ms+10.2ms) by PPI::Lexer::_lex_structure at line 1337, avg 11µs/call # 6188 times (68.1ms+9.71ms) by PPI::Lexer::_lex_document at line 273, avg 13µs/call # 5789 times (67.2ms+32.3ms) by PPI::Lexer::_lex_statement at line 654, avg 17µs/call # 4943 times (56.6ms+29.2ms) by PPI::Lexer::_lex_statement at line 642, avg 17µs/call # 3018 times (23.2ms+4.36ms) by PPI::Lexer::_lex_document at line 294, avg 9µs/call # 81 times (668µs+143µs) by PPI::Lexer::_lex_structure at line 1348, avg 10µs/call # 6 times (72µs+10µs) by PPI::Lexer::_lex_document at line 305, avg 14µs/call # once (7µs+2µs) by PPI::Lexer::_lex_structure at line 1389
sub _add_element {
14375056512.3ms my ($self, $Parent, $Element) = @_;
1438 # my $self = shift;
1439 # my $Parent = _INSTANCE(shift, 'PPI::Node') or die "Bad param 1";
1440 # my $Element = _INSTANCE(shift, 'PPI::Element') or die "Bad param 2";
1441
1442 # Handle a special case, where a statement is not fully resolved
14435056515.8ms if ( ref $Parent eq 'PPI::Statement' ) {
144468837.88ms688349.4ms my $first = $Parent->schild(0);
# spent 49.4ms making 6883 calls to PPI::Node::schild, avg 7µs/call
144568838.05ms6883106ms my $second = $Parent->schild(1);
# spent 106ms making 6883 calls to PPI::Node::schild, avg 15µs/call
1446688354.4ms1360612.3ms if ( $first and $first->isa('PPI::Token::Label') and ! $second ) {
# spent 7.49ms making 6737 calls to UNIVERSAL::isa, avg 1µs/call # spent 4.48ms making 6803 calls to PPI::Util::TRUE, avg 659ns/call # spent 297µs making 66 calls to PPI::Structure::List::isa, avg 4µs/call
1447 # It's a labelled statement
1448 if ( $STATEMENT_CLASSES{$second->content} ) {
1449 bless $Parent, $STATEMENT_CLASSES{$second->content};
1450 }
1451 }
1452 }
1453
1454 # Add first the delayed, from the front, then the passed element
14555056529.9ms foreach my $el ( @{$self->{delayed}} ) {
145618659133ms3731827.7ms Scalar::Util::weaken(
# spent 14.3ms making 18659 calls to Scalar::Util::weaken, avg 768ns/call # spent 13.3ms making 18659 calls to Scalar::Util::refaddr, avg 714ns/call
1457 $_PARENT{Scalar::Util::refaddr $el} = $Parent
1458 );
1459 # Inlined $Parent->__add_element($el);
1460 }
1461 Scalar::Util::weaken(
146250565357ms10113072.5ms $_PARENT{Scalar::Util::refaddr $Element} = $Parent
# spent 40.1ms making 50565 calls to Scalar::Util::weaken, avg 793ns/call # spent 32.4ms making 50565 calls to Scalar::Util::refaddr, avg 641ns/call
1463 );
14645056541.2ms push @{$Parent->{children}}, @{$self->{delayed}}, $Element;
1465
1466 # Clear the delayed elements
146750565148ms $self->{delayed} = [];
1468}
1469
1470# Specifically just add any delayed tokens, if any.
1471
# spent 231ms (202+28.9) within PPI::Lexer::_add_delayed which was called 22172 times, avg 10µs/call: # 7432 times (100ms+17.1ms) by PPI::Lexer::_lex_structure at line 1331, avg 16µs/call # 5789 times (52.2ms+7.17ms) by PPI::Lexer::_lex_structure at line 1358, avg 10µs/call # 5789 times (39.3ms+4.68ms) by PPI::Lexer::_lex_statement at line 653, avg 8µs/call # 3018 times (9.82ms+0s) by PPI::Lexer::_lex_document at line 293, avg 3µs/call # 144 times (528µs+0s) by PPI::Lexer::_lex_document at line 334, avg 4µs/call
sub _add_delayed {
1472221725.51ms my ($self, $Parent) = @_;
1473 # my $self = shift;
1474 # my $Parent = _INSTANCE(shift, 'PPI::Node') or die "Bad param 1";
1475
1476 # Add any delayed
14772217215.8ms foreach my $el ( @{$self->{delayed}} ) {
147818723156ms3744628.9ms Scalar::Util::weaken(
# spent 15.7ms making 18723 calls to Scalar::Util::weaken, avg 836ns/call # spent 13.3ms making 18723 calls to Scalar::Util::refaddr, avg 708ns/call
1479 $_PARENT{Scalar::Util::refaddr $el} = $Parent
1480 );
1481 # Inlined $Parent->__add_element($el);
1482 }
14832217216.2ms push @{$Parent->{children}}, @{$self->{delayed}};
1484
1485 # Clear the delayed elements
14862217260.4ms $self->{delayed} = [];
1487}
1488
1489# Rollback the delayed tokens, plus any passed. Once all the tokens
1490# have been moved back on to the buffer, the order should be.
1491# <--- @{$self->{delayed}}, @_, @{$self->{buffer}} <----
1492
# spent 24.0ms within PPI::Lexer::_rollback which was called 7887 times, avg 3µs/call: # 4057 times (12.3ms+0s) by PPI::Lexer::_lex_statement at line 616, avg 3µs/call # 1393 times (4.56ms+0s) by PPI::Lexer::_lex_statement at line 626, avg 3µs/call # 1016 times (2.56ms+0s) by PPI::Lexer::_statement at line 514, avg 3µs/call # 981 times (3.41ms+0s) by PPI::Lexer::_statement at line 555, avg 3µs/call # 144 times (276µs+0s) by PPI::Lexer::_lex_end at line 690, avg 2µs/call # 119 times (364µs+0s) by PPI::Lexer::_statement at line 443, avg 3µs/call # 84 times (240µs+0s) by PPI::Lexer::_statement at line 451, avg 3µs/call # 81 times (277µs+0s) by PPI::Lexer::_lex_structure at line 1346, avg 3µs/call # 6 times (17µs+0s) by PPI::Lexer::_lex_document at line 303, avg 3µs/call # 6 times (14µs+0s) by PPI::Lexer::_statement at line 530, avg 2µs/call
sub _rollback {
149378871.96ms my $self = shift;
1494
1495 # First, put any passed objects back
149678877.66ms if ( @_ ) {
1497 unshift @{$self->{buffer}}, splice @_;
1498 }
1499
1500 # Then, put back anything delayed
150178875.25ms if ( @{$self->{delayed}} ) {
1502 unshift @{$self->{buffer}}, splice @{$self->{delayed}};
1503 }
1504
1505788727.6ms 1;
1506}
1507
1508# Partial rollback, just return a single list to the buffer
1509
# spent 282µs within PPI::Lexer::_buffer which was called 68 times, avg 4µs/call: # 54 times (245µs+0s) by PPI::Lexer::_curly at line 1278, avg 5µs/call # 7 times (28µs+0s) by PPI::Lexer::_curly at line 1272, avg 4µs/call # 7 times (9µs+0s) by PPI::Lexer::_curly at line 1287, avg 1µs/call
sub _buffer {
15106823µs my $self = shift;
1511
1512 # Put any passed objects back
151368143µs if ( @_ ) {
1514 unshift @{$self->{buffer}}, splice @_;
1515 }
1516
151768192µs 1;
1518}
1519
- -
1524#####################################################################
1525# Error Handling
1526
1527# Set the error message
1528sub _error {
1529 $errstr = $_[1];
1530 undef;
1531}
1532
1533# Clear the error message.
1534# Returns the object as a convenience.
1535
# spent 373µs within PPI::Lexer::_clear which was called 144 times, avg 3µs/call: # 144 times (373µs+0s) by PPI::Lexer::new at line 122, avg 3µs/call
sub _clear {
1536144107µs $errstr = '';
1537144445µs $_[0];
1538}
1539
1540=pod
1541
1542=head2 errstr
1543
1544For any error that occurs, you can use the C<errstr>, as either
1545a static or object method, to access the error message.
1546
1547If no error occurs for any particular action, C<errstr> will return false.
1548
1549=cut
1550
1551sub errstr {
1552 $errstr;
1553}
1554
- -
1559#####################################################################
1560# PDOM Extensions
1561#
1562# This is something of a future expansion... ignore it for now :)
1563#
1564# use PPI::Statement::Sub ();
1565#
1566# sub PPI::Statement::Sub::__LEXER__normal { '' }
1567
156812µs1;
1569
1570=pod
1571
1572=head1 TO DO
1573
1574- Add optional support for some of the more common source filters
1575
1576- Some additional checks for blessing things into various Statement
1577and Structure subclasses.
1578
1579=head1 SUPPORT
1580
1581See the L<support section|PPI/SUPPORT> in the main module.
1582
1583=head1 AUTHOR
1584
1585Adam Kennedy E<lt>adamk@cpan.orgE<gt>
1586
1587=head1 COPYRIGHT
1588
1589Copyright 2001 - 2011 Adam Kennedy.
1590
1591This program is free software; you can redistribute
1592it and/or modify it under the same terms as Perl itself.
1593
1594The full text of the license can be found in the
1595LICENSE file included with this module.
1596
1597=cut
 
# spent 10.9ms within PPI::Lexer::CORE:match which was called 7181 times, avg 2µs/call: # 4810 times (8.76ms+0s) by PPI::Lexer::_continues at line 716, avg 2µs/call # 1993 times (1.74ms+0s) by PPI::Lexer::_curly at line 1203, avg 873ns/call # 111 times (133µs+0s) by PPI::Lexer::_square at line 1040, avg 1µs/call # 83 times (81µs+0s) by PPI::Lexer::_continues at line 959, avg 973ns/call # 83 times (79µs+0s) by PPI::Lexer::_round at line 999, avg 949ns/call # 54 times (81µs+0s) by PPI::Lexer::_curly at line 1254, avg 1µs/call # 33 times (32µs+0s) by PPI::Lexer::_continues at line 817, avg 970ns/call # 14 times (24µs+0s) by PPI::Lexer::_continues at line 788, avg 2µs/call
sub PPI::Lexer::CORE:match; # opcode