File Coverage

blib/lib/Perl/Critic/Policy/Miscellanea/ProhibitUselessNoCritic.pm
Criterion Covered Total %
statement 30 37 81.0
branch 1 4 25.0
condition 0 3 0.0
subroutine 12 14 85.7
pod 4 5 80.0
total 47 63 74.6


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Miscellanea::ProhibitUselessNoCritic;
2              
3 40     40   27014 use 5.010001;
  40         214  
4 40     40   318 use strict;
  40         148  
  40         1370  
5 40     40   247 use warnings;
  40         176  
  40         1119  
6              
7 40     40   251 use Readonly;
  40         148  
  40         2175  
8              
9 40     40   302 use List::SomeUtils qw( none );
  40         117  
  40         2071  
10              
11 40     40   310 use Perl::Critic::Utils qw{ :severities :classification };
  40         152  
  40         2213  
12 40     40   14639 use parent 'Perl::Critic::Policy';
  40         158  
  40         269  
13              
14             our $VERSION = '1.150';
15              
16             #-----------------------------------------------------------------------------
17              
18             Readonly::Scalar my $DESC => q{Useless '## no critic' annotation};
19             Readonly::Scalar my $EXPL => q{This annotation can be removed};
20              
21             #-----------------------------------------------------------------------------
22              
23 89     89 0 1629 sub supported_parameters { return () }
24 74     74 1 296 sub default_severity { return $SEVERITY_LOW }
25 74     74 1 342 sub default_themes { return qw(core maintenance) }
26 1     1 1 3 sub applies_to { return 'PPI::Document' }
27              
28             #-----------------------------------------------------------------------------
29              
30             sub violates {
31 1     1 1 3 my ( $self, undef, $doc ) = @_;
32              
33             # If for some reason $doc is not a P::C::Document, then all bets are off
34 1 50       3 return if not $doc->isa('Perl::Critic::Document');
35              
36 1         7 my @violations;
37 1         9 my @suppressed_viols = $doc->suppressed_violations();
38              
39 1         4 for my $ann ( $doc->annotations() ) {
40 0 0   0   0 if ( none { _annotation_suppresses_violation($ann, $_) } @suppressed_viols ) {
  0         0  
41 0         0 push @violations, $self->violation($DESC, $EXPL, $ann->element());
42             }
43             }
44              
45 1         5 return @violations;
46             }
47              
48             #-----------------------------------------------------------------------------
49              
50             sub _annotation_suppresses_violation {
51 0     0     my ($annotation, $violation) = @_;
52              
53 0           my $policy_name = $violation->policy();
54 0           my $line = $violation->location()->[0];
55              
56 0   0       return $annotation->disables_line($line)
57             && $annotation->disables_policy($policy_name);
58             }
59              
60             #-----------------------------------------------------------------------------
61              
62             1;
63              
64             __END__
65              
66             =pod
67              
68             =head1 NAME
69              
70             Perl::Critic::Policy::Miscellanea::ProhibitUselessNoCritic - Remove ineffective "## no critic" annotations.
71              
72              
73             =head1 AFFILIATION
74              
75             This Policy is part of the core L<Perl::Critic|Perl::Critic> distribution.
76              
77              
78             =head1 DESCRIPTION
79              
80             Sometimes, you may need to use a C<"## no critic"> annotation to work around
81             a false-positive bug in L<Perl::Critic|Perl::Critic>. But eventually, that bug might get
82             fixed, leaving your code with extra C<"## no critic"> annotations lying about.
83             Or you may use them to locally disable a Policy, but then later decide to
84             permanently remove that Policy entirely from your profile, making some of
85             those C<"## no critic"> annotations pointless. Or, you may accidentally
86             disable too many Policies at once, creating an opportunity for new
87             violations to slip in unnoticed.
88              
89             This Policy will emit violations if you have a C<"## no critic"> annotation in
90             your source code that does not actually suppress any violations given your
91             current profile. To resolve this, you should either remove the annotation
92             entirely, or adjust the Policy name patterns in the annotation to match only
93             the Policies that are actually being violated in your code.
94              
95              
96             =head1 EXAMPLE
97              
98             For example, let's say I have a regex, but I don't want to use the C</x> flag,
99             which violates the C<RegularExpressions::RequireExtendedFormatting> policy.
100             In the following code, the C<"## no critic"> annotation will suppress
101             violations of that Policy and ALL Policies that match
102             C<m/RegularExpressions/imx>
103              
104             my $re = qr/foo bar baz/ms; ## no critic (RegularExpressions)
105              
106             However, this creates a potential loop-hole for someone to introduce
107             additional violations in the future, without explicitly acknowledging them.
108             This Policy is designed to catch these situations by warning you that you've
109             disabled more Policies than the situation really requires. The above code
110             should be remedied like this:
111              
112             my $re = qr/foo bar baz/ms; ## no critic (RequireExtendedFormatting)
113              
114             Notice how the C<RequireExtendedFormatting> pattern more precisely matches
115             the name of the Policy that I'm trying to suppress.
116              
117              
118             =head1 NOTE
119              
120             Changing your F<.perlcriticrc> file and disabling policies globally or running
121             at a higher (i.e. less restrictive) severity level may cause this Policy to
122             emit additional violations. So you might want to defer using this Policy
123             until you have a fairly stable profile.
124              
125              
126             =head1 CONFIGURATION
127              
128             This Policy is not configurable except for the standard options.
129              
130              
131             =head1 ACKNOWLEDGMENT
132              
133             This Policy was inspired by Adam Kennedy's article at
134             L<http://use.perl.org/article.pl?sid=08/09/24/1957256>.
135              
136              
137             =head1 AUTHOR
138              
139             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
140              
141              
142             =head1 COPYRIGHT
143              
144             Copyright (c) 2005-2021 Imaginative Software Systems. All rights reserved.
145              
146             This program is free software; you can redistribute it and/or modify
147             it under the same terms as Perl itself. The full text of this license
148             can be found in the LICENSE file included with this module.
149              
150             =cut
151              
152             ##############################################################################
153             # Local Variables:
154             # mode: cperl
155             # cperl-indent-level: 4
156             # fill-column: 78
157             # indent-tabs-mode: nil
158             # c-indentation-style: bsd
159             # End:
160             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :