Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Statement/Variable.pm |
Statements | Executed 17427 statements in 54.9ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1299 | 1 | 1 | 65.2ms | 97.6ms | type | PPI::Statement::Variable::
1299 | 1 | 1 | 1.72ms | 1.72ms | CORE:match (opcode) | PPI::Statement::Variable::
1 | 1 | 1 | 22µs | 22µs | BEGIN@46 | PPI::Statement::Variable::
1 | 1 | 1 | 11µs | 23µs | BEGIN@41 | PPI::Statement::Variable::
1 | 1 | 1 | 7µs | 28µs | BEGIN@42 | PPI::Statement::Variable::
1 | 1 | 1 | 6µs | 33µs | BEGIN@45 | PPI::Statement::Variable::
1 | 1 | 1 | 3µs | 3µs | BEGIN@43 | PPI::Statement::Variable::
0 | 0 | 0 | 0s | 0s | _local_variable | PPI::Statement::Variable::
0 | 0 | 0 | 0s | 0s | symbols | PPI::Statement::Variable::
0 | 0 | 0 | 0s | 0s | variables | PPI::Statement::Variable::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package PPI::Statement::Variable; | ||||
2 | |||||
3 | =pod | ||||
4 | |||||
5 | =head1 NAME | ||||
6 | |||||
7 | PPI::Statement::Variable - Variable declaration statements | ||||
8 | |||||
9 | =head1 SYNOPSIS | ||||
10 | |||||
11 | # All of the following are variable declarations | ||||
12 | my $foo = 1; | ||||
13 | my ($foo, $bar) = (1, 2); | ||||
14 | our $foo = 1; | ||||
15 | local $foo; | ||||
16 | local $foo = 1; | ||||
17 | LABEL: my $foo = 1; | ||||
18 | |||||
19 | =head1 INHERITANCE | ||||
20 | |||||
21 | PPI::Statement::Variable | ||||
22 | isa PPI::Statement::Expression | ||||
23 | isa PPI::Statement | ||||
24 | isa PPI::Node | ||||
25 | isa PPI::Element | ||||
26 | |||||
27 | =head1 DESCRIPTION | ||||
28 | |||||
29 | The main intent of the C<PPI::Statement::Variable> class is to describe | ||||
30 | simple statements that explicitly declare new local or global variables. | ||||
31 | |||||
32 | Note that this does not make it exclusively the only place where variables | ||||
33 | are defined, and later on you should expect that the C<variables> method | ||||
34 | will migrate deeper down the tree to either L<PPI::Statement> or | ||||
35 | L<PPI::Node> to recognise this fact, but for now it stays here. | ||||
36 | |||||
37 | =head1 METHODS | ||||
38 | |||||
39 | =cut | ||||
40 | |||||
41 | 2 | 23µs | 2 | 34µs | # spent 23µs (11+11) within PPI::Statement::Variable::BEGIN@41 which was called:
# once (11µs+11µs) by PPI::Statement::BEGIN@175 at line 41 # spent 23µs making 1 call to PPI::Statement::Variable::BEGIN@41
# spent 11µs making 1 call to strict::import |
42 | 2 | 18µs | 2 | 48µs | # spent 28µs (7+21) within PPI::Statement::Variable::BEGIN@42 which was called:
# once (7µs+21µs) by PPI::Statement::BEGIN@175 at line 42 # spent 28µs making 1 call to PPI::Statement::Variable::BEGIN@42
# spent 21µs making 1 call to Exporter::import |
43 | 2 | 18µs | 1 | 3µs | # spent 3µs within PPI::Statement::Variable::BEGIN@43 which was called:
# once (3µs+0s) by PPI::Statement::BEGIN@175 at line 43 # spent 3µs making 1 call to PPI::Statement::Variable::BEGIN@43 |
44 | |||||
45 | 2 | 37µs | 2 | 60µs | # spent 33µs (6+27) within PPI::Statement::Variable::BEGIN@45 which was called:
# once (6µs+27µs) by PPI::Statement::BEGIN@175 at line 45 # spent 33µs making 1 call to PPI::Statement::Variable::BEGIN@45
# spent 27µs making 1 call to vars::import |
46 | # spent 22µs within PPI::Statement::Variable::BEGIN@46 which was called:
# once (22µs+0s) by PPI::Statement::BEGIN@175 at line 49 | ||||
47 | 1 | 300ns | $VERSION = '1.215'; | ||
48 | 1 | 23µs | @ISA = 'PPI::Statement::Expression'; | ||
49 | 1 | 374µs | 1 | 22µs | } # spent 22µs making 1 call to PPI::Statement::Variable::BEGIN@46 |
50 | |||||
51 | =pod | ||||
52 | |||||
53 | =head2 type | ||||
54 | |||||
55 | The C<type> method checks and returns the declaration type of the statement, | ||||
56 | which will be one of 'my', 'local', 'our', or 'state'. | ||||
57 | |||||
58 | Returns a string of the type, or C<undef> if the type cannot be detected | ||||
59 | (which is probably a bug). | ||||
60 | |||||
61 | =cut | ||||
62 | |||||
63 | # spent 97.6ms (65.2+32.4) within PPI::Statement::Variable::type which was called 1299 times, avg 75µs/call:
# 1299 times (65.2ms+32.4ms) by Perl::Critic::Policy::Variables::ProhibitConditionalDeclarations::violates at line 36 of Perl/Critic/Policy/Variables/ProhibitConditionalDeclarations.pm, avg 75µs/call | ||||
64 | 1299 | 214µs | my $self = shift; | ||
65 | |||||
66 | # Get the first significant child | ||||
67 | 13519 | 16.1ms | 13519 | 12.8ms | my @schild = grep { $_->significant } $self->children; # spent 6.27ms making 7986 calls to PPI::Element::significant, avg 785ns/call
# spent 3.87ms making 4232 calls to PPI::Token::Whitespace::significant, avg 915ns/call
# spent 2.67ms making 1299 calls to PPI::Node::children, avg 2µs/call
# spent 3µs making 2 calls to PPI::Token::Comment::significant, avg 2µs/call |
68 | |||||
69 | # Ignore labels | ||||
70 | 1299 | 10.9ms | 2598 | 10.4ms | shift @schild if _INSTANCE($schild[0], 'PPI::Token::Label'); # spent 8.81ms making 1299 calls to Params::Util::_INSTANCE, avg 7µs/call
# spent 1.60ms making 1299 calls to UNIVERSAL::isa, avg 1µs/call |
71 | |||||
72 | # Get the type | ||||
73 | 1299 | 27.2ms | 7794 | 11.5ms | (_INSTANCE($schild[0], 'PPI::Token::Word') and $schild[0]->content =~ /^(my|local|our|state)$/) # spent 4.59ms making 1299 calls to Params::Util::_INSTANCE, avg 4µs/call
# spent 3.66ms making 2598 calls to PPI::Token::content, avg 1µs/call
# spent 1.72ms making 1299 calls to PPI::Statement::Variable::CORE:match, avg 1µs/call
# spent 797µs making 1299 calls to PPI::Util::TRUE, avg 613ns/call
# spent 762µs making 1299 calls to UNIVERSAL::isa, avg 586ns/call |
74 | ? $schild[0]->content | ||||
75 | : undef; | ||||
76 | } | ||||
77 | |||||
78 | =pod | ||||
79 | |||||
80 | =head2 variables | ||||
81 | |||||
82 | As for several other PDOM Element types that can declare variables, the | ||||
83 | C<variables> method returns a list of the canonical forms of the variables | ||||
84 | defined by the statement. | ||||
85 | |||||
86 | Returns a list of the canonical string forms of variables, or the null list | ||||
87 | if it is unable to find any variables. | ||||
88 | |||||
89 | =begin testing variables | ||||
90 | |||||
91 | # Test the things we assert to work in the synopsis | ||||
92 | my $Document = PPI::Document->new(\<<'END_PERL'); | ||||
93 | package Bar; | ||||
94 | my $foo = 1; | ||||
95 | my ( $foo, $bar) = (1, 2); | ||||
96 | our $foo = 1; | ||||
97 | local $foo; | ||||
98 | local $foo = 1; | ||||
99 | LABEL: my $foo = 1; | ||||
100 | |||||
101 | # As well as those basics, lets also try some harder ones | ||||
102 | local($foo = $bar->$bar(), $bar); | ||||
103 | END_PERL | ||||
104 | isa_ok( $Document, 'PPI::Document' ); | ||||
105 | |||||
106 | # There should be 6 statement objects | ||||
107 | my $ST = $Document->find('Statement::Variable'); | ||||
108 | is( ref($ST), 'ARRAY', 'Found statements' ); | ||||
109 | is( scalar(@$ST), 7, 'Found 7 ::Variable objects' ); | ||||
110 | foreach my $Var ( @$ST ) { | ||||
111 | isa_ok( $Var, 'PPI::Statement::Variable' ); | ||||
112 | } | ||||
113 | is_deeply( [ $ST->[0]->variables ], [ '$foo' ], '1: Found $foo' ); | ||||
114 | is_deeply( [ $ST->[1]->variables ], [ '$foo', '$bar' ], '2: Found $foo and $bar' ); | ||||
115 | is_deeply( [ $ST->[2]->variables ], [ '$foo' ], '3: Found $foo' ); | ||||
116 | is_deeply( [ $ST->[3]->variables ], [ '$foo' ], '4: Found $foo' ); | ||||
117 | is_deeply( [ $ST->[4]->variables ], [ '$foo' ], '5: Found $foo' ); | ||||
118 | is_deeply( [ $ST->[5]->variables ], [ '$foo' ], '6: Found $foo' ); | ||||
119 | is_deeply( [ $ST->[6]->variables ], [ '$foo', '$bar' ], '7: Found $foo and $bar' ); | ||||
120 | |||||
121 | =end testing | ||||
122 | |||||
123 | =cut | ||||
124 | |||||
125 | sub variables { | ||||
126 | map { $_->canonical } $_[0]->symbols; | ||||
127 | } | ||||
128 | |||||
129 | =pod | ||||
130 | |||||
131 | =head2 symbols | ||||
132 | |||||
133 | Returns a list of the variables defined by the statement, as | ||||
134 | L<PPI::Token::Symbol>s. | ||||
135 | |||||
136 | =cut | ||||
137 | |||||
138 | sub symbols { | ||||
139 | my $self = shift; | ||||
140 | |||||
141 | # Get the children we care about | ||||
142 | my @schild = grep { $_->significant } $self->children; | ||||
143 | shift @schild if _INSTANCE($schild[0], 'PPI::Token::Label'); | ||||
144 | |||||
145 | # If the second child is a symbol, return its name | ||||
146 | if ( _INSTANCE($schild[1], 'PPI::Token::Symbol') ) { | ||||
147 | return $schild[1]; | ||||
148 | } | ||||
149 | |||||
150 | # If it's a list, return as a list | ||||
151 | if ( _INSTANCE($schild[1], 'PPI::Structure::List') ) { | ||||
152 | my $Expression = $schild[1]->schild(0); | ||||
153 | $Expression and | ||||
154 | $Expression->isa('PPI::Statement::Expression') or return (); | ||||
155 | |||||
156 | # my and our are simpler than local | ||||
157 | if ( | ||||
158 | $self->type eq 'my' | ||||
159 | or | ||||
160 | $self->type eq 'our' | ||||
161 | or | ||||
162 | $self->type eq 'state' | ||||
163 | ) { | ||||
164 | return grep { | ||||
165 | $_->isa('PPI::Token::Symbol') | ||||
166 | } $Expression->schildren; | ||||
167 | } | ||||
168 | |||||
169 | # Local is much more icky (potentially). | ||||
170 | # Not that we are actually going to deal with it now, | ||||
171 | # but having this seperate is likely going to be needed | ||||
172 | # for future bug reports about local() things. | ||||
173 | |||||
174 | # This is a slightly better way to check. | ||||
175 | return grep { | ||||
176 | $self->_local_variable($_) | ||||
177 | } grep { | ||||
178 | $_->isa('PPI::Token::Symbol') | ||||
179 | } $Expression->schildren; | ||||
180 | } | ||||
181 | |||||
182 | # erm... this is unexpected | ||||
183 | (); | ||||
184 | } | ||||
185 | |||||
186 | sub _local_variable { | ||||
187 | my ($self, $el) = @_; | ||||
188 | |||||
189 | # The last symbol should be a variable | ||||
190 | my $n = $el->snext_sibling or return 1; | ||||
191 | my $p = $el->sprevious_sibling; | ||||
192 | if ( ! $p or $p eq ',' ) { | ||||
193 | # In the middle of a list | ||||
194 | return 1 if $n eq ','; | ||||
195 | |||||
196 | # The first half of an assignment | ||||
197 | return 1 if $n eq '='; | ||||
198 | } | ||||
199 | |||||
200 | # Lets say no for know... additional work | ||||
201 | # should go here. | ||||
202 | return ''; | ||||
203 | } | ||||
204 | |||||
205 | 1 | 2µs | 1; | ||
206 | |||||
207 | =pod | ||||
208 | |||||
209 | =head1 TO DO | ||||
210 | |||||
211 | - Write unit tests for this | ||||
212 | |||||
213 | =head1 SUPPORT | ||||
214 | |||||
215 | See the L<support section|PPI/SUPPORT> in the main module. | ||||
216 | |||||
217 | =head1 AUTHOR | ||||
218 | |||||
219 | Adam Kennedy E<lt>adamk@cpan.orgE<gt> | ||||
220 | |||||
221 | =head1 COPYRIGHT | ||||
222 | |||||
223 | Copyright 2001 - 2011 Adam Kennedy. | ||||
224 | |||||
225 | This program is free software; you can redistribute | ||||
226 | it and/or modify it under the same terms as Perl itself. | ||||
227 | |||||
228 | The full text of the license can be found in the | ||||
229 | LICENSE file included with this module. | ||||
230 | |||||
231 | =cut | ||||
# spent 1.72ms within PPI::Statement::Variable::CORE:match which was called 1299 times, avg 1µs/call:
# 1299 times (1.72ms+0s) by PPI::Statement::Variable::type at line 73, avg 1µs/call |