From cf3ed235a275b7a8163f79252f6a880f01d21a2f Mon Sep 17 00:00:00 2001 From: Steve Hancock Date: Wed, 10 Mar 2021 20:05:51 -0800 Subject: [PATCH] Simplify sub weld_nested_containers --- bin/perltidy | 6 +- lib/Perl/Tidy/Formatter.pm | 119 +++++++++++-------------------------- local-docs/BugLog.pod | 16 ++++- 3 files changed, 54 insertions(+), 87 deletions(-) diff --git a/bin/perltidy b/bin/perltidy index 453a61b1..7a240df3 100755 --- a/bin/perltidy +++ b/bin/perltidy @@ -2884,8 +2884,10 @@ is an abbreviation for B<-sot -sct>. Please note that if both opening and closing tokens are to be stacked, then the newer flag B<-weld-nested-containers> may be preferable because it insures that -stacking is always done symmetrically. It does this by working on formatting -globally rather than locally, as the B<-sot> and B<-sct> flags do. +stacking is always done symmetrically. It also removes an extra level of +unnecessary indentation within welded containers. It is able to do this +because it works on formatting globally rather than locally, as the B<-sot> and +B<-sct> flags do. =item B<-dnl>, B<--delete-old-newlines> diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index df29d6d7..a4ddbd9a 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -6804,24 +6804,29 @@ sub weld_nested_containers { # Variables needed for estimating line lengths my $starting_indent; my $starting_lentot; - my $multiline_gap; my $iline_outer_opening = -1; my $weld_count_this_start = 0; - my $max_gap = max( $rOpts_indent_columns, $rOpts_continuation_indentation ); + # Define a tolarance for new welds to avoid turning welding on and off + my $multiline_tol = + 1 + max( $rOpts_indent_columns, $rOpts_continuation_indentation ); my $excess_length_to_K = sub { my ($K) = @_; # Estimate the length from the line start to a given token - my $length = $self->cumulative_length_before_K($K) - $starting_lentot; + my $length = + $self->cumulative_length_before_K($K) - $starting_lentot + 1; + + # Add a tolerance for welds over multiple lines to avoid blinkers + my $iline_K = $rLL->[$K]->[_LINE_INDEX_]; + my $tol = ( $iline_K > $iline_outer_opening ) ? $multiline_tol : 0; + my $excess_length = - $starting_indent + $length + - $multiline_gap - - $rOpts_maximum_line_length; + $starting_indent + $length + $tol - $rOpts_maximum_line_length; DEBUG_WELD && print <[$Kouter_closing]; my $inner_closing = $rLL->[$Kinner_closing]; - my $iline_oo = $outer_opening->[_LINE_INDEX_]; - my $iline_io = $inner_opening->[_LINE_INDEX_]; - my $iline_ic = $inner_closing->[_LINE_INDEX_]; - # RULE: do not weld to a hash brace. The reason is that it has a very # strong bond strength to the next token, so a line break after it # may not work. Previously we allowed welding to something like @{ @@ -6888,7 +6889,7 @@ EOM next; } - # RULE: do not weld to a square bracket without commas + # RULE: do not weld to a square bracket which does not contain commas if ( $inner_opening->[_TYPE_] eq '[' ) { my $rtype_count = $self->[_rtype_count_by_seqno_]->{$inner_seqno}; next unless ($rtype_count); @@ -6916,29 +6917,24 @@ EOM defined($previous_pair) && $outer_seqno == $previous_pair->[0]; $previous_pair = $item; - # Set a flag if we should not weld. It sometimes looks best not to weld - # when the opening and closing tokens are very close. However, there - # is a danger that we will create a "blinker", which oscillates between - # two semi-stable states, if we do not weld. So the rules for - # not welding have to be carefully defined and tested. my $do_not_weld_rule = 0; my $Msg = ""; - my $is_one_line_weld; + my $iline_oo = $outer_opening->[_LINE_INDEX_]; + my $iline_io = $inner_opening->[_LINE_INDEX_]; + my $iline_ic = $inner_closing->[_LINE_INDEX_]; my $iline_oc = $outer_closing->[_LINE_INDEX_]; - - my $is_old_weld = ( $iline_oo == $iline_io && $iline_ic == $iline_oc ); + my $token_oo = $outer_opening->[_TOKEN_]; if (DEBUG_WELD) { - my $len_oo = $rLL->[$Kouter_opening]->[_CUMULATIVE_LENGTH_]; - my $len_io = $rLL->[$Kinner_opening]->[_CUMULATIVE_LENGTH_]; - my $tok_oo = $rLL->[$Kouter_opening]->[_TOKEN_]; - my $tok_io = $rLL->[$Kinner_opening]->[_TOKEN_]; + my $token_io = $rLL->[$Kinner_opening]->[_TOKEN_]; + my $len_oo = $rLL->[$Kouter_opening]->[_CUMULATIVE_LENGTH_]; + my $len_io = $rLL->[$Kinner_opening]->[_CUMULATIVE_LENGTH_]; $Msg .= <[$iline_oo]->{_rK_range}; my ( $Kfirst, $Klast ) = @{$rK_range}; + + # Back up and count length from a token like '=' or '=>' if -lp is + # used; this fixes b520 + if ($rOpts_line_up_parentheses) { + my $Kprev = $self->K_previous_nonblank($Kfirst); + if ( defined($Kprev) + && substr( $rLL->[$Kprev]->[_TYPE_], 0, 1 ) eq '=' ) + { + $Kfirst = $Kprev; + } + } + $starting_lentot = $Kfirst <= 0 ? 0 : $rLL->[ $Kfirst - 1 ]->[_CUMULATIVE_LENGTH_]; @@ -6968,59 +6976,6 @@ EOM $starting_indent = $rOpts_indent_columns * $level + $ci_level * $rOpts_continuation_indentation; - - # If a line starts with any kind of sequence item, it may be - # subject to additional indentation changes. To avoid making - # a bad weld we add a tolerance. See case b186 - my $type_sequence = $rLL->[$Kfirst]->[_TYPE_SEQUENCE_]; - if ($type_sequence) { $starting_indent += $max_gap } - } - - # Patch to avoid blinkers, case b965: add a possible gap to the - # starting indentation to avoid blinking problems when the -i=n is - # large. For example, the following with -i=9 may have a gap of 6 - # between the opening paren and the next token if vertical - # tightness is set. We have to include the gap in our estimate - # because the _CUMULATIVE_LENGTH_ - # values have maximum space lengths of 1. - - # case b965 - # if( $codonTable - # ->is_start_codon - # (substr( $seq,0,3 ))) - - $multiline_gap = 0; - if ( $iline_io > $iline_oo ) { - - # Note that we are measuring to the end of the line ($Klast) - # rather than the container, $Kouter_opening - $multiline_gap = max( - 0, - $max_gap - ( - $rLL->[$Klast]->[_CUMULATIVE_LENGTH_] - - $starting_lentot - ) - ); - - # The -xci flag is not yet processed and could add one ci - # level later. So assume max possible ci (case b982). - if ( !$ci_level - && $rOpts->{'extended-continuation-indentation'} ) - { - $multiline_gap += $rOpts_continuation_indentation; - } - - if (DEBUG_WELD) { - my $len_Klast = $rLL->[$Klast]->[_CUMULATIVE_LENGTH_]; - my $tok_Klast = $rLL->[$Klast]->[_TOKEN_]; - my $tok_Kfirst = $rLL->[$Kfirst]->[_TOKEN_]; - - print <set_text( gettext( # "Unable to create personal directory - check permissions.") ); - my $token_oo = $outer_opening->[_TOKEN_]; if ( $iline_oc == $iline_oo + 1 && $iline_io == $iline_ic && $token_oo eq '(' ) @@ -7108,8 +7062,6 @@ EOM && !$is_one_line_weld && $iline_ic == $iline_io ) { - - my $token_oo = $outer_opening->[_TOKEN_]; $do_not_weld_rule = 2 if ( $token_oo eq '(' ); } @@ -7118,10 +7070,11 @@ EOM # Use a tolerance which depends on if the old tokens were welded # (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); # Use '>=' instead of '=' here to fix cases b995 b998 b1000 - # b1001 b1007 b1008 b1009 b1010 b1011 b1012 b1016 b1017 b1018 + # b1001 b1007 b1008 b1009 b1010 b1011 b1012 b1016 b1017 b1018 if ( $excess >= 0 ) { $do_not_weld_rule = 3 } if (DEBUG_WELD) { $Msg .= @@ -7313,7 +7266,7 @@ EOM } ##################################### - # DEBUG + # OLD DEBUG CODE ##################################### if (0) { my $count = 0; diff --git a/local-docs/BugLog.pod b/local-docs/BugLog.pod index b3a27038..7e00f886 100644 --- a/local-docs/BugLog.pod +++ b/local-docs/BugLog.pod @@ -2,6 +2,18 @@ =over 4 +=item B + +This update consolidates a number of specialized rules for welding into +fewer, simpler rules which accomplish the same effect. + +These cases are fixed with this update: +b186 b520 b872 b937 b996 b997 b1002 b1003 b1004 b1005 b1006 b1013 b1014 + +There are no current open issues with the weld logic. + +10 Mar 2021. + =item B A minor tolerance adjustment was needed to fix some edge welding cases. @@ -9,7 +21,7 @@ A minor tolerance adjustment was needed to fix some edge welding cases. This fixes cases b995 b998 b1000 b1001 b1007 b1008 b1009 b1010 b1011 b1012 b1016 b1017 b1018 -7 Mar 2021. +7 Mar 2021, b9166ca. =item B @@ -33,7 +45,7 @@ and state 2 is The problem was fixed by turning off caching for outdented long lines. This fixes case b999. -7 Mar 2021. +7 Mar 2021, 3da7e41. =item B -- 2.39.5