Login
Self-compliance with ProhibitUnrestrictedNoCritic
[gknop/Perl-Critic.git] / lib / Perl / Critic / Policy / Modules / ProhibitAutomaticExportation.pm
CommitLineData
6036a254 1##############################################################################
6f52941a
JRT
2# $URL$
3# $Date$
4# $Author$
5# $Revision$
6036a254 6##############################################################################
b393ceb2
JRT
7
8package Perl::Critic::Policy::Modules::ProhibitAutomaticExportation;
9
df6dee2b 10use 5.006001;
b393ceb2
JRT
11use strict;
12use warnings;
c680a9c9
ES
13use Readonly;
14
bbf4108c 15use Perl::Critic::Utils qw{ :severities };
b393ceb2
JRT
16use List::MoreUtils qw(any);
17use base 'Perl::Critic::Policy';
18
173667ce 19our $VERSION = '1.093_01';
b393ceb2 20
6036a254 21#-----------------------------------------------------------------------------
b393ceb2 22
c680a9c9 23Readonly::Scalar my $DESC => q{Symbols are exported by default};
c0631e45 24Readonly::Scalar my $EXPL => q{Use '@EXPORT_OK' or '%EXPORT_TAGS' instead}; ## no critic (RequireInterpolation)
b393ceb2 25
6036a254 26#-----------------------------------------------------------------------------
b393ceb2 27
c680a9c9
ES
28sub supported_parameters { return () }
29sub default_severity { return $SEVERITY_HIGH }
30sub default_themes { return qw( core bugs ) }
31sub applies_to { return 'PPI::Document' }
b393ceb2 32
6036a254 33#-----------------------------------------------------------------------------
b393ceb2
JRT
34
35sub violates {
36 my ( $self, $elem, $doc ) = @_;
37
38 if ( _uses_exporter($doc) ) {
39 if ( my $exp = _has_exports($doc) ) {
c680a9c9 40 return $self->violation( $DESC, $EXPL, $exp );
b393ceb2
JRT
41 }
42 }
43 return; #ok
44}
45
6036a254 46#-----------------------------------------------------------------------------
b393ceb2
JRT
47
48sub _uses_exporter {
49 my ($doc) = @_;
6015ad73
CD
50 my $includes_ref = $doc->find('PPI::Statement::Include');
51 return if !$includes_ref;
5d4b38a3 52 #This covers both C<use Exporter;> and C<use base 'Exporter';>
a0dcf06f 53 return scalar grep { m/ \b Exporter \b/xms } @{ $includes_ref };
b393ceb2
JRT
54}
55
56#------------------
57
58sub _has_exports {
59 my ($doc) = @_;
977dbe11 60 my $wanted = sub {_our_EXPORT(@_) || _vars_EXPORT(@_) || _package_EXPORT(@_)};
b393ceb2
JRT
61 return $doc->find_first( $wanted );
62}
63
64#------------------
65
66sub _our_EXPORT {
e5f6c18d 67 my (undef, $elem) = @_;
b393ceb2
JRT
68 $elem->isa('PPI::Statement::Variable') || return 0;
69 $elem->type() eq 'our' || return 0;
6015ad73 70 return any { $_ eq '@EXPORT' } $elem->variables(); ## no critic(RequireInterpolationOfMetachars)
b393ceb2
JRT
71}
72
73#------------------
74
75sub _vars_EXPORT {
e5f6c18d 76 my (undef, $elem) = @_;
b393ceb2
JRT
77 $elem->isa('PPI::Statement::Include') || return 0;
78 $elem->pragma() eq 'vars' || return 0;
a0dcf06f 79 return $elem =~ m{ \@EXPORT \b }xms; #Crude, but usually works
b393ceb2
JRT
80}
81
82#------------------
83
84sub _package_EXPORT {
e5f6c18d 85 my (undef, $elem) = @_;
b393ceb2 86 $elem->isa('PPI::Token::Symbol') || return 0;
a0dcf06f 87 return $elem =~ m{ \A \@ \S+ ::EXPORT \z }xms;
b393ceb2
JRT
88 #TODO: ensure that it is in _this_ package!
89}
90
911;
92
93__END__
94
6036a254 95#-----------------------------------------------------------------------------
b393ceb2
JRT
96
97=pod
98
99=head1 NAME
100
f017d93a 101Perl::Critic::Policy::Modules::ProhibitAutomaticExportation - Export symbols via C<@EXPORT_OK> or C<%EXPORT_TAGS> instead of C<@EXPORT>.
b393ceb2 102
11f53956 103
af93c316
ES
104=head1 AFFILIATION
105
11f53956
ES
106This Policy is part of the core L<Perl::Critic|Perl::Critic>
107distribution.
af93c316
ES
108
109
b393ceb2
JRT
110=head1 DESCRIPTION
111
11f53956
ES
112When using L<Exporter|Exporter>, symbols placed in the C<@EXPORT>
113variable are automatically exported into the caller's namespace.
114Although convenient, this practice is not polite, and may cause
115serious problems if the caller declares the same symbols. The best
116practice is to place your symbols in C<@EXPORT_OK> or C<%EXPORT_TAGS>
117and let the caller choose exactly which symbols to export.
e63059ae 118
11f53956 119 package Foo;
e63059ae 120
11f53956
ES
121 use base qw(Exporter);
122 our @EXPORT = qw(&foo &bar); # not ok
123 our @EXPORT_OK = qw(&foo &bar); # ok
124 our %EXPORT_TAGS = ( all => [ qw(&foo &bar) ] ); # ok
e63059ae 125
0cb729f0
ES
126
127=head1 CONFIGURATION
128
49860482 129This Policy is not configurable except for the standard options.
0cb729f0
ES
130
131
b393ceb2
JRT
132=head1 AUTHOR
133
134Jeffrey Ryan Thalhammer <thaljef@cpan.org>
135
11f53956 136
b393ceb2
JRT
137=head1 COPYRIGHT
138
20dfddeb 139Copyright (c) 2005-2008 Jeffrey Ryan Thalhammer. All rights reserved.
b393ceb2
JRT
140
141This program is free software; you can redistribute it and/or modify
142it under the same terms as Perl itself. The full text of this license
143can be found in the LICENSE file included with this module.
144
145=cut
737d3b65
CD
146
147# Local Variables:
148# mode: cperl
149# cperl-indent-level: 4
150# fill-column: 78
151# indent-tabs-mode: nil
152# c-indentation-style: bsd
153# End:
96fed375 154# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :