File Coverage

blib/lib/Perl/Lint/Policy/ValuesAndExpressions/ProhibitMixedBooleanOperators.pm
Criterion Covered Total %
statement 45 45 100.0
branch 27 28 96.4
condition 16 18 88.8
subroutine 7 7 100.0
pod 0 1 0.0
total 95 99 95.9


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::ValuesAndExpressions::ProhibitMixedBooleanOperators;
2 133     133   67975 use strict;
  133         196  
  133         3120  
3 133     133   418 use warnings;
  133         155  
  133         2421  
4 133     133   817 use Perl::Lint::Constants::Type;
  133         162  
  133         58019  
5 133     133   549 use parent "Perl::Lint::Policy";
  133         165  
  133         555  
6              
7             use constant {
8 133         7159 DESC => 'Mixed high and low-precedence booleans',
9             EXPL => [70],
10 133     133   6291 };
  133         170  
11              
12             use constant {
13 133         34811 ALPHABETICAL => 1,
14             NON_ALPHABETICAL => 2,
15             INVALID => 3,
16 133     133   451 };
  133         153  
17              
18             sub evaluate {
19 7     7 0 12 my ($class, $file, $tokens, $src, $args) = @_;
20              
21 7         4 my @violations;
22              
23             my @context_for_each_depth;
24 7         7 my $left_paren_num = 0;
25 7         20 for (my $i = 0, my $token_type; my $token = $tokens->[$i]; $i++) {
26 182         122 $token_type = $token->{type};
27              
28 182 100 100     1055 if ($token_type == SEMI_COLON) {
    100 100        
    100 100        
    100 100        
    100 66        
29 13 50       40 if ($left_paren_num <= 0) {
30 13 100       19 if (my $status = $context_for_each_depth[0]) {
31 11 100       16 if ($status == INVALID) {
32             push @violations, {
33             filename => $file,
34             line => $token->{line},
35 4         16 description => DESC,
36             explanation => EXPL,
37             policy => __PACKAGE__,
38             };
39             }
40             }
41 13         27 @context_for_each_depth = ();
42             }
43             }
44             elsif ($token_type == LEFT_PAREN) {
45 22         30 $left_paren_num++;
46             }
47             elsif ($token_type == RIGHT_PAREN) {
48 22 100 66     75 if (@context_for_each_depth and my $status = splice @context_for_each_depth, $left_paren_num) {
49 6 100       12 if ($status == INVALID) {
50             push @violations, {
51             filename => $file,
52             line => $token->{line},
53 2         6 description => DESC,
54             explanation => EXPL,
55             policy => __PACKAGE__,
56             };
57             }
58             }
59 22         33 $left_paren_num--;
60             }
61             elsif (
62             $token_type == AND ||
63             $token_type == OR ||
64             $token_type == NOT
65             ) {
66 16 100       19 if (my $context = $context_for_each_depth[$left_paren_num]) {
67 9 100       15 if ($context != NON_ALPHABETICAL) {
68 4         4 $context_for_each_depth[$left_paren_num] = INVALID;
69             }
70 9         15 next;
71             }
72 7         14 $context_for_each_depth[$left_paren_num] = NON_ALPHABETICAL;
73             }
74             elsif (
75             $token_type == ALPHABET_AND ||
76             $token_type == ALPHABET_OR ||
77             $token_type == ALPHABET_NOT ||
78             $token_type == ALPHABET_XOR
79             ) {
80 21 100       29 if (my $context = $context_for_each_depth[$left_paren_num]) {
81 11 100       16 if ($context != ALPHABETICAL) {
82 6         6 $context_for_each_depth[$left_paren_num] = INVALID;
83             }
84 11         15 next;
85             }
86 10         18 $context_for_each_depth[$left_paren_num] = ALPHABETICAL;
87             }
88             }
89              
90 7         22 return \@violations;
91             }
92              
93             1;
94