Simplified coding of -ibhb and related parameters
authorSteve Hancock <perltidy@users.sourceforge.net>
Sat, 19 Sep 2020 01:04:10 +0000 (18:04 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Sat, 19 Sep 2020 01:04:10 +0000 (18:04 -0700)
CHANGES.md
bin/perltidy
docs/BugLog.html
docs/ChangeLog.html
docs/perltidy.html
lib/Perl/Tidy/Formatter.pm
t/snippets/expect/bbhb.bbhb2
t/snippets/packing_list.txt
t/snippets22.t

index 5ca9d946eb0e47a336203dce66c31544287320f8..88ee52efb3db8351a2a6223b075f21c78d2aa758 100644 (file)
@@ -7,7 +7,8 @@
 
     - Added parameters -bbhb=n (--break-before-hash-brace=n), -bbsb=n (--break-before-square-bracket=n),
       and -bbp=n (--break-before-paren=n) suggested in git #38.  These provide control over the
-      opening container token of a multiple-line list.
+      opening container token of a multiple-line list.  Related new parameters -ihb=n, -isb=n, -ip=n
+      control indentation of these tokens.
 
     - Numerous issues have been found during automated testing and fixed. Many involve references to
       uninitialized variables when perltidy is given random text. A complete list is given in
index a0e34d29380b679775e154e0cb31137b22d0b357..8ce05e3a3a93835aaeea91fca17f21d4f96730cf 100755 (executable)
@@ -2143,7 +2143,7 @@ before the opening brace according to the value given to the integer B<n>:
 
   -bbhb=0 never break [default]
   -bbhb=1 stable: break if the input script had a break
-  -bbhb=2 break if list is 'complex', meaning it contains other broken lists
+  -bbhb=2 break if list is 'complex' (see note below)
   -bbhb=3 always break
 
 For example, 
@@ -2157,20 +2157,25 @@ For example,
         four  => 'IV',
       };
 
-There are a couple of points to note about this flag:
+There are several points to note about this flag:
 
 =over 4
 
 =item *
 
+This parameter only applies to opening hash braces which are preceded by an '='
+or '=>'.
+
+=item *
+
 This parameter only applies if the contents of the container looks like a list.
 The contents need to contain some commas or '=>'s at the next interior level to
 be considered a list.
 
 =item *
 
-This parameter only applies if there is a blank space before the opening brace
-in the default formatting.
+For the B<n=2> option, a list is considered 'complex' if it is part of a nested list
+structure which spans multiple lines in the input file.
 
 =item *
 
@@ -2191,8 +2196,8 @@ Similar flags for controlling parens and square brackets are given in the subseq
 
 =item B<-ihb=n>,  B<--indent-hash-brace=n>
 
-This flag is a companion to B<-bbhb> for controlling the indentation of an opening hash brace.
-The indentation is as follows:
+This flag is a companion to B<-bbhb=n> for controlling the indentation of an opening hash brace
+which is placed on a new line by that parameter.  The indentation is as follows:
 
   -ihb=0 one continuation level [default]
   -ihb=1 outdent by one continuation level
@@ -2224,13 +2229,13 @@ This flag is similar to the flag described above, except it applies to square br
 
   -bbsb=0 never break [default]
   -bbsb=1 stable: break if the input script had a break
-  -bbsb=2 break if list is 'complex', meaning it contains other broken lists
+  -bbsb=2 break if list is 'complex' (part of nested list structure)
   -bbsb=3 always break
 
 =item B<-isb=n>,  B<--indent-square-bracket=n>
 
-This flag is a companion to B<-bbsb> for controlling the indentation of an opening square bracket.
-The indentation is as follows:
+This flag is a companion to B<-bbsb=n> for controlling the indentation of an opening square bracket
+which is placed on a new line by that parameter.  The indentation is as follows:
 
   -isb=0 one continuation level [default]
   -isb=1 outdent by one continuation level
@@ -2242,13 +2247,13 @@ This flag is similar to B<-bbhb=n>, described above, except it applies to parens
 
   -bbp=0 never break [default]
   -bbp=1 stable: break if the input script had a break
-  -bbp=2 break if list is 'complex', meaning it contains other broken lists
+  -bpb=2 break if list is 'complex' (part of nested list structure)
   -bbp=3 always break
 
 =item B<-ip=n>,  B<--indent-paren=n>
 
-This flag is a companion to B<-bbp> for controlling the indentation of an opening paren.
-The indentation is as follows:
+This flag is a companion to B<-bbp=n> for controlling the indentation of an opening paren
+which is placed on a new line by that parameter.  The indentation is as follows:
 
   -ip=0 one continuation level [default]
   -ip=1 outdent by one continuation level
