line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package PPI::Token::Word; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=pod |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
PPI::Token::Word - The generic "word" Token |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 INHERITANCE |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
PPI::Token::Word |
12
|
|
|
|
|
|
|
isa PPI::Token |
13
|
|
|
|
|
|
|
isa PPI::Element |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 DESCRIPTION |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
A C object is a PPI-specific representation of several |
18
|
|
|
|
|
|
|
different types of word-like things, and is one of the most common Token |
19
|
|
|
|
|
|
|
classes found in typical documents. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Specifically, it includes not only barewords, but also any other valid |
22
|
|
|
|
|
|
|
Perl identifier including non-operator keywords and core functions, and |
23
|
|
|
|
|
|
|
any include C<::> separators inside it, as long as it fits the |
24
|
|
|
|
|
|
|
format of a class, function, etc. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 METHODS |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
There are no methods available for C beyond those |
29
|
|
|
|
|
|
|
provided by its L and L parent |
30
|
|
|
|
|
|
|
classes. |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
We expect to add additional methods to help further resolve a Word as |
33
|
|
|
|
|
|
|
a function, method, etc over time. If you need such a thing right |
34
|
|
|
|
|
|
|
now, look at L. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=cut |
37
|
|
|
|
|
|
|
|
38
|
65
|
|
|
65
|
|
383
|
use strict; |
|
65
|
|
|
|
|
111
|
|
|
65
|
|
|
|
|
1476
|
|
39
|
65
|
|
|
65
|
|
295
|
use PPI::Token (); |
|
65
|
|
|
|
|
116
|
|
|
65
|
|
|
|
|
1021
|
|
40
|
65
|
|
|
65
|
|
253
|
use PPI::Singletons qw' %OPERATOR %QUOTELIKE %KEYWORDS '; |
|
65
|
|
|
|
|
93
|
|
|
65
|
|
|
|
|
93991
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
our $VERSION = '1.276'; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
our @ISA = "PPI::Token"; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=pod |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head2 literal |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Returns the value of the Word as a string. This assumes (often |
51
|
|
|
|
|
|
|
incorrectly) that the Word is a bareword and not a function, method, |
52
|
|
|
|
|
|
|
keyword, etc. This differs from C because C expands |
53
|
|
|
|
|
|
|
to C. |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=cut |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub literal { |
58
|
3
|
|
|
3
|
1
|
1245
|
my $self = shift; |
59
|
3
|
|
|
|
|
8
|
my $word = $self->content; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# Expand Foo'Bar to Foo::Bar |
62
|
3
|
|
|
|
|
8
|
$word =~ s/\'/::/g; |
63
|
|
|
|
|
|
|
|
64
|
3
|
|
|
|
|
13
|
return $word; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=pod |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=head2 method_call |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Answers whether this is the name of a method in a method call. Returns true if |
72
|
|
|
|
|
|
|
yes, false if no, and nothing if unknown. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=cut |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub method_call { |
77
|
22
|
|
|
22
|
1
|
4855
|
my $self = shift; |
78
|
|
|
|
|
|
|
|
79
|
22
|
|
|
|
|
54
|
my $previous = $self->sprevious_sibling; |
80
|
22
|
100
|
100
|
|
|
83
|
if ( |
|
|
|
100
|
|
|
|
|
81
|
|
|
|
|
|
|
$previous |
82
|
|
|
|
|
|
|
and |
83
|
|
|
|
|
|
|
$previous->isa('PPI::Token::Operator') |
84
|
|
|
|
|
|
|
and |
85
|
|
|
|
|
|
|
$previous->content eq '->' |
86
|
|
|
|
|
|
|
) { |
87
|
4
|
|
|
|
|
25
|
return 1; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
18
|
|
|
|
|
39
|
my $snext = $self->snext_sibling; |
91
|
18
|
100
|
|
|
|
44
|
return 0 unless $snext; |
92
|
|
|
|
|
|
|
|
93
|
15
|
100
|
100
|
|
|
103
|
if ( |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
94
|
|
|
|
|
|
|
$snext->isa('PPI::Structure::List') |
95
|
|
|
|
|
|
|
or |
96
|
|
|
|
|
|
|
$snext->isa('PPI::Token::Structure') |
97
|
|
|
|
|
|
|
or |
98
|
|
|
|
|
|
|
$snext->isa('PPI::Token::Operator') |
99
|
|
|
|
|
|
|
and ( |
100
|
|
|
|
|
|
|
$snext->content eq ',' |
101
|
|
|
|
|
|
|
or |
102
|
|
|
|
|
|
|
$snext->content eq '=>' |
103
|
|
|
|
|
|
|
) |
104
|
|
|
|
|
|
|
) { |
105
|
9
|
|
|
|
|
33
|
return 0; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
6
|
100
|
100
|
|
|
21
|
if ( |
109
|
|
|
|
|
|
|
$snext->isa('PPI::Token::Word') |
110
|
|
|
|
|
|
|
and |
111
|
|
|
|
|
|
|
$snext->content =~ m< \w :: \z >xms |
112
|
|
|
|
|
|
|
) { |
113
|
1
|
|
|
|
|
5
|
return 1; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
5
|
|
|
|
|
28
|
return; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub __TOKENIZER__on_char { |
121
|
17
|
|
|
17
|
|
34
|
my $class = shift; |
122
|
17
|
|
|
|
|
32
|
my $t = shift; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# Suck in till the end of the bareword |
125
|
17
|
|
|
|
|
51
|
pos $t->{line} = $t->{line_cursor}; |
126
|
17
|
100
|
|
|
|
105
|
if ( $t->{line} =~ m/\G(\w+(?:(?:\'|::)\w+)*(?:::)?)/gc ) { |
127
|
11
|
|
|
|
|
34
|
my $word = $1; |
128
|
|
|
|
|
|
|
# Special Case: If we accidentally treat eq'foo' like |
129
|
|
|
|
|
|
|
# the word "eq'foo", then just make 'eq' (or whatever |
130
|
|
|
|
|
|
|
# else is in the %KEYWORDS hash. |
131
|
11
|
0
|
33
|
|
|
42
|
if ( $word =~ /^(\w+)'/ && $KEYWORDS{$1} ) { |
132
|
0
|
|
|
|
|
0
|
$word = $1; |
133
|
|
|
|
|
|
|
} |
134
|
11
|
|
|
|
|
24
|
$t->{token}->{content} .= $word; |
135
|
11
|
|
|
|
|
35
|
$t->{line_cursor} += length $word; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# We might be a subroutine attribute. |
140
|
17
|
50
|
|
|
|
54
|
if ( __current_token_is_attribute($t) ) { |
141
|
0
|
|
|
|
|
0
|
$t->{class} = $t->{token}->set_class( 'Attribute' ); |
142
|
0
|
|
|
|
|
0
|
return $t->{class}->__TOKENIZER__commit( $t ); |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
17
|
|
|
|
|
97
|
my $word = $t->{token}->{content}; |
146
|
17
|
50
|
|
|
|
77
|
if ( $KEYWORDS{$word} ) { |
147
|
|
|
|
|
|
|
# Check for a Perl keyword that is forced to be a normal word instead |
148
|
0
|
0
|
|
|
|
0
|
if ( $t->__current_token_is_forced_word ) { |
149
|
0
|
|
|
|
|
0
|
$t->{class} = $t->{token}->set_class( 'Word' ); |
150
|
0
|
|
|
|
|
0
|
return $t->{class}->__TOKENIZER__on_char( $t ); |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# Check for a quote like operator. %QUOTELIKE must be subset of %KEYWORDS |
154
|
0
|
0
|
|
|
|
0
|
if ( $QUOTELIKE{$word} ) { |
155
|
0
|
|
|
|
|
0
|
$t->{class} = $t->{token}->set_class( $QUOTELIKE{$word} ); |
156
|
0
|
|
|
|
|
0
|
return $t->{class}->__TOKENIZER__on_char( $t ); |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# Or one of the word operators. %OPERATOR must be subset of %KEYWORDS |
160
|
0
|
0
|
|
|
|
0
|
if ( $OPERATOR{$word} ) { |
161
|
0
|
|
|
|
|
0
|
$t->{class} = $t->{token}->set_class( 'Operator' ); |
162
|
0
|
|
|
|
|
0
|
return $t->_finalize_token->__TOKENIZER__on_char( $t ); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# Unless this is a simple identifier, at this point |
167
|
|
|
|
|
|
|
# it has to be a normal bareword |
168
|
17
|
100
|
|
|
|
63
|
if ( $word =~ /\:/ ) { |
169
|
9
|
|
|
|
|
46
|
return $t->_finalize_token->__TOKENIZER__on_char( $t ); |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
# If the NEXT character in the line is a colon, this |
173
|
|
|
|
|
|
|
# is a label. |
174
|
8
|
|
|
|
|
22
|
my $char = substr( $t->{line}, $t->{line_cursor}, 1 ); |
175
|
8
|
50
|
|
|
|
39
|
if ( $char eq ':' ) { |
|
|
100
|
|
|
|
|
|
176
|
0
|
|
|
|
|
0
|
$t->{token}->{content} .= ':'; |
177
|
0
|
|
|
|
|
0
|
$t->{line_cursor}++; |
178
|
0
|
|
|
|
|
0
|
$t->{class} = $t->{token}->set_class( 'Label' ); |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# If not a label, '_' on its own is the magic filehandle |
181
|
|
|
|
|
|
|
} elsif ( $word eq '_' ) { |
182
|
1
|
|
|
|
|
7
|
$t->{class} = $t->{token}->set_class( 'Magic' ); |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# Finalise and process the character again |
187
|
8
|
|
|
|
|
23
|
$t->_finalize_token->__TOKENIZER__on_char( $t ); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# We are committed to being a bareword. |
193
|
|
|
|
|
|
|
# Or so we would like to believe. |
194
|
|
|
|
|
|
|
sub __TOKENIZER__commit { |
195
|
55744
|
|
|
55744
|
|
94685
|
my ($class, $t) = @_; |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
# Our current position is the first character of the bareword. |
198
|
|
|
|
|
|
|
# Capture the bareword. |
199
|
55744
|
|
|
|
|
121557
|
pos $t->{line} = $t->{line_cursor}; |
200
|
55744
|
50
|
|
|
|
263518
|
unless ( $t->{line} =~ m/\G((?!\d)\w+(?:(?:\'|::)\w+)*(?:::)?)/gc ) { |
201
|
|
|
|
|
|
|
# Programmer error |
202
|
0
|
|
|
|
|
0
|
die sprintf "Fatal error... regex failed to match in '%s' when expected", substr $t->{line}, $t->{line_cursor}; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Special Case: If we accidentally treat eq'foo' like the word "eq'foo", |
206
|
|
|
|
|
|
|
# then unwind it and just make it 'eq' (or the other stringy comparitors) |
207
|
55744
|
|
|
|
|
109247
|
my $word = $1; |
208
|
55744
|
100
|
100
|
|
|
107119
|
if ( $word =~ /^(\w+)'/ && $KEYWORDS{$1} ) { |
209
|
262
|
|
|
|
|
548
|
$word = $1; |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# Advance the position one after the end of the bareword |
213
|
55744
|
|
|
|
|
79632
|
$t->{line_cursor} += length $word; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# We might be a subroutine attribute. |
216
|
55744
|
100
|
|
|
|
90374
|
if ( __current_token_is_attribute($t) ) { |
217
|
1062
|
|
|
|
|
2554
|
$t->_new_token( 'Attribute', $word ); |
218
|
|
|
|
|
|
|
return ($t->{line_cursor} >= $t->{line_length}) ? 0 |
219
|
1062
|
50
|
|
|
|
2994
|
: $t->{class}->__TOKENIZER__on_char($t); |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# Check for the end of the file |
223
|
54682
|
100
|
|
|
|
116937
|
if ( $word eq '__END__' ) { |
224
|
|
|
|
|
|
|
# Create the token for the __END__ itself |
225
|
8
|
|
|
|
|
71
|
$t->_new_token( 'Separator', $1 ); |
226
|
8
|
|
|
|
|
23
|
$t->_finalize_token; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# Move into the End zone (heh) |
229
|
8
|
|
|
|
|
15
|
$t->{zone} = 'PPI::Token::End'; |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# Add the rest of the line as a comment, and a whitespace newline |
232
|
|
|
|
|
|
|
# Anything after the __END__ on the line is "ignored". So we must |
233
|
|
|
|
|
|
|
# also ignore it, by turning it into a comment. |
234
|
8
|
|
|
|
|
23
|
my $end_rest = substr( $t->{line}, $t->{line_cursor} ); |
235
|
8
|
|
|
|
|
14
|
$t->{line_cursor} = length $t->{line}; |
236
|
8
|
100
|
|
|
|
52
|
if ( $end_rest =~ /\n$/ ) { |
237
|
6
|
|
|
|
|
47
|
chomp $end_rest; |
238
|
6
|
100
|
|
|
|
27
|
$t->_new_token( 'Comment', $end_rest ) if length $end_rest; |
239
|
6
|
|
|
|
|
29
|
$t->_new_token( 'Whitespace', "\n" ); |
240
|
|
|
|
|
|
|
} else { |
241
|
2
|
100
|
|
|
|
9
|
$t->_new_token( 'Comment', $end_rest ) if length $end_rest; |
242
|
|
|
|
|
|
|
} |
243
|
8
|
|
|
|
|
25
|
$t->_finalize_token; |
244
|
|
|
|
|
|
|
|
245
|
8
|
|
|
|
|
26
|
return 0; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# Check for the data section |
249
|
54674
|
100
|
|
|
|
89110
|
if ( $word eq '__DATA__' ) { |
250
|
|
|
|
|
|
|
# Create the token for the __DATA__ itself |
251
|
6
|
|
|
|
|
27
|
$t->_new_token( 'Separator', "$1" ); |
252
|
6
|
|
|
|
|
21
|
$t->_finalize_token; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# Move into the Data zone |
255
|
6
|
|
|
|
|
16
|
$t->{zone} = 'PPI::Token::Data'; |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
# Add the rest of the line as the Data token |
258
|
6
|
|
|
|
|
17
|
my $data_rest = substr( $t->{line}, $t->{line_cursor} ); |
259
|
6
|
|
|
|
|
15
|
$t->{line_cursor} = length $t->{line}; |
260
|
6
|
100
|
|
|
|
26
|
if ( $data_rest =~ /\n$/ ) { |
261
|
4
|
|
|
|
|
12
|
chomp $data_rest; |
262
|
4
|
100
|
|
|
|
14
|
$t->_new_token( 'Comment', $data_rest ) if length $data_rest; |
263
|
4
|
|
|
|
|
30
|
$t->_new_token( 'Whitespace', "\n" ); |
264
|
|
|
|
|
|
|
} else { |
265
|
2
|
100
|
|
|
|
6
|
$t->_new_token( 'Comment', $data_rest ) if length $data_rest; |
266
|
|
|
|
|
|
|
} |
267
|
6
|
|
|
|
|
20
|
$t->_finalize_token; |
268
|
|
|
|
|
|
|
|
269
|
6
|
|
|
|
|
19
|
return 0; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
54668
|
|
|
|
|
61584
|
my $token_class; |
273
|
54668
|
100
|
100
|
|
|
232989
|
if ( $word =~ /\:/ ) { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
|
|
|
|
|
274
|
|
|
|
|
|
|
# Since it's not a simple identifier... |
275
|
1432
|
|
|
|
|
2617
|
$token_class = 'Word'; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
} elsif ( $KEYWORDS{$word} and $t->__current_token_is_forced_word ) { |
278
|
6621
|
|
|
|
|
9722
|
$token_class = 'Word'; |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
} elsif ( $QUOTELIKE{$word} ) { |
281
|
|
|
|
|
|
|
# Special Case: A Quote-like operator |
282
|
2705
|
|
|
|
|
6992
|
$t->_new_token( $QUOTELIKE{$word}, $word ); |
283
|
|
|
|
|
|
|
return ($t->{line_cursor} >= $t->{line_length}) ? 0 |
284
|
2705
|
50
|
|
|
|
9579
|
: $t->{class}->__TOKENIZER__on_char( $t ); |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
} elsif ( $OPERATOR{$word} && ($word ne 'x' || $t->_current_x_is_operator) ) { |
287
|
|
|
|
|
|
|
# Word operator |
288
|
1572
|
|
|
|
|
2251
|
$token_class = 'Operator'; |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
} else { |
291
|
|
|
|
|
|
|
# Get tokens early to be sure to not disturb state set up by pos and m//gc. |
292
|
42338
|
|
|
|
|
80323
|
my @tokens = $t->_previous_significant_tokens(1); |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
# If the next character is a ':' then it's a label... |
295
|
42338
|
|
|
|
|
79117
|
pos $t->{line} = $t->{line_cursor}; |
296
|
42338
|
100
|
|
|
|
122414
|
if ( $t->{line} =~ m/\G(\s*:)(?!:)/gc ) { |
|
|
100
|
|
|
|
|
|
297
|
1141
|
100
|
100
|
|
|
4992
|
if ( $tokens[0] and $tokens[0]->{content} eq 'sub' ) { |
298
|
|
|
|
|
|
|
# ... UNLESS it's after 'sub' in which |
299
|
|
|
|
|
|
|
# case it is a sub name and an attribute |
300
|
|
|
|
|
|
|
# operator. |
301
|
|
|
|
|
|
|
# We COULD have checked this at the top |
302
|
|
|
|
|
|
|
# level of checks, but this would impose |
303
|
|
|
|
|
|
|
# an additional performance per-word |
304
|
|
|
|
|
|
|
# penalty, and every other case where the |
305
|
|
|
|
|
|
|
# attribute operator doesn't directly |
306
|
|
|
|
|
|
|
# touch the object name already works. |
307
|
621
|
|
|
|
|
955
|
$token_class = 'Word'; |
308
|
|
|
|
|
|
|
} else { |
309
|
520
|
|
|
|
|
1225
|
$word .= $1; |
310
|
520
|
|
|
|
|
1011
|
$t->{line_cursor} += length($1); |
311
|
520
|
|
|
|
|
922
|
$token_class = 'Label'; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
} elsif ( $word eq '_' ) { |
314
|
453
|
|
|
|
|
768
|
$token_class = 'Magic'; |
315
|
|
|
|
|
|
|
} else { |
316
|
40744
|
|
|
|
|
60916
|
$token_class = 'Word'; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
# Create the new token and finalise |
321
|
51963
|
|
|
|
|
117001
|
$t->_new_token( $token_class, $word ); |
322
|
51963
|
50
|
|
|
|
93156
|
if ( $t->{line_cursor} >= $t->{line_length} ) { |
323
|
|
|
|
|
|
|
# End of the line |
324
|
0
|
|
|
|
|
0
|
$t->_finalize_token; |
325
|
0
|
|
|
|
|
0
|
return 0; |
326
|
|
|
|
|
|
|
} |
327
|
51963
|
|
|
|
|
87662
|
$t->_finalize_token->__TOKENIZER__on_char($t); |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# Is the current Word really a subroutine attribute? |
333
|
|
|
|
|
|
|
sub __current_token_is_attribute { |
334
|
55761
|
|
|
55761
|
|
77906
|
my ( $t ) = @_; |
335
|
55761
|
|
|
|
|
112235
|
my @tokens = $t->_previous_significant_tokens(1); |
336
|
|
|
|
|
|
|
return ( |
337
|
|
|
|
|
|
|
$tokens[0] |
338
|
|
|
|
|
|
|
and ( |
339
|
|
|
|
|
|
|
# hint from tokenizer |
340
|
|
|
|
|
|
|
$tokens[0]->{_attribute} |
341
|
|
|
|
|
|
|
# nothing between attribute and us except whitespace |
342
|
55761
|
|
66
|
|
|
362278
|
or $tokens[0]->isa('PPI::Token::Attribute') |
343
|
|
|
|
|
|
|
) |
344
|
|
|
|
|
|
|
); |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
1; |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=pod |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=head1 TO DO |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
- Add C, C etc detector methods |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=head1 SUPPORT |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
See the L in the main module. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=head1 AUTHOR |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Adam Kennedy Eadamk@cpan.orgE |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=head1 COPYRIGHT |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
Copyright 2001 - 2011 Adam Kennedy. |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
This program is free software; you can redistribute |
368
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
The full text of the license can be found in the |
371
|
|
|
|
|
|
|
LICENSE file included with this module. |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=cut |