Initial Commit
This commit is contained in:
201
database/perl/vendor/lib/PPI/Statement/Compound.pm
vendored
Normal file
201
database/perl/vendor/lib/PPI/Statement/Compound.pm
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
package PPI::Statement::Compound;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
PPI::Statement::Compound - Describes all compound statements
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
# A compound if statement
|
||||
if ( foo ) {
|
||||
bar();
|
||||
} else {
|
||||
baz();
|
||||
}
|
||||
|
||||
# A compound loop statement
|
||||
foreach ( @list ) {
|
||||
bar($_);
|
||||
}
|
||||
|
||||
=head1 INHERITANCE
|
||||
|
||||
PPI::Statement::Compound
|
||||
isa PPI::Statement
|
||||
isa PPI::Node
|
||||
isa PPI::Element
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
C<PPI::Statement::Compound> objects are used to describe all current forms
|
||||
of compound statements, as described in L<perlsyn>.
|
||||
|
||||
This covers blocks using C<if>, C<unless>, C<for>, C<foreach>, C<while>,
|
||||
and C<continue>. Please note this does B<not> cover "simple" statements
|
||||
with trailing conditions. Please note also that "do" is also not part of
|
||||
a compound statement.
|
||||
|
||||
# This is NOT a compound statement
|
||||
my $foo = 1 if $condition;
|
||||
|
||||
# This is also not a compound statement
|
||||
do { ... } until $condition;
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
C<PPI::Statement::Compound> has a number of methods in addition to the
|
||||
standard L<PPI::Statement>, L<PPI::Node> and L<PPI::Element> methods.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use PPI::Statement ();
|
||||
|
||||
our $VERSION = '1.270'; # VERSION
|
||||
|
||||
our @ISA = "PPI::Statement";
|
||||
|
||||
# Keyword type map
|
||||
my %TYPES = (
|
||||
'if' => 'if',
|
||||
'unless' => 'if',
|
||||
'while' => 'while',
|
||||
'until' => 'while',
|
||||
'for' => 'for',
|
||||
'foreach' => 'foreach',
|
||||
);
|
||||
|
||||
# Lexer clues
|
||||
sub __LEXER__normal() { '' }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# PPI::Statement::Compound analysis methods
|
||||
|
||||
=pod
|
||||
|
||||
=head2 type
|
||||
|
||||
The C<type> method returns the syntactic type of the compound statement.
|
||||
|
||||
There are four basic compound statement types.
|
||||
|
||||
The C<'if'> type includes all variations of the if and unless statements,
|
||||
including any C<'elsif'> or C<'else'> parts of the compound statement.
|
||||
|
||||
The C<'while'> type describes the standard while and until statements, but
|
||||
again does B<not> describes simple statements with a trailing while.
|
||||
|
||||
The C<'for'> type covers the C-style for loops, regardless of whether they
|
||||
were declared using C<'for'> or C<'foreach'>.
|
||||
|
||||
The C<'foreach'> type covers loops that iterate over collections,
|
||||
regardless of whether they were declared using C<'for'> or C<'foreach'>.
|
||||
|
||||
All of the compounds are a variation on one of these four.
|
||||
|
||||
Returns the simple string C<'if'>, C<'for'>, C<'foreach'> or C<'while'>,
|
||||
or C<undef> if the type cannot be determined.
|
||||
|
||||
=cut
|
||||
|
||||
sub type {
|
||||
my $self = shift;
|
||||
my $p = 0; # Child position
|
||||
my $Element = $self->schild($p) or return undef;
|
||||
|
||||
# A labelled statement
|
||||
if ( $Element->isa('PPI::Token::Label') ) {
|
||||
$Element = $self->schild(++$p) or return 'label';
|
||||
}
|
||||
|
||||
# Most simple cases
|
||||
my $content = $Element->content;
|
||||
if ( $content =~ /^for(?:each)?\z/ ) {
|
||||
$Element = $self->schild(++$p) or return $content;
|
||||
if ( $Element->isa('PPI::Token') ) {
|
||||
return 'foreach' if $Element->content =~ /^my|our|state\z/;
|
||||
return 'foreach' if $Element->isa('PPI::Token::Symbol');
|
||||
return 'foreach' if $Element->isa('PPI::Token::QuoteLike::Words');
|
||||
}
|
||||
if ( $Element->isa('PPI::Structure::List') ) {
|
||||
return 'foreach';
|
||||
}
|
||||
return 'for';
|
||||
}
|
||||
return $TYPES{$content} if $Element->isa('PPI::Token::Word');
|
||||
return 'continue' if $Element->isa('PPI::Structure::Block');
|
||||
|
||||
# Unknown (shouldn't exist?)
|
||||
undef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# PPI::Node Methods
|
||||
|
||||
sub scope() { 1 }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# PPI::Element Methods
|
||||
|
||||
sub _complete {
|
||||
my $self = shift;
|
||||
my $type = $self->type or die "Illegal compound statement type";
|
||||
|
||||
# Check the different types of compound statements
|
||||
if ( $type eq 'if' ) {
|
||||
# Unless the last significant child is a complete
|
||||
# block, it must be incomplete.
|
||||
my $child = $self->schild(-1) or return '';
|
||||
$child->isa('PPI::Structure') or return '';
|
||||
$child->braces eq '{}' or return '';
|
||||
$child->_complete or return '';
|
||||
|
||||
# It can STILL be
|
||||
} elsif ( $type eq 'while' ) {
|
||||
die "CODE INCOMPLETE";
|
||||
} else {
|
||||
die "CODE INCOMPLETE";
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 TO DO
|
||||
|
||||
- Write unit tests for this package
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
See the L<support section|PPI/SUPPORT> in the main module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Adam Kennedy E<lt>adamk@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2001 - 2011 Adam Kennedy.
|
||||
|
||||
This program is free software; you can redistribute
|
||||
it and/or modify it under the same terms as Perl itself.
|
||||
|
||||
The full text of the license can be found in the
|
||||
LICENSE file included with this module.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user