index 56a91fd6eb813975c8b943d60489fd6514263d60..c3652f3bfb4effc27847c074a66f9cac00797a91 100644 (file)
 
 <dl>
 
+<dt id="fix-incorrect-parsing-of-certain-deprecated-empty-here-docs"><b>fix incorrect parsing of certain deprecated empty here-docs </b></dt>
+<dd>
+
+<p>The following snippet was being incorrecly parsed:</p>
+
+<pre><code> print &lt;&lt;
+ # Hello World 13!
+   ;
+ print &quot;DONE\n&quot;;</code></pre>
+
+<p>This is a deprecated here-doc without a specified target but currently still a valid program. It would have been correctly parsed if the semicolon followed the &#39;&lt;&lt;&#39; operator rather than the here-doc.</p>
+
+<p>This was found in random testing and fixed 16 Sep 2020. A warning message about deprecated here-doc targets was added.</p>
+
+</dd>
 <dt id="make-the-arrow-a-vertical-alignment-token-git-39"><b>make the arrow a vertical alignment token, git #39</b></dt>
 <dd>
 
index d6d37d334bf542c0bf4fe00f0f06e9304c2aa421..04ab4789120d69c57210cc4b1d7092a4efc8f487 100644 (file)
@@ -7,7 +7,8 @@
 
 - Added parameters -bbhb=n (--break-before-hash-brace=n), -bbsb=n (--break-before-square-bracket=n),
   and -bbp=n (--break-before-paren=n) suggested in git #38.  These provide control over the
-  opening container token of a multiple-line list.
+  opening container token of a multiple-line list.  Related new parameters -ihb=n, -isb=n, -ip=n
+  control indentation of these tokens.
 
 - Numerous issues have been found during automated testing and fixed. Many involve references to
   uninitialized variables when perltidy is given random text. A complete list is given in
index 806eba17746bfe5a91f671605e0f1c57a00c5c95..63e003696b71acf0b6093861703e6f605670ffc5 100644 (file)
 
 <pre><code>  -bbhb=0 never break [default]
   -bbhb=1 stable: break if the input script had a break
-  -bbhb=2 break if list is &#39;complex&#39;, meaning it contains other broken lists
+  -bbhb=2 break if list is &#39;complex&#39; (see note below)
   -bbhb=3 always break</code></pre>
 
 <p>For example,</p>
         four  =&gt; &#39;IV&#39;,
       };</code></pre>
 
-<p>There are a couple of points to note about this flag:</p>
+<p>There are several points to note about this flag:</p>
 
 <ul>
 
+<li><p>This parameter only applies to opening hash braces which are preceded by an &#39;=&#39; or &#39;=&gt;&#39;.</p>
+
+</li>
 <li><p>This parameter only applies if the contents of the container looks like a list. The contents need to contain some commas or &#39;=&gt;&#39;s at the next interior level to be considered a list.</p>
 
 </li>
-<li><p>This parameter only applies if there is a blank space before the opening brace in the default formatting.</p>
+<li><p>For the <b>n=2</b> option, a list is considered &#39;complex&#39; if it is part of a nested list structure which spans multiple lines in the input file.</p>
 
 </li>
 <li><p>If multiple opening tokens have been &#39;welded&#39; together with the <b>-wn</b> parameter, then this parameter has no effect.</p>
 <dt id="ihb-n---indent-hash-brace-n"><b>-ihb=n</b>, <b>--indent-hash-brace=n</b></dt>
 <dd>
 
-<p>This flag is a companion to <b>-bbhb</b> for controlling the indentation of an opening hash brace. The indentation is as follows:</p>
+<p>This flag is a companion to <b>-bbhb=n</b> for controlling the indentation of an opening hash brace which is placed on a new line by that parameter. The indentation is as follows:</p>
 
 <pre><code>  -ihb=0 one continuation level [default]
   -ihb=1 outdent by one continuation level
 
 <pre><code>  -bbsb=0 never break [default]
   -bbsb=1 stable: break if the input script had a break
-  -bbsb=2 break if list is &#39;complex&#39;, meaning it contains other broken lists
+  -bbsb=2 break if list is &#39;complex&#39; (part of nested list structure)
   -bbsb=3 always break</code></pre>
 
 </dd>
 <dt id="isb-n---indent-square-bracket-n"><b>-isb=n</b>, <b>--indent-square-bracket=n</b></dt>
 <dd>
 
