Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Token/Magic.pm |
Statements | Executed 366 statements in 1.66ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 1.11ms | 1.20ms | BEGIN@46 | PPI::Token::Magic::
34 | 1 | 1 | 805µs | 1.61ms | __TOKENIZER__on_char | PPI::Token::Magic::
134 | 7 | 1 | 90µs | 90µs | CORE:match (opcode) | PPI::Token::Magic::
30 | 1 | 1 | 89µs | 89µs | CORE:regcomp (opcode) | PPI::Token::Magic::
1 | 1 | 1 | 56µs | 56µs | BEGIN@49 | PPI::Token::Magic::
1 | 1 | 1 | 11µs | 23µs | BEGIN@44 | PPI::Token::Magic::
1 | 1 | 1 | 7µs | 45µs | BEGIN@48 | PPI::Token::Magic::
1 | 1 | 1 | 3µs | 3µs | BEGIN@45 | PPI::Token::Magic::
0 | 0 | 0 | 0s | 0s | canonical | PPI::Token::Magic::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package PPI::Token::Magic; | ||||
2 | |||||
3 | =pod | ||||
4 | |||||
5 | =head1 NAME | ||||
6 | |||||
7 | PPI::Token::Magic - Tokens representing magic variables | ||||
8 | |||||
9 | =head1 INHERITANCE | ||||
10 | |||||
11 | PPI::Token::Magic | ||||
12 | isa PPI::Token::Symbol | ||||
13 | isa PPI::Token | ||||
14 | isa PPI::Element | ||||
15 | |||||
16 | =head1 SYNOPSIS | ||||
17 | |||||
18 | # When we say magic variables, we mean these... | ||||
19 | $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||||
20 | $_ $& $` $' $+ @+ %+ $* $. $/ $| | ||||
21 | $\\ $" $; $% $= $- @- %- $) $# | ||||
22 | $~ $^ $: $? $! %! $@ $$ $< $> | ||||
23 | $( $0 $[ $] @_ @* $} $, $#+ $#- | ||||
24 | $^L $^A $^E $^C $^D $^F $^H | ||||
25 | $^I $^M $^N $^O $^P $^R $^S | ||||
26 | $^T $^V $^W $^X | ||||
27 | |||||
28 | =head1 DESCRIPTION | ||||
29 | |||||
30 | C<PPI::Token::Magic> is a sub-class of L<PPI::Token::Symbol> which | ||||
31 | identifies the token as "magic variable", one of the strange and | ||||
32 | unusual variables that are connected to "things" behind the scenes. | ||||
33 | |||||
34 | Some are extremely common, like C<$_>, and others you will quite | ||||
35 | probably never encounter in your Perl career. | ||||
36 | |||||
37 | =head1 METHODS | ||||
38 | |||||
39 | The class provides no additional methods, beyond those provided by it's | ||||
40 | L<PPI::Token::Symbol>, L<PPI::Token> and L<PPI::Element>. | ||||
41 | |||||
42 | =cut | ||||
43 | |||||
44 | 2 | 22µs | 2 | 35µs | # spent 23µs (11+12) within PPI::Token::Magic::BEGIN@44 which was called:
# once (11µs+12µs) by PPI::Token::BEGIN@53 at line 44 # spent 23µs making 1 call to PPI::Token::Magic::BEGIN@44
# spent 12µs making 1 call to strict::import |
45 | 2 | 15µs | 1 | 3µs | # spent 3µs within PPI::Token::Magic::BEGIN@45 which was called:
# once (3µs+0s) by PPI::Token::BEGIN@53 at line 45 # spent 3µs making 1 call to PPI::Token::Magic::BEGIN@45 |
46 | 2 | 95µs | 1 | 1.20ms | # spent 1.20ms (1.11+88µs) within PPI::Token::Magic::BEGIN@46 which was called:
# once (1.11ms+88µs) by PPI::Token::BEGIN@53 at line 46 # spent 1.20ms making 1 call to PPI::Token::Magic::BEGIN@46 |
47 | |||||
48 | 2 | 71µs | 2 | 82µs | # spent 45µs (7+38) within PPI::Token::Magic::BEGIN@48 which was called:
# once (7µs+38µs) by PPI::Token::BEGIN@53 at line 48 # spent 45µs making 1 call to PPI::Token::Magic::BEGIN@48
# spent 38µs making 1 call to vars::import |
49 | # spent 56µs within PPI::Token::Magic::BEGIN@49 which was called:
# once (56µs+0s) by PPI::Token::BEGIN@53 at line 70 | ||||
50 | 1 | 400ns | $VERSION = '1.215'; | ||
51 | 1 | 6µs | @ISA = 'PPI::Token::Symbol'; | ||
52 | |||||
53 | # Magic variables taken from perlvar. | ||||
54 | # Several things added separately to avoid warnings. | ||||
55 | 1 | 5µs | foreach ( qw{ | ||
56 | $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||||
57 | $_ $& $` $' $+ @+ %+ $* $. $/ $| | ||||
58 | $\\ $" $; $% $= $- @- %- $) | ||||
59 | $~ $^ $: $? $! %! $@ $$ $< $> | ||||
60 | $( $0 $[ $] @_ @* | ||||
61 | |||||
62 | $^L $^A $^E $^C $^D $^F $^H | ||||
63 | $^I $^M $^N $^O $^P $^R $^S | ||||
64 | $^T $^V $^W $^X %^H | ||||
65 | |||||
66 | $::| | ||||
67 | }, '$}', '$,', '$#', '$#+', '$#-' ) { | ||||
68 | 70 | 33µs | $magic{$_} = 1; | ||
69 | } | ||||
70 | 1 | 537µs | 1 | 56µs | } # spent 56µs making 1 call to PPI::Token::Magic::BEGIN@49 |
71 | |||||
72 | =pod | ||||
73 | |||||
74 | =begin testing __TOKENIZER_on_char 30 | ||||
75 | |||||
76 | my $document = PPI::Document->new(\<<'END_PERL'); | ||||
77 | $[; # Magic $[ | ||||
78 | $$; # Magic $$ | ||||
79 | %-; # Magic %- | ||||
80 | $#-; # Magic $#- | ||||
81 | $$foo; # Symbol $foo Dereference of $foo | ||||
82 | $^W; # Magic $^W | ||||
83 | $^WIDE_SYSTEM_CALLS; # Magic $^WIDE_SYSTEM_CALLS | ||||
84 | ${^MATCH}; # Magic ${^MATCH} | ||||
85 | @{^_Bar}; # Magic @{^_Bar} | ||||
86 | ${^_Bar}[0]; # Magic @{^_Bar} | ||||
87 | %{^_Baz}; # Magic %{^_Baz} | ||||
88 | ${^_Baz}{burfle}; # Magic %{^_Baz} | ||||
89 | $${^MATCH}; # Magic ${^MATCH} Dereference of ${^MATCH} | ||||
90 | \${^MATCH}; # Magic ${^MATCH} | ||||
91 | END_PERL | ||||
92 | |||||
93 | isa_ok( $document, 'PPI::Document' ); | ||||
94 | |||||
95 | $document->index_locations(); | ||||
96 | |||||
97 | my $symbols = $document->find( 'PPI::Token::Symbol' ); | ||||
98 | |||||
99 | is( scalar(@$symbols), 14, 'Found 14 symbols' ); | ||||
100 | my $comments = $document->find( 'PPI::Token::Comment' ); | ||||
101 | |||||
102 | foreach my $token ( @$symbols ) { | ||||
103 | my ($hash, $class, $name, $remk) = | ||||
104 | split '\s+', $comments->[$token->line_number - 1], 4; | ||||
105 | isa_ok( $token, "PPI::Token::$class" ); | ||||
106 | is( $token->symbol, $name, $remk || "The symbol is $name" ); | ||||
107 | } | ||||
108 | |||||
109 | =end testing | ||||
110 | |||||
111 | =cut | ||||
112 | |||||
113 | # spent 1.61ms (805µs+807µs) within PPI::Token::Magic::__TOKENIZER__on_char which was called 34 times, avg 47µs/call:
# 34 times (805µs+807µs) by PPI::Tokenizer::_process_next_char at line 554 of PPI/Tokenizer.pm, avg 47µs/call | ||||
114 | 34 | 11µs | my $t = $_[1]; | ||
115 | |||||
116 | # $c is the candidate new content | ||||
117 | 34 | 48µs | my $c = $t->{token}->{content} . substr( $t->{line}, $t->{line_cursor}, 1 ); | ||
118 | |||||
119 | # Do a quick first test so we don't have to do more than this one. | ||||
120 | # All of the tests below match this one, so it should provide a | ||||
121 | # small speed up. This regex should be updated to match the inside | ||||
122 | # tests if they are changed. | ||||
123 | 34 | 175µs | 59 | 58µs | if ( $c =~ /^ \$ .* [ \w : \$ \{ ] $/x ) { # spent 58µs making 59 calls to PPI::Token::Magic::CORE:match, avg 986ns/call |
124 | |||||
125 | 9 | 45µs | 18 | 11µs | if ( $c =~ /^(\$(?:\_[\w:]|::))/ or $c =~ /^\$\'[\w]/ ) { # spent 11µs making 18 calls to PPI::Token::Magic::CORE:match, avg 589ns/call |
126 | # If and only if we have $'\d, it is not a | ||||
127 | # symbol. (this was apparently a concious choice) | ||||
128 | # Note that $::0 on the other hand is legal | ||||
129 | if ( $c =~ /^\$\'\d$/ ) { | ||||
130 | # In this case, we have a magic plus a digit. | ||||
131 | # Save the CURRENT token, and rerun the on_char | ||||
132 | return $t->_finalize_token->__TOKENIZER__on_char( $t ); | ||||
133 | } | ||||
134 | |||||
135 | # A symbol in the style $_foo or $::foo or $'foo. | ||||
136 | # Overwrite the current token | ||||
137 | $t->{class} = $t->{token}->set_class('Symbol'); | ||||
138 | return PPI::Token::Symbol->__TOKENIZER__on_char( $t ); | ||||
139 | } | ||||
140 | |||||
141 | 9 | 32µs | 9 | 3µs | if ( $c =~ /^\$\$\w/ ) { # spent 3µs making 9 calls to PPI::Token::Magic::CORE:match, avg 344ns/call |
142 | # This is really a scalar dereference. ( $$foo ) | ||||
143 | # Add the current token as the cast... | ||||
144 | $t->{token} = PPI::Token::Cast->new( '$' ); | ||||
145 | $t->_finalize_token; | ||||
146 | |||||
147 | # ... and create a new token for the symbol | ||||
148 | return $t->_new_token( 'Symbol', '$' ); | ||||
149 | } | ||||
150 | |||||
151 | 9 | 4µs | if ( $c eq '$${' ) { | ||
152 | # This _might_ be a dereference of one of the | ||||
153 | # control-character symbols. | ||||
154 | my $line = substr $t->{line}, $t->{line_cursor} + 1; | ||||
155 | if ( $line =~ m/$PPI::Token::Unknown::CURLY_SYMBOL/ ) { | ||||
156 | # This is really a dereference. ( $${^_foo} ) | ||||
157 | # Add the current token as the cast... | ||||
158 | $t->{token} = PPI::Token::Cast->new( '$' ); | ||||
159 | $t->_finalize_token; | ||||
160 | |||||
161 | # ... and create a new token for the symbol | ||||
162 | return $t->_new_token( 'Magic', '$' ); | ||||
163 | } | ||||
164 | } | ||||
165 | |||||
166 | 9 | 5µs | if ( $c eq '$#$' or $c eq '$#{' ) { | ||
167 | # This is really an index dereferencing cast, although | ||||
168 | # it has the same two chars as the magic variable $#. | ||||
169 | 1 | 6µs | 1 | 8µs | $t->{class} = $t->{token}->set_class('Cast'); # spent 8µs making 1 call to PPI::Token::set_class |
170 | 1 | 5µs | 2 | 21µs | return $t->_finalize_token->__TOKENIZER__on_char( $t ); # spent 19µs making 1 call to PPI::Token::Whitespace::__TOKENIZER__on_char
# spent 2µs making 1 call to PPI::Tokenizer::_finalize_token |
171 | } | ||||
172 | |||||
173 | 8 | 37µs | 8 | 5µs | if ( $c =~ /^(\$\#)\w/ ) { # spent 5µs making 8 calls to PPI::Token::Magic::CORE:match, avg 588ns/call |
174 | # This is really an array index thingy ( $#array ) | ||||
175 | 3 | 22µs | 3 | 9µs | $t->{token} = PPI::Token::ArrayIndex->new( "$1" ); # spent 9µs making 3 calls to PPI::Token::new, avg 3µs/call |
176 | 3 | 19µs | 6 | 167µs | return PPI::Token::ArrayIndex->__TOKENIZER__on_char( $t ); # spent 150µs making 3 calls to PPI::Token::ArrayIndex::__TOKENIZER__on_char, avg 50µs/call
# spent 17µs making 3 calls to PPI::Element::DESTROY, avg 6µs/call |
177 | } | ||||
178 | |||||
179 | 5 | 13µs | 5 | 2µs | if ( $c =~ /^\$\^\w+$/o ) { # spent 2µs making 5 calls to PPI::Token::Magic::CORE:match, avg 320ns/call |
180 | # It's an escaped char magic... maybe ( like $^M ) | ||||
181 | my $next = substr( $t->{line}, $t->{line_cursor}+1, 1 ); # Peek ahead | ||||
182 | if ($magic{$c} && (!$next || $next !~ /\w/)) { | ||||
183 | $t->{token}->{content} = $c; | ||||
184 | $t->{line_cursor}++; | ||||
185 | } else { | ||||
186 | # Maybe it's a long magic variable like $^WIDE_SYSTEM_CALLS | ||||
187 | return 1; | ||||
188 | } | ||||
189 | } | ||||
190 | |||||
191 | 5 | 14µs | 5 | 2µs | if ( $c =~ /^\$\#\{/ ) { # spent 2µs making 5 calls to PPI::Token::Magic::CORE:match, avg 360ns/call |
192 | # The $# is actually a case, and { is its block | ||||
193 | # Add the current token as the cast... | ||||
194 | $t->{token} = PPI::Token::Cast->new( '$#' ); | ||||
195 | $t->_finalize_token; | ||||
196 | |||||
197 | # ... and create a new token for the block | ||||
198 | return $t->_new_token( 'Structure', '{' ); | ||||
199 | } | ||||
200 | } elsif ($c =~ /^%\^/) { | ||||
201 | return 1 if $c eq '%^'; | ||||
202 | # It's an escaped char magic... maybe ( like %^H ) | ||||
203 | if ($magic{$c}) { | ||||
204 | $t->{token}->{content} = $c; | ||||
205 | $t->{line_cursor}++; | ||||
206 | } else { | ||||
207 | # Back off, treat '%' as an operator | ||||
208 | chop $t->{token}->{content}; | ||||
209 | bless $t->{token}, $t->{class} = 'PPI::Token::Operator'; | ||||
210 | $t->{line_cursor}--; | ||||
211 | } | ||||
212 | } | ||||
213 | |||||
214 | 30 | 19µs | if ( $magic{$c} ) { | ||
215 | # $#+ and $#- | ||||
216 | $t->{line_cursor} += length( $c ) - length( $t->{token}->{content} ); | ||||
217 | $t->{token}->{content} = $c; | ||||
218 | } else { | ||||
219 | 30 | 26µs | my $line = substr( $t->{line}, $t->{line_cursor} ); | ||
220 | 30 | 245µs | 60 | 99µs | if ( $line =~ /($PPI::Token::Unknown::CURLY_SYMBOL)/ ) { # spent 89µs making 30 calls to PPI::Token::Magic::CORE:regcomp, avg 3µs/call
# spent 10µs making 30 calls to PPI::Token::Magic::CORE:match, avg 330ns/call |
221 | # control character symbol (e.g. ${^MATCH}) | ||||
222 | $t->{token}->{content} .= $1; | ||||
223 | $t->{line_cursor} += length $1; | ||||
224 | } | ||||
225 | } | ||||
226 | |||||
227 | # End the current magic token, and recheck | ||||
228 | 30 | 148µs | 60 | 423µs | $t->_finalize_token->__TOKENIZER__on_char( $t ); # spent 318µs making 30 calls to PPI::Token::Whitespace::__TOKENIZER__on_char, avg 11µs/call
# spent 105µs making 30 calls to PPI::Tokenizer::_finalize_token, avg 4µs/call |
229 | } | ||||
230 | |||||
231 | # Our version of canonical is plain simple | ||||
232 | sub canonical { $_[0]->content } | ||||
233 | |||||
234 | 1 | 2µs | 1; | ||
235 | |||||
236 | =pod | ||||
237 | |||||
238 | =head1 SUPPORT | ||||
239 | |||||
240 | See the L<support section|PPI/SUPPORT> in the main module. | ||||
241 | |||||
242 | =head1 AUTHOR | ||||
243 | |||||
244 | Adam Kennedy E<lt>adamk@cpan.orgE<gt> | ||||
245 | |||||
246 | =head1 COPYRIGHT | ||||
247 | |||||
248 | Copyright 2001 - 2011 Adam Kennedy. | ||||
249 | |||||
250 | This program is free software; you can redistribute | ||||
251 | it and/or modify it under the same terms as Perl itself. | ||||
252 | |||||
253 | The full text of the license can be found in the | ||||
254 | LICENSE file included with this module. | ||||
255 | |||||
256 | =cut | ||||
# spent 90µs within PPI::Token::Magic::CORE:match which was called 134 times, avg 671ns/call:
# 59 times (58µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 123, avg 986ns/call
# 30 times (10µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 220, avg 330ns/call
# 18 times (11µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 125, avg 589ns/call
# 9 times (3µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 141, avg 344ns/call
# 8 times (5µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 173, avg 588ns/call
# 5 times (2µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 191, avg 360ns/call
# 5 times (2µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 179, avg 320ns/call | |||||
# spent 89µs within PPI::Token::Magic::CORE:regcomp which was called 30 times, avg 3µs/call:
# 30 times (89µs+0s) by PPI::Token::Magic::__TOKENIZER__on_char at line 220, avg 3µs/call |