File Coverage

blib/lib/Perl/Critic/Policy/TestingAndDebugging/RequireUseStrict.pm
Criterion Covered Total %
statement 71 71 100.0
branch 36 40 90.0
condition 6 9 66.6
subroutine 19 19 100.0
pod 5 6 83.3
total 137 145 94.4


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::TestingAndDebugging::RequireUseStrict;
2              
3 40     40   26349 use 5.010001;
  40         175  
4 40     40   268 use strict;
  40         120  
  40         893  
5 40     40   221 use warnings;
  40         96  
  40         1175  
6              
7 40     40   16769 use version 0.77;
  40         71628  
  40         320  
8 40     40   3316 use Readonly;
  40         131  
  40         2055  
9 40     40   305 use Scalar::Util qw{ blessed };
  40         103  
  40         2104  
10              
11 40     40   276 use Perl::Critic::Utils qw{ :severities $EMPTY };
  40         118  
  40         2032  
12 40     40   5365 use Perl::Critic::Utils::Constants qw{ :equivalent_modules };
  40         124  
  40         4339  
13 40     40   290 use parent 'Perl::Critic::Policy';
  40         110  
  40         248  
14              
15             our $VERSION = '1.146';
16              
17             #-----------------------------------------------------------------------------
18              
19             Readonly::Scalar my $DESC => q{Code before strictures are enabled};
20             Readonly::Scalar my $EXPL => [ 429 ];
21              
22             Readonly::Scalar my $PERL_VERSION_WHICH_IMPLIES_STRICTURE => qv('v5.11.0');
23              
24             #-----------------------------------------------------------------------------
25              
26             sub supported_parameters {
27             return (
28             {
29 112     112 0 2423 name => 'equivalent_modules',
30             description =>
31             q<The additional modules to treat as equivalent to "strict".>,
32             default_string => $EMPTY,
33             behavior => 'string list',
34             list_always_present_values => ['strict', @STRICT_EQUIVALENT_MODULES],
35             },
36             );
37             }
38              
39 103     103 1 475 sub default_severity { return $SEVERITY_HIGHEST }
40 92     92 1 460 sub default_themes { return qw( core pbp bugs certrule certrec ) }
41 58     58 1 223 sub applies_to { return 'PPI::Document' }
42              
43 61     61 1 183 sub default_maximum_violations_per_document { return 1; }
44              
45             #-----------------------------------------------------------------------------
46              
47             sub violates {
48 58     58 1 212 my ( $self, undef, $doc ) = @_;
49              
50             # Find the first 'use strict' statement
51 58         255 my $strict_stmnt = $doc->find_first( $self->_generate_is_use_strict() );
52 58 100       1525 my $strict_line = $strict_stmnt ? $strict_stmnt->location()->[0] : undef;
53              
54             # Find all statements that aren't 'use', 'require', or 'package'
55 58         1151 my $stmnts_ref = $self->_find_isnt_include_or_package($doc);
56 58 100       259 return if not $stmnts_ref;
57              
58             # If the 'use strict' statement is not defined, or the other
59             # statement appears before the 'use strict', then it violates.
60              
61 55         145 my @viols = ();
62 55         130 for my $stmnt ( @{ $stmnts_ref } ) {
  55         194  
63 242 100       806 last if $stmnt->isa('PPI::Statement::End');
64 241 100       733 last if $stmnt->isa('PPI::Statement::Data');
65              
66 240         643 my $stmnt_line = $stmnt->location()->[0];
67 240 100 100     4549 if ( (! defined $strict_line) || ($stmnt_line < $strict_line) ) {
68 29         152 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
69             }
70             }
71 55         274 return @viols;
72             }
73              
74             #-----------------------------------------------------------------------------
75              
76             sub _generate_is_use_strict {
77 58     58   170 my ($self) = @_;
78              
79             return sub {
80 551     551   6305 my (undef, $elem) = @_;
81              
82 551 100       2067 return 0 if !$elem->isa('PPI::Statement::Include');
83 50 100       281 return 0 if $elem->type() ne 'use';
84              
85             # We only want file-scoped pragmas
86 49         1408 my $parent = $elem->parent();
87 49 100       505 return 0 if !$parent->isa('PPI::Document');
88              
89 46 100       201 if ( my $pragma = $elem->pragma() ) {
    100          
    50          
90 37 50       1602 return 1 if $self->{_equivalent_modules}{$pragma};
91             }
92             elsif ( my $module = $elem->module() ) {
93 7 100       416 return 1 if $self->{_equivalent_modules}{$module};
94             }
95             elsif ( my $version = $elem->version() ) {
96             # Currently Adam returns a string here. He has said he may return
97             # a version object in the future, so best be prepared.
98 2 50 33     154 if ( not blessed( $version ) or not $version->isa( 'version' ) ) {
99 2 100 66     16 if ( 'v' ne substr $version, 0, 1
100             and ( $version =~ tr/././ ) > 1 ) {
101 1         5 $version = 'v' . $version;
102             }
103 2         18 $version = version->parse( $version );
104             }
105 2 50       23 return 1 if $PERL_VERSION_WHICH_IMPLIES_STRICTURE <= $version;
106             }
107              
108 2         32 return 0;
109 58         552 };
110             }
111              
112             #-----------------------------------------------------------------------------
113             # Here, we're using the fact that Perl::Critic::Document::find() is optimized
114             # to search for elements based on their type. This is faster than using the
115             # native PPI::Node::find() method with a custom callback function.
116              
117             sub _find_isnt_include_or_package {
118 58     58   204 my ($self, $doc) = @_;
119 58 100       213 my $all_statements = $doc->find('PPI::Statement') or return;
120 56         165 my @wanted_statements = grep { _statement_isnt_include_or_package($_) } @{$all_statements};
  356         760  
  56         146  
121 56 100       341 return @wanted_statements ? \@wanted_statements : ();
122             }
123              
124             #-----------------------------------------------------------------------------
125              
126             sub _statement_isnt_include_or_package {
127 356     356   701 my ($elem) = @_;
128 356 100       1165 return 0 if $elem->isa('PPI::Statement::Package');
129 324 100       972 return 0 if $elem->isa('PPI::Statement::Include');
130 242         651 return 1;
131             }
132              
133             1;
134              
135             __END__
136              
137             #-----------------------------------------------------------------------------
138              
139             =pod
140              
141             =head1 NAME
142              
143             Perl::Critic::Policy::TestingAndDebugging::RequireUseStrict - Always C<use strict>.
144              
145              
146             =head1 AFFILIATION
147              
148             This Policy is part of the core L<Perl::Critic|Perl::Critic>
149             distribution.
150              
151              
152             =head1 DESCRIPTION
153              
154             Using strictures is probably the single most effective way to improve
155             the quality of your code. This policy requires that the C<'use
156             strict'> statement must come before any other statements except
157             C<package>, C<require>, and other C<use> statements. Thus, all the
158             code in the entire package will be affected.
159              
160             There are special exemptions for L<Moose|Moose>,
161             L<Moose::Role|Moose::Role>, and
162             L<Moose::Util::TypeConstraints|Moose::Util::TypeConstraints> because
163             they enforces strictness; e.g. C<'use Moose'> is treated as
164             equivalent to C<'use strict'>.
165              
166             The maximum number of violations per document for this policy defaults
167             to 1.
168              
169              
170             =head1 CONFIGURATION
171              
172             If you make use of things like
173             L<Moose::Exporter|Moose::Exporter>, you can create your own modules
174             that import the L<strict|strict> pragma into the code that is
175             C<use>ing them. There is an option to add to the default set of
176             pragmata and modules in your F<.perlcriticrc>: C<equivalent_modules>.
177              
178             [TestingAndDebugging::RequireUseStrict]
179             equivalent_modules = MooseX::My::Sugar
180              
181              
182             =head1 SEE ALSO
183              
184             L<Perl::Critic::Policy::TestingAndDebugging::ProhibitNoStrict|Perl::Critic::Policy::TestingAndDebugging::ProhibitNoStrict>
185              
186              
187             =head1 AUTHOR
188              
189             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
190              
191              
192             =head1 COPYRIGHT
193              
194             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
195              
196             This program is free software; you can redistribute it and/or modify it under
197             the same terms as Perl itself. The full text of this license can be found in
198             the LICENSE file included with this module
199              
200             =cut
201              
202             ##############################################################################
203             # Local Variables:
204             # mode: cperl
205             # cperl-indent-level: 4
206             # fill-column: 78
207             # indent-tabs-mode: nil
208             # c-indentation-style: bsd
209             # End:
210             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :