File Coverage

blib/lib/Perl/Critic/Policy/Modules/RequireExplicitInclusion.pm
Criterion Covered Total %
statement 76 83 91.5
branch 11 14 78.5
condition 9 11 81.8
subroutine 22 23 95.6
pod 4 5 80.0
total 122 136 89.7


line stmt bran cond sub pod time code
1              
2             use strict;
3 1     1   719 use warnings;
  1         3  
  1         25  
4 1     1   5 use base 'Perl::Critic::Policy';
  1         2  
  1         30  
5 1     1   5  
  1         2  
  1         133  
6             use Perl::Critic::Utils qw(
7 1         43 :characters
8             :severities
9             &hashify
10             &is_class_name
11             &is_function_call
12             &is_perl_builtin
13             &is_qualified_name
14             &policy_short_name
15             );
16 1     1   8  
  1         1  
17             use Perl::Critic::StricterSubs::Utils qw(
18 1         945 &get_package_names_from_include_statements
19             &get_package_names_from_package_statements
20             );
21 1     1   290  
  1         2  
22             #-----------------------------------------------------------------------------
23              
24             our $VERSION = 0.06;
25              
26             my $expl =
27             'Without importing a package, it is unlikely that references to things inside it even exist.';
28              
29             #-----------------------------------------------------------------------------
30              
31              
32 24     24 0 104694 #-----------------------------------------------------------------------------
33 25     25 1 204  
34 0     0 1 0 my ($self, undef, $doc) = @_;
35 24     24 1 218278  
36             my @declared_packages = get_package_names_from_package_statements($doc);
37              
38             if ( @declared_packages > 1 ) {
39             my $fname = $doc->filename() || 'unknown';
40 24     24 1 208 my $pname = policy_short_name(__PACKAGE__);
41             warn qq{$pname: Cannot cope with mutiple packages in file "$fname"\n};
42 24         62 return;
43             }
44 24 50       155  
45 0   0     0 my @included_packages = get_package_names_from_include_statements($doc);
46 0         0 my @builtin_packages = ( qw(main UNIVERSAL CORE CORE::GLOBAL utf8), $EMPTY );
47 0         0  
48 0         0 my %all_packages =
49             hashify( @declared_packages, @included_packages, @builtin_packages );
50              
51 24         57 my @violations = (
52 24         299 $self->_find_subroutine_call_violations( $doc, \%all_packages ),
53             $self->_find_class_method_call_violations( $doc, \%all_packages ),
54 24         69 $self->_find_symbol_violations( $doc, \%all_packages ),
55             );
56              
57 24         353 return @violations;
58             }
59              
60             #-----------------------------------------------------------------------------
61              
62             my $doc = shift;
63 24         98  
64             my $calls =
65             $doc->find(
66             sub {
67             my (undef, $elem) = @_;
68              
69 24     24   32 return
70             $elem->isa('PPI::Token::Word')
71             && is_qualified_name( $elem->content() )
72             && is_function_call( $elem );
73              
74 1004     1004   14718 }
75             );
76              
77 1004   100     2960 return @{$calls} if $calls;
78             return;
79             }
80              
81             #-----------------------------------------------------------------------------
82 24         114  
83             my $doc = shift;
84 24 100       294  
  6         21  
85 18         37 my $calls =
86             $doc->find(
87             sub {
88             my (undef, $elem) = @_;
89              
90             return
91 24     24   33 $elem->isa('PPI::Token::Word')
92             && is_class_name( $elem )
93             && !is_perl_builtin( $elem )
94             && '__PACKAGE__' ne $elem->content(); # RT 43314, 44609
95             # From a design standpoint we should filter later, but
96 1004     1004   13164 # the violation code is generic. The patch included with
97             # 44609, or adding '__PACKAGE__ to @builtin_packages,
98             # would have also allowed, willy-nilly,
99 1004   100     3007 # __PACKAGE__::foo() or $__PACKAGE__::foo, neither of
100             # which is correct. So I just hid __PACKAGE__->foo() from
101             # the violation logic. Mea culpa! Tom Wyant
102             }
103             );
104              
105             return @{$calls} if $calls;
106             return;
107             }
108              
109             #-----------------------------------------------------------------------------
110              
111 24         100 my $doc = shift;
112              
113 24 100       279 my $symbols =
  6         20  
114 18         47 $doc->find(
115             sub {
116             my (undef, $elem) = @_;
117              
118             return
119             $elem->isa('PPI::Token::Symbol')
120 24     24   34 && is_qualified_name( $elem->canonical() );
121             }
122             );
123              
124             return @{$symbols} if $symbols;
125 1004     1004   9079 return;
126             }
127              
128 1004   100     2754 #-----------------------------------------------------------------------------
129              
130              
131 24         97 # Class method calls look like "Foo::Bar->baz()"
132             # So the package name will be the entire word,
133 24 100       273 # which should be everything to the left of "->"
  15         45  
