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   90822 use strict;
  133         269  
  133         4742  
3 133     133   628 use warnings;
  133         212  
  133         3246  
4 133     133   1316 use Perl::Lint::Constants::Type;
  133         207  
  133         80074  
5 133     133   798 use parent "Perl::Lint::Policy";
  133         235  
  133         772  
6              
7             use constant {
8 133         8763 DESC => 'Mixed high and low-precedence booleans',
9             EXPL => [70],
10 133     133   8416 };
  133         235  
11              
12             use constant {
13 133         51862 ALPHABETICAL => 1,
14             NON_ALPHABETICAL => 2,
15             INVALID => 3,
16 133     133   625 };
  133         205  
17              
18             sub evaluate {
19 7     7 0 13 my ($class, $file, $tokens, $src, $args) = @_;
20              
21 7         8 my @violations;
22              
23             my @context_for_each_depth;
24 7         6 my $left_paren_num = 0;
25 7         22 for (my $i = 0, my $token_type; my $token = $tokens->[$i]; $i++) {
26 182         172 $token_type = $token->{type};
27              
28 182 100 100     1276 if ($token_type == SEMI_COLON) {
    100 100        
    100 100        
    100 100        
    100 66        
29 13 50       18 if ($left_paren_num <= 0) {
30 13 100       21 if (my $status = $context_for_each_depth[0]) {
31 11 100       18 if ($status == INVALID) {
32 4         16 push @violations, {
33             filename => $file,
34             line => $token->{line},
35             description => DESC,
36             explanation => EXPL,
37             policy => __PACKAGE__,
38             };
39             }
40             }
41 13         29 @context_for_each_depth = ();
42             }
43             }
44             elsif ($token_type == LEFT_PAREN) {
45 22         41 $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 2         9 push @violations, {
51             filename => $file,
52             line => $token->{line},
53             description => DESC,
54             explanation => EXPL,
55             policy => __PACKAGE__,
56             };
57             }
58             }
59 22         37 $left_paren_num--;
60             }
61             elsif (
62             $token_type == AND ||
63             $token_type == OR ||
64             $token_type == NOT
65             ) {
66 16 100       28 if (my $context = $context_for_each_depth[$left_paren_num]) {
67 9 100       13 if ($context != NON_ALPHABETICAL) {
68 4         6 $context_for_each_depth[$left_paren_num] = INVALID;
69             }
70 9         18 next;
71             }
72 7         13 $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       30 if (my $context = $context_for_each_depth[$left_paren_num]) {
81 11 100       18 if ($context != ALPHABETICAL) {
82 6         5 $context_for_each_depth[$left_paren_num] = INVALID;
83             }
84 11         20 next;
85             }
86 10         20 $context_for_each_depth[$left_paren_num] = ALPHABETICAL;
87             }
88             }
89              
90 7         33 return \@violations;
91             }
92              
93             1;
94