Login
The Perl::Critic::Violation source() method (and therefore the %r
authorTom Wyant <harryfmudd@comcast.net>
Mon, 25 Jul 2011 00:16:10 +0000 (00:16 +0000)
committerTom Wyant <harryfmudd@comcast.net>
Mon, 25 Jul 2011 00:16:10 +0000 (00:16 +0000)
format) now handles multi-line statements by returning the line of the
statement that contains the violation. Or at least, tries very hard to.
The previous version returned the first line, whether or not it
contained the violation.

Changes
lib/Perl/Critic/Violation.pm

diff --git a/Changes b/Changes
index c58c35e..629e161 100644 (file)
--- a/Changes
+++ b/Changes
@@ -13,6 +13,9 @@ Next release, whenever it is:
       character.
     Other Changes:
     * Corrected POD in Perl::Critic::PPI::Utils. RT #68898.
+    * Perl::Critic::Violation source() method now returns the line
+      containing the violation (not the first line) when the statement
+      containing the violation spans multiple lines.
 
 [1.116] Released on 2011-05-15
 
index b9bfd8d..e049a45 100644 (file)
@@ -84,7 +84,7 @@ sub new {
 
     my $top = $elem->top();
     $self->{_filename} = $top->can('filename') ? $top->filename() : undef;
-    $self->{_source}   = _first_line_of_source( $elem );
+    $self->{_source}   = _line_containing_violation( $elem );
     $self->{_location} =
         $elem->location() || [ 0, 0, 0, 0, $self->filename() ];
 
@@ -297,15 +297,20 @@ sub _compare { return "$_[0]" cmp "$_[1]" }
 
 #-----------------------------------------------------------------------------
 
-sub _first_line_of_source {
-    my $elem = shift;
+sub _line_containing_violation {
+    my ( $elem ) = @_;
 
     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;
+    # Split into individual lines
+    my @lines = split qr{ \n\s* }xms, $code_string;
+
+    # Take the line containing the element that is in violation
+    my $inx = ( $elem->line_number() || 0 ) -
+        ( $stmnt->line_number() || 0 );
+    $inx > @lines and return $EMPTY;
+    return $lines[$inx];
 }
 
 #-----------------------------------------------------------------------------
@@ -485,7 +490,8 @@ that created this Violation.
 
 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.
+other blocks), then only the line containing the violation will be
+returned.
 
 
 =item C<element_class()>