From f28ab559dc4536871b2956165a864b1bad63d517 Mon Sep 17 00:00:00 2001
From: Steve Hancock <perltidy@users.sourceforge.net>
Date: Thu, 8 Apr 2021 08:58:16 -0700
Subject: [PATCH] Merge weld rule 6 into rule 3

---
 dev-bin/perltidy_random_run.pl |  2 +-
 lib/Perl/Tidy/FileWriter.pm    |  2 ++
 lib/Perl/Tidy/Formatter.pm     | 54 +++++++++++++++++-----------------
 local-docs/BugLog.pod          | 10 +++++++
 4 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/dev-bin/perltidy_random_run.pl b/dev-bin/perltidy_random_run.pl
index 5b474e60..9a1b00cf 100755
--- a/dev-bin/perltidy_random_run.pl
+++ b/dev-bin/perltidy_random_run.pl
@@ -350,7 +350,7 @@ for ( my $nf = $nf_beg ; $nf <= $nf_end ; $nf++ ) {
 
         # run perltidy on the output to see if it can be reformatted
         # without errors
-        my $cmd2 = "perltidy <$ofile >$chkfile";
+        my $cmd2 = "$binfile <$ofile >$chkfile";
         system_echo( $cmd2, $hash );
 
         #print STDERR "$cmd2\n";
diff --git a/lib/Perl/Tidy/FileWriter.pm b/lib/Perl/Tidy/FileWriter.pm
index 10e72ac3..8dafdec7 100644
--- a/lib/Perl/Tidy/FileWriter.pm
+++ b/lib/Perl/Tidy/FileWriter.pm
@@ -208,6 +208,8 @@ sub write_blank_code_line {
 
     $self->[_consecutive_nonblank_lines_] = 0;
 
+    # Balance old blanks against new (forced) blanks instead of writing them.
+    # This fixes case b1073.
     if ( !$forced && $self->[_consecutive_new_blank_lines_] > 0 ) {
         $self->[_consecutive_new_blank_lines_]--;
         return;
diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm
index 9a87efe7..2eeeb4ef 100644
--- a/lib/Perl/Tidy/Formatter.pm
+++ b/lib/Perl/Tidy/Formatter.pm
@@ -7374,7 +7374,32 @@ EOM
         # (fixes cases b746 b748 b749 b750 b752 b753 b754 b755 b756 b758 b759)
         if ( !$do_not_weld_rule ) {
 
-            my $excess = $excess_length_to_K->($Kinner_opening);
+            # Measure to a little beyond the inner opening token if it is
+            # followed by a bare word, which may have unusual line break rules.
+
+            # NOTE: Originally this was OLD RULE 6: do not weld to a container
+            # which is followed on the same line by an unknown bareword token.
+            # This can cause blinkers (cases b626, b611).  But OK to weld one
+            # line welds to fix cases b1057 b1064.  For generality, OLD RULE 6
+            # has been merged into RULE 3 here to also fix cases b1078 b1091.
+
+            my $K_for_length = $Kinner_opening;
+            my $Knext_io     = $self->K_next_nonblank($Kinner_opening);
+            next unless ( defined($Knext_io) );    # shouldn't happen
+            my $type_io_next = $rLL->[$Knext_io]->[_TYPE_];
+
+            # Note: may need to eventually also include other types here,
+            # such as 'Z' and 'Y':   if ($type_io_next =~ /^[ZYw]$/) {
+            if ( $type_io_next eq 'w' ) {
+                my $Knext_io2 = $self->K_next_nonblank($Knext_io);
+                next unless ( defined($Knext_io2) );
+                my $type_io_next2 = $rLL->[$Knext_io2]->[_TYPE_];
+                if ( !$type_ok_after_bareword{$type_io_next2} ) {
+                    $K_for_length = $Knext_io2;
+                }
+            }
+
+            my $excess = $excess_length_to_K->($K_for_length);
 
             # Use '>=' instead of '=' here to fix cases b995 b998 b1000
             # b1001 b1007 b1008 b1009 b1010 b1011 b1012 b1016 b1017 b1018
@@ -7427,32 +7452,7 @@ EOM
             $do_not_weld_rule = 5;
         }
 
-        # DO-NOT-WELD RULE 6: Do not weld to a container which is followed on
-        # the same line by an unknown bareword token.  This can cause
-        # blinkers (cases b626, b611).
-        # Patched for cases b1057 b1064: skip RULE 6 for a one-line weld.
-        # Note: Another, more general fix is to remove the check on line
-        # numbers and always do this. That was tested and works, and may be
-        # necessary in the future, but it could change some existing code.
-        if ( !$do_not_weld_rule && !$is_one_line_weld ) {
-            my $Knext_io = $self->K_next_nonblank($Kinner_opening);
-            next unless ( defined($Knext_io) );
-            my $iline_io_next = $rLL->[$Knext_io]->[_LINE_INDEX_];
-            if ( $iline_io_next == $iline_io ) {
-                my $type_io_next = $rLL->[$Knext_io]->[_TYPE_];
-
-                # Note: may need to eventually also include other types here,
-                # such as 'Z' and 'Y':   if ($type_io_next =~ /^[ZYw]$/) {
-                if ( $type_io_next eq 'w' ) {
-                    my $Knext_io2 = $self->K_next_nonblank($Knext_io);
-                    next unless ( defined($Knext_io2) );
-                    my $type_io_next2 = $rLL->[$Knext_io2]->[_TYPE_];
-                    if ( !$type_ok_after_bareword{$type_io_next2} ) {
-                        $do_not_weld_rule = 6;
-                    }
-                }
-            }
-        }
+        # DO-NOT-WELD RULE 6: This has been merged into RULE 3 above.
 
         # DO-NOT-WELD RULE 7: Do not weld if this conflicts with -bom
         # (case b973)
diff --git a/local-docs/BugLog.pod b/local-docs/BugLog.pod
index dc79b19f..8afb381c 100644
--- a/local-docs/BugLog.pod
+++ b/local-docs/BugLog.pod
@@ -3,6 +3,16 @@
 
 =over 4
 
+=item B<Merge weld rule 6 into rule 3>
+
+One of the welding rules, RULE 6, has been merged into RULE 3 for
+generality.  This rule restricts welding to an opening container
+followed by a bare word, which can cause instability in some cases.
+The updated code is less restrictive and fixes some cases
+recently found with random testing, b1078 b1091.
+
+8 Apr 2021.
+
 =item B<Moved logic of previous update to the FileWriter module>
 
 The previous update regarding blank line generation was not sufficiently
-- 
2.39.5