File Coverage

blib/lib/Perl/Lint/Policy/Modules/ProhibitConditionalUseStatements.pm
Criterion Covered Total %
statement 58 58 100.0
branch 27 28 96.4
condition 55 63 87.3
subroutine 7 7 100.0
pod 0 1 0.0
total 147 157 93.6


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::Modules::ProhibitConditionalUseStatements;
2 133     133   75035 use strict;
  133         177  
  133         4627  
3 133     133   1064 use warnings;
  133         3028  
  133         5737  
4 133     133   2957 use Perl::Lint::Constants::Type;
  133         751  
  133         62559  
5 133     133   47126 use Perl::Lint::Keywords;
  133         227  
  133         8424  
6 133     133   639 use parent "Perl::Lint::Policy";
  133         163  
  133         435  
7              
8             use constant {
9 133         44855 DESC => 'Conditional "use" statement',
10             EXPL => 'Use "require" to conditionally include a module',
11 133     133   6326 };
  133         151  
12              
13             sub evaluate {
14 90     90 0 131 my ($class, $file, $tokens, $args) = @_;
15              
16 90         77 my @violations;
17 90         87 my $is_in_cond = 0;
18 90         58 my $is_in_if = 0;
19 90         69 my $is_in_do = 0;
20 90         67 my $is_in_BEGIN = 0;
21 90         67 my $left_brace_num = 0;
22 90         67 my $is_in_illegal_do = 0;
23 90         67 my $previous_violation;
24 90         218 for (my $i = 0, my $next_token, my $token_type, my $token_data; my $token = $tokens->[$i]; $i++) {
25 1143         901 $next_token = $tokens->[$i+1];
26 1143         904 $token_type = $token->{type};
27 1143         838 $token_data = $token->{data};
28              
29 1143 100 100     21104 if (
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
      66        
      100        
      100        
      66        
      100        
      100        
      100        
      66        
30             $token_type == UNLESS_STATEMENT ||
31             $token_type == ELSE_STATEMENT ||
32             $token_type == ELSIF_STATEMENT ||
33             $token_type == WHILE_STATEMENT ||
34             $token_type == UNTIL_STATEMENT ||
35             $token_type == FOR_STATEMENT ||
36             $token_type == FOREACH_STATEMENT ||
37             $token_type == CONTINUE ||
38             ($token_type == BUILTIN_FUNC && $token_data eq 'eval')
39             ) {
40 61         60 $is_in_cond = 1;
41 61         113 next;
42             }
43             elsif (
44             ($token_type == AND || $token_type == OR || $token_type == ALPHABET_OR || $token_type == ALPHABET_AND) && $next_token->{type} == DO
45             ) {
46 12         12 $is_in_illegal_do = 1;
47 12         13 $i++;
48 12         21 $next_token = undef;
49             }
50             elsif ($token_type == DO) {
51 21         46 $is_in_do = 1;
52             }
53             elsif ($token_type == IF_STATEMENT) {
54 21         42 $is_in_if = 1;
55             }
56             elsif ($token_type == MOD_WORD && $token_data eq 'BEGIN') {
57 6         13 $is_in_BEGIN = 1;
58             }
59             elsif ($token_type == LEFT_BRACE) {
60 103         168 $left_brace_num++;
61             }
62             elsif ($token_type == RIGHT_BRACE) {
63 103 100       168 if (--$left_brace_num == 0) {
64 99         101 my $next_token_type = $next_token->{type};
65 99 50 100     329 if (
      66        
      66        
66             $is_in_do && $next_token_type &&
67             (
68             $next_token_type eq IF_STATEMENT ||
69             $next_token_type eq FOR_STATEMENT ||
70             $next_token_type eq WHILE_STATEMENT ||
71             $next_token_type eq UNTIL_STATEMENT ||
72             $next_token_type eq UNLESS_STATEMENT ||
73             $next_token_type eq FOREACH_STATEMENT
74             )
75             ) {
76 18 100       32 push @violations, $previous_violation if $previous_violation;
77             }
78 99         71 $is_in_cond = 0;
79 99         53 $is_in_BEGIN = 0;
80 99         69 $is_in_if = 0;
81 99         57 $is_in_do = 0;
82 99         66 $is_in_illegal_do = 0;
83 99         177 $previous_violation = undef;
84             }
85             }
86             elsif ($is_in_cond || $is_in_illegal_do || $is_in_do || ($is_in_BEGIN && $is_in_if)) {
87 580 100       1085 if ($token_type == USE_DECL) {
88 49         37 my $next_token_type = $next_token->{type};
89 49 100 33     151 if (
      66        
90             $next_token_type == NAMESPACE ||
91             ($next_token_type == USED_NAME && !is_perl_pragma($next_token->{data}))
92             ) {
93             $previous_violation = {
94             filename => $file,
95             line => $token->{line},
96 28         108 description => DESC,
97             explanation => EXPL,
98             policy => __PACKAGE__,
99             };
100 28 100       50 if (!$is_in_do) {
101 21         52 push @violations, $previous_violation;
102             }
103             }
104             }
105             }
106             }
107              
108 90         333 return \@violations;
109             }
110              
111             # TODO support post conditional notation
112              
113             1;
114