Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Token/Symbol.pm |
Statements | Executed 97704 statements in 203ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
7754 | 1 | 1 | 211ms | 362ms | __TOKENIZER__on_char | PPI::Token::Symbol::
29489 | 4 | 1 | 26.9ms | 26.9ms | CORE:match (opcode) | PPI::Token::Symbol::
1 | 1 | 1 | 11µs | 23µs | BEGIN@30 | PPI::Token::Symbol::
1 | 1 | 1 | 8µs | 8µs | BEGIN@35 | PPI::Token::Symbol::
1 | 1 | 1 | 7µs | 28µs | BEGIN@31 | PPI::Token::Symbol::
1 | 1 | 1 | 6µs | 34µs | BEGIN@34 | PPI::Token::Symbol::
1 | 1 | 1 | 3µs | 3µs | BEGIN@32 | PPI::Token::Symbol::
0 | 0 | 0 | 0s | 0s | canonical | PPI::Token::Symbol::
0 | 0 | 0 | 0s | 0s | raw_type | PPI::Token::Symbol::
0 | 0 | 0 | 0s | 0s | symbol | PPI::Token::Symbol::
0 | 0 | 0 | 0s | 0s | symbol_type | PPI::Token::Symbol::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package PPI::Token::Symbol; | ||||
2 | |||||
3 | =pod | ||||
4 | |||||
5 | =head1 NAME | ||||
6 | |||||
7 | PPI::Token::Symbol - A token class for variables and other symbols | ||||
8 | |||||
9 | =head1 INHERITANCE | ||||
10 | |||||
11 | PPI::Token::Symbol | ||||
12 | isa PPI::Token | ||||
13 | isa PPI::Element | ||||
14 | |||||
15 | =head1 DESCRIPTION | ||||
16 | |||||
17 | The C<PPI::Token::Symbol> class is used to cover all tokens that represent | ||||
18 | variables and other things that start with a sigil. | ||||
19 | |||||
20 | =head1 METHODS | ||||
21 | |||||
22 | This class has several methods beyond what is provided by its | ||||
23 | L<PPI::Token> and L<PPI::Element> parent classes. | ||||
24 | |||||
25 | Most methods are provided to help work out what the object is actually | ||||
26 | pointing at, rather than what it might appear to be pointing at. | ||||
27 | |||||
28 | =cut | ||||
29 | |||||
30 | 2 | 28µs | 2 | 35µs | # spent 23µs (11+12) within PPI::Token::Symbol::BEGIN@30 which was called:
# once (11µs+12µs) by PPI::Token::BEGIN@51 at line 30 # spent 23µs making 1 call to PPI::Token::Symbol::BEGIN@30
# spent 12µs making 1 call to strict::import |
31 | 2 | 28µs | 2 | 48µs | # spent 28µs (7+21) within PPI::Token::Symbol::BEGIN@31 which was called:
# once (7µs+21µs) by PPI::Token::BEGIN@51 at line 31 # spent 28µs making 1 call to PPI::Token::Symbol::BEGIN@31
# spent 21µs making 1 call to Exporter::import |
32 | 2 | 19µs | 1 | 3µs | # spent 3µs within PPI::Token::Symbol::BEGIN@32 which was called:
# once (3µs+0s) by PPI::Token::BEGIN@51 at line 32 # spent 3µs making 1 call to PPI::Token::Symbol::BEGIN@32 |
33 | |||||
34 | 2 | 41µs | 2 | 63µs | # spent 34µs (6+28) within PPI::Token::Symbol::BEGIN@34 which was called:
# once (6µs+28µs) by PPI::Token::BEGIN@51 at line 34 # spent 34µs making 1 call to PPI::Token::Symbol::BEGIN@34
# spent 28µs making 1 call to vars::import |
35 | # spent 8µs within PPI::Token::Symbol::BEGIN@35 which was called:
# once (8µs+0s) by PPI::Token::BEGIN@51 at line 38 | ||||
36 | 1 | 300ns | $VERSION = '1.215'; | ||
37 | 1 | 9µs | @ISA = 'PPI::Token'; | ||
38 | 1 | 528µs | 1 | 8µs | } # spent 8µs making 1 call to PPI::Token::Symbol::BEGIN@35 |
39 | |||||
- - | |||||
44 | ##################################################################### | ||||
45 | # PPI::Token::Symbol Methods | ||||
46 | |||||
47 | =pod | ||||
48 | |||||
49 | =head2 canonical | ||||
50 | |||||
51 | The C<canonical> method returns a normalized, canonical version of the | ||||
52 | symbol. | ||||
53 | |||||
54 | For example, it converts C<$ ::foo'bar::baz> to C<$main::foo::bar::baz>. | ||||
55 | |||||
56 | This does not fully resolve the symbol, but merely removes syntax | ||||
57 | variations. | ||||
58 | |||||
59 | =cut | ||||
60 | |||||
61 | sub canonical { | ||||
62 | my $symbol = shift->content; | ||||
63 | $symbol =~ s/\s+//; | ||||
64 | $symbol =~ s/(?<=[\$\@\%\&\*])::/main::/; | ||||
65 | $symbol =~ s/\'/::/g; | ||||
66 | $symbol; | ||||
67 | } | ||||
68 | |||||
69 | =pod | ||||
70 | |||||
71 | =head2 symbol | ||||
72 | |||||
73 | The C<symbol> method returns the ACTUAL symbol this token refers to. | ||||
74 | |||||
75 | A token of C<$foo> might actually be referring to C<@foo>, if it is found | ||||
76 | in the form C<$foo[1]>. | ||||
77 | |||||
78 | This method attempts to resolve these issues to determine the actual | ||||
79 | symbol. | ||||
80 | |||||
81 | Returns the symbol as a string. | ||||
82 | |||||
83 | =cut | ||||
84 | |||||
85 | 1 | 3µs | my %cast_which_trumps_braces = map { $_ => 1 } qw{ $ @ }; | ||
86 | |||||
87 | sub symbol { | ||||
88 | my $self = shift; | ||||
89 | my $symbol = $self->canonical; | ||||
90 | |||||
91 | # Immediately return the cases where it can't be anything else | ||||
92 | my $type = substr( $symbol, 0, 1 ); | ||||
93 | return $symbol if $type eq '%'; | ||||
94 | return $symbol if $type eq '&'; | ||||
95 | |||||
96 | # Unless the next significant Element is a structure, it's correct. | ||||
97 | my $after = $self->snext_sibling; | ||||
98 | return $symbol unless _INSTANCE($after, 'PPI::Structure'); | ||||
99 | |||||
100 | # Process the rest for cases where it might actually be something else | ||||
101 | my $braces = $after->braces; | ||||
102 | return $symbol unless defined $braces; | ||||
103 | if ( $type eq '$' ) { | ||||
104 | |||||
105 | # If it is cast to '$' or '@', that trumps any braces | ||||
106 | my $before = $self->sprevious_sibling; | ||||
107 | return $symbol if $before && | ||||
108 | $before->isa( 'PPI::Token::Cast' ) && | ||||
109 | $cast_which_trumps_braces{ $before->content }; | ||||
110 | |||||
111 | # Otherwise the braces rule | ||||
112 | substr( $symbol, 0, 1, '@' ) if $braces eq '[]'; | ||||
113 | substr( $symbol, 0, 1, '%' ) if $braces eq '{}'; | ||||
114 | |||||
115 | } elsif ( $type eq '@' ) { | ||||
116 | substr( $symbol, 0, 1, '%' ) if $braces eq '{}'; | ||||
117 | |||||
118 | } | ||||
119 | |||||
120 | $symbol; | ||||
121 | } | ||||
122 | |||||
123 | =pod | ||||
124 | |||||
125 | =head2 raw_type | ||||
126 | |||||
127 | The C<raw_type> method returns the B<apparent> type of the symbol in the | ||||
128 | form of its sigil. | ||||
129 | |||||
130 | Returns the sigil as a string. | ||||
131 | |||||
132 | =cut | ||||
133 | |||||
134 | sub raw_type { | ||||
135 | substr( $_[0]->content, 0, 1 ); | ||||
136 | } | ||||
137 | |||||
138 | =pod | ||||
139 | |||||
140 | =head2 symbol_type | ||||
141 | |||||
142 | The C<symbol_type> method returns the B<actual> type of the symbol in the | ||||
143 | form of its sigil. | ||||
144 | |||||
145 | Returns the sigil as a string. | ||||
146 | |||||
147 | =cut | ||||
148 | |||||
149 | sub symbol_type { | ||||
150 | substr( $_[0]->symbol, 0, 1 ); | ||||
151 | } | ||||
152 | |||||
- - | |||||
157 | ##################################################################### | ||||
158 | # Tokenizer Methods | ||||
159 | |||||
160 | # spent 362ms (211+151) within PPI::Token::Symbol::__TOKENIZER__on_char which was called 7754 times, avg 47µs/call:
# 7754 times (211ms+151ms) by PPI::Tokenizer::_process_next_char at line 554 of PPI/Tokenizer.pm, avg 47µs/call | ||||
161 | 7754 | 1.32ms | my $t = $_[1]; | ||
162 | |||||
163 | # Suck in till the end of the symbol | ||||
164 | 7754 | 3.84ms | my $line = substr( $t->{line}, $t->{line_cursor} ); | ||
165 | 7754 | 40.4ms | 7754 | 8.72ms | if ( $line =~ /^([\w:\']+)/ ) { # spent 8.72ms making 7754 calls to PPI::Token::Symbol::CORE:match, avg 1µs/call |
166 | 7217 | 7.16ms | $t->{token}->{content} .= $1; | ||
167 | 7217 | 3.74ms | $t->{line_cursor} += length $1; | ||
168 | } | ||||
169 | |||||
170 | # Handle magic things | ||||
171 | 7754 | 3.17ms | my $content = $t->{token}->{content}; | ||
172 | 7754 | 2.09ms | if ( $content eq '@_' or $content eq '$_' ) { | ||
173 | 509 | 949µs | 509 | 4.07ms | $t->{class} = $t->{token}->set_class( 'Magic' ); # spent 4.07ms making 509 calls to PPI::Token::set_class, avg 8µs/call |
174 | 509 | 2.08ms | 1018 | 10.8ms | return $t->_finalize_token->__TOKENIZER__on_char( $t ); # spent 9.48ms making 509 calls to PPI::Token::Whitespace::__TOKENIZER__on_char, avg 19µs/call
# spent 1.33ms making 509 calls to PPI::Tokenizer::_finalize_token, avg 3µs/call |
175 | } | ||||
176 | |||||
177 | # Shortcut for most of the X:: symbols | ||||
178 | 7245 | 411µs | if ( $content eq '$::' ) { | ||
179 | # May well be an alternate form of a Magic | ||||
180 | my $nextchar = substr( $t->{line}, $t->{line_cursor}, 1 ); | ||||
181 | if ( $nextchar eq '|' ) { | ||||
182 | $t->{token}->{content} .= $nextchar; | ||||
183 | $t->{line_cursor}++; | ||||
184 | $t->{class} = $t->{token}->set_class( 'Magic' ); | ||||
185 | } | ||||
186 | return $t->_finalize_token->__TOKENIZER__on_char( $t ); | ||||
187 | } | ||||
188 | 7245 | 25.2ms | 7245 | 2.54ms | if ( $content =~ /^[\$%*@&]::(?:[^\w]|$)/ ) { # spent 2.54ms making 7245 calls to PPI::Token::Symbol::CORE:match, avg 351ns/call |
189 | my $current = substr( $content, 0, 3, '' ); | ||||
190 | $t->{token}->{content} = $current; | ||||
191 | $t->{line_cursor} -= length( $content ); | ||||
192 | return $t->_finalize_token->__TOKENIZER__on_char( $t ); | ||||
193 | } | ||||
194 | 7245 | 24.0ms | 7245 | 5.42ms | if ( $content =~ /^(?:\$|\@)\d+/ ) { # spent 5.42ms making 7245 calls to PPI::Token::Symbol::CORE:match, avg 748ns/call |
195 | $t->{class} = $t->{token}->set_class( 'Magic' ); | ||||
196 | return $t->_finalize_token->__TOKENIZER__on_char( $t ); | ||||
197 | } | ||||
198 | |||||
199 | # Trim off anything we oversucked... | ||||
200 | 7245 | 35.1ms | 7245 | 10.3ms | $content =~ /^( # spent 10.3ms making 7245 calls to PPI::Token::Symbol::CORE:match, avg 1µs/call |
201 | [\$@%&*] | ||||
202 | (?: : (?!:) | # Allow single-colon non-magic vars | ||||
203 | (?: \w+ | \' (?!\d) \w+ | \:: \w+ ) | ||||
204 | (?: | ||||
205 | # Allow both :: and ' in namespace separators | ||||
206 | (?: \' (?!\d) \w+ | \:: \w+ ) | ||||
207 | )* | ||||
208 | (?: :: )? # Technically a compiler-magic hash, but keep it here | ||||
209 | ) | ||||
210 | )/x or return undef; | ||||
211 | 7245 | 4.82ms | unless ( length $1 eq length $content ) { | ||
212 | $t->{line_cursor} += length($1) - length($content); | ||||
213 | $t->{token}->{content} = $1; | ||||
214 | } | ||||
215 | |||||
216 | 7245 | 48.0ms | 14490 | 110ms | $t->_finalize_token->__TOKENIZER__on_char( $t ); # spent 88.5ms making 7245 calls to PPI::Token::Whitespace::__TOKENIZER__on_char, avg 12µs/call
# spent 21.2ms making 7245 calls to PPI::Tokenizer::_finalize_token, avg 3µs/call |
217 | } | ||||
218 | |||||
219 | 1 | 3µs | 1; | ||
220 | |||||
221 | =pod | ||||
222 | |||||
223 | =head1 SUPPORT | ||||
224 | |||||
225 | See the L<support section|PPI/SUPPORT> in the main module. | ||||
226 | |||||
227 | =head1 AUTHOR | ||||
228 | |||||
229 | Adam Kennedy E<lt>adamk@cpan.orgE<gt> | ||||
230 | |||||
231 | =head1 COPYRIGHT | ||||
232 | |||||
233 | Copyright 2001 - 2011 Adam Kennedy. | ||||
234 | |||||
235 | This program is free software; you can redistribute | ||||
236 | it and/or modify it under the same terms as Perl itself. | ||||
237 | |||||
238 | The full text of the license can be found in the | ||||
239 | LICENSE file included with this module. | ||||
240 | |||||
241 | =cut | ||||
# spent 26.9ms within PPI::Token::Symbol::CORE:match which was called 29489 times, avg 914ns/call:
# 7754 times (8.72ms+0s) by PPI::Token::Symbol::__TOKENIZER__on_char at line 165, avg 1µs/call
# 7245 times (10.3ms+0s) by PPI::Token::Symbol::__TOKENIZER__on_char at line 200, avg 1µs/call
# 7245 times (5.42ms+0s) by PPI::Token::Symbol::__TOKENIZER__on_char at line 194, avg 748ns/call
# 7245 times (2.54ms+0s) by PPI::Token::Symbol::__TOKENIZER__on_char at line 188, avg 351ns/call |