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