File: ProhibitNoWarnings.pm

package info (click to toggle)
libperl-critic-perl 1.156-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,544 kB
  • sloc: perl: 24,092; lisp: 341; makefile: 7
file content (202 lines) | stat: -rw-r--r-- 5,915 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings;

use 5.010001;
use strict;
use warnings;
use Readonly;

use List::SomeUtils qw(all);

use Perl::Critic::Exception::Fatal::Internal qw{ throw_internal };
use Perl::Critic::Utils qw{ :characters :severities :data_conversion };
use parent 'Perl::Critic::Policy';

our $VERSION = '1.156';

#-----------------------------------------------------------------------------

Readonly::Scalar my $DESC => q{Warnings disabled};
Readonly::Scalar my $EXPL => [ 431 ];

#-----------------------------------------------------------------------------

sub supported_parameters {
    return (
        {
            name            => 'allow',
            description     => 'Permitted warning categories.',
            default_string  => $EMPTY,
            parser          => \&_parse_allow,
        },
        {
            name           => 'allow_with_category_restriction',
            description    =>
                'Allow "no warnings" if it restricts the kinds of warnings that are turned off.',
            default_string => '0',
            behavior       => 'boolean',
        },
    );
}

sub default_severity { return $SEVERITY_HIGH            }
sub default_themes   { return qw( core bugs pbp certrec )       }
sub applies_to       { return 'PPI::Statement::Include' }

#-----------------------------------------------------------------------------

sub _parse_allow {
    my ($self, undef, $config_string) = @_;

    $self->{_allow} = {};

    if( defined $config_string ) {
        my $allowed = lc $config_string; #String of words
        my %allowed = hashify( $allowed =~ m/ (experimental::\w+|\w+) /gxms );

        $self->{_allow} = \%allowed;
    }

    return;
}

#-----------------------------------------------------------------------------

sub violates {

    my ( $self, $elem, undef ) = @_;

    return if $elem->type()   ne 'no';
    return if $elem->pragma() ne 'warnings';

    my @words = _extract_potential_categories( $elem );
    @words >= 2
        and 'no' eq $words[0]
        and 'warnings' eq $words[1]
        or throw_internal
            q<'no warnings' word list did not begin with qw{ no warnings }>;
    splice @words, 0, 2;

    return if $self->{_allow_with_category_restriction} and @words;
    return if @words && all { exists $self->{_allow}->{$_} } @words;

    #If we get here, then it must be a violation
    return $self->violation( $DESC, $EXPL, $elem );
}

#-----------------------------------------------------------------------------

# Traverse the element, accumulating and ultimately returning things
# that might be warnings categories. These are:
# * Words (because of the 'foo' in 'no warnings foo => "bar"');
# * Quotes (because of 'no warnings "foo"');
# * qw{} strings (obviously);
# * Nodes (because of 'no warnings ( "foo", "bar" )').
# We don't lop off the 'no' and 'warnings' because we recurse.
# RT #74647.

{

    Readonly::Array my @HANDLER => (
        [ 'PPI::Token::Word' => sub { return $_[0]->content() } ],
        [ 'PPI::Token::QuoteLike::Words'  =>
            sub { return $_[0]->literal() }, ],
        [ 'PPI::Token::Quote' => sub { return $_[0]->string() } ],
        [ 'PPI::Node' => sub { _extract_potential_categories( $_[0] ) } ],
    );

    sub _extract_potential_categories {
        my ( $elem ) = @_;

        my @words;
        foreach my $child ( $elem->schildren() ) {
            foreach my $hdlr ( @HANDLER ) {
                $child->isa( $hdlr->[0] )
                    or next;
                push @words, $hdlr->[1]->( $child );
                last;
            }
        }

        return @words;
    }

}

1;

__END__

#-----------------------------------------------------------------------------

=pod

=for stopwords perllexwarn

=head1 NAME

Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings - Prohibit various flavors of C<no warnings>.


=head1 AFFILIATION

This Policy is part of the core L<Perl::Critic|Perl::Critic>
distribution.


=head1 DESCRIPTION

There are good reasons for disabling certain kinds of warnings.  But
if you were wise enough to C<use warnings> in the first place, then it
doesn't make sense to disable them completely.  By default, any
C<no warnings> statement will violate this policy.  However, you can
configure this Policy to allow certain types of warnings to be
disabled (See L<"CONFIGURATION">).  A bare C<no warnings>
statement will always raise a violation.


=head1 CONFIGURATION

The permitted warning types can be configured via the C<allow> option.
The value is a list of whitespace-delimited warning types that you
want to be able to disable.  See L<perllexwarn|perllexwarn> for a list
of possible warning types.  An example of this customization:

    [TestingAndDebugging::ProhibitNoWarnings]
    allow = uninitialized once

If a true value is specified for the
C<allow_with_category_restriction> option, then any C<no warnings>
that restricts the set of warnings that are turned off will pass.

    [TestingAndDebugging::ProhibitNoWarnings]
    allow_with_category_restriction = 1

=head1 SEE ALSO

L<Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings|Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings>


=head1 AUTHOR

Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>


=head1 COPYRIGHT

Copyright (c) 2005-2021 Imaginative Software Systems.  All rights reserved.

This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.  The full text of this license can be found in
the LICENSE file included with this module

=cut

##############################################################################
# Local Variables:
#   mode: cperl
#   cperl-indent-level: 4
#   fill-column: 78
#   indent-tabs-mode: nil
#   c-indentation-style: bsd
# End:
# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :