File Coverage

blib/lib/Perl/Lint/Policy/ControlStructures/ProhibitPostfixControls.pm
Criterion Covered Total %
statement 48 48 100.0
branch 14 14 100.0
condition 26 34 76.4
subroutine 8 8 100.0
pod 0 1 0.0
total 96 105 91.4


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::ControlStructures::ProhibitPostfixControls;
2 134     134   70913 use strict;
  134         211  
  134         3289  
3 134     134   445 use warnings;
  134         169  
  134         2830  
4 134     134   408 use List::Util qw/any/;
  134         175  
  134         6052  
5 134     134   887 use Perl::Lint::Constants::Type;
  134         177  
  134         61496  
6 134     134   647 use parent "Perl::Lint::Policy";
  134         185  
  134         595  
7              
8             use constant {
9 134         54443 DESC => 'Postfix control "%s" used',
10             EXPL => {
11             &IF_STATEMENT => [93, 94],
12             &UNLESS_STATEMENT => [96, 97],
13             &UNTIL_STATEMENT => [96, 97],
14             &FOR_STATEMENT => [96],
15             &FOREACH_STATEMENT => [96],
16             &WHILE_STATEMENT => [96],
17             &WHEN_STATEMENT => q,
18             }
19 134     134   11197 };
  134         478  
20              
21             my %control_statement_tokens = (
22             &IF_STATEMENT => 1,
23             &UNLESS_STATEMENT => 1,
24             &UNTIL_STATEMENT => 1,
25             &FOR_STATEMENT => 1,
26             &FOREACH_STATEMENT => 1,
27             &WHILE_STATEMENT => 1,
28             &WHEN_STATEMENT => 1,
29             );
30              
31             my %like_flow_control_function_tokens = (
32             &GOTO => 1,
33             &RETURN => 1,
34             &NEXT => 1,
35             &LAST => 1,
36             &REDO => 1,
37             );
38              
39             my %flow_control_statements = (
40             exit => 1,
41             die => 1,
42             warn => 1,
43             carp => 1,
44             croak => 1,
45             cluck => 1,
46             confess => 1,
47             exit => 1,
48             );
49              
50             sub evaluate {
51 15     15 0 30 my ($class, $file, $tokens, $src, $args) = @_;
52              
53 15   100     89 my @allow = split /\s+/, ($args->{prohibit_postfix_controls}->{allow} || '');
54              
55 15   100     55 my @flowcontrol = split /\s+/, ($args->{prohibit_postfix_controls}->{flowcontrol} || '');
56 15 100       31 if (@flowcontrol) {
57 2         7 undef %flow_control_statements; # override
58 2         4 for my $flowcontrol (@flowcontrol) {
59 2         5 $flow_control_statements{$flowcontrol} = 1;
60             }
61             }
62              
63 15         16 my @violations;
64 15         21 my $is_postfix = 0;
65 15         53 for (my $i = 0, my $token_type, my $token_data; my $token = $tokens->[$i]; $i++) {
66 569         388 $token_type = $token->{type};
67 569         421 $token_data = $token->{data};
68              
69 569 100 100     1825 if ($token_type == SEMI_COLON || $token_type == LEFT_BRACE || $token_type == RIGHT_BRACE) {
      100        
70 139         88 $is_postfix = 0;
71 139         183 next;
72             }
73              
74 430 100 66     629 if ($is_postfix && $control_statement_tokens{$token_type}) {
75 29 100   28   121 if (any {$_ eq $token_data} @allow) {
  28         23  
76 7         16 next;
77             }
78              
79             push @violations, {
80             filename => $file,
81             line => $token->{line},
82             description => sprintf(DESC, $token_data),
83 22         116 explanation => EXPL->{$token_type},
84             policy => __PACKAGE__,
85             };
86 22         40 next;
87             }
88              
89 401 100 100     1515 if (
      100        
      66        
90             $token_type == BUILTIN_FUNC ||
91             $token_type == KEY ||
92             $token_type == POINTER ||
93             $like_flow_control_function_tokens{$token_type}
94             ) {
95 96 100 66     265 if (
      66        
96             $token_type == POINTER ||
97             $like_flow_control_function_tokens{$token_type} ||
98             $flow_control_statements{$token_data}
99             ) {
100 43         58 for ($i++; $token = $tokens->[$i]; $i++) {
101 70         48 $token_type = $token->{type};
102 70 100 33     240 if (
      33        
103             $token_type == SEMI_COLON ||
104             $token_type == LEFT_BRACE ||
105             $control_statement_tokens{$token_type}
106             ) {
107 43         30 last;
108             }
109             }
110             }
111 96         138 next;
112             }
113              
114 305         441 $is_postfix = 1; # other tokens has came
115             }
116              
117 15         62 return \@violations;
118             }
119              
120             1;
121