File Coverage

blib/lib/Perl/Lint/Policy/Variables/ProhibitUnusedVariables.pm
Criterion Covered Total %
statement 83 89 93.2
branch 34 38 89.4
condition 6 6 100.0
subroutine 8 8 100.0
pod 0 1 0.0
total 131 142 92.2


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::Variables::ProhibitUnusedVariables;
2 133     133   69382 use strict;
  133         174  
  133         3024  
3 133     133   395 use warnings;
  133         151  
  133         2262  
4 133     133   780 use List::Flatten ();
  133         354  
  133         1277  
5 133     133   359 use List::Util ();
  133         144  
  133         1432  
6 133     133   703 use Perl::Lint::Constants::Type;
  133         145  
  133         58884  
7 133     133   572 use parent "Perl::Lint::Policy";
  133         142  
  133         552  
8              
9             use constant {
10 133         71915 DESC => '"%s" is declared but not used.',
11             EXPL => 'Unused variables clutter code and make it harder to read',
12 133     133   6448 };
  133         164  
13              
14             my %var_token_types = (
15             &LOCAL_VAR => 1,
16             &LOCAL_ARRAY_VAR => 1,
17             &LOCAL_HASH_VAR => 1,
18             &GLOBAL_VAR => 1,
19             &GLOBAL_ARRAY_VAR => 1,
20             &GLOBAL_HASH_VAR => 1,
21             &VAR => 1,
22             &ARRAY_VAR => 1,
23             &HASH_VAR => 1,
24             );
25              
26             sub evaluate {
27 20     20 0 34 my ($class, $file, $tokens, $src, $args) = @_;
28              
29 20         17 my @violations;
30             my $depth;
31 0         0 my %vars_by_depth;
32 20         53 for (my $i = 0, my $token_type; my $token = $tokens->[$i]; $i++) {
33 230         175 $token_type = $token->{type};
34              
35 230 100       274 if ($token_type == LEFT_BRACE) {
36 17         15 $depth++;
37 17         27 next;
38             }
39              
40 213 100       239 if ($token_type == RIGHT_BRACE) {
41 17         31 for my $variable (keys %vars_by_depth) {
42             push @violations, {
43             filename => $file,
44 6         33 line => $vars_by_depth{$variable},
45             description => sprintf(DESC, $variable),
46             explanation => EXPL,
47             policy => __PACKAGE__,
48             };
49             }
50 17         18 %vars_by_depth = ();
51              
52 17         15 $depth--;
53 17         30 next;
54             }
55              
56 196 100       220 if ($token_type == VAR_DECL) {
57 23         27 $token = $tokens->[++$i];
58 23 100       36 if ($token->{type} == LEFT_PAREN) {
59 2         2 my $lpnum = 1;
60 2         3 my %vars_in_paren;
61 2         5 for ($i++; $token = $tokens->[$i]; $i++) {
62 10         9 $token_type = $token->{type};
63              
64 10 50       13 if ($token_type == LEFT_PAREN) {
65 0         0 $lpnum++;
66 0         0 next;
67             }
68              
69 10 100       13 if ($token_type == RIGHT_PAREN) {
70 2 50       5 last if --$lpnum <= 0;
71 0         0 next;
72             }
73              
74 8 100       16 if ($var_token_types{$token_type}) {
75 5         8 $vars_in_paren{$token->{data}} = $token->{line};
76 5         7 next;
77             }
78             }
79              
80 2         4 $token = $tokens->[$i+1];
81 2 100       5 if ($token->{type} != ASSIGN) {
82 1         4 %vars_by_depth = (%vars_by_depth, %vars_in_paren);
83             }
84              
85 2         6 next;
86             }
87              
88 21         24 my $next_token = $tokens->[$i+1];
89 21 100       35 if ($next_token->{type} != ASSIGN) {
90 14         23 $vars_by_depth{$token->{data}} = $token->{line};
91             }
92 21         40 next;
93             }
94              
95 173 100 100     430 if ($token_type == OUR_DECL || $token_type == LOCAL_DECL) {
96 2         9 for ($i++; $token = $tokens->[$i]; $i++) {
97 4 100       8 if ($token->{type} == SEMI_COLON) {
98 2         2 last;
99             }
100             }
101 2         5 next;
102             }
103              
104 171 100       227 if ($var_token_types{$token_type}) {
105 10         12 my $variable = $token->{data};
106              
107 10         12 $token = $tokens->[$i+1];
108 10         10 $token_type = $token->{type};
109 10 100       21 if ($token_type == LEFT_BRACKET) {
    100          
110 1         3 $variable = '@' . substr $variable, 1;
111             }
112             elsif ($token_type == LEFT_BRACE) {
113 1         3 $variable = '%' . substr $variable, 1;
114             }
115              
116 10         12 delete $vars_by_depth{$variable};
117 10         17 next;
118             }
119              
120 161 100 100     505 if (
121             $token_type == REG_REPLACE_TO ||
122             $token_type == REG_EXP
123             ) {
124 11         12 my $regex = $token->{data};
125              
126 11         29 while ($regex =~ /(\\*)([\$\@]\w+[\{\[]?)/gc) { # XXX
127 5 50       13 if (length($1) % 2 == 0) {
128             # not escaped
129 5         6 my $variable = $2;
130 5         8 my $last_char = substr $variable, -1, 1;
131 5 100       9 if ($last_char eq '{') {
    50          
132 3         6 $variable = '%' . substr $variable, 1, -1;
133             }
134             elsif ($last_char eq '[') {
135 0         0 $variable = '@' . substr $variable, 1, -1;
136             }
137              
138 5         6 delete $vars_by_depth{$variable};
139 5         12 next;
140             }
141             else {
142             # escaped
143 0         0 next;
144             }
145             }
146              
147 11         15 next;
148             }
149             }
150              
151 20         25 for my $variable (keys %vars_by_depth) {
152             push @violations, {
153             filename => $file,
154 4         22 line => $vars_by_depth{$variable},
155             description => sprintf(DESC, $variable),
156             explanation => EXPL,
157             policy => __PACKAGE__,
158             };
159             }
160              
161 20         75 return \@violations;
162             }
163              
164             1;
165