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   93577 use strict;
  133         239  
  133         4962  
3 133     133   597 use warnings;
  133         235  
  133         3319  
4 133     133   974 use Perl::Lint::Constants::Type;
  133         210  
  133         83035  
5 133     133   55068 use Perl::Lint::Keywords;
  133         320  
  133         11191  
6 133     133   917 use parent "Perl::Lint::Policy";
  133         213  
  133         576  
7              
8             use constant {
9 133         62780 DESC => 'Conditional "use" statement',
10             EXPL => 'Use "require" to conditionally include a module',
11 133     133   8328 };
  133         231  
12              
13             sub evaluate {
14 90     90 0 165 my ($class, $file, $tokens, $args) = @_;
15              
16 90         100 my @violations;
17 90         91 my $is_in_cond = 0;
18 90         91 my $is_in_if = 0;
19 90         82 my $is_in_do = 0;
20 90         85 my $is_in_BEGIN = 0;
21 90         91 my $left_brace_num = 0;
22 90         83 my $is_in_illegal_do = 0;
23 90         78 my $previous_violation;
24 90         280 for (my $i = 0, my $next_token, my $token_type, my $token_data; my $token = $tokens->[$i]; $i++) {
25 1143         1118 $next_token = $tokens->[$i+1];
26 1143         1060 $token_type = $token->{type};
27 1143         1115 $token_data = $token->{data};
28              
29 1143 100 100     26933 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         52 $is_in_cond = 1;
41 61         155 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         14 $is_in_illegal_do = 1;
47 12         12 $i++;
48 12         25 $next_token = undef;
49             }
50             elsif ($token_type == DO) {
51 21         81 $is_in_do = 1;
52             }
53             elsif ($token_type == IF_STATEMENT) {
54 21         56 $is_in_if = 1;
55             }
56             elsif ($token_type == MOD_WORD && $token_data eq 'BEGIN') {
57 6         24 $is_in_BEGIN = 1;
58             }
59             elsif ($token_type == LEFT_BRACE) {
60 103         197 $left_brace_num++;
61             }
62             elsif ($token_type == RIGHT_BRACE) {
63 103 100       167 if (--$left_brace_num == 0) {
64 99         189 my $next_token_type = $next_token->{type};
65 99 50 100     379 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       40 push @violations, $previous_violation if $previous_violation;
77             }
78 99         83 $is_in_cond = 0;
79 99         90 $is_in_BEGIN = 0;
80 99         81 $is_in_if = 0;
81 99         84 $is_in_do = 0;
82 99         92 $is_in_illegal_do = 0;
83 99         239 $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       1567 if ($token_type == USE_DECL) {
88 49         63 my $next_token_type = $next_token->{type};
89 49 100 33     194 if (
      66        
90             $next_token_type == NAMESPACE ||
91             ($next_token_type == USED_NAME && !is_perl_pragma($next_token->{data}))
92             ) {
93 28         145 $previous_violation = {
94             filename => $file,
95             line => $token->{line},
96             description => DESC,
97             explanation => EXPL,
98             policy => __PACKAGE__,
99             };
100 28 100       61 if (!$is_in_do) {
101 21         66 push @violations, $previous_violation;
102             }
103             }
104             }
105             }
106             }
107              
108 90         519 return \@violations;
109             }
110              
111             # TODO support post conditional notation
112              
113             1;
114