File Coverage

blib/lib/Perl/Lint/Policy/ErrorHandling/RequireCarping.pm
Criterion Covered Total %
statement 78 80 97.5
branch 48 54 88.8
condition 70 80 87.5
subroutine 8 8 100.0
pod 0 1 0.0
total 204 223 91.4


line stmt bran cond sub pod time code
1             package Perl::Lint::Policy::ErrorHandling::RequireCarping;
2 133     133   98805 use strict;
  133         285  
  133         5967  
3 133     133   1945 use warnings;
  133         1135  
  133         5468  
4 133     133   1966 use Perl::Lint::Constants::Type;
  133         1819  
  133         87998  
5 133     133   1761 use parent "Perl::Lint::Policy";
  133         1197  
  133         5102  
6              
7             use constant {
8 133         30791 DESC => q{Don't complain about die or warn if the message ends in a newline},
9             EXPL => [283],
10 133     133   11128 };
  133         221  
11              
12             sub evaluate {
13 29     29 0 82 my ($class, $file, $tokens, $src, $args) = @_;
14              
15 29         75 my $options = $args->{require_carping};
16 29         49 my $allow_messages_ending_with_newlines = 1;
17 29 100       101 if (defined $options->{allow_messages_ending_with_newlines}) {
18 1         3 $allow_messages_ending_with_newlines =
19             $options->{allow_messages_ending_with_newlines};
20             }
21             my $allow_in_main_unless_in_subroutine =
22 29   100     125 $options->{allow_in_main_unless_in_subroutine } || 0;
23              
24 29         47 my $is_in_main = 1;
25 29         43 my $is_in_sub = 0;
26              
27 29         35 my $left_brace_num = 0;
28              
29 29         35 my @violations;
30 29         59 my $token_num = scalar @$tokens;
31              
32 29         89 for (my $i = 0; $i < $token_num; $i++) {
33 357         427 my $token = $tokens->[$i];
34 357         339 my $token_type = $token->{type};
35 357         346 my $token_data = $token->{data};
36              
37 357 100 100     1449 if (
    100 66        
    100          
    100          
    100          
38             $token_type eq BUILTIN_FUNC &&
39             ($token_data eq 'die' || $token_data eq 'warn')
40             ) {
41 137         122 my %last_msg;
42 137         259 for ($i++; $i <= $token_num; $i++) {
43 789         755 $token = $tokens->[$i];
44 789         719 $token_type = $token->{type};
45 789         786 $token_data = $token->{data};
46              
47 133     133   708 no warnings qw/uninitialized/;
  133         3417  
  133         69338  
48 789 100 100     12995 if ($token_type == STRING) {
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 100        
    100 66        
    50 100        
      100        
      100        
      100        
      66        
49 82         231 %last_msg = (type => 'not_raw', data => $token_data);
50             }
51             elsif ($token_type == REG_DOUBLE_QUOTE) {
52 10         48 %last_msg = (type => 'not_raw', data => $tokens->[$i+=2]->{data});
53             }
54             elsif ($token_type == RAW_STRING) {
55 53         146 %last_msg = (type => 'raw', data => $token_data);
56             }
57             elsif ($token_type == REG_QUOTE) {
58 39         135 %last_msg = (type => 'raw', data => $tokens->[$i+=2]->{data});
59             }
60             elsif ($token_type == HERE_DOCUMENT_TAG || $token_type == HERE_DOCUMENT_RAW_TAG) {
61 2         10 %last_msg = (type => 'heredoc', data => $token_data);
62             }
63             elsif (
64             $i + 1 >= $token_num ||
65             $token_type == SEMI_COLON ||
66             $token_type == IF_STATEMENT ||
67             $token_type == UNLESS_STATEMENT ||
68             $token_type == WHILE_STATEMENT ||
69             $token_type == FOR_STATEMENT ||
70             $token_type == FOREACH_STATEMENT ||
71             $token_type == UNTIL_STATEMENT ||
72             $token_type == HERE_DOCUMENT_END
73             ) {
74 137         157 my $last_msg_type = $last_msg{type};
75 137         126 my $last_msg_data = $last_msg{data};
76              
77 137 100 66     1280 if(
      66        
      66        
      66        
      100        
      100        
      66        
78             !(defined $last_msg_type && defined $last_msg_data) ||
79             ($last_msg_type eq 'raw' && (substr($last_msg_data, -1) ne "\n" || !$allow_messages_ending_with_newlines)) ||
80             ($last_msg_type eq 'not_raw' && ($last_msg_data !~ /(?:\\n|\n)\Z/ || !$allow_messages_ending_with_newlines))
81             ) {
82 82 100 66     390 if ($is_in_sub || !($is_in_main && $allow_in_main_unless_in_subroutine)) {
      100        
83 74   66     377 push @violations, {
84             filename => $file,
85             line => $token->{line} // $tokens->[-1]->{line},
86             description => DESC,
87             explanation => EXPL,
88             policy => __PACKAGE__,
89             };
90             }
91             }
92 137         393 last;
93             }
94             elsif ($token_type == METHOD) {
95 3         4 $i++; # Skip a left parenthesis
96 3         5 my $left_paren_num = 1;
97 3         10 for ($i++; $i < $token_num; $i++) {
98 7         9 my $token_type = $tokens->[$i]->{type};
99              
100 7 100       12 if ($token_type == RIGHT_PAREN) {
    50          
101 3         3 $left_paren_num--;
102             }
103             elsif ($token_type == LEFT_PAREN) {
104 0         0 $left_paren_num++;
105             }
106              
107 7 100       15 if ($left_paren_num <= 0) {
108 3         6 last;
109             }
110             }
111             }
112             elsif (
113             $token_type == BUILTIN_FUNC ||
114             $token_type == KEY
115             ) {
116 13         13 my $left_paren_num = 0;
117 13         34 for ($i++; $i < $token_num; $i++) {
118 21         23 my $token_type = $tokens->[$i]->{type};
119              
120 21 100       38 if ($token_type == RIGHT_PAREN) {
    100          
121 4         4 $left_paren_num--;
122             }
123             elsif ($token_type == LEFT_PAREN) {
124 4         5 $left_paren_num++;
125             }
126              
127 21 100       38 if ($left_paren_num <= 0) {
128 13         25 last;
129             }
130             }
131             }
132             elsif (
133             $token_type != REG_DELIM &&
134             $token_type != COMMA &&
135             $token_type != RIGHT_PAREN &&
136             $token_type != HERE_DOCUMENT &&
137             $token_type != RAW_HERE_DOCUMENT
138             ) {
139 207         426 %last_msg = ();
140             }
141             elsif ($token_type == PACKAGE) {
142 0 0       0 $is_in_main = $tokens->[++$i]->{data} eq 'main' ? 1 : 0;
143             }
144              
145 133     133   784 use warnings;
  133         241  
  133         30909  
146             }
147             }
148             elsif ($token_type == PACKAGE) {
149 2 50       10 $is_in_main = $tokens->[++$i]->{data} eq 'main' ? 1 : 0;
150             }
151             elsif ($token_type == FUNCTION_DECL) {
152 2         5 $is_in_sub = 1;
153             }
154             elsif ($token_type == LEFT_BRACE) {
155 5         11 $left_brace_num++;
156             }
157             elsif ($token_type == RIGHT_BRACE) {
158 9         12 $left_brace_num--;
159 9 50       16 if ($left_brace_num <= 0) {
160 9         21 $is_in_sub = 0;
161             }
162             }
163             }
164              
165 29         187 return \@violations;
166             }
167              
168             1;
169