1 package PPI::Token::Structure;
7 PPI::Token::Structure - Token class for characters that define code structure
17 The C<PPI::Token::Structure> class is used for tokens that control the
18 generally tree structure or code.
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
26 This class has no methods beyond what is provided by its
27 L<PPI::Token> and L<PPI::Element> parent classes.
34 use vars qw{$VERSION @ISA};
40 # Set the matching braces, done as an array
41 # for slightly faster lookups.
42 use vars qw{@MATCH @OPENS @CLOSES};
44 $MATCH[ord '{'] = '}';
45 $MATCH[ord '}'] = '{';
46 $MATCH[ord '['] = ']';
47 $MATCH[ord ']'] = '[';
48 $MATCH[ord '('] = ')';
49 $MATCH[ord ')'] = '(';
64 #####################################################################
67 sub __TOKENIZER__on_char {
68 # Structures are one character long, always.
69 # Finalize and process again.
70 $_[1]->_finalize_token->__TOKENIZER__on_char( $_[1] );
73 sub __TOKENIZER__commit {
75 $t->_new_token( 'Structure', substr( $t->{line}, $t->{line_cursor}, 1 ) );
84 #####################################################################
87 # For a given brace, find its opposing pair
88 sub __LEXER__opposite {
89 $MATCH[ord $_[0]->{content} ];
96 #####################################################################
97 # PPI::Element Methods
99 # There is a unusual situation in regards to "siblings".
101 # As an Element, braces sit outside the normal tree structure, and in
102 # this context they NEVER have siblings.
104 # However, as tokens they DO have siblings.
106 # As such, we need special versions of _all_ of the sibling methods to
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.
113 return $_[0]->SUPER::next_sibling if $_[0]->{content} eq ';';
118 return $_[0]->SUPER::snext_sibling if $_[0]->{content} eq ';';
122 sub previous_sibling {
123 return $_[0]->SUPER::previous_sibling if $_[0]->{content} eq ';';
127 sub sprevious_sibling {
128 return $_[0]->SUPER::sprevious_sibling if $_[0]->{content} eq ';';
134 return $self->SUPER::next_token if $self->{content} eq ';';
135 my $structure = $self->parent or return '';
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);
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;
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.
155 # We can use the default implement, if we call it from the
156 # parent structure of the closing brace.
157 $structure->next_token;
162 return $self->SUPER::previous_token if $self->{content} eq ';';
163 my $structure = $self->parent or return '';
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);
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;
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.
183 # We can use the default implement, if we call it from the
184 # parent structure of the closing brace.
185 $structure->previous_token;
194 See the L<support section|PPI/SUPPORT> in the main module.
198 Adam Kennedy E<lt>adamk@cpan.orgE<gt>
202 Copyright 2001 - 2009 Adam Kennedy.
204 This program is free software; you can redistribute
205 it and/or modify it under the same terms as Perl itself.
207 The full text of the license can be found in the
208 LICENSE file included with this module.