File Coverage

blib/lib/Perl/Lint/Policy/ControlStructures/ProhibitPostfixControls.pm
Criterion Covered Total %
statement 48 48 100.0
branch 14 14 100.0
condition 31 34 91.1
subroutine 8 8 100.0
pod 0 1 0.0
total 101 105 96.1


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::ControlStructures::ProhibitPostfixControls;
2 134     134   94787 use strict;
  134         290  
  134         4798  
3 134     134   628 use warnings;
  134         231  
  134         4016  
4 134     134   632 use List::Util qw/any/;
  134         208  
  134         8454  
5 134     134   1070 use Perl::Lint::Constants::Type;
  134         301  
  134         81197  
6 134     134   802 use parent "Perl::Lint::Policy";
  134         242  
  134         789  
7              
8             use constant {
9 134         69056 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   13996 };
  134         720  
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 72 my ($class, $file, $tokens, $src, $args) = @_;
52              
53 15   100     132 my @allow = split /\s+/, ($args->{prohibit_postfix_controls}->{allow} || '');
54              
55 15   100     100 my @flowcontrol = split /\s+/, ($args->{prohibit_postfix_controls}->{flowcontrol} || '');
56 15 100       51 if (@flowcontrol) {
57 2         7 undef %flow_control_statements; # override
58 2         5 for my $flowcontrol (@flowcontrol) {
59 2         6 $flow_control_statements{$flowcontrol} = 1;
60             }
61             }
62              
63 15         25 my @violations;
64 15         22 my $is_postfix = 0;
65 15         79 for (my $i = 0, my $token_type, my $token_data; my $token = $tokens->[$i]; $i++) {
66 569         536 $token_type = $token->{type};
67 569         619 $token_data = $token->{data};
68              
69 569 100 100     2352 if ($token_type == SEMI_COLON || $token_type == LEFT_BRACE || $token_type == RIGHT_BRACE) {
      100        
70 139         112 $is_postfix = 0;
71 139         262 next;
72             }
73              
74 430 100 100     1121 if ($is_postfix && $control_statement_tokens{$token_type}) {
75 29 100   28   161 if (any {$_ eq $token_data} @allow) {
  28         29  
76 7         20 next;
77             }
78              
79 22         158 push @violations, {
80             filename => $file,
81             line => $token->{line},
82             description => sprintf(DESC, $token_data),
83             explanation => EXPL->{$token_type},
84             policy => __PACKAGE__,
85             };
86 22         59 next;
87             }
88              
89 401 100 100     2392 if (
      100        
      100        
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 100     509 if (
      100        
96             $token_type == POINTER ||
97             $like_flow_control_function_tokens{$token_type} ||
98             $flow_control_statements{$token_data}
99             ) {
100 43         112 for ($i++; $token = $tokens->[$i]; $i++) {
101 70         69 $token_type = $token->{type};
102 70 100 33     416 if (
      66        
103             $token_type == SEMI_COLON ||
104             $token_type == LEFT_BRACE ||
105             $control_statement_tokens{$token_type}
106             ) {
107 43         42 last;
108             }
109             }
110             }
111 96         206 next;
112             }
113              
114 305         654 $is_postfix = 1; # other tokens has came
115             }
116              
117 15         92 return \@violations;
118             }
119              
120             1;
121