line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package PPI::Document; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=pod |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
PPI::Document - Object representation of a Perl document |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 INHERITANCE |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
PPI::Document |
12
|
|
|
|
|
|
|
isa PPI::Node |
13
|
|
|
|
|
|
|
isa PPI::Element |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 SYNOPSIS |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
use PPI; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# Load a document from a file |
20
|
|
|
|
|
|
|
my $Document = PPI::Document->new('My/Module.pm'); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# Strip out comments |
23
|
|
|
|
|
|
|
$Document->prune('PPI::Token::Comment'); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Find all the named subroutines |
26
|
|
|
|
|
|
|
my $sub_nodes = $Document->find( |
27
|
|
|
|
|
|
|
sub { $_[1]->isa('PPI::Statement::Sub') and $_[1]->name } |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
my @sub_names = map { $_->name } @$sub_nodes; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# Save the file |
32
|
|
|
|
|
|
|
$Document->save('My/Module.pm.stripped'); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 DESCRIPTION |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
The C class represents a single Perl "document". A |
37
|
|
|
|
|
|
|
C object acts as a root L, with some |
38
|
|
|
|
|
|
|
additional methods for loading and saving, and working with |
39
|
|
|
|
|
|
|
the line/column locations of Elements within a file. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
The exemption to its L-like behavior this is that a |
42
|
|
|
|
|
|
|
C object can NEVER have a parent node, and is always |
43
|
|
|
|
|
|
|
the root node in a tree. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head2 Storable Support |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
C implements the necessary C and |
48
|
|
|
|
|
|
|
C hooks to provide native support for L, |
49
|
|
|
|
|
|
|
if you have it installed. |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
However if you want to clone a Document, you are highly recommended |
52
|
|
|
|
|
|
|
to use the C<$Document-Eclone> method rather than Storable's |
53
|
|
|
|
|
|
|
C function (although C should still work). |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 METHODS |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
Most of the things you are likely to want to do with a Document are |
58
|
|
|
|
|
|
|
probably going to involve the methods from L class, of which |
59
|
|
|
|
|
|
|
this is a subclass. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
The methods listed here are the remaining few methods that are truly |
62
|
|
|
|
|
|
|
Document-specific. |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=cut |
65
|
|
|
|
|
|
|
|
66
|
63
|
|
|
63
|
|
621951
|
use strict; |
|
63
|
|
|
|
|
201
|
|
|
63
|
|
|
|
|
1427
|
|
67
|
63
|
|
|
63
|
|
251
|
use Carp (); |
|
63
|
|
|
|
|
108
|
|
|
63
|
|
|
|
|
1196
|
|
68
|
63
|
|
|
63
|
|
249
|
use List::Util 1.33 (); |
|
63
|
|
|
|
|
1134
|
|
|
63
|
|
|
|
|
1360
|
|
69
|
63
|
|
|
63
|
|
3770
|
use Params::Util 1.00 qw{_SCALAR0 _ARRAY0 _INSTANCE}; |
|
63
|
|
|
|
|
47300
|
|
|
63
|
|
|
|
|
2898
|
|
70
|
63
|
|
|
63
|
|
329
|
use Digest::MD5 (); |
|
63
|
|
|
|
|
100
|
|
|
63
|
|
|
|
|
1163
|
|
71
|
63
|
|
|
63
|
|
4555
|
use PPI::Util (); |
|
63
|
|
|
|
|
119
|
|
|
63
|
|
|
|
|
978
|
|
72
|
63
|
|
|
63
|
|
5747
|
use PPI (); |
|
63
|
|
|
|
|
133
|
|
|
63
|
|
|
|
|
1023
|
|
73
|
63
|
|
|
63
|
|
269
|
use PPI::Node (); |
|
63
|
|
|
|
|
103
|
|
|
63
|
|
|
|
|
2033
|
|
74
|
|
|
|
|
|
|
|
75
|
63
|
|
|
63
|
|
301
|
use overload 'bool' => \&PPI::Util::TRUE; |
|
63
|
|
|
|
|
110
|
|
|
63
|
|
|
|
|
505
|
|
76
|
63
|
|
|
63
|
|
3912
|
use overload '""' => 'content'; |
|
63
|
|
|
|
|
169
|
|
|
63
|
|
|
|
|
236
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
our $VERSION = '1.275'; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
our ( $errstr, @ISA ) = ( "", "PPI::Node" ); |
81
|
|
|
|
|
|
|
|
82
|
63
|
|
|
63
|
|
22265
|
use PPI::Document::Fragment (); |
|
63
|
|
|
|
|
173
|
|
|
63
|
|
|
|
|
1564
|
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# Document cache |
85
|
|
|
|
|
|
|
my $CACHE; |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# Convenience constants related to constants |
88
|
63
|
|
|
63
|
|
323
|
use constant LOCATION_LINE => 0; |
|
63
|
|
|
|
|
95
|
|
|
63
|
|
|
|
|
3183
|
|
89
|
63
|
|
|
63
|
|
297
|
use constant LOCATION_CHARACTER => 1; |
|
63
|
|
|
|
|
102
|
|
|
63
|
|
|
|
|
2290
|
|
90
|
63
|
|
|
63
|
|
282
|
use constant LOCATION_COLUMN => 2; |
|
63
|
|
|
|
|
96
|
|
|
63
|
|
|
|
|
2254
|
|
91
|
63
|
|
|
63
|
|
283
|
use constant LOCATION_LOGICAL_LINE => 3; |
|
63
|
|
|
|
|
108
|
|
|
63
|
|
|
|
|
2298
|
|
92
|
63
|
|
|
63
|
|
284
|
use constant LOCATION_LOGICAL_FILE => 4; |
|
63
|
|
|
|
|
90
|
|
|
63
|
|
|
|
|
157862
|
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
##################################################################### |
99
|
|
|
|
|
|
|
# Constructor and Static Methods |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=pod |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=head2 new |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Simple construction |
106
|
|
|
|
|
|
|
$doc = PPI::Document->new( $filename ); |
107
|
|
|
|
|
|
|
$doc = PPI::Document->new( \$source ); |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# With the readonly attribute set |
110
|
|
|
|
|
|
|
$doc = PPI::Document->new( $filename, |
111
|
|
|
|
|
|
|
readonly => 1, |
112
|
|
|
|
|
|
|
); |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
The C constructor takes as argument a variety of different sources of |
115
|
|
|
|
|
|
|
Perl code, and creates a single cohesive Perl C |
116
|
|
|
|
|
|
|
for it. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
If passed a file name as a normal string, it will attempt to load the |
119
|
|
|
|
|
|
|
document from the file. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
If passed a reference to a C, this is taken to be source code and |
122
|
|
|
|
|
|
|
parsed directly to create the document. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
If passed zero arguments, a "blank" document will be created that contains |
125
|
|
|
|
|
|
|
no content at all. |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
In all cases, the document is considered to be "anonymous" and not tied back |
128
|
|
|
|
|
|
|
to where it was created from. Specifically, if you create a PPI::Document from |
129
|
|
|
|
|
|
|
a filename, the document will B remember where it was created from. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
The constructor also takes attribute flags. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
At this time, the only available attribute is the C flag. |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Setting C to true will allow various systems to provide |
136
|
|
|
|
|
|
|
additional optimisations and caching. Note that because C is an |
137
|
|
|
|
|
|
|
optimisation flag, it is off by default and you will need to explicitly |
138
|
|
|
|
|
|
|
enable it. |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Returns a C object, or C if parsing fails. |
141
|
|
|
|
|
|
|
L objects can also be thrown if there are parsing problems. |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=cut |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub new { |
146
|
33406
|
|
|
33406
|
1
|
7738195
|
local $_; # An extra one, just in case |
147
|
33406
|
50
|
|
|
|
62335
|
my $class = ref $_[0] ? ref shift : shift; |
148
|
|
|
|
|
|
|
|
149
|
33406
|
100
|
|
|
|
60009
|
unless ( @_ ) { |
150
|
16704
|
|
|
|
|
39123
|
my $self = $class->SUPER::new; |
151
|
16704
|
|
|
|
|
34492
|
$self->{readonly} = ! 1; |
152
|
16704
|
|
|
|
|
22447
|
$self->{tab_width} = 1; |
153
|
16704
|
|
|
|
|
33038
|
return $self; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# Check constructor attributes |
157
|
16702
|
|
|
|
|
20470
|
my $source = shift; |
158
|
16702
|
|
|
|
|
23851
|
my %attr = @_; |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# Check the data source |
161
|
16702
|
50
|
|
|
|
57937
|
if ( ! defined $source ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
162
|
0
|
|
|
|
|
0
|
$class->_error("An undefined value was passed to PPI::Document::new"); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
} elsif ( ! ref $source ) { |
165
|
|
|
|
|
|
|
# Catch people using the old API |
166
|
498
|
50
|
|
|
|
2249
|
if ( $source =~ /(?:\012|\015)/ ) { |
167
|
0
|
|
|
|
|
0
|
Carp::croak("API CHANGE: Source code should only be passed to PPI::Document->new as a SCALAR reference"); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Save the filename |
171
|
498
|
|
66
|
|
|
2572
|
$attr{filename} ||= $source; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# When loading from a filename, use the caching layer if it exists. |
174
|
498
|
100
|
|
|
|
1129
|
if ( $CACHE ) { |
175
|
3
|
|
|
|
|
8
|
my $file_contents = PPI::Util::_slurp( $source ); |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# Errors returned as plain string |
178
|
3
|
50
|
|
|
|
8
|
return $class->_error($file_contents) if !ref $file_contents; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Retrieve the document from the cache |
181
|
3
|
|
|
|
|
10
|
my $document = $CACHE->get_document($file_contents); |
182
|
3
|
100
|
|
|
|
13
|
return $class->_setattr( $document, %attr ) if $document; |
183
|
|
|
|
|
|
|
|
184
|
1
|
|
|
|
|
7
|
$document = PPI::Lexer->lex_source( $$file_contents ); |
185
|
1
|
50
|
|
|
|
5
|
if ( $document ) { |
186
|
|
|
|
|
|
|
# Save in the cache |
187
|
1
|
|
|
|
|
3
|
$CACHE->store_document( $document ); |
188
|
1
|
|
|
|
|
44
|
return $class->_setattr( $document, %attr ); |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
} else { |
191
|
495
|
|
|
|
|
2641
|
my $document = PPI::Lexer->lex_file( $source ); |
192
|
495
|
50
|
|
|
|
3303
|
return $class->_setattr( $document, %attr ) if $document; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
} elsif ( _SCALAR0($source) ) { |
196
|
16201
|
|
|
|
|
44728
|
my $document = PPI::Lexer->lex_source( $$source ); |
197
|
16201
|
100
|
|
|
|
65069
|
return $class->_setattr( $document, %attr ) if $document; |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
} elsif ( _ARRAY0($source) ) { |
200
|
3
|
|
|
|
|
8
|
$source = join '', map { "$_\n" } @$source; |
|
5
|
|
|
|
|
11
|
|
201
|
3
|
|
|
|
|
9
|
my $document = PPI::Lexer->lex_source( $source ); |
202
|
3
|
50
|
|
|
|
18
|
return $class->_setattr( $document, %attr ) if $document; |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
} else { |
205
|
0
|
|
|
|
|
0
|
$class->_error("Unknown object or reference was passed to PPI::Document::new"); |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Pull and store the error from the lexer |
209
|
1
|
|
|
|
|
2
|
my $errstr; |
210
|
1
|
50
|
|
|
|
9
|
if ( _INSTANCE($@, 'PPI::Exception') ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
211
|
1
|
|
|
|
|
3
|
$errstr = $@->message; |
212
|
|
|
|
|
|
|
} elsif ( $@ ) { |
213
|
0
|
|
|
|
|
0
|
$errstr = $@; |
214
|
0
|
|
|
|
|
0
|
$errstr =~ s/\sat line\s.+$//; |
215
|
|
|
|
|
|
|
} elsif ( PPI::Lexer->errstr ) { |
216
|
0
|
|
|
|
|
0
|
$errstr = PPI::Lexer->errstr; |
217
|
|
|
|
|
|
|
} else { |
218
|
0
|
|
|
|
|
0
|
$errstr = "Unknown error parsing Perl document"; |
219
|
|
|
|
|
|
|
} |
220
|
1
|
|
|
|
|
3
|
PPI::Lexer->_clear; |
221
|
1
|
|
|
|
|
3
|
$class->_error( $errstr ); |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub load { |
225
|
0
|
|
|
0
|
0
|
0
|
Carp::croak("API CHANGE: File names should now be passed to PPI::Document->new to load a file"); |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub _setattr { |
229
|
16701
|
|
|
16701
|
|
31113
|
my ($class, $document, %attr) = @_; |
230
|
16701
|
|
|
|
|
29682
|
$document->{readonly} = !! $attr{readonly}; |
231
|
16701
|
|
|
|
|
26467
|
$document->{filename} = $attr{filename}; |
232
|
16701
|
|
|
|
|
51728
|
return $document; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=pod |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head2 set_cache $cache |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
As of L 1.100, C supports parser caching. |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
The default cache class L provides a L-based |
242
|
|
|
|
|
|
|
caching or the parsed document based on the MD5 hash of the document as |
243
|
|
|
|
|
|
|
a string. |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
The static C method is used to set the cache object for |
246
|
|
|
|
|
|
|
C to use when loading documents. It takes as argument |
247
|
|
|
|
|
|
|
a L object (or something that C the same). |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
If passed C, this method will stop using the current cache, if any. |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
For more information on caching, see L. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
Returns true on success, or C if not passed a valid param. |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=cut |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
sub set_cache { |
258
|
3
|
50
|
|
3
|
1
|
14
|
my $class = ref $_[0] ? ref shift : shift; |
259
|
|
|
|
|
|
|
|
260
|
3
|
100
|
|
|
|
6
|
if ( defined $_[0] ) { |
261
|
|
|
|
|
|
|
# Enable the cache |
262
|
2
|
50
|
|
|
|
15
|
my $object = _INSTANCE(shift, 'PPI::Cache') or return undef; |
263
|
2
|
|
|
|
|
3
|
$CACHE = $object; |
264
|
|
|
|
|
|
|
} else { |
265
|
|
|
|
|
|
|
# Disable the cache |
266
|
1
|
|
|
|
|
3
|
$CACHE = undef; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
3
|
|
|
|
|
11
|
1; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=pod |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=head2 get_cache |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
If a document cache is currently set, the C method will |
277
|
|
|
|
|
|
|
return it. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
Returns a L object, or C if there is no cache |
280
|
|
|
|
|
|
|
currently set for C. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=cut |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub get_cache { |
285
|
7
|
|
|
7
|
1
|
1133
|
$CACHE; |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
##################################################################### |
293
|
|
|
|
|
|
|
# PPI::Document Instance Methods |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=pod |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head2 filename |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
The C accessor returns the name of the file in which the document |
300
|
|
|
|
|
|
|
is stored. |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=cut |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
sub filename { |
305
|
255
|
|
|
255
|
1
|
1287
|
$_[0]->{filename}; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=pod |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head2 readonly |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
The C attribute indicates if the document is intended to be |
313
|
|
|
|
|
|
|
read-only, and will never be modified. This is an advisory flag, that |
314
|
|
|
|
|
|
|
writers of L-related systems may or may not use to enable |
315
|
|
|
|
|
|
|
optimisations and caches for your document. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
Returns true if the document is read-only or false if not. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=cut |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub readonly { |
322
|
4
|
|
|
4
|
1
|
1344
|
$_[0]->{readonly}; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=pod |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=head2 tab_width [ $width ] |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
In order to handle support for C correctly, C |
330
|
|
|
|
|
|
|
need to understand the concept of tabs and tab width. The C |
331
|
|
|
|
|
|
|
method is used to get and set the size of the tab width. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
At the present time, PPI only supports "naive" (width 1) tabs, but we do |
334
|
|
|
|
|
|
|
plan on supporting arbitrary, default and auto-sensing tab widths later. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Returns the tab width as an integer, or Cs if you attempt to set the |
337
|
|
|
|
|
|
|
tab width. |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=cut |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
sub tab_width { |
342
|
55660
|
|
|
55660
|
1
|
57584
|
my $self = shift; |
343
|
55660
|
100
|
|
|
|
88497
|
return $self->{tab_width} unless @_; |
344
|
2
|
|
|
|
|
5
|
$self->{tab_width} = shift; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=pod |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=head2 save |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
$document->save( $file ) |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
The C method serializes the C object and saves the |
354
|
|
|
|
|
|
|
resulting Perl document to a file. Returns C on failure to open |
355
|
|
|
|
|
|
|
or write to the file. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=cut |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
sub save { |
360
|
2
|
|
|
2
|
1
|
4
|
my $self = shift; |
361
|
2
|
|
|
|
|
5
|
local *FILE; |
362
|
2
|
50
|
|
|
|
131
|
open( FILE, '>', $_[0] ) or return undef; |
363
|
2
|
|
|
|
|
8
|
binmode FILE; |
364
|
2
|
50
|
|
|
|
17
|
print FILE $self->serialize or return undef; |
365
|
2
|
50
|
|
|
|
163
|
close FILE or return undef; |
366
|
2
|
|
|
|
|
18
|
return 1; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=pod |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=head2 serialize |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Unlike the C method, which shows only the immediate content |
374
|
|
|
|
|
|
|
within an element, Document objects also have to be able to be written |
375
|
|
|
|
|
|
|
out to a file again. |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
When doing this we need to take into account some additional factors. |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
Primarily, we need to handle here-docs correctly, so that are written |
380
|
|
|
|
|
|
|
to the file in the expected place. |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
The C method generates the actual file content for a given |
383
|
|
|
|
|
|
|
Document object. The resulting string can be written straight to a file. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
Returns the serialized document as a string. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=cut |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub serialize { |
390
|
7055
|
|
|
7055
|
1
|
286926
|
my $self = shift; |
391
|
7055
|
|
|
|
|
15288
|
my @tokens = $self->tokens; |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
# The here-doc content buffer |
394
|
7055
|
|
|
|
|
11395
|
my $heredoc = ''; |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
# Start the main loop |
397
|
7055
|
|
|
|
|
8226
|
my $output = ''; |
398
|
7055
|
|
|
|
|
15005
|
foreach my $i ( 0 .. $#tokens ) { |
399
|
264430
|
|
|
|
|
267637
|
my $Token = $tokens[$i]; |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
# Handle normal tokens |
402
|
264430
|
100
|
|
|
|
522203
|
unless ( $Token->isa('PPI::Token::HereDoc') ) { |
403
|
263827
|
|
|
|
|
356305
|
my $content = $Token->content; |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
# Handle the trivial cases |
406
|
263827
|
100
|
100
|
|
|
393991
|
unless ( $heredoc ne '' and $content =~ /\n/ ) { |
407
|
263411
|
|
|
|
|
268307
|
$output .= $content; |
408
|
263411
|
|
|
|
|
298709
|
next; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# We have pending here-doc content that needs to be |
412
|
|
|
|
|
|
|
# inserted just after the first newline in the content. |
413
|
416
|
100
|
|
|
|
822
|
if ( $content eq "\n" ) { |
414
|
|
|
|
|
|
|
# Shortcut the most common case for speed |
415
|
294
|
|
|
|
|
516
|
$output .= $content . $heredoc; |
416
|
|
|
|
|
|
|
} else { |
417
|
|
|
|
|
|
|
# Slower and more general version |
418
|
122
|
|
|
|
|
559
|
$content =~ s/\n/\n$heredoc/; |
419
|
122
|
|
|
|
|
244
|
$output .= $content; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
416
|
|
|
|
|
498
|
$heredoc = ''; |
423
|
416
|
|
|
|
|
668
|
next; |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
# This token is a HereDoc. |
427
|
|
|
|
|
|
|
# First, add the token content as normal, which in this |
428
|
|
|
|
|
|
|
# case will definitely not contain a newline. |
429
|
603
|
|
|
|
|
1247
|
$output .= $Token->content; |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
# Pick up the indentation, which may be undef. |
432
|
603
|
|
100
|
|
|
1465
|
my $indentation = $Token->indentation || ''; |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
# Now add all of the here-doc content to the heredoc buffer. |
435
|
603
|
|
|
|
|
1245
|
foreach my $line ( $Token->heredoc ) { |
436
|
947
|
100
|
|
|
|
1902
|
$heredoc .= "\n" eq $line ? $line : $indentation . $line; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
603
|
100
|
|
|
|
1249
|
if ( $Token->{_damaged} ) { |
440
|
|
|
|
|
|
|
# Special Case: |
441
|
|
|
|
|
|
|
# There are a couple of warning/bug situations |
442
|
|
|
|
|
|
|
# that can occur when a HereDoc content was read in |
443
|
|
|
|
|
|
|
# from the end of a file that we silently allow. |
444
|
|
|
|
|
|
|
# |
445
|
|
|
|
|
|
|
# When writing back out to the file we have to |
446
|
|
|
|
|
|
|
# auto-repair these problems if we aren't going back |
447
|
|
|
|
|
|
|
# on to the end of the file. |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# When calculating $last_line, ignore the final token if |
450
|
|
|
|
|
|
|
# and only if it has a single newline at the end. |
451
|
459
|
|
|
|
|
604
|
my $last_index = $#tokens; |
452
|
459
|
100
|
|
|
|
1913
|
if ( $tokens[$last_index]->{content} =~ /^[^\n]*\n$/ ) { |
453
|
284
|
|
|
|
|
396
|
$last_index--; |
454
|
|
|
|
|
|
|
} |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
# This is a two part test. |
457
|
|
|
|
|
|
|
# First, are we on the last line of the |
458
|
|
|
|
|
|
|
# content part of the file |
459
|
|
|
|
|
|
|
my $last_line = List::Util::none { |
460
|
1252
|
50
|
|
1252
|
|
4243
|
$tokens[$_] and $tokens[$_]->{content} =~ /\n/ |
461
|
459
|
|
|
|
|
2259
|
} (($i + 1) .. $last_index); |
462
|
459
|
50
|
|
|
|
1626
|
if ( ! defined $last_line ) { |
463
|
|
|
|
|
|
|
# Handles the null list case |
464
|
0
|
|
|
|
|
0
|
$last_line = 1; |
465
|
|
|
|
|
|
|
} |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
# Secondly, are their any more here-docs after us, |
468
|
|
|
|
|
|
|
# (with content or a terminator) |
469
|
|
|
|
|
|
|
my $any_after = List::Util::any { |
470
|
|
|
|
|
|
|
$tokens[$_]->isa('PPI::Token::HereDoc') |
471
|
|
|
|
|
|
|
and ( |
472
|
2
|
|
|
|
|
8
|
scalar(@{$tokens[$_]->{_heredoc}}) |
473
|
|
|
|
|
|
|
or |
474
|
|
|
|
|
|
|
defined $tokens[$_]->{_terminator_line} |
475
|
|
|
|
|
|
|
) |
476
|
459
|
100
|
33
|
1536
|
|
1386
|
} (($i + 1) .. $#tokens); |
|
1536
|
|
|
|
|
4018
|
|
477
|
459
|
50
|
|
|
|
1541
|
if ( ! defined $any_after ) { |
478
|
|
|
|
|
|
|
# Handles the null list case |
479
|
0
|
|
|
|
|
0
|
$any_after = ''; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
# We don't need to repair the last here-doc on the |
483
|
|
|
|
|
|
|
# last line. But we do need to repair anything else. |
484
|
459
|
50
|
33
|
|
|
1314
|
unless ( $last_line and ! $any_after ) { |
485
|
|
|
|
|
|
|
# Add a terminating string if it didn't have one |
486
|
0
|
0
|
|
|
|
0
|
unless ( defined $Token->{_terminator_line} ) { |
487
|
0
|
|
|
|
|
0
|
$Token->{_terminator_line} = $Token->{_terminator}; |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# Add a trailing newline to the terminating |
491
|
|
|
|
|
|
|
# string if it didn't have one. |
492
|
0
|
0
|
|
|
|
0
|
unless ( $Token->{_terminator_line} =~ /\n$/ ) { |
493
|
0
|
|
|
|
|
0
|
$Token->{_terminator_line} .= "\n"; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
# Now add the termination line to the heredoc buffer |
499
|
603
|
100
|
|
|
|
1300
|
if ( defined $Token->{_terminator_line} ) { |
500
|
151
|
|
|
|
|
349
|
$heredoc .= $indentation . $Token->{_terminator_line}; |
501
|
|
|
|
|
|
|
} |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
# End of tokens |
505
|
|
|
|
|
|
|
|
506
|
7055
|
50
|
|
|
|
12967
|
if ( $heredoc ne '' ) { |
507
|
|
|
|
|
|
|
# If the file doesn't end in a newline, we need to add one |
508
|
|
|
|
|
|
|
# so that the here-doc content starts on the next line. |
509
|
0
|
0
|
|
|
|
0
|
unless ( $output =~ /\n$/ ) { |
510
|
0
|
|
|
|
|
0
|
$output .= "\n"; |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
# Now we add the remaining here-doc content |
514
|
|
|
|
|
|
|
# to the end of the file. |
515
|
0
|
|
|
|
|
0
|
$output .= $heredoc; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
7055
|
|
|
|
|
26411
|
$output; |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=pod |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=head2 hex_id |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
The C method generates an unique identifier for the Perl document. |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
This identifier is basically just the serialized document, with |
528
|
|
|
|
|
|
|
Unix-specific newlines, passed through MD5 to produce a hexadecimal string. |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
This identifier is used by a variety of systems (such as L |
531
|
|
|
|
|
|
|
and L) as a unique key against which to store or cache |
532
|
|
|
|
|
|
|
information about a document (or indeed, to cache the document itself). |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
Returns a 32 character hexadecimal string. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=cut |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
sub hex_id { |
539
|
163
|
|
|
163
|
1
|
67165
|
PPI::Util::md5hex($_[0]->serialize); |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=pod |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=head2 index_locations |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
Within a document, all L objects can be considered to have a |
547
|
|
|
|
|
|
|
"location", a line/column position within the document when considered as a |
548
|
|
|
|
|
|
|
file. This position is primarily useful for debugging type activities. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
The method for finding the position of a single Element is a bit laborious, |
551
|
|
|
|
|
|
|
and very slow if you need to do it a lot. So the C method |
552
|
|
|
|
|
|
|
will index and save the locations of every Element within the Document in |
553
|
|
|
|
|
|
|
advance, making future calls to virtually free. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
Please note that this index should always be cleared using C |
556
|
|
|
|
|
|
|
once you are finished with the locations. If content is added to or removed |
557
|
|
|
|
|
|
|
from the file, these indexed locations will be B. |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=cut |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub index_locations { |
562
|
255
|
|
|
255
|
1
|
2262
|
my $self = shift; |
563
|
255
|
|
|
|
|
618
|
my @tokens = $self->tokens; |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
# Whenever we hit a heredoc we will need to increment by |
566
|
|
|
|
|
|
|
# the number of lines in its content section when we |
567
|
|
|
|
|
|
|
# encounter the next token with a newline in it. |
568
|
255
|
|
|
|
|
701
|
my $heredoc = 0; |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
# Find the first Token without a location |
571
|
255
|
|
|
|
|
442
|
my ($first, $location) = (); |
572
|
255
|
|
|
|
|
825
|
foreach ( 0 .. $#tokens ) { |
573
|
254
|
|
|
|
|
458
|
my $Token = $tokens[$_]; |
574
|
254
|
50
|
|
|
|
566
|
next if $Token->{_location}; |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
# Found the first Token without a location |
577
|
|
|
|
|
|
|
# Calculate the new location if needed. |
578
|
254
|
50
|
|
|
|
513
|
if ($_) { |
579
|
0
|
|
|
|
|
0
|
$location = |
580
|
|
|
|
|
|
|
$self->_add_location( $location, $tokens[$_ - 1], \$heredoc ); |
581
|
|
|
|
|
|
|
} else { |
582
|
254
|
50
|
|
|
|
1028
|
my $logical_file = |
583
|
|
|
|
|
|
|
$self->can('filename') ? $self->filename : undef; |
584
|
254
|
|
|
|
|
653
|
$location = [ 1, 1, 1, 1, $logical_file ]; |
585
|
|
|
|
|
|
|
} |
586
|
254
|
|
|
|
|
384
|
$first = $_; |
587
|
254
|
|
|
|
|
350
|
last; |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
# Calculate locations for the rest |
591
|
255
|
100
|
|
|
|
527
|
if ( defined $first ) { |
592
|
254
|
|
|
|
|
548
|
foreach ( $first .. $#tokens ) { |
593
|
66261
|
|
|
|
|
75908
|
my $Token = $tokens[$_]; |
594
|
66261
|
|
|
|
|
88817
|
$Token->{_location} = $location; |
595
|
66261
|
|
|
|
|
84465
|
$location = $self->_add_location( $location, $Token, \$heredoc ); |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
# Add any here-doc lines to the counter |
598
|
66261
|
100
|
|
|
|
169467
|
if ( $Token->isa('PPI::Token::HereDoc') ) { |
599
|
34
|
|
|
|
|
84
|
$heredoc += $Token->heredoc + 1; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
|
604
|
255
|
|
|
|
|
3136
|
1; |
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
sub _add_location { |
608
|
66261
|
|
|
66261
|
|
80898
|
my ($self, $start, $Token, $heredoc) = @_; |
609
|
66261
|
|
|
|
|
95090
|
my $content = $Token->{content}; |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Does the content contain any newlines |
612
|
66261
|
|
|
|
|
93397
|
my $newlines =()= $content =~ /\n/g; |
613
|
66261
|
|
|
|
|
87146
|
my ($logical_line, $logical_file) = |
614
|
|
|
|
|
|
|
$self->_logical_line_and_file($start, $Token, $newlines); |
615
|
|
|
|
|
|
|
|
616
|
66261
|
100
|
|
|
|
90454
|
unless ( $newlines ) { |
617
|
|
|
|
|
|
|
# Handle the simple case |
618
|
|
|
|
|
|
|
return [ |
619
|
55382
|
|
|
|
|
82757
|
$start->[LOCATION_LINE], |
620
|
|
|
|
|
|
|
$start->[LOCATION_CHARACTER] + length($content), |
621
|
|
|
|
|
|
|
$start->[LOCATION_COLUMN] |
622
|
|
|
|
|
|
|
+ $self->_visual_length( |
623
|
|
|
|
|
|
|
$content, |
624
|
|
|
|
|
|
|
$start->[LOCATION_COLUMN] |
625
|
|
|
|
|
|
|
), |
626
|
|
|
|
|
|
|
$logical_line, |
627
|
|
|
|
|
|
|
$logical_file, |
628
|
|
|
|
|
|
|
]; |
629
|
|
|
|
|
|
|
} |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
# This is the more complex case where we hit or |
632
|
|
|
|
|
|
|
# span a newline boundary. |
633
|
10879
|
|
|
|
|
12274
|
my $physical_line = $start->[LOCATION_LINE] + $newlines; |
634
|
10879
|
|
|
|
|
22189
|
my $location = [ $physical_line, 1, 1, $logical_line, $logical_file ]; |
635
|
10879
|
100
|
66
|
|
|
26558
|
if ( $heredoc and $$heredoc ) { |
636
|
31
|
|
|
|
|
62
|
$location->[LOCATION_LINE] += $$heredoc; |
637
|
31
|
|
|
|
|
41
|
$location->[LOCATION_LOGICAL_LINE] += $$heredoc; |
638
|
31
|
|
|
|
|
40
|
$$heredoc = 0; |
639
|
|
|
|
|
|
|
} |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
# Does the token have additional characters |
642
|
|
|
|
|
|
|
# after their last newline. |
643
|
10879
|
100
|
|
|
|
22661
|
if ( $content =~ /\n([^\n]+?)\z/ ) { |
644
|
275
|
|
|
|
|
745
|
$location->[LOCATION_CHARACTER] += length($1); |
645
|
275
|
|
|
|
|
508
|
$location->[LOCATION_COLUMN] += |
646
|
|
|
|
|
|
|
$self->_visual_length( |
647
|
|
|
|
|
|
|
$1, $location->[LOCATION_COLUMN], |
648
|
|
|
|
|
|
|
); |
649
|
|
|
|
|
|
|
} |
650
|
|
|
|
|
|
|
|
651
|
10879
|
|
|
|
|
15257
|
$location; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
sub _logical_line_and_file { |
655
|
66261
|
|
|
66261
|
|
76765
|
my ($self, $start, $Token, $newlines) = @_; |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
# Regex taken from perlsyn, with the correction that there's no space |
658
|
|
|
|
|
|
|
# required between the line number and the file name. |
659
|
66261
|
100
|
|
|
|
89944
|
if ($start->[LOCATION_CHARACTER] == 1) { |
660
|
10630
|
100
|
|
|
|
32331
|
if ( $Token->isa('PPI::Token::Comment') ) { |
|
|
100
|
|
|
|
|
|
661
|
1764
|
100
|
|
|
|
3253
|
if ( |
662
|
|
|
|
|
|
|
$Token->content =~ m< |
663
|
|
|
|
|
|
|
\A |
664
|
|
|
|
|
|
|
\# \s* |
665
|
|
|
|
|
|
|
line \s+ |
666
|
|
|
|
|
|
|
(\d+) \s* |
667
|
|
|
|
|
|
|
(?: (\"?) ([^\"]* [^\s\"]) \2 )? |
668
|
|
|
|
|
|
|
\s* |
669
|
|
|
|
|
|
|
\z |
670
|
|
|
|
|
|
|
>xms |
671
|
|
|
|
|
|
|
) { |
672
|
13
|
|
66
|
|
|
64
|
return $1, ($3 || $start->[LOCATION_LOGICAL_FILE]); |
673
|
|
|
|
|
|
|
} |
674
|
|
|
|
|
|
|
} |
675
|
|
|
|
|
|
|
elsif ( $Token->isa('PPI::Token::Pod') ) { |
676
|
343
|
|
|
|
|
829
|
my $content = $Token->content; |
677
|
343
|
|
|
|
|
455
|
my $line; |
678
|
343
|
|
|
|
|
403
|
my $file = $start->[LOCATION_LOGICAL_FILE]; |
679
|
343
|
|
|
|
|
379
|
my $end_of_directive; |
680
|
343
|
|
|
|
|
1184
|
while ( |
681
|
|
|
|
|
|
|
$content =~ m< |
682
|
|
|
|
|
|
|
^ |
683
|
|
|
|
|
|
|
\# \s*? |
684
|
|
|
|
|
|
|
line \s+? |
685
|
|
|
|
|
|
|
(\d+) (?: (?! \n) \s)* |
686
|
|
|
|
|
|
|
(?: (\"?) ([^\"]*? [^\s\"]) \2 )?? |
687
|
|
|
|
|
|
|
\s*? |
688
|
|
|
|
|
|
|
$ |
689
|
|
|
|
|
|
|
>xmsg |
690
|
|
|
|
|
|
|
) { |
691
|
6
|
|
66
|
|
|
50
|
($line, $file) = ($1, ( $3 || $file ) ); |
692
|
6
|
|
|
|
|
13
|
$end_of_directive = pos $content; |
693
|
|
|
|
|
|
|
} |
694
|
|
|
|
|
|
|
|
695
|
343
|
100
|
|
|
|
615
|
if (defined $line) { |
696
|
6
|
|
|
|
|
9
|
pos $content = $end_of_directive; |
697
|
6
|
|
|
|
|
23
|
my $post_directive_newlines =()= $content =~ m< \G [^\n]* \n >xmsg; |
698
|
6
|
|
|
|
|
20
|
return $line + $post_directive_newlines - 1, $file; |
699
|
|
|
|
|
|
|
} |
700
|
|
|
|
|
|
|
} |
701
|
|
|
|
|
|
|
} |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
return |
704
|
66242
|
|
|
|
|
109179
|
$start->[LOCATION_LOGICAL_LINE] + $newlines, |
705
|
|
|
|
|
|
|
$start->[LOCATION_LOGICAL_FILE]; |
706
|
|
|
|
|
|
|
} |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
sub _visual_length { |
709
|
55657
|
|
|
55657
|
|
67691
|
my ($self, $content, $pos) = @_; |
710
|
|
|
|
|
|
|
|
711
|
55657
|
|
|
|
|
63890
|
my $tab_width = $self->tab_width; |
712
|
55657
|
|
|
|
|
59192
|
my ($length, $vis_inc); |
713
|
|
|
|
|
|
|
|
714
|
55657
|
100
|
|
|
|
178793
|
return length $content if $content !~ /\t/; |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
# Split the content in tab and non-tab parts and calculate the |
717
|
|
|
|
|
|
|
# "visual increase" of each part. |
718
|
4253
|
|
|
|
|
14320
|
for my $part ( split(/(\t)/, $content) ) { |
719
|
15647
|
100
|
|
|
|
18353
|
if ($part eq "\t") { |
720
|
7798
|
|
|
|
|
9495
|
$vis_inc = $tab_width - ($pos-1) % $tab_width; |
721
|
|
|
|
|
|
|
} |
722
|
|
|
|
|
|
|
else { |
723
|
7849
|
|
|
|
|
7737
|
$vis_inc = length $part; |
724
|
|
|
|
|
|
|
} |
725
|
15647
|
|
|
|
|
14358
|
$length += $vis_inc; |
726
|
15647
|
|
|
|
|
16044
|
$pos += $vis_inc; |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
|
729
|
4253
|
|
|
|
|
13883
|
$length; |
730
|
|
|
|
|
|
|
} |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=pod |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=head2 flush_locations |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
When no longer needed, the C method clears all location data |
737
|
|
|
|
|
|
|
from the tokens. |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
=cut |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
sub flush_locations { |
742
|
1
|
|
|
1
|
1
|
552
|
shift->_flush_locations(@_); |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
=pod |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
=head2 normalized |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
The C method is used to generate a "Layer 1" |
750
|
|
|
|
|
|
|
L object for the current Document. |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
A "normalized" Perl Document is an arbitrary structure that removes any |
753
|
|
|
|
|
|
|
irrelevant parts of the document and refactors out variations in style, |
754
|
|
|
|
|
|
|
to attempt to approach something that is closer to the "true meaning" |
755
|
|
|
|
|
|
|
of the Document. |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
See L for more information on document normalization and |
758
|
|
|
|
|
|
|
the tasks for which it is useful. |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
Returns a L object, or C on error. |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
=cut |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
sub normalized { |
765
|
|
|
|
|
|
|
# The normalization process will utterly destroy and mangle |
766
|
|
|
|
|
|
|
# anything passed to it, so we are going to only give it a |
767
|
|
|
|
|
|
|
# clone of ourselves. |
768
|
4
|
|
|
4
|
1
|
1390
|
PPI::Normal->process( $_[0]->clone ); |
769
|
|
|
|
|
|
|
} |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
=pod |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
=head1 complete |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
The C method is used to determine if a document is cleanly |
776
|
|
|
|
|
|
|
structured, all braces are closed, the final statement is |
777
|
|
|
|
|
|
|
fully terminated and all heredocs are fully entered. |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
Returns true if the document is complete or false if not. |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
=cut |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
sub complete { |
784
|
2
|
|
|
2
|
0
|
663
|
my $self = shift; |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
# Every structure has to be complete |
787
|
|
|
|
|
|
|
$self->find_any( sub { |
788
|
15
|
50
|
|
15
|
|
57
|
$_[1]->isa('PPI::Structure') |
789
|
|
|
|
|
|
|
and |
790
|
|
|
|
|
|
|
! $_[1]->complete |
791
|
|
|
|
|
|
|
} ) |
792
|
2
|
50
|
|
|
|
14
|
and return ''; |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
# Strip anything that isn't a statement off the end |
795
|
2
|
|
|
|
|
14
|
my @child = $self->children; |
796
|
2
|
|
66
|
|
|
13
|
while ( @child and not $child[-1]->isa('PPI::Statement') ) { |
797
|
2
|
|
|
|
|
7
|
pop @child; |
798
|
|
|
|
|
|
|
} |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
# We must have at least one statement |
801
|
2
|
50
|
|
|
|
11
|
return '' unless @child; |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
# Check the completeness of the last statement |
804
|
2
|
|
|
|
|
7
|
return $child[-1]->_complete; |
805
|
|
|
|
|
|
|
} |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
##################################################################### |
812
|
|
|
|
|
|
|
# PPI::Node Methods |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
# We are a scope boundary |
815
|
|
|
|
|
|
|
### XS -> PPI/XS.xs:_PPI_Document__scope 0.903+ |
816
|
|
|
|
|
|
|
sub scope() { 1 } |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
##################################################################### |
823
|
|
|
|
|
|
|
# PPI::Element Methods |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
sub insert_before { |
826
|
0
|
|
|
0
|
1
|
0
|
return undef; |
827
|
|
|
|
|
|
|
# die "Cannot insert_before a PPI::Document"; |
828
|
|
|
|
|
|
|
} |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
sub insert_after { |
831
|
0
|
|
|
0
|
1
|
0
|
return undef; |
832
|
|
|
|
|
|
|
# die "Cannot insert_after a PPI::Document"; |
833
|
|
|
|
|
|
|
} |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
sub replace { |
836
|
0
|
|
|
0
|
1
|
0
|
return undef; |
837
|
|
|
|
|
|
|
# die "Cannot replace a PPI::Document"; |
838
|
|
|
|
|
|
|
} |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
##################################################################### |
845
|
|
|
|
|
|
|
# Error Handling |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
# Set the error message |
848
|
|
|
|
|
|
|
sub _error { |
849
|
1
|
|
|
1
|
|
2
|
$errstr = $_[1]; |
850
|
1
|
|
|
|
|
3
|
undef; |
851
|
|
|
|
|
|
|
} |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
# Clear the error message. |
854
|
|
|
|
|
|
|
# Returns the object as a convenience. |
855
|
|
|
|
|
|
|
sub _clear { |
856
|
2327
|
|
|
2327
|
|
3627
|
$errstr = ''; |
857
|
2327
|
|
|
|
|
3241
|
$_[0]; |
858
|
|
|
|
|
|
|
} |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
=pod |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
=head2 errstr |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
For error that occur when loading and saving documents, you can use |
865
|
|
|
|
|
|
|
C, as either a static or object method, to access the error message. |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
If a Document loads or saves without error, C will return false. |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
=cut |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
sub errstr { |
872
|
2339
|
|
|
2339
|
1
|
11340
|
$errstr; |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
##################################################################### |
880
|
|
|
|
|
|
|
# Native Storable Support |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
sub STORABLE_freeze { |
883
|
4
|
|
|
4
|
0
|
698
|
my $self = shift; |
884
|
4
|
|
|
|
|
9
|
my $class = ref $self; |
885
|
4
|
|
|
|
|
18
|
my %hash = %$self; |
886
|
4
|
|
|
|
|
489
|
return ($class, \%hash); |
887
|
|
|
|
|
|
|
} |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
sub STORABLE_thaw { |
890
|
6
|
|
|
6
|
0
|
565
|
my ($self, undef, $class, $hash) = @_; |
891
|
6
|
|
|
|
|
12
|
bless $self, $class; |
892
|
6
|
|
|
|
|
19
|
foreach ( keys %$hash ) { |
893
|
21
|
|
|
|
|
38
|
$self->{$_} = delete $hash->{$_}; |
894
|
|
|
|
|
|
|
} |
895
|
6
|
|
|
|
|
24
|
$self->__link_children; |
896
|
|
|
|
|
|
|
} |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
1; |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
=pod |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
=head1 TO DO |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
- May need to overload some methods to forcefully prevent Document |
905
|
|
|
|
|
|
|
objects becoming children of another Node. |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
=head1 SUPPORT |
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
See the L in the main module. |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
=head1 AUTHOR |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
Adam Kennedy Eadamk@cpan.orgE |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
=head1 SEE ALSO |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
L, L |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
=head1 COPYRIGHT |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
Copyright 2001 - 2011 Adam Kennedy. |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
This program is free software; you can redistribute |
924
|
|
|
|
|
|
|
it and/or modify it under the same terms as Perl itself. |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
The full text of the license can be found in the |
927
|
|
|
|
|
|
|
LICENSE file included with this module. |
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
=cut |