| 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 | PPI::Statement::Variable::type |
| 1299 | 1 | 1 | 1.72ms | 1.72ms | PPI::Statement::Variable::CORE:match (opcode) |
| 1 | 1 | 1 | 22µs | 22µs | PPI::Statement::Variable::BEGIN@46 |
| 1 | 1 | 1 | 11µs | 23µs | PPI::Statement::Variable::BEGIN@41 |
| 1 | 1 | 1 | 7µs | 28µs | PPI::Statement::Variable::BEGIN@42 |
| 1 | 1 | 1 | 6µs | 33µs | PPI::Statement::Variable::BEGIN@45 |
| 1 | 1 | 1 | 3µs | 3µs | PPI::Statement::Variable::BEGIN@43 |
| 0 | 0 | 0 | 0s | 0s | PPI::Statement::Variable::_local_variable |
| 0 | 0 | 0 | 0s | 0s | PPI::Statement::Variable::symbols |
| 0 | 0 | 0 | 0s | 0s | PPI::Statement::Variable::variables |
| 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 |