]> git.donarmstrong.com Git - perltidy.git/commitdiff
fix git#22, keep sub signature on a single line
authorSteve Hancock <perltidy@users.sourceforge.net>
Wed, 18 Mar 2020 14:10:52 +0000 (07:10 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Wed, 18 Mar 2020 14:10:52 +0000 (07:10 -0700)
CHANGES.md
dev-bin/build.pl
lib/Perl/Tidy/Formatter.pm
t/snippets/expect/signature.def [new file with mode: 0644]
t/snippets/packing_list.txt
t/snippets/signature.in [new file with mode: 0644]
t/snippets17.t

index cfe41afd5284436c1756f4ca5cc41b800d9d8232..edab30770f84d6a28522fb69e32cc06ccea8ee20 100644 (file)
@@ -2,6 +2,10 @@
 
 ## 2020 01 10.01
 
+    - Fix for git#22, Preserve function signature on a single line. An
+      unwanted line break was being introduced when a closing signature paren
+      followed a closing do brace.
+
     - Fix RT#132059, the -dac parameter was not working and caused an error exit
 
     - When -utf8 is used, any error output is encoded as utf8
index 483ca8d079925f8de54277030cc9db15af0a6eb9..4d31bfd6b2d9e81a381bd9edfd2c56e4a8ca85a9 100755 (executable)
@@ -49,7 +49,7 @@ my $rstatus = {};
 foreach my $step ( @{$rsteps} ) { $rstatus->{$step} = 'TBD' }
 
 my $rcode = {
-    'A'   => \&autopilot,
+    ## 'A'   => \&autopilot,   # can be confusing, deactivated
     'CHK' => sub {
         openurl("local-docs/Release-Checklist.md")
           unless $rstatus->{CHK} eq 'OK';
@@ -73,12 +73,12 @@ $fh_log->close();
 
 sub main {
     while (1) {
+##A        - run All Steps...
         print <<EOM;
 -------------------------------------------
 Perltidy Build Main Menu - Case Insensitive
 -------------------------------------------
 
-A        - run All Steps...
 chk      - view release CHecKlist          status: $rstatus->{'CHK'}
 v        - check/update Version Number     status: $rstatus->{'V'}
 tidy     - run tidyall (tidy & critic)     status: $rstatus->{'TIDY'}
index 38e94a044d1932f930a37e4f24d6a21838222e38..c5dadcef53248b7e2e524f1d6b2beab88dc1d2bf 100644 (file)
@@ -3843,6 +3843,8 @@ sub weld_containers {
 
     $self->weld_cuddled_blocks();
 
+    $self->weld_signature_parens();
+
     return;
 }
 
@@ -3858,6 +3860,90 @@ sub cumulative_length_after_K {
     return $rLL->[$KK]->[_CUMULATIVE_LENGTH_];
 }
 
+sub weld_signature_parens {
+    my $self = shift;
+
+    # This routine fixes a problem in which an unwanted line break can
+    # be inserted between a closing block brace and a closing sub signature
+    # paren.  This is a fix for issue git#22.
+
+    # For example, in the following snippet:
+    #  sub foo ( $self, $$opts = do { ... } ) { $something=1 }
+    # we do not want a break after the closing do brace
+
+    # Method: Look through the file for closing sub signature parens which
+    # follow closing braces, and weld any such parens to those braces so that
+    # they do not get separated.
+
+    # We want to do the following steps:
+    # 1. look for an opening sub brace,
+    # 2. look back one nonblank character for a closing paren [the signature]
+    # 3. if we find one, look back one more character for any closing brace,
+    # 4. and if we find one, then 'weld' that closing brace to that closing
+    # paren.
+
+    # Note that some good test cases are in 'signatures.t' in a perl
+    # distribution
+
+    # TODO: Improve efficiency by creating a list of K values of opening sub
+    # braces in advance, and just loop through them rather than all containers.
+
+    my $rLL = $self->{rLL};
+    return unless ( defined($rLL) && @{$rLL} );
+
+    # Loop over all container items in the file
+    my $KNEXT         = 0;
+    my $KK            = 0;
+    my $token         = "";
+    my $type_sequence = "";
+    while ( defined($KNEXT) ) {
+        my $KLAST              = $KK;
+        my $token_last         = $token;
+        my $type_sequence_last = $type_sequence;
+
+        $KK    = $KNEXT;
+        $KNEXT = $rLL->[$KNEXT]->[_KNEXT_SEQ_ITEM_];
+        my $rtoken_vars = $rLL->[$KK];
+        $type_sequence = $rtoken_vars->[_TYPE_SEQUENCE_];
+        $token         = $rtoken_vars->[_TOKEN_];
+        my $block_type = $rtoken_vars->[_BLOCK_TYPE_];
+
+        # 1. look for an opening sub brace...
+        # 2. following a closing paren (with possible blank between)...
+        if (
+               $is_opening_token{$token}
+            && $KLAST
+            && $KK - $KLAST <= 2
+            && $token_last eq ')'
+            && (   $block_type =~ /$SUB_PATTERN/
+                || $block_type =~ /$ASUB_PATTERN/ )
+          )
+        {
+
+            # any intervening char must be a blank
+            if ( $KK - $KLAST == 2 ) {
+                if ( $rLL->[ $KK - 1 ]->[_TYPE_] ne 'b' ) {
+                    next;
+                }
+            }
+
+            # 3. following a closing block brace of any kind...
+            my $Kp = $self->K_previous_nonblank($KLAST);
+            if ($Kp) {
+                my $block_type_p = $rLL->[$Kp]->[_BLOCK_TYPE_];
+                if ($block_type_p) {
+
+                    # 4. Found it; set the weld flag for this brace.
+                    # It will be checked in sub output_line_to_go
+                    my $type_sequence_p = $rLL->[$Kp]->[_TYPE_SEQUENCE_];
+                    $weld_len_right_closing{$type_sequence_p} = 1;
+                }
+            }
+        }
+    }
+    return;
+}
+
 sub weld_cuddled_blocks {
     my $self = shift;
 
diff --git a/t/snippets/expect/signature.def b/t/snippets/expect/signature.def
new file mode 100644 (file)
index 0000000..de0dc88
--- /dev/null
@@ -0,0 +1,21 @@
+# git22: Preserve function signature on a single line
+# This behavior is controlled by 'sub weld_signature_parens'
+
+sub foo ( $x, $y = "abcd" ) {
+    $x . $y;
+}
+
+# do not break after closing do brace
+sub foo ( $x, $y = do { {} }, $z = 42, $w = do { "abcd" } ) {
+    $x . $y . $z;
+}
+
+# This signature should get put back on one line
+sub t022 ( $p = do { $z += 10; 222 }, $a = do { $z++; 333 } ) {
+    "$p/$a";
+}
+
+# anonymous sub with signature
+my $subref = sub ( $cat, $id = do { state $auto_id = 0; $auto_id++ } ) {
+    ...;
+};
index 4ac536286888d73e773a957f770b1fb979e5cca7..47ac806e6195570a5832e9fc7db262c065b5103e 100644 (file)
 ../snippets16.t        rt130394.rt130394
 ../snippets16.t        git18.def
 ../snippets16.t        here2.def
+../snippets17.t        rt132059.def
+../snippets17.t        rt132059.rt132059
+../snippets17.t        signature.def
 ../snippets2.t angle.def
 ../snippets2.t arrows1.def
 ../snippets2.t arrows2.def
 ../snippets9.t rt98902.def
 ../snippets9.t rt98902.rt98902
 ../snippets9.t rt99961.def
-../snippets17.t        rt132059.def
-../snippets17.t        rt132059.rt132059
diff --git a/t/snippets/signature.in b/t/snippets/signature.in
new file mode 100644 (file)
index 0000000..def25b5
--- /dev/null
@@ -0,0 +1,21 @@
+# git22: Preserve function signature on a single line
+# This behavior is controlled by 'sub weld_signature_parens'
+
+sub foo($x, $y="abcd") {
+  $x.$y;
+}
+
+# do not break after closing do brace
+sub foo($x, $y=do{{}}, $z=42, $w=do{"abcd"}) {
+  $x.$y.$z;
+}
+
+# This signature should get put back on one line
+sub t022 (
+    $p = do { $z += 10; 222 }, $a = do { $z++; 333 }
+) { "$p/$a" }
+
+# anonymous sub with signature
+my $subref = sub ( $cat, $id = do { state $auto_id = 0; $auto_id++ } ) {
+    ...;
+};
index 0a6c1ec63c4637f575aa1f463c94b7448d7e6ab6..61a73748c948941ccb5739858294047526559a11 100644 (file)
@@ -3,6 +3,7 @@
 # Contents:
 #1 rt132059.def
 #2 rt132059.rt132059
+#3 signature.def
 
 # To locate test #13 you can search for its name or the string '#13'
 
@@ -43,6 +44,30 @@ bonjour!
 =cut
 
 $i++;
+----------
+
+        'signature' => <<'----------',
+# git22: Preserve function signature on a single line
+# This behavior is controlled by 'sub weld_signature_parens'
+
+sub foo($x, $y="abcd") {
+  $x.$y;
+}
+
+# do not break after closing do brace
+sub foo($x, $y=do{{}}, $z=42, $w=do{"abcd"}) {
+  $x.$y.$z;
+}
+
+# This signature should get put back on one line
+sub t022 (
+    $p = do { $z += 10; 222 }, $a = do { $z++; 333 }
+) { "$p/$a" }
+
+# anonymous sub with signature
+my $subref = sub ( $cat, $id = do { state $auto_id = 0; $auto_id++ } ) {
+    ...;
+};
 ----------
     };
 
@@ -86,6 +111,34 @@ sub f {
 $i++;
 #2...........
         },
+
+        'signature.def' => {
+            source => "signature",
+            params => "def",
+            expect => <<'#3...........',
+# git22: Preserve function signature on a single line
+# This behavior is controlled by 'sub weld_signature_parens'
+
+sub foo ( $x, $y = "abcd" ) {
+    $x . $y;
+}
+
+# do not break after closing do brace
+sub foo ( $x, $y = do { {} }, $z = 42, $w = do { "abcd" } ) {
+    $x . $y . $z;
+}
+
+# This signature should get put back on one line
+sub t022 ( $p = do { $z += 10; 222 }, $a = do { $z++; 333 } ) {
+    "$p/$a";
+}
+
+# anonymous sub with signature
+my $subref = sub ( $cat, $id = do { state $auto_id = 0; $auto_id++ } ) {
+    ...;
+};
+#3...........
+        },
     };
 
     my $ntests = 0 + keys %{$rtests};