134 9         20  
135             my $word = shift;
136              
137             # Remove trailing double colon, which is allowed and can be used for
138             # disambiguation.
139             $word =~ s/::$//xms;
140              
141             return $word;
142             }
143              
144             #-----------------------------------------------------------------------------
145 18     18   26  
146              
147             # Subroutine calls look like "Foo::Bar::baz()"
148             # So the package name will be everything up
149 18         34 # to (but not including) the last "::".
150              
151 18         71 my $word = shift;
152             if ($word->content() =~ m/\A ( .* ) :: [^:]* \z/xms) {
153             return $1;
154             }
155              
156             return;
157             }
158              
159             #-----------------------------------------------------------------------------
160              
161              
162 15     15   21 # Qualified symbols look like "$Foo::Bar::baz"
163 15 50       31 # So the package name will be everything between
164 15         121 # the sigil and the last "::".
165              
166             my $symbol = shift;
167 0         0 if ($symbol->canonical() =~ m/\A [\$*@%&] ( .* ) :: [^:]+ \z/xms) {
168             return $1;
169             }
170              
171             return;
172             }
173              
174             #-----------------------------------------------------------------------------
175              
176              
177             my ($self, $doc, $included_packages, $finder, $package_extractor) = @_;
178 26     26   36 my @violations = ();
179 26 50       51  
180 26         345 for my $call ( $finder->( $doc ) ) {
181             my $package = $package_extractor->( $call );
182             next if exists $included_packages->{ $package };
183 0         0  
184             my $desc = qq{Use of "$call" without including "$package"};
185             push @violations, $self->violation( $desc, $expl, $call );
186             }
187              
188             return @violations;
189             }
190 72     72   123  
191 72         97 #-----------------------------------------------------------------------------
192              
193 72         123 my ($self, $doc, $packages) = @_;
194 59         2350 my $finder = \&_find_qualified_subroutine_calls;
195 59 100       136 my $extractor = \&_extract_package_from_subroutine_call;
196             return $self->_find_violations( $doc, $packages, $finder, $extractor );
197 25         74 }
198 25         136  
199             #-----------------------------------------------------------------------------
200              
201 72         1650 my ($self, $doc, $packages) = @_;
202             my $finder = \&_find_class_method_calls;
203             my $extractor = \&_extract_package_from_class_method_call;
204             return $self->_find_violations( $doc, $packages, $finder, $extractor );
205             }
206              
207 24     24   44 #-----------------------------------------------------------------------------
208 24         43  
209 24         38 my ($self, $doc, $packages) = @_;
210 24         50 my $finder = \&_find_qualified_symbols;
211             my $extractor = \&_extract_package_from_symbol;
212             return $self->_find_violations( $doc, $packages, $finder, $extractor );
213             }
214              
215             #-----------------------------------------------------------------------------
216 24     24   42  
217 24         42 1;
218 24         41  
219 24         44  
220             =pod
221              
222             =head1 NAME
223              
224             Perl::Critic::Policy::Modules::RequireExplicitInclusion
225 24     24   71  
226 24         38 =head1 AFFILIATION
227 24         45  
228 24         48 This policy is part of L<Perl::Critic::StricterSubs|Perl::Critic::StricterSubs>.
229              
230             =head1 DESCRIPTION
231              
232             Checks that, if a reference is made to something inside of another
233             package, that a module with the name of the package has been C<use>d
234             or C<require>d.
235              
236             Without importing a package, it is unlikely that references to things
237             inside it even exist. Due to the flexible nature of Perl, C<use
238             strict;> can not complain about references to things outside of the
239             current package and thus won't detect this situation.
240              
241             =head2 Explanation
242              
243             As an example, assume there is a third-party C<Foo> module with a
244             C<bar()> subroutine. You then create a module of your own.
245              
246             package My::Module;
247              
248             ...
249             $x = Foo::bar($y);
250             ...
251              
252             You don't have to worry about whether C<Foo> exports C<bar()> or not
253             because you're fully qualifying the name. Or do you? You then create
254             a program F<plugh> that uses your module that also needs to use C<Foo>
255             directly.
256              
257             #!/usr/bin/perl
258             ...
259             use Foo;
260             use My::Module qw{ &frob };
261             ...
262              
263             This works fine. At some later time, you use your module in a
264             F<xyzzy> program.
265              
266             #!/usr/bin/perl
267             ...
268             use My::Module qw{ &frob };
269             ...
270              
271             You now get compilation problems in the previously robust
272             C<My::Module>. What is going on is that F<plugh> loaded the C<Foo>
273             module prior to C<My::Module>, which means that, when C<My::Module>
274             refers to C<Foo::bar()>, the subroutine actually exists, even though
275             C<My::Module> didn't actually C<use Foo;>. When F<xyzzy> attempted to
276             use C<My::Module> without doing a C<use Foo;>, C<My::Module> fails
277             because C<Foo::bar()> doesn't exist.
278              
279             =head2 Enforcement
280              
281             Assuming that there are no C<use> or C<require> statements within the
282             current scope:
283              
284             @foo = localtime; #ok
285             @Bar::foo = localtime #not ok
286             @::foo = localtime; #ok
287             @main::foo = localtime; #ok
288              
289             baz(23, 'something', $x); #ok
290             Bar::baz(23, 'something', $x); #not ok
291             ::baz(23, 'something', $x); #ok
292             main::baz(23, 'something', $x); #ok
293              
294             Only modules that are symbolically referenced by a C<use> or
295             C<require> are considered valid. Loading a file does not count.
296              
297             use Foo;
298             require Bar;
299             require 'Baz.pm';
300              
301             $Foo:x = 57; #ok
302             $Bar:x = 57; #ok
303             $Baz:x = 57; #not ok
304              
305             Qualifying a name with the name of the current package is valid.
306              
307             package Xyzzy;
308              
309             my $ducks;
310              
311             sub increment_duck_count {
312             $Xyzzy::ducks++; #ok
313             }
314              
315             A C<use> or C<require> statement is taken into account only when it is
316             in the scope of a file or a C<BEGIN>, C<CHECK>, or C<INIT> block.
317              
318             use File::Scope;
319              
320             BEGIN {
321             require Begin::Block;
322             }
323              
324             CHECK {
325             require Check::Block;
326             }
327              
328             INIT {
329             require Init::Block;
330             }
331              
332             END {
333             require End::Block;
334             }
335              
336             push @File::Scope::numbers, 52, 93, 25; #ok
337             push @Begin::Block::numbers, 52, 93, 25; #ok
338             push @Check::Block::numbers, 52, 93, 25; #ok
339             push @Init::Block::numbers, 52, 93, 25; #ok
340             push @End::Block::numbers, 52, 93, 25; #not ok
341              
342             {
343             require Lexical::Block;
344              
345             push @Lexical::Block::numbers, 52, 93, 25; #not ok
346             }
347              
348              
349             =head1 CAVEATS
350              
351             1.) It is assumed that the code for a package exists in a module of
352             the same name.
353              
354              
355             2.) It is assumed that a module will contain no more than one package.
356             This Policy will not complain about any problems in a module
357             containing multiple C<package> statements. For example, a module
358             containing
359              
360             package Foo;
361              
362             sub frob {
363             $Xyzzy::factor = rand 100;
364             }
365              
366             package Bar;
367              
368             sub frob {
369             $Plugh::factor = rand 1000;
370             }
371              
372             will not result in any violations. There really shouldn't be more
373             than one package within a module anyway.
374              
375              
376             3.) No checks of whether the name actually exists in the referenced
377             package are done. E.g., if a call to a C<Foo::process_widgets()>
378             subroutine is made, this Policy does not check that a
379             C<process_widgets()> subroutine actually exists in the C<Foo> package.
380              
381              
382             =head1 CONFIGURATION
383              
384             None.
385              
386             =head1 DIAGNOSTICS
387              
388             =over
389              
390             =item C<Modules::RequireExplicitInclusion: Cannot cope with mutiple packages in file>
391              
392             This warning happens when the file under analysis contains multiple packages,
393             which is not currently supported. This Policy will simply ignore any file
394             with multiple packages.
395              
396             L<Perl::Critic|Perl::Critic> advises putting multiple packages in one file, and has
397             additional Policies to help enforce that.
398              
399             =back
400              
401             =head1 SEE ALSO
402              
403             L<Perl::Critic::Policy::Modules::ProhibitMultiplePackages|Perl::Critic::Policy::Modules::ProhibitMultiplePackages>
404              
405             =head1 AUTHOR
406              
407             Jeffrey Ryan Thalhammer <thaljef@cpan.org>
408              
409             =head1 COPYRIGHT
410              
411             Copyright (c) 2007 Jeffrey Ryan Thalhammer. All rights reserved.
412              
413             This program is free software; you can redistribute it and/or modify it under
414             the same terms as Perl itself. The full text of this license can be found in
415             the LICENSE file included with this module.
416              
417             =cut
418              
419              
420             ##############################################################################
421             # Local Variables:
422             # mode: cperl
423             # cperl-indent-level: 4
424             # fill-column: 78
425             # indent-tabs-mode: nil
426             # c-indentation-style: bsd
427             # End:
428             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab :