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   25961 use 5.010001;
  40         182  
4 40     40   267 use strict;
  40         155  
  40         823  
5 40     40   228 use warnings;
  40         94  
  40         1116  
6              
7 40     40   16520 use version 0.77;
  40         71545  
  40         310  
8 40     40   3415 use Readonly;
  40         126  
  40         2052  
9 40     40   304 use Scalar::Util qw{ blessed };
  40         104  
  40         2143  
10              
11 40     40   289 use Perl::Critic::Utils qw{ :severities $EMPTY };
  40         135  
  40         2002  
12 40     40   5397 use Perl::Critic::Utils::Constants qw{ :equivalent_modules };
  40         134  
  40         4157  
13 40     40   295 use parent 'Perl::Critic::Policy';
  40         122  
  40         246  
14              
15             our $VERSION = '1.148';
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 2360 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 476 sub default_severity { return $SEVERITY_HIGHEST }
40 92     92 1 501 sub default_themes { return qw( core pbp bugs certrule certrec ) }
41 58     58 1 209 sub applies_to { return 'PPI::Document' }
42              
43 61     61 1 193 sub default_maximum_violations_per_document { return 1; }
44              
45             #-----------------------------------------------------------------------------
46              
47             sub violates {
48 58     58 1 213 my ( $self, undef, $doc ) = @_;
49              
50             # Find the first 'use strict' statement
51 58         273 my $strict_stmnt = $doc->find_first( $self->_generate_is_use_strict() );
52 58 100       1461 my $strict_line = $strict_stmnt ? $strict_stmnt->location()->[0] : undef;
53              
54             # Find all statements that aren't 'use', 'require', or 'package'
55 58         1280 my $stmnts_ref = $self->_find_isnt_include_or_package($doc);
56 58 100       356 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         152 my @viols = ();
62 55         134 for my $stmnt ( @{ $stmnts_ref } ) {
  55         185  
63 242 100       899 last if $stmnt->isa('PPI::Statement::End');
64 241 100       841 last if $stmnt->isa('PPI::Statement::Data');
65              
66 240         694 my $stmnt_line = $stmnt->location()->[0];
67 240 100 100     4549 if ( (! defined $strict_line) || ($stmnt_line < $strict_line) ) {
68 29         163 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
69             }
70             }
71 55         273 return @viols;
72             }
73              
74             #-----------------------------------------------------------------------------
75              
76             sub _generate_is_use_strict {
77 58     58   168 my ($self) = @_;
78              
79             return sub {
80 551     551   6628 my (undef, $elem) = @_;
81              
82 551 100       2098 return 0 if !$elem->isa('PPI::Statement::Include');
83 50 100       314 return 0 if $elem->type() ne 'use';
84              
85             # We only want file-scoped pragmas
86 49         1421 my $parent = $elem->parent();
87 49 100       475 return 0 if !$parent->isa('PPI::Document');
88              
89 46 100       204 if ( my $pragma = $elem->pragma() ) {
    100          
    50          
90 37 50       1563 return 1 if $self->{_equivalent_modules}{$pragma};
91             }
92             elsif ( my $module = $elem->module() ) {
93 7 100       454 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     166 if ( not blessed( $version ) or not $version->isa( 'version' ) ) {
99 2 100 66     20 if ( 'v' ne substr $version, 0, 1
100             and ( $version =~ tr/././ ) > 1 ) {
101 1         4 $version = 'v' . $version;
102             }
103 2         26 $version = version->parse( $version );
104             }
105 2 50       23 return 1 if $PERL_VERSION_WHICH_IMPLIES_STRICTURE <= $version;
106             }
107              
108 2         22 return 0;
109 58         579 };
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   218 my ($self, $doc) = @_;
119 58 100       224 my $all_statements = $doc->find('PPI::Statement') or return;
120 56         176 my @wanted_statements = grep { _statement_isnt_include_or_package($_) } @{$all_statements};
  356         773  
  56         161  
121 56 100       372 return @wanted_statements ? \@wanted_statements : ();
122             }
123              
124             #-----------------------------------------------------------------------------
125              
126             sub _statement_isnt_include_or_package {
127 356     356   666 my ($elem) = @_;
128 356 100       1217 return 0 if $elem->isa('PPI::Statement::Package');
129 324 100       1062 return 0 if $elem->isa('PPI::Statement::Include');
130 242         624 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 :