# Copyright 2009 Kevin Ryde
# This file is part of Perl-Critic-Pulp.
# Perl-Critic-Pulp is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# Perl-Critic-Pulp is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with Perl-Critic-Pulp. If not, see .
package Perl::Critic::Policy::Compatibility::PodMinimumVersion;
use 5.006;
use strict;
use warnings;
use Pod::MinimumVersion;
use base 'Perl::Critic::Policy';
use Perl::Critic::Pulp;
use Perl::Critic::Utils qw(:severities);
our $VERSION = 22;
use constant DEBUG => 0;
sub default_severity { return $SEVERITY_LOW; }
sub default_themes { return qw(pulp compatibility); }
sub applies_to { return 'PPI::Document'; }
sub supported_parameters {
return ({ name => 'above_version',
description => 'Check only things above this version of Perl.',
behavior => 'string',
parser => \&Perl::Critic::Pulp::parameter_parse_version,
});
}
sub violates {
my ($self, $document) = @_;
my $doc_version = $document->highest_explicit_perl_version;
my $str = $document->serialize;
my $pmv = Pod::MinimumVersion->new (string => $str,
above_version => $doc_version,
one_report_per_version => 1,
);
my @reports = $pmv->reports;
@reports = sort {$a->{'version'} <=> $b->{'version'}} @reports;
return map {
my $report = $_;
my $violation = $self->violation
("Pod requires perl $report->{'version'} due to: $report->{'why'}.",
'',
$document);
_violation_override_linenum ($violation, $str, $report->{'linenum'});
} @reports;
}
# Hack to set Perl::Critic::Violation location to $linenum in $doc_str.
# Have thought about validating _location and _source fields before mangling
# them, but hopefully there'll be a documented interface to use before long.
#
sub _violation_override_linenum {
my ($violation, $doc_str, $linenum) = @_;
# if ($violation->can('set_line_number_offset')) {
# $violation->set_line_number_offset ($linenum - 1);
# } else {
bless $violation, 'Perl::Critic::Pulp::PodMinimumVersionViolation';
$violation->{_Pulp_linenum_offset} = $linenum - 1;
$violation->{'_source'} = _str_line_n ($doc_str, $linenum);
return $violation;
}
# starting from $n==0 for first line
sub _str_line_n {
my ($str, $n) = @_;
$n--;
return ($str =~ /^(.*\n){$n}(.*)/ ? $2 : '');
}
package Perl::Critic::Pulp::PodMinimumVersionViolation;
use base 'Perl::Critic::Violation';
sub location {
my ($self) = @_;
my $offset = ($self->{_Pulp_linenum_offset} || 0);
my @location = @{$self->SUPER::location()};
$location[0] += $offset; # line
if ($#location >= 3) {
$location[3] += $offset; # logical line, new in ppi 1.205
}
return \@location;
}
1;
__END__
=head1 NAME
Perl::Critic::Policy::Compatibility::PodMinimumVersion - check Perl version declared against POD features used
=head1 DESCRIPTION
This policy is part of the L|Perl::Critic::Pulp>
addon. It checks that the POD features you use don't exceed your target
Perl version as indicated by C