MooseX-CoverableModifiers
view release on metacpan or search on metacpan
inc/Perl/Tidy.pm view on Meta::CPAN
);
@is_digraph{@_} = (1) x scalar(@_);
@_ = qw( ... **= <<= >>= &&= ||= //= <=> );
@is_trigraph{@_} = (1) x scalar(@_);
@_ = qw(
= **= += *= &= <<= &&=
-= /= |= >>= ||= //=
.= %= ^=
x=
);
@is_assignment{@_} = (1) x scalar(@_);
@_ = qw(
grep
keys
map
reverse
sort
split
);
@is_keyword_returning_list{@_} = (1) x scalar(@_);
@_ = qw(is if unless and or err last next redo return);
@is_if_unless_and_or_last_next_redo_return{@_} = (1) x scalar(@_);
# always break after a closing curly of these block types:
@_ = qw(until while for if elsif else);
@is_until_while_for_if_elsif_else{@_} = (1) x scalar(@_);
@_ = qw(last next redo return);
@is_last_next_redo_return{@_} = (1) x scalar(@_);
@_ = qw(sort map grep);
@is_sort_map_grep{@_} = (1) x scalar(@_);
@_ = qw(sort map grep eval);
@is_sort_map_grep_eval{@_} = (1) x scalar(@_);
@_ = qw(sort map grep eval do);
@is_sort_map_grep_eval_do{@_} = (1) x scalar(@_);
@_ = qw(if unless);
@is_if_unless{@_} = (1) x scalar(@_);
@_ = qw(and or err);
@is_and_or{@_} = (1) x scalar(@_);
# Identify certain operators which often occur in chains.
# Note: the minus (-) causes a side effect of padding of the first line in
# something like this (by sub set_logical_padding):
# Checkbutton => 'Transmission checked',
# -variable => \$TRANS
# This usually improves appearance so it seems ok.
@_ = qw(&& || and or : ? . + - * /);
@is_chain_operator{@_} = (1) x scalar(@_);
# We can remove semicolons after blocks preceded by these keywords
@_ =
qw(BEGIN END CHECK INIT AUTOLOAD DESTROY UNITCHECK continue if elsif else
unless while until for foreach);
@is_block_without_semicolon{@_} = (1) x scalar(@_);
# 'L' is token for opening { at hash key
@_ = qw" L { ( [ ";
@is_opening_type{@_} = (1) x scalar(@_);
# 'R' is token for closing } at hash key
@_ = qw" R } ) ] ";
@is_closing_type{@_} = (1) x scalar(@_);
@_ = qw" { ( [ ";
@is_opening_token{@_} = (1) x scalar(@_);
@_ = qw" } ) ] ";
@is_closing_token{@_} = (1) x scalar(@_);
}
# whitespace codes
use constant WS_YES => 1;
use constant WS_OPTIONAL => 0;
use constant WS_NO => -1;
# Token bond strengths.
use constant NO_BREAK => 10000;
use constant VERY_STRONG => 100;
use constant STRONG => 2.1;
use constant NOMINAL => 1.1;
use constant WEAK => 0.8;
use constant VERY_WEAK => 0.55;
# values for testing indexes in output array
use constant UNDEFINED_INDEX => -1;
# Maximum number of little messages; probably need not be changed.
use constant MAX_NAG_MESSAGES => 6;
# increment between sequence numbers for each type
# For example, ?: pairs might have numbers 7,11,15,...
use constant TYPE_SEQUENCE_INCREMENT => 4;
{
# methods to count instances
my $_count = 0;
sub get_count { $_count; }
sub _increment_count { ++$_count }
sub _decrement_count { --$_count }
}
sub trim {
# trim leading and trailing whitespace from a string
$_[0] =~ s/\s+$//;
$_[0] =~ s/^\s+//;
return $_[0];
}
sub split_words {
inc/Perl/Tidy.pm view on Meta::CPAN
scan_identifier();
},
# type = 'pp' for pre-increment, '++' for post-increment
'++' => sub {
if ( $expecting == TERM ) { $type = 'pp' }
elsif ( $expecting == UNKNOWN ) {
my ( $next_nonblank_token, $i_next ) =
find_next_nonblank_token( $i, $rtokens, $max_token_index );
if ( $next_nonblank_token eq '$' ) { $type = 'pp' }
}
},
'=>' => sub {
if ( $last_nonblank_type eq $tok ) {
complain("Repeated '=>'s \n");
}
# patch for operator_expected: note if we are in the list (use.t)
# TODO: make version numbers a new token type
if ( $statement_type eq 'use' ) { $statement_type = '_use' }
},
# type = 'mm' for pre-decrement, '--' for post-decrement
'--' => sub {
if ( $expecting == TERM ) { $type = 'mm' }
elsif ( $expecting == UNKNOWN ) {
my ( $next_nonblank_token, $i_next ) =
find_next_nonblank_token( $i, $rtokens, $max_token_index );
if ( $next_nonblank_token eq '$' ) { $type = 'mm' }
}
},
'&&' => sub {
error_if_expecting_TERM()
if ( $expecting == TERM );
},
'||' => sub {
error_if_expecting_TERM()
if ( $expecting == TERM );
},
'//' => sub {
error_if_expecting_TERM()
if ( $expecting == TERM );
},
};
# ------------------------------------------------------------
# end hash of code for handling individual token types
# ------------------------------------------------------------
my %matching_start_token = ( '}' => '{', ']' => '[', ')' => '(' );
# These block types terminate statements and do not need a trailing
# semicolon
# patched for SWITCH/CASE/
my %is_zero_continuation_block_type;
@_ = qw( } { BEGIN END CHECK INIT AUTOLOAD DESTROY UNITCHECK continue ;
if elsif else unless while until for foreach switch case given when);
@is_zero_continuation_block_type{@_} = (1) x scalar(@_);
my %is_not_zero_continuation_block_type;
@_ = qw(sort grep map do eval);
@is_not_zero_continuation_block_type{@_} = (1) x scalar(@_);
my %is_logical_container;
@_ = qw(if elsif unless while and or err not && ! || for foreach);
@is_logical_container{@_} = (1) x scalar(@_);
my %is_binary_type;
@_ = qw(|| &&);
@is_binary_type{@_} = (1) x scalar(@_);
my %is_binary_keyword;
@_ = qw(and or err eq ne cmp);
@is_binary_keyword{@_} = (1) x scalar(@_);
# 'L' is token for opening { at hash key
my %is_opening_type;
@_ = qw" L { ( [ ";
@is_opening_type{@_} = (1) x scalar(@_);
# 'R' is token for closing } at hash key
my %is_closing_type;
@_ = qw" R } ) ] ";
@is_closing_type{@_} = (1) x scalar(@_);
my %is_redo_last_next_goto;
@_ = qw(redo last next goto);
@is_redo_last_next_goto{@_} = (1) x scalar(@_);
my %is_use_require;
@_ = qw(use require);
@is_use_require{@_} = (1) x scalar(@_);
my %is_sub_package;
@_ = qw(sub package);
@is_sub_package{@_} = (1) x scalar(@_);
# This hash holds the hash key in $tokenizer_self for these keywords:
my %is_format_END_DATA = (
'format' => '_in_format',
'__END__' => '_in_end',
'__DATA__' => '_in_data',
);
# ref: camel 3 p 147,
# but perl may accept undocumented flags
# perl 5.10 adds 'p' (preserve)
my %quote_modifiers = (
's' => '[cegimosxp]',
'y' => '[cds]',
'tr' => '[cds]',
'm' => '[cgimosxp]',
'qr' => '[imosxp]',
'q' => "",
'qq' => "",
'qw' => "",
inc/Perl/Tidy.pm view on Meta::CPAN
#
# This looks best when 'ci' is one-half of the indentation (i.e., 2 and 4)
my $total_ci = $ci_string_sum;
if (
!$routput_block_type->[$i] # patch: skip for BLOCK
&& ($in_statement_continuation)
&& !( $forced_indentation_flag && $type eq ':' )
)
{
$total_ci += $in_statement_continuation
unless ( $ci_string_in_tokenizer =~ /1$/ );
}
$ci_string_i = $total_ci;
$in_statement_continuation = 0;
}
elsif ($type eq '}'
|| $type eq 'R'
|| $forced_indentation_flag < 0 )
{
# only a nesting error in the script would prevent popping here
if ( @{$rslevel_stack} > 1 ) { pop( @{$rslevel_stack} ); }
$level_i = --$level_in_tokenizer;
# restore previous level values
if ( length($nesting_block_string) > 1 )
{ # true for valid script
chop $nesting_block_string;
$nesting_block_flag = ( $nesting_block_string =~ /1$/ );
chop $nesting_list_string;
$nesting_list_flag = ( $nesting_list_string =~ /1$/ );
chop $ci_string_in_tokenizer;
$ci_string_sum = ones_count($ci_string_in_tokenizer);
$in_statement_continuation =
chop $continuation_string_in_tokenizer;
# zero continuation flag at terminal BLOCK '}' which
# ends a statement.
if ( $routput_block_type->[$i] ) {
# ...These include non-anonymous subs
# note: could be sub ::abc { or sub 'abc
if ( $routput_block_type->[$i] =~ m/^sub\s*/gc ) {
# note: older versions of perl require the /gc modifier
# here or else the \G does not work.
if ( $routput_block_type->[$i] =~ /\G('|::|\w)/gc )
{
$in_statement_continuation = 0;
}
}
# ...and include all block types except user subs with
# block prototypes and these: (sort|grep|map|do|eval)
# /^(\}|\{|BEGIN|END|CHECK|INIT|AUTOLOAD|DESTROY|UNITCHECK|continue|;|if|elsif|else|unless|while|until|for|foreach)$/
elsif (
$is_zero_continuation_block_type{
$routput_block_type->[$i] } )
{
$in_statement_continuation = 0;
}
# ..but these are not terminal types:
# /^(sort|grep|map|do|eval)$/ )
elsif (
$is_not_zero_continuation_block_type{
$routput_block_type->[$i] } )
{
}
# ..and a block introduced by a label
# /^\w+\s*:$/gc ) {
elsif ( $routput_block_type->[$i] =~ /:$/ ) {
$in_statement_continuation = 0;
}
# user function with block prototype
else {
$in_statement_continuation = 0;
}
}
# If we are in a list, then
# we must set continuatoin indentation at the closing
# paren of something like this (paren after $check):
# assert(
# __LINE__,
# ( not defined $check )
# or ref $check
# or $check eq "new"
# or $check eq "old",
# );
elsif ( $tok eq ')' ) {
$in_statement_continuation = 1
if $routput_container_type->[$i] =~ /^[;,\{\}]$/;
}
elsif ( $tok eq ';' ) { $in_statement_continuation = 0 }
}
# use environment after updating
$container_environment =
$nesting_block_flag ? 'BLOCK'
: $nesting_list_flag ? 'LIST'
: "";
$ci_string_i = $ci_string_sum + $in_statement_continuation;
$nesting_block_string_i = $nesting_block_string;
$nesting_list_string_i = $nesting_list_string;
}
# not a structural indentation type..
else {
$container_environment =
$nesting_block_flag ? 'BLOCK'
inc/Perl/Tidy.pm view on Meta::CPAN
# print "BLOCK_TYPE EXAMINING: type=$last_nonblank_type tok=$last_nonblank_token\n";
my ( $i, $rtokens, $rtoken_type, $max_token_index ) = @_;
if ( $last_nonblank_token eq '{'
&& $last_nonblank_type eq $last_nonblank_token )
{
# opening brace where a statement may appear is probably
# a code block but might be and anonymous hash reference
if ( $brace_type[$brace_depth] ) {
return decide_if_code_block( $i, $rtokens, $rtoken_type,
$max_token_index );
}
# cannot start a code block within an anonymous hash
else {
return "";
}
}
elsif ( $last_nonblank_token eq ';' ) {
# an opening brace where a statement may appear is probably
# a code block but might be and anonymous hash reference
return decide_if_code_block( $i, $rtokens, $rtoken_type,
$max_token_index );
}
# handle case of '}{'
elsif ($last_nonblank_token eq '}'
&& $last_nonblank_type eq $last_nonblank_token )
{
# a } { situation ...
# could be hash reference after code block..(blktype1.t)
if ($last_nonblank_block_type) {
return decide_if_code_block( $i, $rtokens, $rtoken_type,
$max_token_index );
}
# must be a block if it follows a closing hash reference
else {
return $last_nonblank_token;
}
}
# NOTE: braces after type characters start code blocks, but for
# simplicity these are not identified as such. See also
# sub is_non_structural_brace.
# elsif ( $last_nonblank_type eq 't' ) {
# return $last_nonblank_token;
# }
# brace after label:
elsif ( $last_nonblank_type eq 'J' ) {
return $last_nonblank_token;
}
# otherwise, look at previous token. This must be a code block if
# it follows any of these:
# /^(BEGIN|END|CHECK|INIT|AUTOLOAD|DESTROY|UNITCHECK|continue|if|elsif|else|unless|do|while|until|eval|for|foreach|map|grep|sort)$/
elsif ( $is_code_block_token{$last_nonblank_token} ) {
# Bug Patch: Note that the opening brace after the 'if' in the following
# snippet is an anonymous hash ref and not a code block!
# print 'hi' if { x => 1, }->{x};
# We can identify this situation because the last nonblank type
# will be a keyword (instead of a closing peren)
if ( $last_nonblank_token =~ /^(if|unless)$/
&& $last_nonblank_type eq 'k' )
{
return "";
}
else {
return $last_nonblank_token;
}
}
# or a sub definition
elsif ( ( $last_nonblank_type eq 'i' || $last_nonblank_type eq 't' )
&& $last_nonblank_token =~ /^sub\b/ )
{
return $last_nonblank_token;
}
# user-defined subs with block parameters (like grep/map/eval)
elsif ( $last_nonblank_type eq 'G' ) {
return $last_nonblank_token;
}
# check bareword
elsif ( $last_nonblank_type eq 'w' ) {
return decide_if_code_block( $i, $rtokens, $rtoken_type,
$max_token_index );
}
# anything else must be anonymous hash reference
else {
return "";
}
}
sub decide_if_code_block {
# USES GLOBAL VARIABLES: $last_nonblank_token
my ( $i, $rtokens, $rtoken_type, $max_token_index ) = @_;
my ( $next_nonblank_token, $i_next ) =
find_next_nonblank_token( $i, $rtokens, $max_token_index );
# we are at a '{' where a statement may appear.
# We must decide if this brace starts an anonymous hash or a code
# block.
# return "" if anonymous hash, and $last_nonblank_token otherwise
# initialize to be code BLOCK
my $code_block_type = $last_nonblank_token;
# Check for the common case of an empty anonymous hash reference:
# Maybe something like sub { { } }
if ( $next_nonblank_token eq '}' ) {
$code_block_type = "";
inc/Perl/Tidy.pm view on Meta::CPAN
POD_START - line starting pod, such as '=head'
POD - pod documentation text
POD_END - last line of pod section, '=cut'
HERE - text of here-document
HERE_END - last line of here-doc (target word)
FORMAT - format section
FORMAT_END - last line of format section, '.'
DATA_START - __DATA__ line
DATA - unidentified text following __DATA__
END_START - __END__ line
END - unidentified text following __END__
ERROR - we are in big trouble, probably not a perl script
END_OF_LIST
}
BEGIN {
# These names are used in error messages
@opening_brace_names = qw# '{' '[' '(' '?' #;
@closing_brace_names = qw# '}' ']' ')' ':' #;
my @digraphs = qw(
.. :: << >> ** && .. || // -> => += -= .= %= &= |= ^= *= <>
<= >= == =~ !~ != ++ -- /= x= ~~
);
@is_digraph{@digraphs} = (1) x scalar(@digraphs);
my @trigraphs = qw( ... **= <<= >>= &&= ||= //= <=> !~~ );
@is_trigraph{@trigraphs} = (1) x scalar(@trigraphs);
# make a hash of all valid token types for self-checking the tokenizer
# (adding NEW_TOKENS : select a new character and add to this list)
my @valid_token_types = qw#
A b C G L R f h Q k t w i q n p m F pp mm U j J Y Z v
{ } ( ) [ ] ; + - / * | % ! x ~ = \ ? : . < > ^ &
#;
push( @valid_token_types, @digraphs );
push( @valid_token_types, @trigraphs );
push( @valid_token_types, '#' );
push( @valid_token_types, ',' );
@is_valid_token_type{@valid_token_types} = (1) x scalar(@valid_token_types);
# a list of file test letters, as in -e (Table 3-4 of 'camel 3')
my @file_test_operators =
qw( A B C M O R S T W X b c d e f g k l o p r s t u w x z);
@is_file_test_operator{@file_test_operators} =
(1) x scalar(@file_test_operators);
# these functions have prototypes of the form (&), so when they are
# followed by a block, that block MAY BE followed by an operator.
@_ = qw( do eval );
@is_block_operator{@_} = (1) x scalar(@_);
# these functions allow an identifier in the indirect object slot
@_ = qw( print printf sort exec system say);
@is_indirect_object_taker{@_} = (1) x scalar(@_);
# These tokens may precede a code block
# patched for SWITCH/CASE
@_ =
qw( BEGIN END CHECK INIT AUTOLOAD DESTROY UNITCHECK continue if elsif else
unless do while until eval for foreach map grep sort
switch case given when);
@is_code_block_token{@_} = (1) x scalar(@_);
# I'll build the list of keywords incrementally
my @Keywords = ();
# keywords and tokens after which a value or pattern is expected,
# but not an operator. In other words, these should consume terms
# to their right, or at least they are not expected to be followed
# immediately by operators.
my @value_requestor = qw(
AUTOLOAD
BEGIN
CHECK
DESTROY
END
EQ
GE
GT
INIT
LE
LT
NE
UNITCHECK
abs
accept
alarm
and
atan2
bind
binmode
bless
break
caller
chdir
chmod
chomp
chop
chown
chr
chroot
close
closedir
cmp
connect
continue
cos
crypt
dbmclose
dbmopen
defined
delete
die
dump
each
else
elsif
eof
eq
exec
exists
exit
exp
fcntl
fileno
flock
for
foreach
formline
ge
getc
getgrgid
getgrnam
gethostbyaddr
gethostbyname
getnetbyaddr
getnetbyname
getpeername
getpgrp
getpriority
getprotobyname
getprotobynumber
getpwnam
getpwuid
( run in 2.793 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )