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   67755 use strict;
  133         185  
  133         3195  
3 133     133   410 use warnings;
  133         145  
  133         2467  
4 133     133   748 use Perl::Lint::Constants::Type;
  133         154  
  133         56958  
5 133     133   581 use parent "Perl::Lint::Policy";
  133         150  
  133         550  
6              
7             use constant {
8 133         7143 DESC => 'Mixed high and low-precedence booleans',
9             EXPL => [70],
10 133     133   6331 };
  133         178  
11              
12             use constant {
13 133         35067 ALPHABETICAL => 1,
14             NON_ALPHABETICAL => 2,
15             INVALID => 3,
16 133     133   449 };
  133         144  
17              
18             sub evaluate {
19 7     7 0 11 my ($class, $file, $tokens, $src, $args) = @_;
20              
21 7         5 my @violations;
22              
23             my @context_for_each_depth;
24 7         6 my $left_paren_num = 0;
25 7         19 for (my $i = 0, my $token_type; my $token = $tokens->[$i]; $i++) {
26 182         106 $token_type = $token->{type};
27              
28 182 100 100     1052 if ($token_type == SEMI_COLON) {
    100 100        
    100 100        
    100 100        
    100 66        
29 13 50       19 if ($left_paren_num <= 0) {
30 13 100       20 if (my $status = $context_for_each_depth[0]) {
31 11 100       14 if ($status == INVALID) {
32             push @violations, {
33             filename => $file,
34             line => $token->{line},
35 4         15 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     64 if (@context_for_each_depth and my $status = splice @context_for_each_depth, $left_paren_num) {
49 6 100       8 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       21 if (my $context = $context_for_each_depth[$left_paren_num]) {
67 9 100       17 if ($context != NON_ALPHABETICAL) {
68 4         5 $context_for_each_depth[$left_paren_num] = INVALID;
69             }
70 9         15 next;
71             }
72 7         12 $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       14 if ($context != ALPHABETICAL) {
82 6         6 $context_for_each_depth[$left_paren_num] = INVALID;
83             }
84 11         19 next;
85             }
86 10         15 $context_for_each_depth[$left_paren_num] = ALPHABETICAL;
87             }
88             }
89              
90 7         23 return \@violations;
91             }
92              
93             1;
94