File Coverage

blib/lib/PPI/Statement.pm
Criterion Covered Total %
statement 76 92 82.6
branch 3 20 15.0
condition 2 9 22.2
subroutine 24 28 85.7
pod 5 6 83.3
total 110 155 70.9


line stmt bran cond sub pod time code
1             package PPI::Statement;
2              
3             =pod
4              
5             =head1 NAME
6              
7             PPI::Statement - The base class for Perl statements
8              
9             =head1 INHERITANCE
10              
11             PPI::Statement
12             isa PPI::Node
13             isa PPI::Element
14              
15             =head1 DESCRIPTION
16              
17             PPI::Statement is the root class for all Perl statements. This includes (from
18             L<perlsyn>) "Declarations", "Simple Statements" and "Compound Statements".
19              
20             The class PPI::Statement itself represents a "Simple Statement" as defined
21             in the L<perlsyn> manpage.
22              
23             =head1 STATEMENT CLASSES
24              
25             Please note that unless documented themselves, these classes are yet to be
26             frozen/finalised. Names may change slightly or be added or removed.
27              
28             =head2 L<PPI::Statement::Scheduled>
29              
30             This covers all "scheduled" blocks, chunks of code that are executed separately
31             from the main body of the code, at a particular time. This includes all
32             C<BEGIN>, C<CHECK>, C<UNITCHECK>, C<INIT> and C<END> blocks.
33              
34             =head2 L<PPI::Statement::Package>
35              
36             A package declaration, as defined in L<perlfunc|perlfunc/package>.
37              
38             =head2 L<PPI::Statement::Include>
39              
40             A statement that loads or unloads another module.
41              
42             This includes 'use', 'no', and 'require' statements.
43              
44             =head2 L<PPI::Statement::Sub>
45              
46             A named subroutine declaration, or forward declaration
47              
48             =head2 L<PPI::Statement::Variable>
49              
50             A variable declaration statement. This could be either a straight
51             declaration or also be an expression.
52              
53             This includes all 'my', 'state', 'local' and 'our' statements.
54              
55             =head2 L<PPI::Statement::Compound>
56              
57             This covers the whole family of 'compound' statements, as described in
58             L<perlsyn|perlsyn>.
59              
60             This includes all statements starting with 'if', 'unless', 'for', 'foreach'
61             and 'while'. Note that this does NOT include 'do', as it is treated
62             differently.
63              
64             All compound statements have implicit ends. That is, they do not end with
65             a ';' statement terminator.
66              
67             =head2 L<PPI::Statement::Break>
68              
69             A statement that breaks out of a structure.
70              
71             This includes all of 'redo', 'goto', 'next', 'last' and 'return' statements.
72              
73             =head2 L<PPI::Statement::Given>
74              
75             The kind of statement introduced in Perl 5.10 that starts with 'given'. This
76             has an implicit end.
77              
78             =head2 L<PPI::Statement::When>
79              
80             The kind of statement introduced in Perl 5.10 that starts with 'when' or
81             'default'. This also has an implicit end.
82              
83             =head2 L<PPI::Statement::Data>
84              
85             A special statement which encompasses an entire C<__DATA__> block, including
86             the initial C<'__DATA__'> token itself and the entire contents.
87              
88             =head2 L<PPI::Statement::End>
89              
90             A special statement which encompasses an entire __END__ block, including
91             the initial '__END__' token itself and the entire contents, including any
92             parsed PPI::Token::POD that may occur in it.
93              
94             =head2 L<PPI::Statement::Expression>
95              
96             L<PPI::Statement::Expression> is a little more speculative, and is intended
97             to help represent the special rules relating to "expressions" such as in:
98              
99             # Several examples of expression statements
100            
101             # Boolean conditions
102             if ( expression ) { ... }
103            
104             # Lists, such as for arguments
105             Foo->bar( expression )
106              
107             =head2 L<PPI::Statement::Null>
108              
109             A null statement is a special case for where we encounter two consecutive
110             statement terminators. ( ;; )
111              
112             The second terminator is given an entire statement of its own, but one
113             that serves no purpose. Hence a 'null' statement.
114              
115             Theoretically, assuming a correct parsing of a perl file, all null statements
116             are superfluous and should be able to be removed without damage to the file.
117              
118             But don't do that, in case PPI has parsed something wrong.
119              
120             =head2 L<PPI::Statement::UnmatchedBrace>
121              
122             Because L<PPI> is intended for use when parsing incorrect or incomplete code,
123             the problem arises of what to do with a stray closing brace.
124              
125             Rather than die, it is allocated its own "unmatched brace" statement,
126             which really means "unmatched closing brace". An unmatched open brace at the
127             end of a file would become a structure with no contents and no closing brace.
128              
129             If the document loaded is intended to be correct and valid, finding a
130             L<PPI::Statement::UnmatchedBrace> in the PDOM is generally indicative of a
131             misparse.
132              
133             =head2 L<PPI::Statement::Unknown>
134              
135             This is used temporarily mid-parsing to hold statements for which the lexer
136             cannot yet determine what class it should be, usually because there are
137             insufficient clues, or it might be more than one thing.
138              
139             You should never encounter these in a fully parsed PDOM tree.
140              
141             =head1 METHODS
142              
143             C<PPI::Statement> itself has very few methods. Most of the time, you will be
144             working with the more generic L<PPI::Element> or L<PPI::Node> methods, or one
145             of the methods that are subclass-specific.
146              
147             =cut
148              
149 66     66   337 use strict;
  66         102  
  66         1916  
