X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FPerl%2FCritic%2FPolicy%2FDynamic%2FNoIndirect.pm;h=a727d0b1471fae40756e6c7a3f05cfda0a09d6b6;hb=02874d1921ce233fdba66551df64da11dd36948a;hp=556ecc6013c209778fce30672b363fd3b85682a0;hpb=05870b723b862a0daadd62a71b81e3e8bca7f881;p=perl%2Fmodules%2FPerl-Critic-Policy-Dynamic-NoIndirect.git diff --git a/lib/Perl/Critic/Policy/Dynamic/NoIndirect.pm b/lib/Perl/Critic/Policy/Dynamic/NoIndirect.pm index 556ecc6..a727d0b 100644 --- a/lib/Perl/Critic/Policy/Dynamic/NoIndirect.pm +++ b/lib/Perl/Critic/Policy/Dynamic/NoIndirect.pm @@ -11,11 +11,11 @@ Perl::Critic::Policy::Dynamic::NoIndirect - Perl::Critic policy against indirect =head1 VERSION -Version 0.03 +Version 0.06 =cut -our $VERSION = '0.03'; +our $VERSION = '0.06'; =head1 DESCRIPTION @@ -26,12 +26,12 @@ Since it wraps around L, it needs to compile the audited code and as s =cut -use base qw/Perl::Critic::DynamicPolicy/; +use base qw; -use Perl::Critic::Utils qw/:severities/; +use Perl::Critic::Utils qw<:severities>; sub default_severity { $SEVERITY_HIGH } -sub default_themes { qw/dynamic maintenance/ } +sub default_themes { qw } sub applies_to { 'PPI::Document' } my $tag_obj = sub { @@ -43,37 +43,40 @@ my $tag_obj = sub { sub violates_dynamic { my ($self, undef, $doc) = @_; - my $src; - + my ($src, $file); if ($doc->isa('PPI::Document::File')) { - my $file = $doc->filename; + $file = $doc->filename; open my $fh, '<', $file or do { require Carp; Carp::confess("Can't open $file for reading: $!") }; $src = do { local $/; <$fh> }; } else { - $src = $doc->serialize; + $file = '(eval 0)'; + $src = $doc->serialize; } + $file =~ s/(? sub { push \@errs, [ \@_ ] }; - { - ; + no strict; + no warnings; + no indirect hook => \$hook; + do { +#line 1 "$file" $src } - } WRAPPER { local ($@, *_); eval $wrapper; ## no critic - if ($@) { + if (my $err = $@) { require Carp; - Carp::confess("Couldn't compile the source wrapper: $@"); + Carp::croak("Couldn't compile the source wrapper: $err"); } } @@ -83,7 +86,6 @@ sub violates_dynamic { my %errs_tags; for (@errs) { my ($obj, $meth, $line) = @$_[0, 1, 3]; - $line -= $offset; my $tag = join "\0", $line, $meth, $tag_obj->($obj); push @{$errs_tags{$tag}}, [ $obj, $meth ]; } @@ -117,17 +119,26 @@ sub violates_dynamic { =head1 CAVEATS -The uses of the L pragma inside the auditted code take precedence over this policy. +The uses of the L pragma inside the audited code take precedence over this policy. Hence no violations will be reported for indirect method calls that are located inside the lexical scope of C or C<< no indirect hook => ... >>. Occurrences of C won't be a problem. +Since the reports generated by L are remapped to the corresponding L objects, the order in which the violations are returned is different from the order given by L : the former is the document order (top to bottom, left to right) while the latter is the optree order (arguments before function calls). + =head1 DEPENDENCIES L 5.8, L. L, L. -L. +L 0.20. + +=head1 SEE ALSO + +L is a L policy that statically checks for indirect constructs. +But to be static it has to be very restricted : you have to manually specify which subroutine names are methods for which the indirect form should be forbidden. +This can lead to false positives (a subroutine with the name you gave is defined in the current scope) and negatives (indirect constructs for methods you didn't specify). +But you don't need to actually compile (or run, as it's more or less the same thing) the code. =head1 AUTHOR @@ -144,11 +155,11 @@ I will be notified, and then you'll automatically be notified of progress on you You can find documentation for this module with the perldoc command. - perldoc Perl::Critic::Policy::Dynamic::NoIndirect + perldoc Perl::Critic::Policy::Dynamic::NoIndirect =head1 COPYRIGHT & LICENSE -Copyright 2009 Vincent Pit, all rights reserved. +Copyright 2009,2010,2011 Vincent Pit, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.