-<p>This flag is a companion to <b>-bbsb</b> for controlling the indentation of an opening square bracket. The indentation is as follows:</p>
+<p>This flag is a companion to <b>-bbsb=n</b> for controlling the indentation of an opening square bracket which is placed on a new line by that parameter. The indentation is as follows:</p>
 
 <pre><code>  -isb=0 one continuation level [default]
   -isb=1 outdent by one continuation level
 
 <pre><code>  -bbp=0 never break [default]
   -bbp=1 stable: break if the input script had a break
-  -bbp=2 break if list is &#39;complex&#39;, meaning it contains other broken lists
+  -bpb=2 break if list is &#39;complex&#39; (part of nested list structure)
   -bbp=3 always break</code></pre>
 
 </dd>
 <dt id="ip-n---indent-paren-n"><b>-ip=n</b>, <b>--indent-paren=n</b></dt>
 <dd>
 
-<p>This flag is a companion to <b>-bbp</b> for controlling the indentation of an opening paren. The indentation is as follows:</p>
+<p>This flag is a companion to <b>-bbp=n</b> for controlling the indentation of an opening paren which is placed on a new line by that parameter. The indentation is as follows:</p>
 
 <pre><code>  -ip=0 one continuation level [default]
   -ip=1 outdent by one continuation level
index 12f3ad14da9b487fcd47910bc9c1f3631a6eae8b..f7789610c70a6ad51d1004cbeaca6b046fe59c9f 100644 (file)
@@ -73,6 +73,7 @@ my (
     %is_closing_type,
     %is_opening_token,
     %is_closing_token,
+    %is_equal_or_fat_comma,
 
     # Initialized in check_options. These are constants and could
     # just as well be initialized in a BEGIN block.
@@ -106,7 +107,7 @@ my (
     %want_break_before,
 
     %break_before_container_types,
-    %container_indentation_options, 
+    %container_indentation_options,
 
     %space_after_keyword,
 
@@ -402,6 +403,9 @@ BEGIN {
     @q = qw< } ) ] >;
     @is_closing_token{@q} = (1) x scalar(@q);
 