150 66     66   252 use Scalar::Util ();
  66         122  
  66         1185  
151 66     66   229 use Params::Util qw{_INSTANCE};
  66         85  
  66         2763  
152 66     66   251 use PPI::Node ();
  66         102  
  66         776  
153 66     66   241 use PPI::Exception ();
  66         143  
  66         1137  
154 66     66   203 use PPI::Singletons '%_PARENT';
  66         116  
  66         9065  
155              
156             our $VERSION = '1.284';
157              
158             our @ISA = "PPI::Node";
159              
160 66     66   24438 use PPI::Statement::Break ();
  66         206  
  66         1274  
161 66     66   24096 use PPI::Statement::Compound ();
  66         170  
  66         1665  
162 66     66   24054 use PPI::Statement::Data ();
  66         160  
  66         1423  
163 66     66   23255 use PPI::Statement::End ();
  66         163  
  66         1404  
164 66     66   22614 use PPI::Statement::Expression ();
  66         152  
  66         1375  
165 66     66   25564 use PPI::Statement::Include ();
  66         149  
  66         1911  
166 66     66   24403 use PPI::Statement::Null ();
  66         150  
  66         1696  
167 66     66   24136 use PPI::Statement::Package ();
  66         174  
  66         1841  
168 66     66   23796 use PPI::Statement::Scheduled ();
  66         158  
  66         1961  
169 66     66   336 use PPI::Statement::Sub ();
  66         100  
  66         924  
170 66     66   23722 use PPI::Statement::Given ();
  66         159  
  66         1907  
171 66     66   23708 use PPI::Statement::UnmatchedBrace ();
  66         145  
  66         1933  
172 66     66   22831 use PPI::Statement::Unknown ();
  66         148  
  66         1939  
173 66     66   24319 use PPI::Statement::Variable ();
  66         188  
  66         2355  
174 66     66   24277 use PPI::Statement::When ();
  66         189  
  66         31254  
