File Coverage

blib/lib/Perl/Critic/Policy/CodeLayout/RequireKRParens.pm
Criterion Covered Total %
statement 54 55 98.1
branch 26 28 92.8
condition 18 27 66.6
subroutine 12 13 92.3
pod 4 4 100.0
total 114 127 89.7


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::CodeLayout::RequireKRParens;
2 2     2   2032 use strict;
  2         6  
  2         60  
3 2     2   10 use warnings;
  2         4  
  2         58  
4 2     2   11 use parent qw[ Perl::Critic::Policy ];
  2         16  
  2         24  
5 2     2   133 use Perl::Critic::Utils qw[ :severities :classification ];
  2         5  
  2         114  
6              
7 2     2   681 use constant PBP_PAGE => 9;
  2         5  
  2         1325  
8              
9 12     12 1 127 sub default_severity { return $SEVERITY_LOW }
10 0     0 1 0 sub default_themes { return qw[ cosmetic pbp ] }
11              
12             sub applies_to {
13 11     11 1 132352 return qw[
14             PPI::Token::Word
15             PPI::Structure::Condition
16             PPI::Statement::Compound
17             ];
18             }
19              
20             sub violates {
21 37     37 1 1917 my ($self, $elem, $doc) = @_;
22              
23 37 100       177 goto &_violates_subroutine if $elem->isa('PPI::Token::Word');
24 10 100       42 goto &_violates_condition if $elem->isa('PPI::Structure::Condition');
25 5         16 goto &_violates_compound; # PPI::Statement::Compound
26             }
27              
28             sub _violates_condition {
29 5     5   14 my ($self, $elem, $doc) = @_;
30              
31 5         10 my @violations;
32 5         18 my $prev = $elem->previous_sibling;
33 5 100 66     136 if (ref $prev and not $prev->isa('PPI::Token::Whitespace')) {
34 3         12 push @violations,
35             $self->violation('No whitespace before opening condition parenthesis', PBP_PAGE, $elem);
36             }
37              
38 5         704 my $next = $elem->next_sibling; # end of statement means it's a trailing condition
39 5 100 66     137 if (ref $next and not $next->isa('PPI::Token::Whitespace') and not _is_end_of_statement($next)) {
      100        
40 2         7 push @violations,
41             $self->violation('No whitespace after closing condition parenthesis', PBP_PAGE, $elem);
42             }
43              
44 5         494 return @violations;
45             }
46              
47             sub _violates_subroutine {
48 27     27   58 my ($self, $elem, $doc) = @_;
49 27 100       73 return if is_perl_builtin($elem);
50 24 100 100     601 return if not is_function_call($elem) and not is_method_call($elem);
51              
52             # Check for calls with no parentheses
53 12         2676 my $parens = $elem->snext_sibling();
54 12 100 66     243 return if ref $parens and not $parens->isa('PPI::Structure::List');
55              
56 11         101 my $next_sib = $elem->next_sibling();
57 11 100 66     208 if (ref $next_sib and $next_sib->isa('PPI::Token::Whitespace')) {
58 4         18 return $self->violation('Whitespace between subroutine name and its opening parenthesis',
59             PBP_PAGE, $elem);
60             }
61              
62 7         62 return;
63             }
64              
65             sub _violates_compound {
66 5     5   10 my ($self, $elem, $doc) = @_;
67 5         14 my $type = $elem->type;
68              
69 5 100       208 my $parens =
    100          
70             $type eq 'foreach' ? $elem->find_first('PPI::Structure::List')
71             : $type eq 'for' ? $elem->find_first('PPI::Structure::For')
72             : return; # if and while are handled in _violates_condition()
73              
74 2         641 my @violations;
75 2         14 my $prev = $parens->previous_sibling;
76 2 50 33     61 if (ref $prev and not $prev->isa('PPI::Token::Whitespace')) {
77 2         13 push @violations,
78             $self->violation("No whitespace before opening $type parenthesis", PBP_PAGE, $parens);
79             }
80              
81 2         545 my $next = $parens->next_sibling;
82 2 100 66     59 if (ref $next and not $next->isa('PPI::Token::Whitespace')) {
83 1         7 push @violations,
84             $self->violation("No whitespace after closing $type parenthesis", PBP_PAGE, $parens);
85             }
86              
87 2         274 return @violations;
88             }
89              
90             sub _is_end_of_statement {
91 4     4   11 my ($elem) = @_;
92 4 50       14 return if not ref $elem;
93 4 100       21 return if not $elem->isa('PPI::Token::Structure');
94 2   33     8 return ($elem eq '}' or $elem eq ';');
95             }
96              
97             1;
98             __END__
99             =pod
100              
101             =head1 NAME
102              
103             Perl::Critic::Policy::CodeLayout::RequireKRParens - parenthesise in K&R style
104              
105             =head1 AFFILIATION
106              
107             This policy as a part of the L<Perl::Critic::PolicyBundle::SNEZ> distribution.
108              
109             =head1 DESCRIPTION
110              
111             Put spaces on the outside of parentheses when they are not argument lists.
112              
113             # not ok
114             do_something (12);
115             foreach my $elem(@array) {
116             ...
117             }
118              
119             # ok
120             do_something(12);
121             foreach my $elem (@array) {
122             ...
123             }
124              
125             =head1 CONFIGURATION
126              
127             This Policy is not configurable except for the standard options.
128              
129             =head1 COPYRIGHT
130              
131             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
132              
133             =cut