]> git.donarmstrong.com Git - perltidy.git/commitdiff
Fix several problems with -lp formatting
authorSteve Hancock <perltidy@users.sourceforge.net>
Wed, 26 May 2021 04:08:38 +0000 (21:08 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Wed, 26 May 2021 04:08:38 +0000 (21:08 -0700)
lib/Perl/Tidy/Formatter.pm
lib/Perl/Tidy/VerticalAligner.pm
local-docs/BugLog.pod

index d89afbf17b142799b1d249bf0063d0b7dee79283..9108ba96efe58e9f64183f85e193c4292d53ff3b 100644 (file)
@@ -8194,10 +8194,8 @@ sub weld_nested_quotes {
             # Change the level of a closing qw token to be that of the outer
             # containing token. This will allow -lp indentation to function
             # correctly in the vertical aligner.
-            # Patch to fix c002: but not if it contains text and is not -lp.
-            if ( $rOpts_line_up_parentheses
-                || length( $rLL->[$Kinner_closing]->[_TOKEN_] ) == 1 )
-            {
+            # Patch to fix c002: but not if it contains text
+            if ( length( $rLL->[$Kinner_closing]->[_TOKEN_] ) == 1 ) {
                 $rLL->[$Kinner_closing]->[_LEVEL_] =
                   $rLL->[$Kouter_closing]->[_LEVEL_];
             }
@@ -18912,7 +18910,6 @@ sub send_lines_to_vertical_aligner {
         $rvalign_hash->{list_seqno}                = $list_seqno;
         $rvalign_hash->{outdent_long_lines}        = $outdent_long_lines;
         $rvalign_hash->{is_terminal_ternary}       = $is_terminal_ternary;
-        $rvalign_hash->{is_terminal_statement}     = $is_semicolon_terminated;
         $rvalign_hash->{rvertical_tightness_flags} = $rvertical_tightness_flags;
         $rvalign_hash->{level_jump}                = $level_jump;
         $rvalign_hash->{rfields}                   = $rfields;
@@ -19364,8 +19361,18 @@ sub get_seqno {
         }
 
         # Loop over all lines of the batch ...
+
+        # Workaround for problem c007, in which the combination -lp -xci
+        # can produce a "Program bug" message in unusual circumstances.
+        my $skip_SECTION_1 = $rOpts_line_up_parentheses
+          && $rOpts->{'extended-continuation-indentation'};
+
         foreach my $line ( 0 .. $max_line ) {
 
+            my $ibeg = $ri_first->[$line];
+            my $iend = $ri_last->[$line];
+            my $lev  = $levels_to_go[$ibeg];
+
             ####################################
             # SECTION 1: Undo needless common CI
             ####################################
@@ -19388,10 +19395,7 @@ sub get_seqno {
             #        sort { $a <=> $b }
             #        grep { $lookup->{$_} ne $default } keys %$lookup );
 
-            my $ibeg = $ri_first->[$line];
-            my $iend = $ri_last->[$line];
-            my $lev  = $levels_to_go[$ibeg];
-            if ( $line > 0 ) {
+            if ( $line > 0 && !$skip_SECTION_1 ) {
 
                 # if we have started a chain..
                 if ($line_1) {
index 5090b39c98f212ed7985cb64eb884d3c0e81b9a5..8eecfe8ce54e3afe248309c01656badaa0479639 100644 (file)
@@ -118,7 +118,6 @@ BEGIN {
         _zero_count_                  => $i++,
         _last_leading_space_count_    => $i++,
         _comment_leading_space_count_ => $i++,
-        _extra_indent_ok_             => $i++,
     };
 
     # Debug flag. This is a relic from the original program development
@@ -191,7 +190,6 @@ sub new {
     $self->[_zero_count_]                  = 0;
     $self->[_comment_leading_space_count_] = 0;
     $self->[_last_leading_space_count_]    = 0;
-    $self->[_extra_indent_ok_]             = 0;
 
     # Memory of what has been processed
     $self->[_last_level_written_]            = -1;
@@ -400,7 +398,6 @@ sub valign_input {
     my $list_seqno                = $rline_hash->{list_seqno};
     my $outdent_long_lines        = $rline_hash->{outdent_long_lines};
     my $is_terminal_ternary       = $rline_hash->{is_terminal_ternary};
-    my $is_terminal_statement     = $rline_hash->{is_terminal_statement};
     my $rvertical_tightness_flags = $rline_hash->{rvertical_tightness_flags};
     my $level_jump                = $rline_hash->{level_jump};
     my $rfields                   = $rline_hash->{rfields};
@@ -507,20 +504,7 @@ sub valign_input {
     # or if vertical alignment is turned off for debugging
     if ( $level != $group_level || $is_outdented || !$self->[_rOpts_valign_] ) {
 
-        # we are allowed to shift a group of lines to the right if its
-        # level is greater than the previous and next group
-        $self->[_extra_indent_ok_] =
-          (      $level < $group_level
-              && $self->[_last_level_written_] < $group_level );
-
-        $self->_flush_group_lines();
-
-        # If we know that this line will get flushed out by itself because
-        # of level changes, we can leave the extra_indent_ok flag set.
-        # That way, if we get an external flush call, we will still be
-        # able to do some -lp alignment if necessary.
-        $self->[_extra_indent_ok_] =
-          ( $is_terminal_statement && $level > $group_level );
+        $self->_flush_group_lines( $level - $group_level );
 
         $group_level = $level;
         $self->[_group_level_] = $group_level;
@@ -729,7 +713,7 @@ EOM
 
     # Force break after jump to lower level
     if ( $level_jump < 0 ) {
-        $self->_flush_group_lines();
+        $self->_flush_group_lines($level_jump);
     }
 
     # --------------------------------------------------------------------
@@ -1396,7 +1380,10 @@ sub _flush_group_lines {
 
     # This is the vertical aligner internal flush, which leaves the cache
     # intact
-    my ($self) = @_;
+    my ( $self, $level_jump ) = @_;
+
+    # $level_jump = $next_level-$group_level, if known
+    #             = undef if not known
 
     my $rgroup_lines = $self->[_rgroup_lines_];
     return unless ( @{$rgroup_lines} );
@@ -1445,8 +1432,29 @@ sub _flush_group_lines {
 
     # STEP 5: For the -lp option, increase the indentation of lists
     # to the desired amount, but do not exceed the line length limit.
+
+    # We are allowed to shift a group of lines to the right if:
+    #  (1) its level is greater than the level of the previous group, and
+    #  (2) its level is greater than the level of the next line to be written.
+
+    my $extra_indent_ok;
+    if ( $group_level > $self->[_last_level_written_] ) {
+
+        # Use the level jump to next line to come, if given
+        if ( defined($level_jump) ) {
+            $extra_indent_ok = $level_jump < 0;
+        }
+
+        # Otherwise, assume the next line has the level of the end of last line.
+        # This fixes case c008.
+        else {
+            my $level_end = $rgroup_lines->[-1]->get_level_end();
+            $extra_indent_ok = $group_level > $level_end;
+        }
+    }
+
     my $extra_leading_spaces =
-      $self->[_extra_indent_ok_]
+      $extra_indent_ok
       ? get_extra_leading_spaces( $rgroup_lines, $rgroups )
       : 0;
 
@@ -5098,7 +5106,6 @@ sub get_output_line_number {
 
         $self->[_last_level_written_]       = $level;
         $self->[_last_side_comment_length_] = $side_comment_length;
-        $self->[_extra_indent_ok_]          = 0;
         return;
     }
 }
index 1c2946b09ce143439169f837bec1599412b74727..5ca2f9f7fe55258959245c11a8c7224540d68e48 100644 (file)
@@ -2,6 +2,99 @@
 
 =over 4
 
+=item B<Fix several problems with -lp formatting>
+
+This update fixes several problems with -lp formatting which are all somewhat
+related.
+
+ISSUE #1 (case c002): A problem involving -lp -wn and certain qw lists
+
+The last line of a welded qw list was being outdented even if it contained text
+as well as the closing container token.  This update fixes the problem and
+simplifies the logic.
+
+A few examples (all use 'perltidy -wn -lp'):
+
+    # OLD and NEW: OK, closing qw paren is on separate line
+    $roads->add_capacity_path( qw( CoolCity 10 ChocolateGulch 8
+                               PecanPeak 10 BlueberryWoods 6
+                               HotCity
+    ) );
+
+    # OLD: poor; outdented text not aligned with previous text
+    $roads->add_capacity_path( qw( CoolCity 10 ChocolateGulch 8
+                               PecanPeak 10 BlueberryWoods 6
+    HotCity ) );
+
+    # NEW:
+    $roads->add_capacity_path( qw( CoolCity 10 ChocolateGulch 8
+                               PecanPeak 10 BlueberryWoods 6
+                               HotCity ) );
+
+    # OLD:
+    $roads->add_capacity_path( qw( ChocolateGulch 3 StrawberryFields 0
+    StrawberryFields ) );
+
+    # NEW:
+    $roads->add_capacity_path( qw( ChocolateGulch 3 StrawberryFields 0
+                               StrawberryFields ) );
+
+    # OLD:
+    my $mon_name = ( qw(January February March April
+                     May June July August
+    September October November December) )[$mon];
+
+    # NEW
+    my $mon_name = ( qw(January February March April
+                     May June July August
+                     September October November December) )[$mon];
+
+ISSUE #2 (case c007): A rare program error could be triggered with -lp -xci
+
+In some very rare circumstances it was possible to trigger a "Program error"
+message.  The program still ran to completion.  The conditions for this to occur
+were that flags -lp -xci were set, and that there was a container of sort/map/grep
+blocks, and there was a side comment on the closing paren.  For example:
+
+    # OLD: perltidy -lp -xci, gave an error message and extra indentation here
+    my %specified_opts = (
+          (
+                          map { /^no-?(.*)$/i ? ($1 => 0) : ($_ => 1) }
+                          map { /^--([\-_\w]+)$/ } @ARGV
+          ),    # this comment caused an error with flags -lp -xci
+    );
+
+    # NEW: perltidy -lp -xci, no error
+    my %specified_opts = (
+          (
+             map { /^no-?(.*)$/i ? ( $1 => 0 ) : ( $_ => 1 ) }
+             map { /^--([\-_\w]+)$/ } @ARGV
+          ),    # this comment caused an error with flags -lp -xci
+    );
+
+
+ISSUE #3 (case c008): In some unusual cases the -lp formatting style was not
+being applied when it should have been.  For example (text is shifted right):
+
+    # NEW: perltidy -lp
+    $result = runperl(
+        switches => [ '-I.', "-w" ],
+        stderr   => 1,
+        prog     => <<'PROG' );
+    SIG
+    PROG
+
+    # NEW: perltidy -lp
+    $result = runperl(
+                       switches => [ '-I.', "-w" ],
+                       stderr   => 1,
+                       prog     => <<'PROG' );
+    SIG
+    PROG
+
+
+25 May 2021.
+
 =item B<Modify welding rules>
 
 This is an update to the patch 19 Apr 2021, eeeaf09. It restricts that patch