| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPI/Token/Structure.pm |
| Statements | Executed 62429 statements in 160ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 13365 | 1 | 1 | 133ms | 313ms | PPI::Token::Structure::__TOKENIZER__commit |
| 3157 | 1 | 1 | 34.7ms | 69.1ms | PPI::Token::Structure::__TOKENIZER__on_char |
| 5789 | 1 | 1 | 10.0ms | 10.0ms | PPI::Token::Structure::__LEXER__opposite |
| 1 | 1 | 1 | 11µs | 23µs | PPI::Token::Structure::BEGIN@31 |
| 1 | 1 | 1 | 11µs | 11µs | PPI::Token::Structure::BEGIN@35 |
| 1 | 1 | 1 | 8µs | 8µs | PPI::Token::Structure::BEGIN@43 |
| 1 | 1 | 1 | 6µs | 33µs | PPI::Token::Structure::BEGIN@34 |
| 1 | 1 | 1 | 6µs | 45µs | PPI::Token::Structure::BEGIN@42 |
| 1 | 1 | 1 | 4µs | 4µs | PPI::Token::Structure::BEGIN@32 |
| 0 | 0 | 0 | 0s | 0s | PPI::Token::Structure::next_sibling |
| 0 | 0 | 0 | 0s | 0s | PPI::Token::Structure::next_token |
| 0 | 0 | 0 | 0s | 0s | PPI::Token::Structure::previous_sibling |
| 0 | 0 | 0 | 0s | 0s | PPI::Token::Structure::previous_token |
| 0 | 0 | 0 | 0s | 0s | PPI::Token::Structure::snext_sibling |
| 0 | 0 | 0 | 0s | 0s | PPI::Token::Structure::sprevious_sibling |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package PPI::Token::Structure; | ||||
| 2 | |||||
| 3 | =pod | ||||
| 4 | |||||
| 5 | =head1 NAME | ||||
| 6 | |||||
| 7 | PPI::Token::Structure - Token class for characters that define code structure | ||||
| 8 | |||||
| 9 | =head1 INHERITANCE | ||||
| 10 | |||||
| 11 | PPI::Token::Structure | ||||
| 12 | isa PPI::Token | ||||
| 13 | isa PPI::Element | ||||
| 14 | |||||
| 15 | =head1 DESCRIPTION | ||||
| 16 | |||||
| 17 | The C<PPI::Token::Structure> class is used for tokens that control the | ||||
| 18 | generally tree structure or code. | ||||
| 19 | |||||
| 20 | This consists of seven characters. These are the six brace characters from | ||||
| 21 | the "round", "curly" and "square" pairs, plus the semi-colon statement | ||||
| 22 | separator C<;>. | ||||
| 23 | |||||
| 24 | =head1 METHODS | ||||
| 25 | |||||
| 26 | This class has no methods beyond what is provided by its | ||||
| 27 | L<PPI::Token> and L<PPI::Element> parent classes. | ||||
| 28 | |||||
| 29 | =cut | ||||
| 30 | |||||
| 31 | 2 | 18µs | 2 | 34µs | # spent 23µs (11+12) within PPI::Token::Structure::BEGIN@31 which was called:
# once (11µs+12µs) by PPI::Token::BEGIN@68 at line 31 # spent 23µs making 1 call to PPI::Token::Structure::BEGIN@31
# spent 12µs making 1 call to strict::import |
| 32 | 2 | 23µs | 1 | 4µs | # spent 4µs within PPI::Token::Structure::BEGIN@32 which was called:
# once (4µs+0s) by PPI::Token::BEGIN@68 at line 32 # spent 4µs making 1 call to PPI::Token::Structure::BEGIN@32 |
| 33 | |||||
| 34 | 2 | 30µs | 2 | 60µs | # spent 33µs (6+27) within PPI::Token::Structure::BEGIN@34 which was called:
# once (6µs+27µs) by PPI::Token::BEGIN@68 at line 34 # spent 33µs making 1 call to PPI::Token::Structure::BEGIN@34
# spent 27µs making 1 call to vars::import |
| 35 | # spent 11µs within PPI::Token::Structure::BEGIN@35 which was called:
# once (11µs+0s) by PPI::Token::BEGIN@68 at line 38 | ||||
| 36 | 1 | 300ns | $VERSION = '1.215'; | ||
| 37 | 1 | 12µs | @ISA = 'PPI::Token'; | ||
| 38 | 1 | 18µs | 1 | 11µs | } # spent 11µs making 1 call to PPI::Token::Structure::BEGIN@35 |
| 39 | |||||
| 40 | # Set the matching braces, done as an array | ||||
| 41 | # for slightly faster lookups. | ||||
| 42 | 2 | 83µs | 2 | 84µs | # spent 45µs (6+39) within PPI::Token::Structure::BEGIN@42 which was called:
# once (6µs+39µs) by PPI::Token::BEGIN@68 at line 42 # spent 45µs making 1 call to PPI::Token::Structure::BEGIN@42
# spent 39µs making 1 call to vars::import |
| 43 | # spent 8µs within PPI::Token::Structure::BEGIN@43 which was called:
# once (8µs+0s) by PPI::Token::BEGIN@68 at line 58 | ||||
| 44 | 1 | 600ns | $MATCH[ord '{'] = '}'; | ||
| 45 | 1 | 3µs | $MATCH[ord '}'] = '{'; | ||
| 46 | 1 | 200ns | $MATCH[ord '['] = ']'; | ||
| 47 | 1 | 100ns | $MATCH[ord ']'] = '['; | ||
| 48 | 1 | 200ns | $MATCH[ord '('] = ')'; | ||
| 49 | 1 | 100ns | $MATCH[ord ')'] = '('; | ||
| 50 | |||||
| 51 | 1 | 300ns | $OPENS[ord '{'] = 1; | ||
| 52 | 1 | 100ns | $OPENS[ord '['] = 1; | ||
| 53 | 1 | 0s | $OPENS[ord '('] = 1; | ||
| 54 | |||||
| 55 | 1 | 200ns | $CLOSES[ord '}'] = 1; | ||
| 56 | 1 | 0s | $CLOSES[ord ']'] = 1; | ||
| 57 | 1 | 4µs | $CLOSES[ord ')'] = 1; | ||
| 58 | 1 | 325µs | 1 | 8µs | } # spent 8µs making 1 call to PPI::Token::Structure::BEGIN@43 |
| 59 | |||||
| - - | |||||
| 64 | ##################################################################### | ||||
| 65 | # Tokenizer Methods | ||||
| 66 | |||||
| 67 | # spent 69.1ms (34.7+34.5) within PPI::Token::Structure::__TOKENIZER__on_char which was called 3157 times, avg 22µs/call:
# 3157 times (34.7ms+34.5ms) by PPI::Tokenizer::_process_next_char at line 554 of PPI/Tokenizer.pm, avg 22µs/call | ||||
| 68 | # Structures are one character long, always. | ||||
| 69 | # Finalize and process again. | ||||
| 70 | 3157 | 33.7ms | 6314 | 34.5ms | $_[1]->_finalize_token->__TOKENIZER__on_char( $_[1] ); # spent 27.6ms making 3157 calls to PPI::Token::Whitespace::__TOKENIZER__on_char, avg 9µs/call
# spent 6.88ms making 3157 calls to PPI::Tokenizer::_finalize_token, avg 2µs/call |
| 71 | } | ||||
| 72 | |||||
| 73 | # spent 313ms (133+180) within PPI::Token::Structure::__TOKENIZER__commit which was called 13365 times, avg 23µs/call:
# 13365 times (133ms+180ms) by PPI::Token::Whitespace::__TOKENIZER__on_char at line 206 of PPI/Token/Whitespace.pm, avg 23µs/call | ||||
| 74 | 13365 | 2.37ms | my $t = $_[1]; | ||
| 75 | 13365 | 24.9ms | 13365 | 150ms | $t->_new_token( 'Structure', substr( $t->{line}, $t->{line_cursor}, 1 ) ); # spent 150ms making 13365 calls to PPI::Tokenizer::_new_token, avg 11µs/call |
| 76 | 13365 | 12.7ms | 13365 | 29.4ms | $t->_finalize_token; # spent 29.4ms making 13365 calls to PPI::Tokenizer::_finalize_token, avg 2µs/call |
| 77 | 13365 | 53.5ms | 0; | ||
| 78 | } | ||||
| 79 | |||||
| - - | |||||
| 84 | ##################################################################### | ||||
| 85 | # Lexer Methods | ||||
| 86 | |||||
| 87 | # For a given brace, find its opposing pair | ||||
| 88 | # spent 10.0ms within PPI::Token::Structure::__LEXER__opposite which was called 5789 times, avg 2µs/call:
# 5789 times (10.0ms+0s) by PPI::Lexer::_lex_structure at line 1356 of PPI/Lexer.pm, avg 2µs/call | ||||
| 89 | 5789 | 32.3ms | $MATCH[ord $_[0]->{content} ]; | ||
| 90 | } | ||||
| 91 | |||||
| - - | |||||
| 96 | ##################################################################### | ||||
| 97 | # PPI::Element Methods | ||||
| 98 | |||||
| 99 | # There is a unusual situation in regards to "siblings". | ||||
| 100 | # | ||||
| 101 | # As an Element, braces sit outside the normal tree structure, and in | ||||
| 102 | # this context they NEVER have siblings. | ||||
| 103 | # | ||||
| 104 | # However, as tokens they DO have siblings. | ||||
| 105 | # | ||||
| 106 | # As such, we need special versions of _all_ of the sibling methods to | ||||
| 107 | # handle this. | ||||
| 108 | # | ||||
| 109 | # Statement terminators do not have these problems, and for them sibling | ||||
| 110 | # calls work as normal, and so they can just be passed upwards. | ||||
| 111 | |||||
| 112 | sub next_sibling { | ||||
| 113 | return $_[0]->SUPER::next_sibling if $_[0]->{content} eq ';'; | ||||
| 114 | return ''; | ||||
| 115 | } | ||||
| 116 | |||||
| 117 | sub snext_sibling { | ||||
| 118 | return $_[0]->SUPER::snext_sibling if $_[0]->{content} eq ';'; | ||||
| 119 | return ''; | ||||
| 120 | } | ||||
| 121 | |||||
| 122 | sub previous_sibling { | ||||
| 123 | return $_[0]->SUPER::previous_sibling if $_[0]->{content} eq ';'; | ||||
| 124 | return ''; | ||||
| 125 | } | ||||
| 126 | |||||
| 127 | sub sprevious_sibling { | ||||
| 128 | return $_[0]->SUPER::sprevious_sibling if $_[0]->{content} eq ';'; | ||||
| 129 | return ''; | ||||
| 130 | } | ||||
| 131 | |||||
| 132 | sub next_token { | ||||
| 133 | my $self = shift; | ||||
| 134 | return $self->SUPER::next_token if $self->{content} eq ';'; | ||||
| 135 | my $structure = $self->parent or return ''; | ||||
| 136 | |||||
| 137 | # If this is an opening brace, descend down into our parent | ||||
| 138 | # structure, if it has children. | ||||
| 139 | if ( $OPENS[ ord $self->{content} ] ) { | ||||
| 140 | my $child = $structure->child(0); | ||||
| 141 | if ( $child ) { | ||||
| 142 | # Decend deeper, or return if it is a token | ||||
| 143 | return $child->isa('PPI::Token') ? $child : $child->first_token; | ||||
| 144 | } elsif ( $structure->finish ) { | ||||
| 145 | # Empty structure, so next is closing brace | ||||
| 146 | return $structure->finish; | ||||
| 147 | } | ||||
| 148 | |||||
| 149 | # Anything that slips through to here is a structure | ||||
| 150 | # with an opening brace, but no closing brace, so we | ||||
| 151 | # just have to go with it, and continue as we would | ||||
| 152 | # if we started with a closing brace. | ||||
| 153 | } | ||||
| 154 | |||||
| 155 | # We can use the default implement, if we call it from the | ||||
| 156 | # parent structure of the closing brace. | ||||
| 157 | $structure->next_token; | ||||
| 158 | } | ||||
| 159 | |||||
| 160 | sub previous_token { | ||||
| 161 | my $self = shift; | ||||
| 162 | return $self->SUPER::previous_token if $self->{content} eq ';'; | ||||
| 163 | my $structure = $self->parent or return ''; | ||||
| 164 | |||||
| 165 | # If this is a closing brace, descend down into our parent | ||||
| 166 | # structure, if it has children. | ||||
| 167 | if ( $CLOSES[ ord $self->{content} ] ) { | ||||
| 168 | my $child = $structure->child(-1); | ||||
| 169 | if ( $child ) { | ||||
| 170 | # Decend deeper, or return if it is a token | ||||
| 171 | return $child->isa('PPI::Token') ? $child : $child->last_token; | ||||
| 172 | } elsif ( $structure->start ) { | ||||
| 173 | # Empty structure, so next is closing brace | ||||
| 174 | return $structure->start; | ||||
| 175 | } | ||||
| 176 | |||||
| 177 | # Anything that slips through to here is a structure | ||||
| 178 | # with a closing brace, but no opening brace, so we | ||||
| 179 | # just have to go with it, and continue as we would | ||||
| 180 | # if we started with a opening brace. | ||||
| 181 | } | ||||
| 182 | |||||
| 183 | # We can use the default implement, if we call it from the | ||||
| 184 | # parent structure of the closing brace. | ||||
| 185 | $structure->previous_token; | ||||
| 186 | } | ||||
| 187 | |||||
| 188 | 1 | 2µs | 1; | ||
| 189 | |||||
| 190 | =pod | ||||
| 191 | |||||
| 192 | =head1 SUPPORT | ||||
| 193 | |||||
| 194 | See the L<support section|PPI/SUPPORT> in the main module. | ||||
| 195 | |||||
| 196 | =head1 AUTHOR | ||||
| 197 | |||||
| 198 | Adam Kennedy E<lt>adamk@cpan.orgE<gt> | ||||
| 199 | |||||
| 200 | =head1 COPYRIGHT | ||||
| 201 | |||||
| 202 | Copyright 2001 - 2011 Adam Kennedy. | ||||
| 203 | |||||
| 204 | This program is free software; you can redistribute | ||||
| 205 | it and/or modify it under the same terms as Perl itself. | ||||
| 206 | |||||
| 207 | The full text of the license can be found in the | ||||
| 208 | LICENSE file included with this module. | ||||
| 209 | |||||
| 210 | =cut |