175              
176             # "Normal" statements end at a statement terminator ;
177             # Some are not, and need the more rigorous _continues to see
178             # if we are at an implicit statement boundary.
179             sub __LEXER__normal() { 1 }
180              
181              
182              
183              
184              
185             #####################################################################
186             # Constructor
187              
188             sub new {
189 59180     59180 0 78650 my $class = shift;
190 59180 50       97826 if ( ref $class ) {
191 0         0 PPI::Exception->throw;
192             }
193              
194             # Create the object
195 59180         147617 my $self = bless {
196             children => [],
197             }, $class;
198              
199             # If we have been passed what should be an initial token, add it
200 59180         76721 my $token = shift;
201 59180 100       245886 if ( _INSTANCE($token, 'PPI::Token') ) {
202             # Inlined $self->__add_element(shift);
203             Scalar::Util::weaken(
204 57788         159573 $_PARENT{Scalar::Util::refaddr $token} = $self
205             );
206 57788         60955 push @{$self->{children}}, $token;
  57788         123589  
207             }
208              
209 59180         105480 $self;
210             }
211              
212             =pod
213              
214             =head2 label
215              
216             One factor common to most statements is their ability to be labeled.
217              
218             The C<label> method returns the label for a statement, if one has been
219             defined, but without the trailing colon. Take the following example
220              
221             MYLABEL: while ( 1 .. 10 ) { last MYLABEL if $_ > 5 }
222              
223             For the above statement, the C<label> method would return 'MYLABEL'.
224              
225             Returns false if the statement does not have a label.
226              
227             =cut
228              
229             sub label {
230 0 0   0 1 0 my $first = shift->schild(1) or return '';
231 0 0       0 $first->isa('PPI::Token::Label')
232             ? substr($first, 0, length($first) - 1)
233             : '';
234             }
235              
236             =pod
237              
238             =head2 specialized
239              
240             Answer whether this is a plain statement or one that has more
241             significance.
242              
243             Returns true if the statement is a subclass of this one, false
244             otherwise.
245              
246             =cut
247              
248             # Yes, this is doing precisely what it's intending to prevent
249             # client code from doing. However, since it's here, if the
250             # implementation changes, code outside PPI doesn't care.
251             sub specialized {
252 10     10 1 916 __PACKAGE__ ne ref $_[0];
253             }
254              
255             =pod
256              
257             =head2 stable
258              
259             Much like the L<PPI::Document> method of the same name, the ->stable
260             method converts a statement to source and back again, to determine if
261             a modified statement is still legal, and won't be interpreted in a
262             different way.
263              
264             Returns true if the statement is stable, false if not, or C<undef> on
265             error.
266              
267             =cut
268              
269             sub stable {
270 0     0 1 0 die "The ->stable method has not yet been implemented";
271             }
272              
273              
274              
275              
276              
277             #####################################################################
278             # PPI::Element Methods
279              
280             # Is the statement complete.
281             # By default for a statement, we need a semi-colon at the end.
282             sub _complete {
283 2     2   3 my $self = shift;
284 2         6 my $semi = $self->schild(-1);
285             return !! (
286 2   66     18 defined $semi
287             and
288             $semi->isa('PPI::Token::Structure')
289             and
290             $semi->content eq ';'
291             );
292             }
293              
294             # You can insert either a statement or a non-significant token.
295             sub insert_before {
296 0     0 1   my $self = shift;
297 0 0         my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
298 0 0 0       if ( $Element->isa('PPI::Statement') ) {
    0          
299 0           return $self->__insert_before($Element);
300             } elsif ( $Element->isa('PPI::Token') and ! $Element->significant ) {
301 0           return $self->__insert_before($Element);
302             }
303 0           '';
304             }
305              
306             # As above, you can insert a statement, or a non-significant token
307             sub insert_after {
308 0     0 1   my $self = shift;
309 0 0         my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
310 0 0 0       if ( $Element->isa('PPI::Statement') ) {
    0          
311 0           return $self->__insert_after($Element);
312             } elsif ( $Element->isa('PPI::Token') and ! $Element->significant ) {
313 0           return $self->__insert_after($Element);
314             }
315 0           '';
316             }
317              
318             1;
319              
320             =pod
321              
322             =head1 TO DO
323              
324             - Complete, freeze and document the remaining classes
325              
326             =head1 SUPPORT
327              
328             See the L<support section|PPI/SUPPORT> in the main module.
329              
330             =head1 AUTHOR
331              
332             Adam Kennedy E<lt>adamk@cpan.orgE<gt>
333              
334             =head1 COPYRIGHT
335              
336             Copyright 2001 - 2011 Adam Kennedy.
337              
338             This program is free software; you can redistribute
339             it and/or modify it under the same terms as Perl itself.
340              
341             The full text of the license can be found in the
342             LICENSE file included with this module.
343              
344             =cut