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   26961 use 5.010001;
  40         202  
4 40     40   260 use strict;
  40         104  
  40         847  
5 40     40   207 use warnings;
  40         139  
  40         940  
6 40     40   220 use Readonly;
  40         124  
  40         1733  
7              
8 40     40   248 use version ();
  40         133  
  40         912  
9              
10 40     40   242 use Perl::Critic::Utils qw{ :severities $EMPTY };
  40         116  
  40         1961  
11 40     40   5355 use Perl::Critic::Utils::Constants qw{ :equivalent_modules };
  40         139  
  40         4256  
12 40     40   318 use parent 'Perl::Critic::Policy';
  40         113  
  40         265  
13              
14             our $VERSION = '1.146';
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 2214 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 446 sub default_severity { return $SEVERITY_HIGH }
40 92     92 1 415 sub default_themes { return qw( core pbp bugs certrule ) }
41 55     55 1 229 sub applies_to { return 'PPI::Document' }
42              
43 58     58 1 178 sub default_maximum_violations_per_document { return 1; }
44              
45             #-----------------------------------------------------------------------------
46              
47             sub violates {
48 55     55 1 189 my ( $self, undef, $document ) = @_;
49              
50 55         235 my $version = $document->highest_explicit_perl_version();
51 55 100 100     241 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         278 my $warn_stmnt = $document->find_first( $self->_generate_is_use_warnings() );
55 53 100       1108 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       221 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         121 my @viols = ();
65 48         101 for my $stmnt ( @{ $stmnts_ref } ) {
  48         165  
66 229 50       748 last if $stmnt->isa('PPI::Statement::End');
67 229 100       697 last if $stmnt->isa('PPI::Statement::Data');
68              
69 228         556 my $stmnt_line = $stmnt->location()->[0];
70 228 100 100     4137 if ( (! defined $warn_line) || ($stmnt_line < $warn_line) ) {
71 24         110 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
72             }
73             }
74 48         293 return @viols;
75             }
76              
77             #-----------------------------------------------------------------------------
78              
79             sub _generate_is_use_warnings {
80 53     53   153 my ($self) = @_;
81              
82             return sub {
83 699     699   7200 my (undef, $elem) = @_;
84              
85 699 100       2559 return 0 if !$elem->isa('PPI::Statement::Include');
86 75 100       314 return 0 if $elem->type() ne 'use';
87              
88             # We only want file-scoped pragmas
89 74         1853 my $parent = $elem->parent();
90 74 100       559 return 0 if !$parent->isa('PPI::Document');
91              
92 72 100       255 if ( my $pragma = $elem->pragma() ) {
    100          
93 65 100       2310 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         154 return 0;
100 53         566 };
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   175 my ($self, $doc) = @_;
110 53 100       218 my $all_statements = $doc->find('PPI::Statement') or return;
111 49         141 my @wanted_statements = grep { _statement_isnt_include_or_package($_) } @{$all_statements};
  337         677  
  49         157  
112 49 100       263 return @wanted_statements ? \@wanted_statements : ();
113             }
114              
115             #-----------------------------------------------------------------------------
116              
117             sub _statement_isnt_include_or_package {
118 337     337   641 my ($elem) = @_;
119 337 100       1047 return 0 if $elem->isa('PPI::Statement::Package');
120 306 100       1013 return 0 if $elem->isa('PPI::Statement::Include');
121 229         539 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 :