File Coverage

blib/lib/Perl/Lint/Policy/Variables/RequireNegativeIndices.pm
Criterion Covered Total %
statement 67 67 100.0
branch 35 40 87.5
condition 22 24 91.6
subroutine 6 6 100.0
pod 0 1 0.0
total 130 138 94.2


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::Variables::RequireNegativeIndices;
2 133     133   100954 use strict;
  133         235  
  133         5244  
3 133     133   586 use warnings;
  133         194  
  133         3526  
4 133     133   956 use Perl::Lint::Constants::Type;
  133         182  
  133         83814  
5 133     133   783 use parent "Perl::Lint::Policy";
  133         198  
  133         789  
6              
7             use constant {
8 133         76287 DESC => 'Negative array index should be used',
9             EXPL => [88],
10 133     133   8973 };
  133         206  
11              
12             my %var_token_types = (
13             &VAR => 1,
14             &GLOBAL_VAR => 1,
15             );
16              
17             my %array_dereference_token_types = (
18             &ARRAY_DEREFERENCE => 1,
19             &ARRAY_SIZE_DEREFERENCE => 1,
20             );
21              
22             my %array_var_token_types = (
23             &ARRAY_VAR => 1,
24             &GLOBAL_ARRAY_VAR => 1,
25             );
26              
27             sub evaluate {
28 5     5 0 17 my ($class, $file, $tokens, $src, $args) = @_;
29              
30 5         12 my @violations;
31 5         46 for (my $i = 0, my $token_type, my $token_data; my $token = $tokens->[$i]; $i++) {
32 118         310 $token_type = $token->{type};
33 118         181 $token_data = $token->{data};
34              
35 118         124 my $is_reference = 0;
36 118 100 100     892 if ($var_token_types{$token_type} || $token_type == SHORT_SCALAR_DEREFERENCE) {
37 45         49 my $var_name;
38 45 100       91 if ($token_type == SHORT_SCALAR_DEREFERENCE) {
39 9         17 $token = $tokens->[++$i];
40 9 50       22 last if !$token;
41              
42 9         16 $var_name = $token->{data};
43 9         13 $is_reference = 1;
44             }
45             else {
46 36         83 $var_name = substr($token->{data}, 1);
47             }
48              
49 45         59 $token = $tokens->[++$i];
50 45 50       89 last if !$token;
51              
52 45 100       114 if ($token->{type} == POINTER) {
53 13         17 $is_reference = 1;
54 13         19 $token = $tokens->[++$i];
55 13 50       33 last if !$token;
56             }
57              
58 45 100       125 if ($token->{type} == LEFT_BRACKET) {
59 36         68 my $nlbracket = 1;
60 36         92 for ($i++; $token = $tokens->[$i]; $i++) {
61 138         203 $token_type = $token->{type};
62              
63 138 100       255 if ($token_type == LEFT_BRACKET) {
64 1         3 $nlbracket++;
65 1         3 next;
66             }
67              
68 137 100       242 if ($token_type == RIGHT_BRACKET) {
69 37 100       150 last if --$nlbracket <= 0;
70 1         3 next;
71             }
72              
73 100 100 100     428 if (
      66        
74             $token_type == ARRAY_SIZE ||
75             ($is_reference && $token_type == SHORT_ARRAY_DEREFERENCE)
76             ) {
77 14         24 $token = $tokens->[++$i];
78 14 50       33 last if !$token;
79              
80 14         24 $token_type = $token->{type};
81              
82 14         18 my $array_size_data;
83 14 100 100     77 if ($is_reference && $var_token_types{$token_type}) {
    100          
84 2         7 $array_size_data = substr $token->{data}, 1;
85             }
86             elsif ($token->{type} == KEY) {
87 11         20 $array_size_data = $token->{data};
88             }
89              
90 14 100       32 if ($array_size_data) {
91 13         39 $array_size_data =~ s/\W.*\Z//; # XXX workaround
92             # ref: https://github.com/goccy/p5-Compiler-Lexer/issues/48
93 13 100       33 if ($array_size_data eq $var_name) {
94 10         68 push @violations, {
95             filename => $file,
96             line => $token->{line},
97             description => DESC,
98             explanation => EXPL,
99             policy => __PACKAGE__,
100             };
101             }
102             }
103              
104 14         47 next;
105             }
106              
107 86 100 100     471 if (
      66        
108             $token_type == ARRAY_DEREFERENCE ||
109             ($is_reference && $token_type == ARRAY_SIZE_DEREFERENCE)
110             ) {
111 5         10 $token = $tokens->[++$i];
112 5 50       18 last if !$token;
113             } # fall through
114 86 100 100     568 if (
      100        
115             (!$is_reference && $array_var_token_types{$token_type}) ||
116             $array_dereference_token_types{$token_type}
117             ) {
118 11         58 ($token_data = substr $token->{data}, 1) =~ s/\W.*\Z//; # XXX workaround
119             # ref: https://github.com/goccy/p5-Compiler-Lexer/issues/48
120 11 100       33 if ($token_data eq $var_name) {
121 8         59 push @violations, {
122             filename => $file,
123             line => $token->{line},
124             description => DESC,
125             explanation => EXPL,
126             policy => __PACKAGE__,
127             };
128             }
129 11         41 next;
130             }
131             }
132             }
133             }
134              
135             }
136              
137 5         55 return \@violations;
138             }
139              
140             1;
141