File Coverage

blib/lib/Perl/Critic/Policy/TestingAndDebugging/RequireUseWarnings.pm
Criterion Covered Total %
statement 65 65 100.0
branch 33 34 97.0
condition 9 9 100.0
subroutine 18 18 100.0
pod 5 6 83.3
total 130 132 98.4


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings;
2              
3 40     40   27107 use 5.010001;
  40         230  
4 40     40   313 use strict;
  40         128  
  40         869  
5 40     40   215 use warnings;
  40         110  
  40         918  
6 40     40   211 use Readonly;
  40         111  
  40         1810  
7              
8 40     40   264 use version ();
  40         116  
  40         844  
9              
10 40     40   227 use Perl::Critic::Utils qw{ :severities $EMPTY };
  40         119  
  40         1994  
11 40     40   5369 use Perl::Critic::Utils::Constants qw{ :equivalent_modules };
  40         126  
  40         4270  
12 40     40   309 use parent 'Perl::Critic::Policy';
  40         109  
  40         288  
13              
14             our $VERSION = '1.148';
15              
16             #-----------------------------------------------------------------------------
17              
18             Readonly::Scalar my $DESC => q{Code before warnings are enabled};
19             Readonly::Scalar my $EXPL => [431];
20              
21             Readonly::Scalar my $MINIMUM_VERSION => version->new(5.006);
22             Readonly::Scalar my $PERL_VERSION_WHICH_IMPLIES_WARNINGS => version->new(5.036);
23              
24             #-----------------------------------------------------------------------------
25              
26             sub supported_parameters {
27             return (
28             {
29 113     113 0 2364 name => 'equivalent_modules',
30             description =>
31             q<The additional modules to treat as equivalent to "warnings".>,
32             default_string => $EMPTY,
33             behavior => 'string list',
34             list_always_present_values => ['warnings', @WARNINGS_EQUIVALENT_MODULES],
35             },
36             );
37             }
38              
39 98     98 1 453 sub default_severity { return $SEVERITY_HIGH }
40 92     92 1 632 sub default_themes { return qw( core pbp bugs certrule ) }
41 55     55 1 230 sub applies_to { return 'PPI::Document' }
42              
43 58     58 1 194 sub default_maximum_violations_per_document { return 1; }
44              
45             #-----------------------------------------------------------------------------
46              
47             sub violates {
48 55     55 1 165 my ( $self, undef, $document ) = @_;
49              
50 55         211 my $version = $document->highest_explicit_perl_version();
51 55 100 100     308 return if $version and ($version < $MINIMUM_VERSION or $version >= $PERL_VERSION_WHICH_IMPLIES_WARNINGS);
      100        
52              
53             # Find the first 'use warnings' statement
54 53         219 my $warn_stmnt = $document->find_first( $self->_generate_is_use_warnings() );
55 53 100       1066 my $warn_line = $warn_stmnt ? $warn_stmnt->location()->[0] : undef;
56              
57             # Find all statements that aren't 'use', 'require', or 'package'
58 53         995 my $stmnts_ref = $self->_find_isnt_include_or_package($document);
59 53 100       201 return if !$stmnts_ref;
60              
61             # If the 'use warnings' statement is not defined, or the other
62             # statement appears before the 'use warnings', then it violates.
63              
64 48         146 my @viols = ();
65 48         100 for my $stmnt ( @{ $stmnts_ref } ) {
  48         198  
66 229 50       822 last if $stmnt->isa('PPI::Statement::End');
67 229 100       750 last if $stmnt->isa('PPI::Statement::Data');
68              
69 228         560 my $stmnt_line = $stmnt->location()->[0];
70 228 100 100     4225 if ( (! defined $warn_line) || ($stmnt_line < $warn_line) ) {
71 24         110 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
72             }
73             }
74 48         229 return @viols;
75             }
76              
77             #-----------------------------------------------------------------------------
78              
79             sub _generate_is_use_warnings {
80 53     53   175 my ($self) = @_;
81              
82             return sub {
83 699     699   7271 my (undef, $elem) = @_;
84              
85 699 100       2459 return 0 if !$elem->isa('PPI::Statement::Include');
86 75 100       257 return 0 if $elem->type() ne 'use';
87              
88             # We only want file-scoped pragmas
89 74         1952 my $parent = $elem->parent();
90 74 100       586 return 0 if !$parent->isa('PPI::Document');
91              
92 72 100       234 if ( my $pragma = $elem->pragma() ) {
    100          
93 65 100       2478 return 1 if $self->{_equivalent_modules}{$pragma};
94             }
95             elsif ( my $module = $elem->module() ) {
96 6 100       354 return 1 if $self->{_equivalent_modules}{$module};
97             }
98              
99 32         156 return 0;
100 53         481 };
101             }
102              
103             #-----------------------------------------------------------------------------
104             # Here, we're using the fact that Perl::Critic::Document::find() is optimized
105             # to search for elements based on their type. This is faster than using the
106             # native PPI::Node::find() method with a custom callback function.
107              
108             sub _find_isnt_include_or_package {
109 53     53   214 my ($self, $doc) = @_;
110 53 100       217 my $all_statements = $doc->find('PPI::Statement') or return;
111 49         138 my @wanted_statements = grep { _statement_isnt_include_or_package($_) } @{$all_statements};
  337         702  
  49         136  
112 49 100       281 return @wanted_statements ? \@wanted_statements : ();
113             }
114              
115             #-----------------------------------------------------------------------------
116              
117             sub _statement_isnt_include_or_package {
118 337     337   635 my ($elem) = @_;
119 337 100       1064 return 0 if $elem->isa('PPI::Statement::Package');
120 306 100       963 return 0 if $elem->isa('PPI::Statement::Include');
121 229         619 return 1;
122             }
123              
124             1;
125              
126             __END__
127              
128             #-----------------------------------------------------------------------------
129              
130             =pod
131              
132             =head1 NAME
133              
134             Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings - Always C<use warnings>.
135              
136              
137             =head1 AFFILIATION
138              
139             This Policy is part of the core L<Perl::Critic|Perl::Critic>
140             distribution.
141              
142              
143             =head1 DESCRIPTION
144              
145             Using warnings, and paying attention to what they say, is probably the
146             single most effective way to improve the quality of your code. This
147             policy requires that the C<'use warnings'> statement must come before
148             any other statements except C<package>, C<require>, and other C<use>
149             statements. Thus, all the code in the entire package will be
150             affected.
151              
152             There are special exemptions for L<Moose|Moose>,
153             L<Moose::Role|Moose::Role>, and
154             L<Moose::Util::TypeConstraints|Moose::Util::TypeConstraints> because
155             they enforces warnings; e.g. C<'use Moose'> is treated as
156             equivalent to C<'use warnings'>.
157              
158             This policy will not complain if the file explicitly states that it is
159             compatible with a version of perl prior to 5.6 via an include
160             statement, e.g. by having C<require 5.005> in it.
161              
162             The maximum number of violations per document for this policy defaults
163             to 1.
164              
165              
166             =head1 CONFIGURATION
167              
168             If you make use of things like
169             L<Moose::Exporter|Moose::Exporter>, you can create your own modules
170             that import the L<warnings|warnings> pragma into the code that is
171             C<use>ing them. There is an option to add to the default set of
172             pragmata and modules in your F<.perlcriticrc>: C<equivalent_modules>.
173              
174             [TestingAndDebugging::RequireUseWarnings]
175             equivalent_modules = MooseX::My::Sugar
176              
177              
178             =head1 BUGS
179              
180             Needs to check for -w on the shebang line.
181              
182              
183             =head1 SEE ALSO
184              
185             L<Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings|Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings>
186              
187              
188             =head1 AUTHOR
189              
190             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
191              
192              
193             =head1 COPYRIGHT
194              
195             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
196              
197             This program is free software; you can redistribute it and/or modify
198             it under the same terms as Perl itself. The full text of this license
199             can be found in the LICENSE file included with this module
200              
201             =cut
202              
203             ##############################################################################
204             # Local Variables:
205             # mode: cperl
206             # cperl-indent-level: 4
207             # fill-column: 78
208             # indent-tabs-mode: nil
209             # c-indentation-style: bsd
210             # End:
211             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :