File Coverage

blib/lib/Perl/Critic/Policy/Subroutines/ProhibitCallsToUndeclaredSubs.pm
Criterion Covered Total %
statement 50 53 94.3
branch 11 12 91.6
condition n/a
subroutine 11 13 84.6
pod 5 6 83.3
total 77 84 91.6


line stmt bran cond sub pod time code
1              
2             use strict;
3 1     1   552 use warnings;
  1         2  
  1         24  
4 1     1   5 use base 'Perl::Critic::Policy';
  1         2  
  1         21  
5 1     1   4  
  1         2  
  1         95  
6             use Perl::Critic::StricterSubs::Utils qw(
7 1         98 &find_declared_constant_names
8             &find_declared_subroutine_names
9             &find_imported_subroutine_names
10             &find_subroutine_calls
11             &get_package_names_from_include_statements
12             );
13 1     1   7  
  1         2  
14             use Perl::Critic::Utils qw(
15 1         39 :severities
16             &hashify
17             &is_qualified_name
18             &words_from_string
19             );
20 1     1   6  
  1         2  
21             #-----------------------------------------------------------------------------
22              
23             our $VERSION = 0.06;
24              
25             #-----------------------------------------------------------------------------
26              
27              
28 0     0 0 0 #-----------------------------------------------------------------------------
29 19     19 1 148  
30 0     0 1 0 my ( $class, %args ) = @_;
31 28     28 1 263395 my $self = bless {}, $class;
32             $self->{_exempt_subs} = {};
33              
34             if (defined $args{exempt_subs} ) {
35             for my $qualified_sub ( words_from_string( $args{exempt_subs} ) ){
36 28     28 1 90587 my ($package, $sub_name) = _parse_sub_name( $qualified_sub );
37 28         64 $self->{_exempt_subs}->{$package}->{$sub_name} = 1;
38 28         102 }
39             }
40 28 100       71  
41 5         16 return $self;
42 10         40 }
43 10         35  
44             #-----------------------------------------------------------------------------
45              
46              
47 28         70 my $full_name = shift;
48              
49             if ( $full_name =~ m/\A ( .+ ) :: ([^:]+) \z/xms ) {
50              
51             my ($package_name, $sub_name) = ($1, $2);
52             return ($package_name, $sub_name);
53             }
54 10     10   14 else {
55              
56 10 50       40 die qq{Sub name "$full_name" must be fully qualifed.\n};
57             }
58 10         28 }
59 10         26  
60             #-----------------------------------------------------------------------------
61              
62              
63 0         0 my ($self, $sub_name, $included_packages) = @_;
64             for my $package ( @{$included_packages} ) {
65             return 1 if exists $self->{_exempt_subs}->{$package}->{$sub_name};
66             }
67              
68             return;
69             }
70              
71 69     69   119 #-----------------------------------------------------------------------------
72 69         94  
  69         113  
73 90 100       271  
74             my ($self, undef, $doc) = @_;
75              
76 64         209 my @declared_constants = find_declared_constant_names( $doc );
77             my @declared_sub_names = find_declared_subroutine_names( $doc );
78             my @imported_sub_names = find_imported_subroutine_names( $doc );
79              
80             my %defined_sub_names = hashify(@declared_sub_names,
81             @imported_sub_names,
82             @declared_constants);
83 28     28 1 259  
84             my @included_packages = get_package_names_from_include_statements( $doc );
85 28         72  
86 28         67 my @violations = ();
87 28         62 for my $elem ( find_subroutine_calls($doc) ){
88              
89 28         67 next if is_qualified_name( $elem );
90             next if $self->_is_exempt_subroutine( $elem, \@included_packages );
91              
92             my ( $name ) = ( $elem =~ m{&?(\w+)}mxs );
93 28         188 if ( not exists $defined_sub_names{$name} ){
94             my $expl = q{This might be a major bug};
95 28         318 my $desc = qq{Subroutine "$elem" is neither declared nor explicitly imported};
96 28         71 push @violations, $self->violation($desc, $expl, $elem);
97             }
98 78 100       2027 }
99 69 100       630  
100             return @violations;
101 64         114 }
102 64 100       392  
103 19         30 #-----------------------------------------------------------------------------
104 19         45  
105 19         98 1;
106              
107              
108             =pod
109 28         795  
110             =head1 NAME
111              
112             Perl::Critic::Policy::Subroutines::ProhibitCallsToUndeclaredSubs
113              
114             =head1 AFFILIATION
115              
116             This policy is part of L<Perl::Critic::StricterSubs|Perl::Critic::StricterSubs>.
117              
118             =head1 DESCRIPTION
119              
120             This Policy checks that every unqualified subroutine call has a matching
121             subroutine declaration in the current file, or that it explicitly appears in
122             the import list for one of the included modules.
123              
124             Some modules do not use the L<Exporter|Exporter> interface, and rely on other
125             mechanisms to export symbols into your code. In those cases, this Policy will
126             report a false violation. However, you can instruct this policy to ignore a
127             particular subroutine name, as long as the appropriate package has been
128             included in your file. See L</"CONFIGURATION"> for more details.
129              
130             =head1 CONFIGURATION
131              
132             A list of exempt subroutines for this Policy can defined by specifying
133             'exempt_subs' as a string of space-delimited, fully-qualified subroutine
134             names. For example, putting this in your F<.perlcriticrc> file would allow
135             you to call the C<ok> and C<is> functions without explicitly importing or
136             declaring those functions, as long as the C<Test::More> package has been
137             included in the file somewhere.
138              
139             [Subroutines::ProhibitCallsToUndeclaredSubs]
140             exempt_subs = Test::More::ok Test::More::is
141              
142             By default, there are no exempt subroutines, but we're working on compiling a
143             list of the most common ones.
144              
145             =head1 LIMITATIONS
146              
147             This Policy assumes that the file has no more than one C<package> declaration
148             and that all subs declared within the file are, in fact, declared into that
149             same package. In most cases, violating either of these assumptions means
150             you're probably doing something that you shouldn't do. Think twice about what
151             you're doing.
152              
153             Also, if you C<require> a module and subsequently call the C<import> method on
154             that module, this Policy will not detect the symbols that might have been
155             imported. In which case, you'll probably get bogus violations.
156              
157              
158             =head1 AUTHOR
159              
160             Jeffrey Ryan Thalhammer <thaljef@cpan.org>
161              
162             =head1 COPYRIGHT
163              
164             Copyright (c) 2007 Jeffrey Ryan Thalhammer. All rights reserved.
165              
166             This program is free software; you can redistribute it and/or modify it under
167             the same terms as Perl itself. The full text of this license can be found in
168             the LICENSE file included with this module.
169              
170             =cut
171              
172             ##############################################################################
173             # Local Variables:
174             # mode: cperl
175             # cperl-indent-level: 4
176             # fill-column: 78
177             # indent-tabs-mode: nil
178             # c-indentation-style: bsd
179             # End:
180             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab :