File Coverage

blib/lib/Perl/Lint/Policy/ValuesAndExpressions/ProhibitCommaSeparatedStatements.pm
Criterion Covered Total %
statement 94 97 96.9
branch 59 66 89.3
condition 20 21 95.2
subroutine 7 7 100.0
pod 0 1 0.0
total 180 192 93.7


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::ValuesAndExpressions::ProhibitCommaSeparatedStatements;
2 133     133   69210 use strict;
  133         186  
  133         3081  
3 133     133   407 use warnings;
  133         162  
  133         2456  
4 133     133   746 use Perl::Lint::Constants::Type;
  133         156  
  133         57384  
5 133     133   915 use Perl::Lint::Keywords;
  133         185  
  133         6913  
6 133     133   468 use parent "Perl::Lint::Policy";
  133         147  
  133         540  
7              
8             use constant {
9 133         69886 DESC => 'Comma used to separate statements',
10             EXPL => [68, 71],
11 133     133   6359 };
  133         168  
12              
13             sub evaluate {
14 34     34 0 48 my ($class, $file, $tokens, $src, $args) = @_;
15              
16 34         32 my $allow_last_statement_to_be_comma_separated_in_map_and_grep;
17 34 100       69 if (my $this_policies_arg = $args->{prohibit_comma_separated_statements}) {
18 1         3 $allow_last_statement_to_be_comma_separated_in_map_and_grep = $this_policies_arg->{allow_last_statement_to_be_comma_separated_in_map_and_grep};
19             }
20              
21 34         43 my @violations;
22 34         84 for (my $i = 0; my $token = $tokens->[$i]; $i++) {
23 174         135 my $token_type = $token->{type};
24              
25 174 100       383 if ($token_type == ASSIGN) {
    100          
26 30         44 $token = $tokens->[++$i];
27 30         30 $token_type = $token->{type};
28              
29             # if rvalues are surrounded by parans, theres are no problem
30 30 100 100     146 if ($token_type != LEFT_PAREN && $token_type != LEFT_BRACE && $token_type != LEFT_BRACKET) {
      100        
31 24         29 my $does_comma_exist = 0;
32              
33             ONE_LINE:
34 24         46 for (; $token = $tokens->[$i]; $i++) {
35 63         53 $token_type = $token->{type};
36              
37 63 100 100     213 if ($token_type == COMMA) {
    100          
    100          
38 4         9 $does_comma_exist = 1;
39             }
40             elsif ($token_type == SEMI_COLON) {
41 14         13 last;
42             }
43             elsif ($token_type == KEY || $token_type == BUILTIN_FUNC) {
44 23         31 my $token_data = $token->{data};
45 23 100 100     75 if (
46             $token_type == BUILTIN_FUNC &&
47             is_perl_builtin_which_take_multiple_arguments($token_data)
48             ) {
49 9 100 100     34 my $is_map_or_grep = ($token_data eq 'map' || $token_data eq 'grep') ? 1 : 0;
50              
51 9         12 my $next_token = $tokens->[$i+1];
52 9         10 my $next_token_type = $next_token->{type};
53 9 100       13 if ($next_token_type == LEFT_PAREN) {
54 2         3 my $left_paren_num = 1;
55 2         5 for ($i+=2; $token = $tokens->[$i]; $i++) {
56 6         8 $token_type = $token->{type};
57 6 50       14 if ($token_type == LEFT_PAREN) {
    100          
58 0         0 $left_paren_num++;
59             }
60             elsif ($token_type == RIGHT_PAREN) {
61 2 50       6 last if --$left_paren_num <= 0;
62             }
63             }
64             }
65             else {
66 7         7 my $left_brace_num = 0;
67              
68 7 100 100     23 if ($is_map_or_grep && !$allow_last_statement_to_be_comma_separated_in_map_and_grep) {
69 2         7 for (; $token = $tokens->[$i]; $i++) {
70 12         12 $token_type = $token->{type};
71              
72 12 100       37 if ($token_type == LEFT_BRACE) {
    100          
    100          
73 2         14 $left_brace_num++;
74             }
75             elsif ($token_type == RIGHT_BRACE) {
76 2 50       4 last if --$left_brace_num <= 0;
77             }
78             elsif ($token_type == COMMA) {
79 2         4 my $next_token = $tokens->[$i+1];
80 2         2 my $next_token_type = $next_token->{type};
81 2 50       15 if ($next_token_type != KEY) {
82 2         7 $does_comma_exist = 1;
83             }
84             }
85             }
86 2         2 $i++;
87             }
88              
89 7         15 for (; $token = $tokens->[$i]; $i++) {
90 39         27 $token_type = $token->{type};
91 39 100       96 if ($token_type == SEMI_COLON) {
92 7         13 last ONE_LINE;
93             }
94             }
95             }
96             }
97              
98 16         28 for ($i++; $token = $tokens->[$i]; $i++) {
99 35         23 $token_type = $token->{type};
100 35 100       71 if ($token_type == COMMA) {
    100          
101 13         14 my $next_token = $tokens->[$i+1];
102 13         15 my $next_token_type = $next_token->{type};
103 13 100       22 if ($next_token_type != KEY) {
104 12         12 $does_comma_exist = 1;
105             }
106              
107 13         27 last;
108             }
109             elsif ($token_type == SEMI_COLON) {
110 3         6 last ONE_LINE;
111             }
112             }
113             }
114             }
115              
116 24 100       55 if ($does_comma_exist) {
117             push @violations, {
118             filename => $file,
119             line => $token->{line}, # TODO
120 17         102 description => DESC,
121             explanation => EXPL,
122             policy => __PACKAGE__,
123             };
124             }
125             }
126             else {
127 6         16 for ($i++; $token = $tokens->[$i]; $i++) {
128 50         42 $token_type = $token->{type};
129              
130 50 100       105 if ($token_type == SEMI_COLON) {
131 6         15 last;
132             }
133             }
134             }
135             }
136             elsif ($token_type == FOR_STATEMENT) {
137 2         5 my $next_token = $tokens->[$i+1];
138              
139 2 50       7 if ($next_token->{type} != LEFT_PAREN) {
140 0         0 next;
141             }
142              
143 2         2 my $left_paren_num = 1;
144 2         4 my $does_comma_exist = 0;
145 2         3 my $is_semi_colon_in_paren = 0; # XXX
146 2         6 for ($i+=2; $token = $tokens->[$i]; $i++) {
147 28         18 $token_type = $token->{type};
148              
149 28 50       77 if ($token_type == LEFT_PAREN) {
    100          
    100          
    100          
150 0         0 $left_paren_num++;
151             }
152             elsif ($token_type == RIGHT_PAREN) {
153 2 100 66     11 if ($does_comma_exist && $is_semi_colon_in_paren) {
154             push @violations, {
155             filename => $file,
156             line => $token->{line}, # TODO
157 1         5 description => DESC,
158             explanation => EXPL,
159             policy => __PACKAGE__,
160             };
161             }
162              
163 2 50       9 last if --$left_paren_num <= 0;
164             }
165             elsif ($token_type == COMMA) {
166 6         11 $does_comma_exist = 1;
167             }
168             elsif ($token_type == SEMI_COLON) {
169 2 100       5 if ($does_comma_exist) {
170             push @violations, {
171             filename => $file,
172             line => $token->{line}, # TODO
173 1         8 description => DESC,
174             explanation => EXPL,
175             policy => __PACKAGE__,
176             };
177             }
178 2         2 $is_semi_colon_in_paren = 1;
179 2         4 $does_comma_exist = 0;
180             }
181             }
182             }
183             }
184              
185 34         111 return \@violations;
186             }
187              
188             1;
189