1package Perl::Critic::Policy::Documentation::RequirePodAtEnd;
2
3use 5.006001;
4use strict;
5use warnings;
6use Readonly;
7
8use List::Util qw(first);
9
10use Perl::Critic::Utils qw{ :severities };
11use base 'Perl::Critic::Policy';
12
13our $VERSION = '1.140';
14
15#-----------------------------------------------------------------------------
16
17Readonly::Scalar my $POD_RX => qr{\A = (?: for|begin|end ) }xms;
18Readonly::Scalar my $DESC => q{POD before __END__};
19Readonly::Scalar my $EXPL => [139, 140];
20
21#-----------------------------------------------------------------------------
22
23sub supported_parameters { return ()                      }
24sub default_severity     { return $SEVERITY_LOWEST        }
25sub default_themes       { return qw( core cosmetic pbp ) }
26sub applies_to           { return 'PPI::Document'         }
27
28#-----------------------------------------------------------------------------
29
30sub violates {
31    my ( $self, $elem, $doc ) = @_;
32
33    # No POD means no violation
34    my $pods_ref = $doc->find('PPI::Token::Pod');
35    return if !$pods_ref;
36
37    # Look for first POD tag that isn't =for, =begin, or =end
38    my $pod = first { $_ !~ $POD_RX} @{ $pods_ref };
39    return if !$pod;
40
41    my $end = $doc->find_first('PPI::Statement::End');
42    if ($end) {  # No __END__ means definite violation
43        my $pod_loc = $pod->location();
44        my $end_loc = $end->location();
45        if ( $pod_loc->[0] > $end_loc->[0] ) {
46            # POD is after __END__, or relative position couldn't be determined
47            return;
48        }
49    }
50
51    return $self->violation( $DESC, $EXPL, $pod );
52}
53
541;
55
56__END__
57
58#-----------------------------------------------------------------------------
59
60=pod
61
62=head1 NAME
63
64Perl::Critic::Policy::Documentation::RequirePodAtEnd - All POD should be after C<__END__>.
65
66
67=head1 AFFILIATION
68
69This Policy is part of the core L<Perl::Critic|Perl::Critic>
70distribution.
71
72
73=head1 DESCRIPTION
74
75Perl stops processing code when it sees an C<__END__> statement.  So,
76to save processing time, it's faster to put documentation after the
77C<__END__>.  Also, writing all the POD in one place usually leads to a
78more cohesive document, rather than being forced to follow the layout
79of your code.  This policy issues violations if any POD is found
80before an C<__END__>.
81
82
83=head1 CONFIGURATION
84
85This Policy is not configurable except for the standard options.
86
87
88=head1 NOTES
89
90Some folks like to use C<=for>, and C<=begin>, and C<=end> tags to
91create block comments in-line with their code.  Since those tags
92aren't usually part of the documentation, this Policy does allows them
93to appear before the C<__END__> statement.
94
95    =begin comments
96
97    frobulate()
98    Accepts:  A list of things to frobulate
99    Returns:  True if successful
100
101    =end comments
102
103    sub frobulate { ... }
104
105=head1 AUTHOR
106
107Chris Dolan <cdolan@cpan.org>
108
109
110=head1 COPYRIGHT
111
112Copyright (c) 2006-2011 Chris Dolan.
113
114This program is free software; you can redistribute it and/or modify
115it under the same terms as Perl itself.  The full text of this license
116can be found in the LICENSE file included with this module
117
118=cut
119
120# Local Variables:
121#   mode: cperl
122#   cperl-indent-level: 4
123#   fill-column: 78
124#   indent-tabs-mode: nil
125#   c-indentation-style: bsd
126# End:
127# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :
128