Benchmark-Perl-Formance-Cargo
view release on metacpan or search on metacpan
share/PerlCritic/Critic/Policy/RegularExpressions/ProhibitEnumeratedClasses.pm view on Meta::CPAN
##############################################################################
# $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/distributions/Perl-Critic/lib/Perl/Critic/Policy/RegularExpressions/ProhibitEnumeratedClasses.pm $
# $Date: 2010-06-22 16:14:07 -0400 (Tue, 22 Jun 2010) $
# $Author: clonezone $
# $Revision: 3843 $
##############################################################################
package # hide from indexer
Perl::Critic::Policy::RegularExpressions::ProhibitEnumeratedClasses;
use 5.006001;
use strict;
use warnings;
use Readonly;
use English qw(-no_match_vars);
use List::MoreUtils qw(all);
use Carp qw(carp);
use Perl::Critic::Utils qw{ :booleans :severities hashify };
use base 'Perl::Critic::Policy';
our $VERSION = '1.108';
#-----------------------------------------------------------------------------
Readonly::Scalar my $DESC => q{Use named character classes};
Readonly::Scalar my $EXPL => [248];
Readonly::Array my @PATTERNS => ( # order matters: most to least specific
[q{ },'\\t','\\r','\\n'] => ['\\s', '\\S'],
['A-Z','a-z','_'] => ['\\w', '\\W'],
['A-Z','a-z'] => ['[[:alpha:]]','[[:^alpha:]]'],
['A-Z'] => ['[[:upper:]]','[[:^upper:]]'],
['a-z'] => ['[[:lower:]]','[[:^lower:]]'],
['0-9'] => ['\\d','\\D'],
['\w'] => [undef, '\\W'],
['\s'] => [undef, '\\S'],
);
#-----------------------------------------------------------------------------
sub supported_parameters { return qw() }
sub default_severity { return $SEVERITY_LOWEST }
sub default_themes { return qw( core pbp cosmetic unicode ) }
sub applies_to { return qw(PPI::Token::Regexp::Match
PPI::Token::Regexp::Substitute
PPI::Token::QuoteLike::Regexp) }
#-----------------------------------------------------------------------------
sub initialize_if_enabled {
return eval { require PPIx::Regexp; 1 } ? $TRUE : $FALSE;
}
#-----------------------------------------------------------------------------
sub violates {
my ( $self, $elem, undef ) = @_;
# optimization: don't bother parsing the regexp if there are no character classes
return if $elem !~ m/\[/xms;
my $re = PPIx::Regexp->new_from_cache( $elem ) or return;
$re->failures() and return;
my $anyofs = $re->find( 'PPIx::Regexp::Structure::CharClass' )
or return;
foreach my $anyof ( @{ $anyofs } ) {
my $violation;
$violation = $self->_get_character_class_violations( $elem, $anyof )
and return $violation;
}
return; # OK
}
sub _get_character_class_violations {
my ($self, $elem, $anyof) = @_;
my %elements;
foreach my $element ( $anyof->children() ) {
$elements{ _fixup( $element ) } = 1;
}
for (my $i = 0; $i < @PATTERNS; $i += 2) { ##no critic (CStyleForLoop)
if (all { exists $elements{$_} } @{$PATTERNS[$i]}) {
my $neg = $anyof->negated();
my $improvement = $PATTERNS[$i + 1]->[$neg ? 1 : 0];
next if !defined $improvement;
if ($neg && ! defined $PATTERNS[$i + 1]->[0]) {
# the [^\w] => \W rule only applies if \w is the only token.
# that is it does not apply to [^\w\s]
next if 1 != scalar keys %elements;
}
my $orig = join q{}, '[', ($neg ? q{^} : ()), @{$PATTERNS[$i]}, ']';
return $self->violation( $DESC . " ($orig vs. $improvement)", $EXPL, $elem );
}
}
return; # OK
}
( run in 0.322 second using v1.01-cache-2.11-cpan-71847e10f99 )