+    @q = qw( = => );
+    @is_equal_or_fat_comma{@q} = (1) x scalar(@q);
+
 }
 
 {    ## begin closure to count instanes
@@ -4592,7 +4596,7 @@ sub adjust_indentation_levels {
     # Adjust indentation for list containers
     $self->adjust_container_indentation();
 
-    # Set adjusted levels for the whitespace cycle option.  
+    # Set adjusted levels for the whitespace cycle option.
     $self->whitespace_cycle_adjustment();
 
     # Adjust continuation indentation if -bli is set
@@ -4798,26 +4802,45 @@ sub adjust_container_indentation {
     }
 
     # Loop over all opening container tokens
-    my $K_opening_container = $self->[_K_opening_container_];
+    my $K_opening_container  = $self->[_K_opening_container_];
+    my $ris_broken_container = $self->[_ris_broken_container_];
     foreach my $seqno ( keys %{$K_opening_container} ) {
-        my $KK          = $K_opening_container->{$seqno};
-        my $rtoken_vars = $rLL->[$KK];
-        my $block_type  = $rtoken_vars->[_BLOCK_TYPE_];
+        my $KK = $K_opening_container->{$seqno};
 
         # this routine is not for code block braces
+        my $block_type = $rLL->[$KK]->[_BLOCK_TYPE_];
         next if ($block_type);
 
-        my $token = $rtoken_vars->[_TOKEN_];
-        my $flag  = $container_indentation_options{$token};
+        # These flags only apply if the corresponding -bb* flags
+        # have been set to non-default values
+        my $rtoken_vars = $rLL->[$KK];
+        my $token       = $rtoken_vars->[_TOKEN_];
+        my $flag        = $container_indentation_options{$token};
         next unless ($flag);
 
+        # Require previous nonblank to be certain types (= and =>)
+        # Note similar coding in sub insert_breaks_before...
+        my $Kprev = $KK - 1;
+        next if ( $Kprev < 0 );
+        my $prev_type = $rLL->[$Kprev]->[_TYPE_];
+        if ( $prev_type eq 'b' ) {
+            $Kprev--;
+            next if ( $Kprev < 0 );
+            $prev_type = $rLL->[$Kprev]->[_TYPE_];
+        }
+        next unless ( $is_equal_or_fat_comma{$prev_type} );
+
         # This is only for list containers
         next unless $self->is_list($seqno);
 
+        # and only for broken lists
+        next unless $ris_broken_container->{$seqno};
+
         # NOTE: We are adjusting indentation of the opening container. The
         # closing container will normally follow the indentation of the opening
         # container automatically, so this is not currently done.
         my $ci = $rLL->[$KK]->[_CI_LEVEL_];
+        next unless ($ci);
 
         # option 1: outdent
         if ( $flag == 1 ) {
@@ -6263,24 +6286,23 @@ EOM
     %container_indentation_options = ();
     for ( $rOpts->{'indent-hash-brace'} ) {
         my $tok = '{';
-        if ( defined($_) && $_>0 && $break_before_container_types{$tok} ) {
-            $container_indentation_options{$tok} = $_; 
+        if ( defined($_) && $_ > 0 && $break_before_container_types{$tok} ) {
+            $container_indentation_options{$tok} = $_;
         }
     }
     for ( $rOpts->{'indent-square-bracket'} ) {
         my $tok = '[';
-        if ( defined($_) && $_>0 && $break_before_container_types{$tok} ) {
-            $container_indentation_options{$tok} = $_; 
+        if ( defined($_) && $_ > 0 && $break_before_container_types{$tok} ) {
+            $container_indentation_options{$tok} = $_;
         }
     }
     for ( $rOpts->{'indent-paren'} ) {
         my $tok = '(';
-        if ( defined($_) && $_>0 && $break_before_container_types{$tok} ) {
-            $container_indentation_options{$tok} = $_; 
+        if ( defined($_) && $_ > 0 && $break_before_container_types{$tok} ) {
+            $container_indentation_options{$tok} = $_;
         }
     }
 
-
     # Define here tokens which may follow the closing brace of a do statement
     # on the same line, as in:
     #   } while ( $something);
@@ -17931,16 +17953,28 @@ sub break_equals {
 
 sub is_list {
 
-    # Try to decide if the immediate contents of a container is a list.
+    # Return true if the immediate contents of a container appears to be a
+    # list.
 
     my ( $self, $seqno ) = @_;
-    my $rLL                  = $self->[_rLL_];
-    my $rtype_count_by_seqno = $self->[_rtype_count_by_seqno_];
+    return unless defined($seqno);
+
+    my $K_opening_container = $self->[_K_opening_container_];
+    my $K_opening           = $K_opening_container->{$seqno};
+    return unless ( defined($K_opening) );
+
+    my $rLL        = $self->[_rLL_];
+    my $block_type = $rLL->[$K_opening]->[_BLOCK_TYPE_];
+    return if ($block_type);
+
+    my $token = $rLL->[$K_opening]->[_TOKEN_];
+    return if ( $token eq ':' );
 
     # We will require at least 2 commas or 1 fat comma in the
     # immediate lower level.
-    my $fat_comma_count = $rtype_count_by_seqno->{$seqno}->{'=>'};
-    my $comma_count     = $rtype_count_by_seqno->{$seqno}->{','};
+    my $rtype_count_by_seqno = $self->[_rtype_count_by_seqno_];
+    my $fat_comma_count      = $rtype_count_by_seqno->{$seqno}->{'=>'};
+    my $comma_count          = $rtype_count_by_seqno->{$seqno}->{','};
     my $is_list = ( $fat_comma_count || $comma_count && $comma_count > 1 );
     return $is_list;
 }
@@ -17957,6 +17991,7 @@ sub insert_breaks_before_list_opening_containers {
     my $rLL                   = $self->[_rLL_];
     my $ris_broken_container  = $self->[_ris_broken_container_];
     my $rhas_broken_container = $self->[_rhas_broken_container_];
+    my $rparent_of_seqno      = $self->[_rparent_of_seqno_];
 
     # scan the ends of all lines
     my @insert_list;
@@ -17970,7 +18005,7 @@ sub insert_breaks_before_list_opening_containers {
         my $iend     = $ir;
         my $type_end = $rLL->[$Kr]->[_TYPE_];
 
-        # backup before a side comment
+        # Backup before any side comment
         if ( $type_end eq '#' ) {
             $Kend = $self->K_previous_nonblank($Kr);
             next unless defined($Kend);
@@ -17978,46 +18013,36 @@ sub insert_breaks_before_list_opening_containers {
             $iend     = $ir + ( $Kend - $Kr );
         }
 
-        # This is only for line-ending tokens with a preceding blank
-        # on the same line.
         next unless ( $Kl < $Kend - 1 );
 
-        # And only for some kind of container token
         my $seqno = $rLL->[$Kend]->[_TYPE_SEQUENCE_];
         next unless ( defined($seqno) );
 
-        # And only for selected types of container tokens
+       # Only for types of container tokens with a non-default break option
         my $token_end    = $rLL->[$Kend]->[_TOKEN_];
         my $break_option = $break_before_container_types{$token_end};
         next unless ($break_option);
 
-        # This is not for code block braces
-        my $block_type = $rLL->[$Kend]->[_BLOCK_TYPE_];
-        next if ($block_type);
-
-        # Require a space before the line ending token
-        next unless ( $rLL->[ $Kend - 1 ]->[_TYPE_] eq 'b' );
+        # Require previous nonblank to be certain types (= and =>)
+        # Note similar coding in sub adjust_container_indentation
+        my $Kprev     = $Kend - 1;
+        my $prev_type = $rLL->[$Kprev]->[_TYPE_];
+        if ( $prev_type eq 'b' ) {
+            $Kprev--;
+            next if ( $Kprev <= $Kl );
+            $prev_type = $rLL->[$Kprev]->[_TYPE_];
+        }
+        next unless ( $is_equal_or_fat_comma{$prev_type} );
 
+        # This must be a list (this will exclude all code blocks)
         next unless $self->is_list($seqno);
 
-        # Do not break a weld
+        # Never break a weld
         next if ( $self->weld_len_left( $seqno, $token_end ) );
 
-        # Parens cannot break after certain keywords
-        if ( $token_end eq '(' ) {
-            my $iend_m2 = $iend - 2;
-            if ( $iend_m2 >= $il ) {
-                if ( $types_to_go[$iend_m2] eq 'k'
-                    && $is_if_elsif_else_unless_while_until_for_foreach{
-                        $tokens_to_go[$iend_m2] } )
-                {
-                    next;
-                }
-            }
-        }
+        # Final decision is based on selected option:
 
-        # Final decision is based on selected option
-        # 1 = stable
+        # Option 1 = stable, try to follow input
         my $ok_to_break;
         if ( $break_option == 1 ) {
             if ( $ir - 2 > $il ) {
@@ -18025,32 +18050,36 @@ sub insert_breaks_before_list_opening_containers {
             }
         }
 
-        # 2 = only if complex list
+        # Option 2 = only if complex list, meaning:
+        #  - this list contains a broken container, or
+        #  - this list is contained in a broken list
         elsif ( $break_option == 2 ) {
             $ok_to_break = $rhas_broken_container->{$seqno};
+            if ( !$ok_to_break ) {
+                my $parent = $rparent_of_seqno->{$seqno};
+                $ok_to_break = $self->is_list($parent);
+            }
         }
 
-        # 3 = always break
+        # Option 3 = always break
         elsif ( $break_option == 3 ) {
             $ok_to_break = 1;
         }
 
-        # Shouldn't happen! Bad flag, make same as 3
+        # Shouldn't happen! Bad flag, but make behavior same as 3
         else {
             $ok_to_break = 1;
         }
 
         next unless ($ok_to_break);
 
-        # This meets the criteria, so install a break
+        # This meets the criteria, so install a break before the opening token.
         my $Kbreak = $self->K_previous_nonblank($Kend);
         my $ibreak = $Kbreak - $Kl + $il;
         next if ( $ibreak < $il );
         next if ( $nobreak_to_go[$ibreak] );
         push @insert_list, $ibreak;
 
-        # FIXME: at this point we could inform any child containers that they
-        # are part of a complex container.
     }
 
     # insert any new break points
index 670c04d3f53b7b8268a31c80a015a27a9208961d..a39f536ae5991229f787b2877bb0440f0a3add18 100644 (file)
@@ -1,8 +1,9 @@
 my %temp =
   (
     supsup => 123,
-    nested => {
+    nested =>
+      {
         asdf => 456,
         yarg => 'yarp',
-    },
+      },
   );
index 93e1f572c48f53b637feb4139f8fb779e6527258..4b5dd44c356f320a9858cf527ccdbb799f54df67 100644 (file)
 ../snippets22.t        bbhb.bbhb2
 ../snippets22.t        bbhb.bbhb3
 ../snippets22.t        bbhb.def
+../snippets22.t        bbhb.bbhb4
+../snippets22.t        bbhb.bbhb5
 ../snippets3.t ce_wn1.ce_wn
 ../snippets3.t ce_wn1.def
 ../snippets3.t colin.colin
 ../snippets9.t rt98902.def
 ../snippets9.t rt98902.rt98902
 ../snippets9.t rt99961.def
-../snippets22.t        bbhb.bbhb4
-../snippets22.t        bbhb.bbhb5
index 4ae6b70274a96375311da8d1fefdf9c02d57749e..104fe8465aa0ccf79e86caccdb8bf180b56b3f38 100644 (file)
@@ -83,10 +83,11 @@ END_OF_SELECT
 my %temp =
   (
     supsup => 123,
-    nested => {
+    nested =>
+      {
         asdf => 456,
         yarg => 'yarp',
-    },
+      },
   );
 #2...........
         },