File Coverage

blib/lib/PPI/Token.pm
Criterion Covered Total %
statement 150 157 95.5
branch 14 26 53.8
condition n/a
subroutine 53 53 100.0
pod 6 8 75.0
total 223 244 91.3


line stmt bran cond sub pod time code
1             package PPI::Token;
2              
3             =pod
4              
5             =head1 NAME
6              
7             PPI::Token - A single token of Perl source code
8              
9             =head1 INHERITANCE
10              
11             PPI::Token
12             isa PPI::Element
13              
14             =head1 DESCRIPTION
15              
16             C is the abstract base class for all Tokens. In PPI terms, a "Token" is
17             a L that directly represents bytes of source code.
18              
19             =head1 METHODS
20              
21             =cut
22              
23 67     67   480 use strict;
  67         152  
  67         3341  
24 67     67   880 use Params::Util qw{_INSTANCE};
  67         6583  
  67         6314  
25 67     67   941 use PPI::Element ();
  67         134  
  67         1284  
26 67     67   895 use PPI::Exception ();
  67         153  
  67         4007  
27              
28             our $VERSION = '1.28401'; # TRIAL
29              
30             our @ISA = 'PPI::Element';
31              
32             # We don't load the abstracts, they are loaded
33             # as part of the inheritance process.
34              
35             # Load the token classes
36 67     67   33997 use PPI::Token::BOM ();
  67         204  
  67         6375  
37 67     67   38156 use PPI::Token::Whitespace ();
  67         309  
  67         2854  
38 67     67   33071 use PPI::Token::Comment ();
  67         212  
  67         2105  
39 67     67   32016 use PPI::Token::Pod ();
  67         246  
  67         2346  
40 67     67   32704 use PPI::Token::Number ();
  67         215  
  67         2425  
41 67     67   34189 use PPI::Token::Number::Binary ();
  67         219  
  67         2343  
42 67     67   32939 use PPI::Token::Number::Octal ();
  67         275  
  67         2357  
43 67     67   31833 use PPI::Token::Number::Hex ();
  67         209  
  67         2470  
44 67     67   34728 use PPI::Token::Number::Float ();
  67         234  
  67         2741  
45 67     67   38203 use PPI::Token::Number::Exp ();
  67         200  
  67         2680  
46 67     67   38543 use PPI::Token::Number::Version ();
  67         244  
  67         3131  
47 67     67   37201 use PPI::Token::Word ();
  67         385  
  67         3159  
48 67     67   32639 use PPI::Token::DashedWord ();
  67         233  
  67         3190  
49 67     67   34678 use PPI::Token::Symbol ();
  67         232  
  67         3622  
50 67     67   31251 use PPI::Token::ArrayIndex ();
  67         556  
  67         3528  
51 67     67   32056 use PPI::Token::Magic ();
  67         281  
  67         3890  
52 67     67   37105 use PPI::Token::Quote::Single ();
  67         264  
  67         3997  
53 67     67   36915 use PPI::Token::Quote::Double ();
  67         237  
  67         3809  
54 67     67   35742 use PPI::Token::Quote::Literal ();
  67         225  
  67         4864  
55 67     67   42024 use PPI::Token::Quote::Interpolate ();
  67         248  
  67         3766  
56 67     67   34868 use PPI::Token::QuoteLike::Backtick ();
  67         222  
  67         3809  
57 67     67   33570 use PPI::Token::QuoteLike::Command ();
  67         213  
  67         3898  
58 67     67   33671 use PPI::Token::QuoteLike::Regexp ();
  67         222  
  67         3876  
59 67     67   34178 use PPI::Token::QuoteLike::Words ();
  67         207  
  67         4232  
60 67     67   36470 use PPI::Token::QuoteLike::Readline ();
  67         218  
  67         4453  
61 67     67   36376 use PPI::Token::Regexp::Match ();
  67         206  
  67         4143  
62 67     67   32915 use PPI::Token::Regexp::Substitute ();
  67         205  
  67         3919  
63 67     67   34034 use PPI::Token::Regexp::Transliterate ();
  67         206  
  67         4487  
64 67     67   35253 use PPI::Token::Operator ();
  67         236  
  67         4902  
65 67     67   32608 use PPI::Token::Cast ();
  67         232  
  67         15492  
66 67     67   32648 use PPI::Token::Structure ();
  67         234  
  67         5248  
67 67     67   33227 use PPI::Token::Label ();
  67         220  
  67         5456  
68 67     67   50756 use PPI::Token::HereDoc ();
  67         449  
  67         5788  
69 67     67   31481 use PPI::Token::Separator ();
  67         226  
  67         4686  
70 67     67   33401 use PPI::Token::Data ();
  67         276  
  67         7158  
71 67     67   45257 use PPI::Token::End ();
  67         250  
  67         5935  
72 67     67   33390 use PPI::Token::Prototype ();
  67         226  
  67         5419  
73 67     67   31230 use PPI::Token::Attribute ();
  67         251  
  67         5722  
