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   72943 use strict;
  133         177  
  133         5306  
3 133     133   406 use warnings;
  133         153  
  133         4527  
4 133     133   2417 use Perl::Lint::Constants::Type;
  133         4645  
  133         64106  
5 133     133   48756 use Perl::Lint::Keywords;
  133         230  
  133         8273  
6 133     133   592 use parent "Perl::Lint::Policy";
  133         158  
  133         427  
7              
8             use constant {
9 133         44462 DESC => 'Conditional "use" statement',
10             EXPL => 'Use "require" to conditionally include a module',
11 133     133   6177 };
  133         167  
12              
13             sub evaluate {
14 90     90 0 129 my ($class, $file, $tokens, $args) = @_;
15              
16 90         80 my @violations;
17 90         74 my $is_in_cond = 0;
18 90         64 my $is_in_if = 0;
19 90         80 my $is_in_do = 0;
20 90         66 my $is_in_BEGIN = 0;
21 90         67 my $left_brace_num = 0;
22 90         80 my $is_in_illegal_do = 0;
23 90         74 my $previous_violation;
24 90         217 for (my $i = 0, my $next_token, my $token_type, my $token_data; my $token = $tokens->[$i]; $i++) {
25 1143         1023 $next_token = $tokens->[$i+1];
26 1143         803 $token_type = $token->{type};
27 1143         872 $token_data = $token->{data};
28              
29 1143 100 100     22443 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         54 $is_in_cond = 1;
41 61         118 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         9 $is_in_illegal_do = 1;
47 12         15 $i++;
48 12         25 $next_token = undef;
49             }
50             elsif ($token_type == DO) {
51 21         51 $is_in_do = 1;
52             }
53             elsif ($token_type == IF_STATEMENT) {
54 21         46 $is_in_if = 1;
55             }
56             elsif ($token_type == MOD_WORD && $token_data eq 'BEGIN') {
57 6         14 $is_in_BEGIN = 1;
58             }
59             elsif ($token_type == LEFT_BRACE) {
60 103         180 $left_brace_num++;
61             }
62             elsif ($token_type == RIGHT_BRACE) {
63 103 100       152 if (--$left_brace_num == 0) {
64 99         109 my $next_token_type = $next_token->{type};
65 99 50 100     318 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       34 push @violations, $previous_violation if $previous_violation;
77             }
78 99         68 $is_in_cond = 0;
79 99         67 $is_in_BEGIN = 0;
80 99         63 $is_in_if = 0;
81 99         66 $is_in_do = 0;
82 99         62 $is_in_illegal_do = 0;
83 99         195 $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       1271 if ($token_type == USE_DECL) {
88 49         43 my $next_token_type = $next_token->{type};
89 49 100 33     148 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         104 description => DESC,
97             explanation => EXPL,
98             policy => __PACKAGE__,
99             };
100 28 100       54 if (!$is_in_do) {
101 21         52 push @violations, $previous_violation;
102             }
103             }
104             }
105             }
106             }
107              
108 90         378 return \@violations;
109             }
110              
111             # TODO support post conditional notation
112              
113             1;
114