File Coverage

blib/lib/Perl/Lint/Policy/Subroutines/RequireArgUnpacking.pm
Criterion Covered Total %
statement 84 86 97.6
branch 46 48 95.8
condition 32 36 88.8
subroutine 8 8 100.0
pod 0 1 0.0
total 170 179 94.9


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::Subroutines::RequireArgUnpacking;
2 133     133   70579 use strict;
  133         184  
  133         3098  
3 133     133   442 use warnings;
  133         176  
  133         2875  
4 133     133   468 use List::Util qw/any/;
  133         157  
  133         6543  
5 133     133   850 use Perl::Lint::Constants::Type;
  133         175  
  133         58487  
6 133     133   594 use parent "Perl::Lint::Policy";
  133         182  
  133         582  
7              
8             use constant {
9 133         68062 DESC => 'Always unpack @_ first',
10             EXPL => [178],
11 133     133   6854 };
  133         174  
12              
13             sub evaluate {
14 21     21 0 35 my ($class, $file, $tokens, $src, $args) = @_;
15              
16 21         28 my $require_arg_unpacking_arg = $args->{require_arg_unpacking};
17 21   100     96 my $short_subroutine_statements = $require_arg_unpacking_arg->{short_subroutine_statements} || undef;
18 21   100     75 my $allow_subscripts = $require_arg_unpacking_arg->{allow_subscripts} || 0;
19 21   100     100 my @allow_delegation_to = split(/ /, $require_arg_unpacking_arg->{allow_delegation_to} || '');
20              
21 21         49 my @violations;
22 21         65 for (my $i = 0; my $token = $tokens->[$i]; $i++) {
23 72         63 my $token_type = $token->{type};
24 72         76 my $next_token = $tokens->[$i+1];
25              
26 72 100 66     213 if (
      66        
27             $token_type == FUNCTION_DECL ||
28             ($token_type == KEY && $next_token->{type} == LEFT_BRACE)
29             ) {
30 21         17 my $function_token = $token;
31 21         58 for ($i++; $token = $tokens->[$i]; $i++) {
32 82         68 $token_type = $token->{type};
33              
34 82 100       223 if ($token_type == LEFT_BRACE) {
    100          
35 32         42 my $begin_line = $token->{line};
36              
37             # variable for each line
38 32         22 my $is_inherited = 0;
39 32         36 my $package_name = '';
40              
41 32         30 my $is_violated = 0;
42 32         24 my $left_brace_num = 1;
43 32         67 for ($i++; $token = $tokens->[$i]; $i++) {
44 823         533 $token_type = $token->{type};
45 823         539 my $token_data = $token->{data};
46              
47 823 100 100     4736 if ($token_type == LEFT_BRACE) {
    100 66        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
48 20         26 $left_brace_num++;
49             }
50             elsif ($token_type == RIGHT_BRACE) {
51 52 100       88 if (--$left_brace_num <= 0) {
52 32         31 my $end_line = $token->{line};
53 32 100       50 if ($is_violated) {
54 15 100 100     44 if (
55             not(defined $short_subroutine_statements) ||
56             (($end_line - $begin_line - 1) > $short_subroutine_statements)
57             ) {
58             push @violations, {
59             filename => $file,
60             line => $function_token->{line},
61 14         62 description => DESC,
62             explanation => EXPL,
63             policy => __PACKAGE__,
64             };
65             }
66             }
67 32         109 last;
68             }
69             }
70             elsif ($token_type == BUILTIN_FUNC && $token_data eq 'shift') {
71 11         17 $token = $tokens->[++$i];
72 11         32 $token_type = $token->{type};
73 11 50       24 if ($token_type == LEFT_PAREN) {
74 0         0 $token = $tokens->[++$i];
75 0         0 $token_type = $token->{type};
76             }
77 11 100       30 if ($token_type == ARGUMENT_ARRAY) {
78 2         7 $is_violated = 1;
79             }
80             }
81             elsif ($token_type == SPECIFIC_VALUE && $token_data eq '$_') {
82 29         26 $token = $tokens->[++$i];
83 29         25 $token_type = $token->{type};
84 29 50       43 if ($token_type == LEFT_BRACKET) {
85 29         26 $token = $tokens->[++$i];
86 29         20 $token_type = $token->{type};
87 29 100       40 if ($token_type == INT) {
88 26         48 $is_violated = 1;
89             }
90             }
91             }
92             elsif ($token_type == ARGUMENT_ARRAY && !$allow_subscripts) {
93 56         48 $token = $tokens->[++$i];
94 56         38 $token_type = $token->{type};
95 56 100       105 if ($token_type == LEFT_BRACKET) {
96 1         2 $is_violated = 1;
97             }
98             }
99             elsif ($token_type == NAMESPACE || $token_type == METHOD) {
100 13 100 100     55 if ($is_inherited || $token_data eq 'NEXT' || $token_data eq 'SUPER') {
      100        
101 4         5 $is_inherited = 1;
102 4         4 $package_name .= $token_data;
103 4         8 next;
104             }
105              
106 9         13 my $next_token = $tokens->[$i+1];
107 9         8 my $next_token_type = $next_token->{type};
108 9 100       19 if ($next_token_type == LEFT_PAREN) {
109 5         8 $next_token = $tokens->[$i+2];
110 5         8 $next_token_type = $next_token->{type};
111             }
112 9 100       17 if ($next_token_type == ARGUMENT_ARRAY) {
113 4 100 66 3   41 if (@allow_delegation_to && any {$_ eq $package_name || $_ eq $token_data} @allow_delegation_to) {
  3 100       17  
114 2         10 next;
115             }
116 2         3 $is_violated = 1;
117             }
118 7         17 $package_name .= $token_data;
119             }
120             elsif ($token_type == NAMESPACE_RESOLVER) {
121 6         9 $package_name .= $token_data;
122             }
123             elsif ($token_type == SEMI_COLON) {
124 102         71 $is_inherited = 0;
125 102         158 $package_name = '';
126             }
127             }
128             }
129             elsif ($token_type == SEMI_COLON) {
130 1         3 last;
131             }
132             }
133             }
134             }
135              
136 21         101 return \@violations;
137             }
138              
139             1;
140