Build all packages removed dependencies of libtest-exception-perl libtest-warn-perl...
[dh-make-perl] / dev / i386 / libperl-critic-perl / libperl-critic-perl-1.088 / lib / Perl / Critic / Violation.pm
diff --git a/dev/i386/libperl-critic-perl/libperl-critic-perl-1.088/lib/Perl/Critic/Violation.pm b/dev/i386/libperl-critic-perl/libperl-critic-perl-1.088/lib/Perl/Critic/Violation.pm
new file mode 100644 (file)
index 0000000..7bed034
--- /dev/null
@@ -0,0 +1,451 @@
+##############################################################################
+#      $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Violation.pm $
+#     $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
+#   $Author: clonezone $
+# $Revision: 2489 $
+##############################################################################
+
+package Perl::Critic::Violation;
+
+use 5.006001;
+use strict;
+use warnings;
+use English qw(-no_match_vars);
+use Readonly;
+
+use File::Basename qw(basename);
+use IO::String qw();
+use Pod::PlainText qw();
+use String::Format qw(stringf);
+
+use overload ( q{""} => 'to_string', cmp => '_compare' );
+
+use Perl::Critic::Utils qw< :characters :internal_lookup >;
+use Perl::Critic::Utils::POD qw<
+    get_pod_section_for_module
+    trim_pod_section
+>;
+use Perl::Critic::Exception::Fatal::Internal qw< &throw_internal >;
+
+our $VERSION = '1.088';
+
+#Class variables...
+our $FORMAT = "%m at line %l, column %c. %e.\n"; #Default stringy format
+my %DIAGNOSTICS = ();  #Cache of diagnostic messages
+
+#-----------------------------------------------------------------------------
+
+Readonly::Scalar my $CONSTRUCTOR_ARG_COUNT => 5;
+
+sub new {
+    my ( $class, $desc, $expl, $elem, $sev ) = @_;
+
+    #Check arguments to help out developers who might
+    #be creating new Perl::Critic::Policy modules.
+
+    if ( @_ != $CONSTRUCTOR_ARG_COUNT ) {
+        throw_internal 'Wrong number of args to Violation->new()';
+    }
+
+    if ( ! eval { $elem->isa( 'PPI::Element' ) } ) {
+
+        if ( eval { $elem->isa( 'Perl::Critic::Document' ) } ) {
+            # break the facade, return the real PPI::Document
+            $elem = $elem->{_doc};
+        }
+        else {
+            throw_internal
+                '3rd arg to Violation->new() must be a PPI::Element';
+        }
+    }
+
+    #Create object
+    my $self = bless {}, $class;
+    $self->{_description} = $desc;
+    $self->{_explanation} = $expl;
+    $self->{_severity}    = $sev;
+    $self->{_policy}      = caller;
+    $self->{_elem}        = $elem;
+
+    # Do these now before the weakened $doc gets garbage collected
+    my $top = $elem->top();
+    $self->{_filename} = $top->can('filename') ? $top->filename() : undef;
+    $self->{_source}   = _first_line_of_source( $elem );
+
+    return $self;
+}
+
+#-----------------------------------------------------------------------------
+
+sub set_format { return $FORMAT = verbosity_to_format( $_[0] ); }  ##no critic(ArgUnpacking)
+sub get_format { return $FORMAT;         }
+
+#-----------------------------------------------------------------------------
+
+sub sort_by_location {  ##no critic(ArgUnpacking)
+
+    ref $_[0] || shift;              #Can call as object or class method
+    return scalar @_ if ! wantarray; #In case we are called in scalar context
+
+    ## no critic qw(RequireSimpleSort);
+    ## TODO: What if $a and $b are not Violation objects?
+    return
+        map {$_->[0]}
+            sort { ($a->[1] <=> $b->[1]) || ($a->[2] <=> $b->[2]) }
+                map {[$_, $_->location->[0] || 0, $_->location->[1] || 0]}
+                    @_;
+}
+
+#-----------------------------------------------------------------------------
+
+sub sort_by_severity {  ##no critic(ArgUnpacking)
+
+    ref $_[0] || shift;              #Can call as object or class method
+    return scalar @_ if ! wantarray; #In case we are called in scalar context
+
+    ## no critic qw(RequireSimpleSort);
+    ## TODO: What if $a and $b are not Violation objects?
+    return
+        map {$_->[0]}
+            sort { $a->[1] <=> $b->[1] }
+                map {[$_, $_->severity() || 0]}
+                    @_;
+}
+
+#-----------------------------------------------------------------------------
+
+sub location {
+    my $self = shift;
+
+    return $self->{_location} ||= $self->{_elem}->location() || [0,0,0];
+}
+
+#-----------------------------------------------------------------------------
+
+sub diagnostics {
+    my ($self) = @_;
+    my $policy = $self->policy();
+
+    if ( not $DIAGNOSTICS{$policy} ) {
+        eval {              ## no critic (RequireCheckingReturnValueOfEval)
+            my $module_name = ref $policy || $policy;
+            $DIAGNOSTICS{$policy} =
+                trim_pod_section(
+                    get_pod_section_for_module( $module_name, 'DESCRIPTION' )
+                );
+        };
+        $DIAGNOSTICS{$policy} ||= "    No diagnostics available\n";
+    }
+    return $DIAGNOSTICS{$policy};
+}
+
+#-----------------------------------------------------------------------------
+
+sub description {
+    my $self = shift;
+    return $self->{_description};
+}
+
+#-----------------------------------------------------------------------------
+
+sub explanation {
+    my $self = shift;
+    my $expl = $self->{_explanation};
+    if ( !$expl ) {
+       $expl = '(no explanation)';
+    }
+    if ( ref $expl eq 'ARRAY' ) {
+        my $page = @{$expl} > 1 ? 'pages' : 'page';
+        $page .= $SPACE . join $COMMA, @{$expl};
+        $expl = "See $page of PBP";
+    }
+    return $expl;
+}
+
+#-----------------------------------------------------------------------------
+
+sub severity {
+    my $self = shift;
+    return $self->{_severity};
+}
+
+#-----------------------------------------------------------------------------
+
+sub policy {
+    my $self = shift;
+    return $self->{_policy};
+}
+
+#-----------------------------------------------------------------------------
+
+sub filename {
+    my $self = shift;
+    return $self->{_filename};
+}
+
+#-----------------------------------------------------------------------------
+
+
+sub source {
+    my $self = shift;
+    return $self->{_source};
+}
+
+#-----------------------------------------------------------------------------
+
+sub to_string {
+    my $self = shift;
+
+    my $long_policy = $self->policy();
+    (my $short_policy = $long_policy) =~ s/ \A Perl::Critic::Policy:: //xms;
+
+    # Wrap the more expensive ones in sub{} to postpone evaluation
+    my %fspec = (
+         'f' => sub { $self->filename() },
+         'F' => sub { basename( $self->filename()) },
+         'l' => sub { $self->location->[0] },
+         'c' => sub { $self->location->[1] },
+         'm' => $self->description(),
+         'e' => $self->explanation(),
+         's' => $self->severity(),
+         'd' => sub { $self->diagnostics() },
+         'r' => sub { $self->source() },
+         'P' => $long_policy,
+         'p' => $short_policy,
+    );
+    return stringf($FORMAT, %fspec);
+}
+
+#-----------------------------------------------------------------------------
+# Apparently, some perls do not implicitly stringify overloading
+# objects before doing a comparison.  This causes a couple of our
+# sorting tests to fail.  To work around this, we overload C<cmp> to
+# do it explicitly.
+#
+# 20060503 - More information:  This problem has been traced to
+# Test::Simple versions <= 0.60, not perl itself.  Upgrading to
+# Test::Simple v0.62 will fix the problem.  But rather than forcing
+# everyone to upgrade, I have decided to leave this workaround in
+# place.
+
+sub _compare { return "$_[0]" cmp "$_[1]" }
+
+#-----------------------------------------------------------------------------
+
+sub _first_line_of_source {
+    my $elem = shift;
+
+    my $stmnt = $elem->statement() || $elem;
+    my $code_string = $stmnt->content() || $EMPTY;
+
+    #Chop everything but the first line (without newline);
+    $code_string =~ s{ \n.* }{}smx;
+    return $code_string;
+}
+
+
+1;
+
+#-----------------------------------------------------------------------------
+
+__END__
+
+=head1 NAME
+
+Perl::Critic::Violation - A violation of a Policy found in some source code.
+
+=head1 SYNOPSIS
+
+  use PPI;
+  use Perl::Critic::Violation;
+
+  my $elem = $doc->child(0);      #$doc is a PPI::Document object
+  my $desc = 'Offending code';    #Describe the violation
+  my $expl = [1,45,67];           #Page numbers from PBP
+  my $sev  = 5;                   #Severity level of this violation
+
+  my $vio  = Perl::Critic::Violation->new($desc, $expl, $node, $sev);
+
+=head1 DESCRIPTION
+
+Perl::Critic::Violation is the generic representation of an individual
+Policy violation.  Its primary purpose is to provide an abstraction
+layer so that clients of L<Perl::Critic> don't have to know anything
+about L<PPI>.  The C<violations> method of all L<Perl::Critic::Policy>
+subclasses must return a list of these Perl::Critic::Violation
+objects.
+
+=head1 CONSTRUCTOR
+
+=over 8
+
+=item C<new( $description, $explanation, $element, $severity )>
+
+Returns a reference to a new C<Perl::Critic::Violation> object. The
+arguments are a description of the violation (as string), an
+explanation for the policy (as string) or a series of page numbers in
+PBP (as an ARRAY ref), a reference to the L<PPI> element that caused
+the violation, and the severity of the violation (as an integer).
+
+=back
+
+=head1 METHODS
+
+=over 8
+
+=item C<description()>
+
+Returns a brief description of the specific violation.  In other
+words, this value may change on a per violation basis.
+
+=item C<explanation()>
+
+Returns an explanation of the policy as a string or as reference to
+an array of page numbers in PBP.  This value will generally not change
+based upon the specific code violating the policy.
+
+=item C<location()>
+
+Returns a three-element array reference containing the line and real
+& virtual column numbers where this Violation occurred, as in
+L<PPI::Element>.
+
+=item C<filename()>
+
+Returns the path to the file where this Violation occurred.  In some
+cases, the path may be undefined because the source code was not read
+directly from a file.
+
+=item C<severity()>
+
+Returns the severity of this Violation as an integer ranging from 1 to
+5, where 5 is the "most" severe.
+
+=item C<sort_by_severity( @violation_objects )>
+
+If you need to sort Violations by severity, use this handy routine:
+
+   @sorted = Perl::Critic::Violation::sort_by_severity(@violations);
+
+=item C<sort_by_location( @violation_objects )>
+
+If you need to sort Violations by location, use this handy routine:
+
+   @sorted = Perl::Critic::Violation::sort_by_location(@violations);
+
+=item C<diagnostics()>
+
+Returns a formatted string containing a full discussion of the
+motivation for and details of the Policy module that created this
+Violation.  This information is automatically extracted from the
+C<DESCRIPTION> section of the Policy module's POD.
+
+=item C<policy()>
+
+Returns the name of the L<Perl::Critic::Policy> that created this
+Violation.
+
+=item C<source()>
+
+Returns the string of source code that caused this exception.  If the
+code spans multiple lines (e.g. multi-line statements, subroutines or
+other blocks), then only the first line will be returned.
+
+=item C<set_format( $FORMAT )>
+
+Class method.  Sets the format for all Violation objects when they are
+evaluated in string context.  The default is C<'%d at line %l, column
+%c. %e'>.  See L<"OVERLOADS"> for formatting options.
+
+=item C<get_format()>
+
+Class method. Returns the current format for all Violation objects
+when they are evaluated in string context.
+
+=item C<to_string()>
+
+Returns a string representation of this violation.  The content of the
+string depends on the current value of the C<$FORMAT> package
+variable.  See L<"OVERLOADS"> for the details.
+
+=back
+
+=head1 FIELDS
+
+=over 8
+
+=item C<$Perl::Critic::Violation::FORMAT>
+
+B<DEPRECATED:> Use the C<set_format> and C<get_format> methods instead.
+
+Sets the format for all Violation objects when they are evaluated in string
+context.  The default is C<'%d at line %l, column %c. %e'>.  See
+L<"OVERLOADS"> for formatting options.  If you want to change C<$FORMAT>, you
+should probably localize it first.
+
+=back
+
+=head1 OVERLOADS
+
+Perl::Critic::Violation overloads the C<""> operator to produce neat
+little messages when evaluated in string context.  The format depends
+on the current value of the C<$FORMAT> package variable.
+
+Formats are a combination of literal and escape characters similar to
+the way C<sprintf> works.  If you want to know the specific formatting
+capabilities, look at L<String::Format>. Valid escape characters are:
+
+    Escape    Meaning
+    -------   ----------------------------------------------------------------
+    %c        Column number where the violation occurred
+    %d        Full diagnostic discussion of the violation
+    %e        Explanation of violation or page numbers in PBP
+    %F        Just the name of the file where the violation occurred.
+    %f        Path to the file where the violation occurred.
+    %l        Line number where the violation occurred
+    %m        Brief description of the violation
+    %P        Full name of the Policy module that created the violation
+    %p        Name of the Policy without the Perl::Critic::Policy:: prefix
+    %r        The string of source code that caused the violation
+    %s        The severity level of the violation
+
+Here are some examples:
+
+  $Perl::Critic::Violation::FORMAT = "%m at line %l, column %c.\n";
+  #looks like "Mixed case variable name at line 6, column 23."
+
+  $Perl::Critic::Violation::FORMAT = "%m near '%r'\n";
+  #looks like "Mixed case variable name near 'my $theGreatAnswer = 42;'"
+
+  $Perl::Critic::Violation::FORMAT = "%l:%c:%p\n";
+  #looks like "6:23:NamingConventions::ProhibitMixedCaseVars"
+
+  $Perl::Critic::Violation::FORMAT = "%m at line %l. %e. \n%d\n";
+  #looks like "Mixed case variable name at line 6.  See page 44 of PBP.
+                    Conway's recommended naming convention is to use lower-case words
+                    separated by underscores.  Well-recognized acronyms can be in ALL
+                    CAPS, but must be separated by underscores from other parts of the
+                    name."
+
+=head1 AUTHOR
+
+Jeffrey Ryan Thalhammer <thaljef@cpan.org>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2005-2008 Jeffrey Ryan Thalhammer.  All rights reserved.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.  The full text of this license
+can be found in the LICENSE file included with this module.
+
+=cut
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 78
+#   indent-tabs-mode: nil
+#   c-indentation-style: bsd
+# End:
+# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :