]> git.donarmstrong.com Git - perltidy.git/commitdiff
replace sub 'weld_signature_parens' with 'tight_paren_follows'
authorSteve Hancock <perltidy@users.sourceforge.net>
Mon, 30 Mar 2020 15:35:17 +0000 (08:35 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Mon, 30 Mar 2020 15:35:17 +0000 (08:35 -0700)
lib/Perl/Tidy/Formatter.pm
t/snippets/expect/wn7.def
t/snippets/packing_list.txt
t/snippets17.t

index a2a3037c24310392535e6849f6e0e648184276ae..3d0fbe3a204bdad80640db2d6386a420e52fb762 100644 (file)
@@ -3822,7 +3822,9 @@ sub weld_containers {
 
     $self->weld_cuddled_blocks();
 
-    $self->weld_signature_parens();
+    # Deactivated; sub tight_paren_follows() does this now
+    # FIXME: to be deleted
+    ## $self->weld_signature_parens();
 
     return;
 }
@@ -3842,6 +3844,9 @@ sub cumulative_length_after_K {
 sub weld_signature_parens {
     my $self = shift;
 
+    # FIXME: this routine has been replaced by sub tight_following_paren
+    # and can be removed
+
     # 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.
@@ -4272,16 +4277,16 @@ sub weld_nested_containers {
         }
 
         # DO-NOT-WELD RULE 2b:
-       # Do not weld to open hash brace which is not separated from its closing
-       # brace by two lines.  We want to avoid something like this
+        # Do not weld to open hash brace which is not separated from its
+        # closing brace by two lines.  We want to avoid something like this
         #                foreach
         #                  (@{$numbers{$num}->{$num . $rowcode . $colcode}})
         #  and prefer this:
-        #            $Self->_Add(
-        #                $SortOrderDisplay{$Field->GenerateFieldForSelectSQL()});
+        #        $Self->_Add(
+        #            $SortOrderDisplay{$Field->GenerateFieldForSelectSQL()});
         # instead of this:
-        #            $Self->_Add($SortOrderDisplay{$Field
-        #                  ->GenerateFieldForSelectSQL()});
+        #        $Self->_Add($SortOrderDisplay{$Field
+        #              ->GenerateFieldForSelectSQL()});
         if ( $iline_ic - $iline_io < 2 ) {
             my $type_io = $inner_opening->[_TYPE_];
             $do_not_weld ||= $type_io eq 'L';
@@ -7184,6 +7189,125 @@ EOM
         return ( $val1 && $val2 || !$val1 && !$val2 );
     }
 
+    sub tight_paren_follows {
+
+       # We are at the closing brace of a 'do' block.  See if this brace is
+       # followed by a closing paren, and if so, set a flag which indicates
+       # that we do not want a line break between the '}' and ')'.  We do not
+       # want a line break if the expression within parens is fairly 'simple'.
+
+       # 'Simple' is hard to define, but for now will consider the expression
+       # to be simple if either it is a sub signature, or there are (1) no
+       # other container tokens and (2) no commas between the opening paren
+       # and brace. 
+
+        # For example the following expression is simple because there is just the
+       # keyword 'do' between the '(' and the '{', so we do not add line break:
+       # 'do' block is the only expression within the parens:
+
+        #    if ( do { $2 !~ /&/ } ) { ... }
+
+        # (Note: in this case the weld option -wn will accomplish the same effect)
+
+       # For anything more complex than this, we also require that the expression
+       # be on one line in the input.
+
+       # For example, we will set the flag for the following expression
+       # written in one line:
+       # example:
+
+        #   $self->debug( 'Error: ' . do { local $/; <$err> } );
+
+       # but not if it is on multiple lines on input, since the user may prefer
+       # it on multiple lines:
+
+        #   $self->debug(
+        #       'Error: ' . do { local $/; <$err> }
+        #   );
+
+        # The following will not be simple by these rules (comma between the '('
+       # and the '{':
+
+        #    for my $to ( 'tmp', do { \my $o } ) {
+
+       # and this will not be simple (extra parens between the '(' and '{]):
+
+        #  if (  !defined($warnings::VERSION)
+        #    || do { no warnings "numeric"; $warnings::VERSION < 1.03 } )
+
+        # Subscript notation:
+        # _i = inner container (braces in this case)
+        # _o = outer container (parens in this case)
+        # _io = inner opening = '{'
+        # _ic = inner closing = '}'
+        # _oo = outer opening = '('
+        # _oc = outer closing = ')'
+
+        my ( $self, $K_ic ) = @_;
+        return unless defined($K_ic);
+        my $rLL = $self->{rLL};
+
+        # we should only be called at a closing block
+        my $seqno_i = $rLL->[$K_ic]->[_TYPE_SEQUENCE_];
+        return unless ($seqno_i);    # shouldn't happen;
+
+        # Look at next nonblank, see if it is a ')'
+        my $K_oc = $self->K_next_nonblank($K_ic);
+        return unless defined($K_oc);
+        my $token_next = $rLL->[$K_oc]->[_TOKEN_];
+        return unless ( $token_next eq ')' );
+
+        my $seqno_o = $rLL->[$K_oc]->[_TYPE_SEQUENCE_];
+        my $K_io    = $self->{K_opening_container}->{$seqno_i};
+        my $K_oo    = $self->{K_opening_container}->{$seqno_o};
+
+        # Never break a simple parenthesized do of the form ( do { ... } )
+        my $K_test = $self->K_next_nonblank($K_oo);
+        if ( $K_test < $K_io )  { $K_test = $self->K_next_nonblank($K_test); }
+        if ( $K_test == $K_io ) { return 1 }
+
+        # Never break before a closing signature paren. 
+        # This is a fix for issue git#22.
+        $K_test = $self->K_next_nonblank($K_oc);
+        my $block_type = $rLL->[$K_test]->[_BLOCK_TYPE_];
+        if (
+            $block_type
+            && (   $block_type =~ /$SUB_PATTERN/
+                || $block_type =~ /$ASUB_PATTERN/ )
+          )
+        {
+            return 1;
+        }
+
+       # If there are intervening container item(s) between the outer '(' and
+       # the innier '{' then this is considered a complex statement
+        $K_test = $rLL->[$K_oo]->[_KNEXT_SEQ_ITEM_];
+        if ( $K_test != $K_io ) {
+            return;
+        }
+
+        # see if this is one line on input and possibly on output
+        return if ( $K_oo < $K_to_go[0] );
+
+       # require input on one line for anything more complex unless signature
+        if ( !$rOpts->{'ignore-old-breakpoints'} ) {
+            my $iline_oo = $rLL->[$K_oo]->[_LINE_INDEX_];
+            my $iline_oc = $rLL->[$K_oc]->[_LINE_INDEX_];
+            return if ( $iline_oo != $iline_oc );
+        }
+
+       # If there are any commas between the '(' and '{' then the expression
+       # is considered complex.  This is a potentially slow test so we save it
+       # for last.
+        for ( my $KK = $K_oo + 1 ; $KK < $K_io ; $KK++ ) {
+            my $type = $rLL->[$KK]->[_TYPE_];
+            return if ( $type eq ',' );
+        }
+
+       # Not a complex expression
+        return 1;
+    }
+
     sub print_line_of_tokens {
 
         my ( $self, $line_of_tokens ) = @_;
@@ -7699,6 +7823,9 @@ EOM
                 # tokens
                 if ( $block_type eq 'do' ) {
                     $rbrace_follower = \%is_do_follower;
+                    if ( $self->tight_paren_follows($Ktoken_vars) ) {
+                        $rbrace_follower = { ')' => 1 };
+                    }
                 }
                 elsif ( $block_type =~ /^(if|elsif|unless)$/ ) {
                     $rbrace_follower = \%is_if_brace_follower;
@@ -12588,9 +12715,9 @@ sub terminal_type_K {
         #    $a->$b($c);
         $binary_bond_strength{'i'}{'->'} = 1.45 * STRONG;
 
-       # Note that the following alternative strength would make the break at the
-       # '->' rather than opening the '('.  Both have advantages and disadvantages.
-        # $binary_bond_strength{'i'}{'->'} = 0.5*STRONG + 0.5 * NOMINAL; #
+    # Note that the following alternative strength would make the break at the
+    # '->' rather than opening the '('.  Both have advantages and disadvantages.
+    # $binary_bond_strength{'i'}{'->'} = 0.5*STRONG + 0.5 * NOMINAL; #
 
         $binary_bond_strength{'))'}{'->'} = 0.1 * STRONG + 0.9 * NOMINAL;
         $binary_bond_strength{']]'}{'->'} = 0.1 * STRONG + 0.9 * NOMINAL;
index 9113237f0689b71517bbd3bd7037c444b878664f..0e8c99235c5f244a638c84548afe2cd50b62ce36 100644 (file)
@@ -6,6 +6,4 @@
 
                     # rule 2a forerly applied to all blocks, but now only
                     # applies to subs, so this weld is now okay with -wn
-                    f(
-                        do { 1; !!( my $x = bless [] ); }
-                    );
+                    f( do { 1; !!( my $x = bless [] ); } );
index 263a65038b54ff49d06983db828308492d64b483..0c4d130b32669ccdce838ff143eb577ea15d298e 100644 (file)
 ../snippets17.t        signature.def
 ../snippets17.t        rperl.def
 ../snippets17.t        rperl.rperl
+../snippets17.t        wn7.def
+../snippets17.t        wn7.wn
 ../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        wn7.def
-../snippets17.t        wn7.wn
index b87523af66717c4f1a13d3cd5fc6867a554d9409..15aac77fb33a51806eb30c61753972c2079850d7 100644 (file)
@@ -231,9 +231,7 @@ sub foo_subroutine_in_main {
 
                     # rule 2a forerly applied to all blocks, but now only
                     # applies to subs, so this weld is now okay with -wn
-                    f(
-                        do { 1; !!( my $x = bless [] ); }
-                    );
+                    f( do { 1; !!( my $x = bless [] ); } );
 #6...........
         },