74 67     67   490 use PPI::Token::Unknown ();
  67         159  
  67         78591  
75              
76              
77              
78              
79              
80             #####################################################################
81             # Constructor and Related
82              
83             sub new {
84 377654 50   377654 0 5006396 bless { content => (defined $_[1] ? "$_[1]" : '') }, $_[0];
85             }
86              
87             sub set_class {
88 35479     35479 0 72345 my $self = shift;
89             # @_ or throw Exception("No arguments to set_class");
90 35479 50       118218 my $class = substr( $_[0], 0, 12 ) eq 'PPI::Token::' ? shift : 'PPI::Token::' . shift;
91              
92             # Find out if the current and new classes are complex
93 35479 50       182432 my $old_quote = (ref($self) =~ /\b(?:Quote|Regex)\b/o) ? 1 : 0;
94 35479 50       116622 my $new_quote = ($class =~ /\b(?:Quote|Regex)\b/o) ? 1 : 0;
95              
96             # No matter what happens, we will have to rebless
97 35479         87302 bless $self, $class;
98              
99             # If we are changing to or from a Quote style token, we
100             # can't just rebless and need to do some extra thing
101             # Otherwise, we have done enough
102 35479 50       151109 return $class if ($old_quote - $new_quote) == 0;
103              
104             # Make a new token from the old content, and overwrite the current
105             # token's attributes with the new token's attributes.
106 0         0 my $token = $class->new( $self->{content} );
107 0         0 %$self = %$token;
108              
109             # Return the class as a convenience
110 0         0 return $class;
111             }
112              
113              
114              
115              
116              
117             #####################################################################
118             # PPI::Token Methods
119              
120             =pod
121              
122             =head2 set_content $string
123              
124             The C method allows you to set/change the string that the
125             C object represents.
126              
127             Returns the string you set the Token to
128              
129             =cut
130              
131             sub set_content {
132 1     1 1 8 $_[0]->{content} = $_[1];
133             }
134              
135             =pod
136              
137             =head2 add_content $string
138              
139             The C method allows you to add additional bytes of code
140             to the end of the Token.
141              
142             Returns the new full string after the bytes have been added.
143              
144             =cut
145              
146 1     1 1 8 sub add_content { $_[0]->{content} .= $_[1] }
147              
148             =pod
149              
150             =head2 length
151              
152             The C method returns the length of the string in a Token.
153              
154             =cut
155              
156 7     7 1 242 sub length { CORE::length($_[0]->{content}) }
157              
158              
159              
160              
161              
162             #####################################################################
163             # Overloaded PPI::Element methods
164              
165             sub content {
166 1162040     1162040 1 4378117 $_[0]->{content};
167             }
168              
169             # You can insert either a statement, or a non-significant token.
170             sub insert_before {
171 1     1 1 3 my $self = shift;
172 1 50       13 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
173 1 50       11 if ( $Element->isa('PPI::Structure') ) {
    50          
174 0         0 return $self->__insert_before($Element);
175             } elsif ( $Element->isa('PPI::Token') ) {
176 1         7 return $self->__insert_before($Element);
177             }
178 0         0 '';
179             }
180              
181             # As above, you can insert a statement, or a non-significant token
182             sub insert_after {
183 1     1 1 3 my $self = shift;
184 1 50       14 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
185 1 50       10 if ( $Element->isa('PPI::Structure') ) {
    50          
186 0         0 return $self->__insert_after($Element);
187             } elsif ( $Element->isa('PPI::Token') ) {
188 1         6 return $self->__insert_after($Element);
189             }
190 0         0 '';
191             }
192              
193              
194              
195              
196              
197             #####################################################################
198             # Tokenizer Methods
199              
200             sub __TOKENIZER__on_line_start() { 1 }
201             sub __TOKENIZER__on_line_end() { 1 }
202             sub __TOKENIZER__on_char() { 'Unknown' }
203              
204              
205              
206              
207              
208             #####################################################################
209             # Lexer Methods
210              
211             sub __LEXER__opens {
212             ref($_[0]) eq 'PPI::Token::Structure'
213             and
214 46666 50   46666   387386 $_[0]->{content} =~ /(?:\(|\[|\{)/
215             }
216              
217             sub __LEXER__closes {
218             ref($_[0]) eq 'PPI::Token::Structure'
219             and
220 193807 100   193807   1651169 $_[0]->{content} =~ /(?:\)|\]|\})/
221             }
222              
223             1;
224              
225             =pod
226              
227             =head1 SUPPORT
228              
229             See the L in the main module.
230              
231             =head1 AUTHOR
232              
233             Adam Kennedy Eadamk@cpan.orgE
234              
235             =head1 COPYRIGHT
236              
237             Copyright 2001 - 2011 Adam Kennedy.
238              
239             This program is free software; you can redistribute
240             it and/or modify it under the same terms as Perl itself.
241              
242             The full text of the license can be found in the
243             LICENSE file included with this module.
244              
245             =cut