File Coverage

blib/lib/Perl/Critic/Policy/RegularExpressions/ProhibitSingleCharAlternation.pm
Criterion Covered Total %
statement 51 51 100.0
branch 16 18 88.8
condition 10 12 83.3
subroutine 15 15 100.0
pod 4 5 80.0
total 96 101 95.0


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::RegularExpressions::ProhibitSingleCharAlternation;
2              
3 40     40   26850 use 5.010001;
  40         190  
4 40     40   296 use strict;
  40         147  
  40         880  
5 40     40   234 use warnings;
  40         133  
  40         1092  
6              
7 40     40   843 use Carp;
  40         156  
  40         2594  
8 40     40   345 use English qw(-no_match_vars);
  40         171  
  40         317  
9 40     40   15030 use List::SomeUtils qw(all);
  40         152  
  40         2161  
10 40     40   292 use Readonly;
  40         121  
  40         2178  
11              
12 40     40   318 use Perl::Critic::Utils qw{ :booleans :characters :severities };
  40         156  
  40         2030  
13 40     40   12982 use parent 'Perl::Critic::Policy';
  40         644  
  40         331  
14              
15             our $VERSION = '1.148';
16              
17             #-----------------------------------------------------------------------------
18              
19             Readonly::Scalar my $EXPL => [265];
20              
21             #-----------------------------------------------------------------------------
22              
23 95     95 0 1642 sub supported_parameters { return qw() }
24 77     77 1 389 sub default_severity { return $SEVERITY_LOWEST }
25 86     86 1 376 sub default_themes { return qw( core pbp performance ) }
26 36     36 1 147 sub applies_to { return qw(PPI::Token::Regexp::Match
27             PPI::Token::Regexp::Substitute
28             PPI::Token::QuoteLike::Regexp) }
29              
30             #-----------------------------------------------------------------------------
31              
32             sub violates {
33 12     12 1 34 my ( $self, $elem, $document ) = @_;
34              
35             # optimization: don't bother parsing the regexp if there are no pipes
36 12 100       47 return if $elem !~ m/[|]/xms;
37              
38 9 50       98 my $re = $document->ppix_regexp_from_element( $elem ) or return;
39 9 100       144254 $re->failures() and return;
40              
41 8         72 my @violations;
42 8         23 foreach my $node ( @{ $re->find_parents( sub {
43 304   66 304   5288 return $_[1]->isa( 'PPIx::Regexp::Token::Operator' )
44             && $_[1]->content() eq q<|>;
45 8 50       63 } ) || [] } ) {
46              
47 9         642 my @singles;
48             my @alternative;
49 9         37 foreach my $kid ( $node->children() ) {
50 172 100 66     812 if ( $kid->isa( 'PPIx::Regexp::Token::Operator' )
    100          
51             && $kid->content() eq q<|>
52             ) {
53             @alternative == 1
54             and $alternative[0]->isa( 'PPIx::Regexp::Token::Literal' )
55 33 100 100     309 and push @singles, map { $_->content() } @alternative;
  13         37  
56 33         126 @alternative = ();
57             } elsif ( $kid->significant() ) {
58 70         277 push @alternative, $kid;
59             }
60             }
61             @alternative == 1
62             and $alternative[0]->isa( 'PPIx::Regexp::Token::Literal' )
63 9 100 100     86 and push @singles, map { $_->content() } @alternative;
  3         10  
64              
65 9 100       50 if ( 1 < @singles ) {
66 3         24 my $description =
67             'Use ['
68             . join( $EMPTY, @singles )
69             . '] instead of '
70             . join q<|>, @singles;
71 3         23 push @violations, $self->violation( $description, $EXPL, $elem );
72             }
73             }
74              
75 8         71 return @violations;
76             }
77              
78             1;
79              
80             __END__
81              
82             #-----------------------------------------------------------------------------
83              
84             =pod
85              
86             =head1 NAME
87              
88             Perl::Critic::Policy::RegularExpressions::ProhibitSingleCharAlternation - Use C<[abc]> instead of C<a|b|c>.
89              
90              
91             =head1 AFFILIATION
92              
93             This Policy is part of the core L<Perl::Critic|Perl::Critic>
94             distribution.
95              
96              
97             =head1 DESCRIPTION
98              
99             Character classes (like C<[abc]>) are significantly faster than single
100             character alternations (like C<(?:a|b|c)>). This policy complains if
101             you have more than one instance of a single character in an
102             alternation. So C<(?:a|the)> is allowed, but C<(?:a|e|i|o|u)> is not.
103              
104              
105             =head1 CONFIGURATION
106              
107             This Policy is not configurable except for the standard options.
108              
109              
110             =head1 CREDITS
111              
112             Initial development of this policy was supported by a grant from the
113             Perl Foundation.
114              
115              
116             =head1 AUTHOR
117              
118             Chris Dolan <cdolan@cpan.org>
119              
120              
121             =head1 COPYRIGHT
122              
123             Copyright (c) 2007-2022 Chris Dolan. Many rights reserved.
124              
125             This program is free software; you can redistribute it and/or modify
126             it under the same terms as Perl itself. The full text of this license
127             can be found in the LICENSE file included with this module
128              
129             =cut
130              
131             # Local Variables:
132             # mode: cperl
133             # cperl-indent-level: 4
134             # fill-column: 78
135             # indent-tabs-mode: nil
136             # c-indentation-style: bsd
137             # End:
138             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :