File Coverage

blib/lib/Perl/Lint/Policy/BuiltinFunctions/ProhibitUselessTopic.pm
Criterion Covered Total %
statement 55 56 98.2
branch 23 26 88.4
condition 19 27 70.3
subroutine 8 8 100.0
pod 0 1 0.0
total 105 118 88.9


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::BuiltinFunctions::ProhibitUselessTopic;
2 134     134   106517 use strict;
  134         260  
  134         5124  
3 134     134   662 use warnings;
  134         237  
  134         3667  
4 134     134   936 use Perl::Lint::Constants::Type;
  134         228  
  134         99199  
5 134     134   1362 use Perl::Lint::Constants::Kind;
  134         276  
  134         9648  
6 134     134   674 use parent "Perl::Lint::Policy";
  134         276  
  134         876  
7              
8             use constant {
9 134         24235 DESC => 'Useless use of $_',
10             EXPL_FILETEST => '$_ should be omitted when using a filetest operator',
11             EXPL_FUNCTION => '$_ should be omitted when calling "%s"',
12             EXPL_FUNCTION_SPLIT => '$_ should be omitted when calling "split" with two arguments',
13 134     134   9631 };
  134         267  
14              
15             use constant {
16 134         76575 FILETEST_OPERATORS => {
17             -r => 1,
18             -w => 1,
19             -x => 1,
20             -o => 1,
21             -R => 1,
22             -W => 1,
23             -X => 1,
24             -O => 1,
25             -e => 1,
26             -z => 1,
27             -s => 1,
28             -f => 1,
29             -d => 1,
30             -l => 1,
31             -p => 1,
32             -S => 1,
33             -b => 1,
34             -c => 1,
35             -u => 1,
36             -g => 1,
37             -k => 1,
38             -T => 1,
39             -B => 1,
40             -M => 1,
41             -A => 1,
42             -C => 1,
43             },
44             TOPICAL_FUNCS => {
45             abs => 1,
46             alarm => 1,
47             chomp => 1,
48             chop => 1,
49             chr => 1,
50             chroot => 1,
51             cos => 1,
52             defined => 1,
53             eval => 1,
54             exp => 1,
55             glob => 1,
56             hex => 1,
57             int => 1,
58             lc => 1,
59             lcfirst => 1,
60             length => 1,
61             log => 1,
62             lstat => 1,
63             mkdir => 1,
64             oct => 1,
65             ord => 1,
66             pos => 1,
67             print => 1,
68             quotemeta => 1,
69             readlink => 1,
70             readpipe => 1,
71             ref => 1,
72             require => 1,
73             reverse => 1,
74             rmdir => 1,
75             sin => 1,
76             split => 1,
77             sqrt => 1,
78             stat => 1,
79             study => 1,
80             uc => 1,
81             ucfirst => 1,
82             unlink => 1,
83             unpack => 1,
84             },
85 134     134   818 };
  134         289  
86              
87             sub evaluate {
88 8     8 0 18 my ($class, $file, $tokens, $src, $args) = @_;
89              
90 8         14 my @violations;
91 8         39 for (my $i = 0; my $token = $tokens->[$i]; $i++) {
92 180         159 my $token_type = $token->{type};
93 180         159 my $token_data = $token->{data};
94              
95 180 100 100     792 if ($token_type == HANDLE && FILETEST_OPERATORS->{$token_data}) {
    100 66        
96 7         9 $token = $tokens->[++$i];
97 7 50 33     30 if ($token->{type} == SPECIFIC_VALUE && $token->{data} eq '$_') {
98 7         38 push @violations, {
99             filename => $file,
100             line => $token->{line},
101             description => DESC,
102             explanation => EXPL_FILETEST,
103             policy => __PACKAGE__,
104             };
105             }
106             }
107             elsif ($token_type == BUILTIN_FUNC && TOPICAL_FUNCS->{$token_data}) {
108             # Ignore when reverse() called in context of assigning into array
109 18         21 my $function_name = $token_data;
110 18 100       33 if ($function_name eq 'reverse') {
111 3         7 my $two_before_token_type = $tokens->[$i-2]->{type};
112 3 100 66     24 if (
      33        
113             $tokens->[$i-1]->{type} == ASSIGN &&
114             (
115             $two_before_token_type == ARRAY_VAR ||
116             $two_before_token_type == LOCAL_ARRAY_VAR ||
117             $two_before_token_type == GLOBAL_ARRAY_VAR
118             )
119             ) {
120 2         7 next;
121             }
122             }
123              
124 16 100       62 my $expl = $function_name eq 'split' ? EXPL_FUNCTION_SPLIT
125             : sprintf EXPL_FUNCTION, $function_name;
126              
127 16         18 $token = $tokens->[++$i];
128              
129 16 100       35 if ($token->{type} == LEFT_PAREN) {
130 7         6 my $left_paren_num = 1;
131 7         15 for ($i++; $token = $tokens->[$i]; $i++) {
132 26         25 $token_type = $token->{type};
133 26 50       62 if ($token_type == LEFT_PAREN) {
    100          
134 0         0 $left_paren_num++;
135             }
136             elsif ($token_type == RIGHT_PAREN) {
137 7 50       13 if (--$left_paren_num <= 0) {
138 7         8 my $previous_token = $tokens->[$i-1];
139 7 100 100     37 if (
      66        
140             $tokens->[$i-2]->{kind} != KIND_OP &&
141             $previous_token->{type} == SPECIFIC_VALUE &&
142             $previous_token->{data} eq '$_'
143             ) {
144 5         18 push @violations, {
145             filename => $file,
146             line => $token->{line},
147             description => DESC,
148             explanation => $expl,
149             policy => __PACKAGE__,
150             };
151             }
152             }
153 7         16 last;
154             }
155             }
156             }
157             else {
158 9         24 for (; $token = $tokens->[$i]; $i++) {
159 30         32 $token_type = $token->{type};
160 30 100       74 if ($token_type == SEMI_COLON) {
161 9         15 my $previous_token = $tokens->[$i-1];
162 9 100 100     64 if (
      66        
163             $tokens->[$i-2]->{kind} != KIND_OP &&
164             $previous_token->{type} == SPECIFIC_VALUE &&
165             $previous_token->{data} eq '$_'
166             ) {
167 6         37 push @violations, {
168             filename => $file,
169             line => $token->{line},
170             description => DESC,
171             explanation => $expl,
172             policy => __PACKAGE__,
173             };
174             }
175 9         32 last;
176             }
177             }
178             }
179             }
180             }
181              
182 8         44 return \@violations;
183             }
184              
185             1;
186