From 2727c49196790cbfc59b926bc594cfa506ff5454 Mon Sep 17 00:00:00 2001 From: Steve Hancock Date: Wed, 2 Oct 2024 07:03:46 -0700 Subject: [PATCH] reduce max known iterations to converge (b878) This involved the unusual combination of using -boc on a list with line breaks both before and after commas. This was a simple fix. The max known number of iterations to converge is now 3 instead of 5. --- lib/Perl/Tidy.pm | 2 +- lib/Perl/Tidy/Formatter.pm | 74 +++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/lib/Perl/Tidy.pm b/lib/Perl/Tidy.pm index 30c83552..e2133172 100644 --- a/lib/Perl/Tidy.pm +++ b/lib/Perl/Tidy.pm @@ -2704,7 +2704,7 @@ EOM } ## end sub process_filter_layer # For safety, set an upper bound on number of iterations before stopping. -# The average number of iterations is 2. No known cases exceed 5. +# The average number of iterations is 2. No known cases exceed 3. use constant ITERATION_LIMIT => 6; sub process_iteration_layer { diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index e92f0fbc..b3c9e57a 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -33224,28 +33224,70 @@ sub copy_old_breakpoints { # We are formatting a list and have decided to make comma breaks # the same as in the input file. + + # If the comma style is under certain controls, and if this is a + # comma breakpoint with the comma is at the beginning of the next + # line, then we must pass that index instead. This will allow sub + # set_forced_breakpoints to check and follow the user settings. This + # produces a uniform style and can prevent instability (b1422). + # + # The flag '$controlled_comma_style' will be set if the user + # entered any of -wbb=',' -wba=',' -kbb=',' -kba=','. It is not + # set for the -boc flag, but we will need to treat -boc in the + # same way for lists with breaks both before and after commas to + # avoid excess iterations. + + my @i_old_breaks; for my $i ( $i_first_comma .. $i_last_comma ) { if ( $old_breakpoint_to_go[$i] ) { + push @i_old_breaks, $i; + } + } - # If the comma style is under certain controls, and if this is a - # comma breakpoint with the comma is at the beginning of the next - # line, then we must pass that index instead. This will allow sub - # set_forced_breakpoints to check and follow the user settings. This - # produces a uniform style and can prevent instability (b1422). - # - # The flag '$controlled_comma_style' will be set if the user - # entered any of -wbb=',' -wba=',' -kbb=',' -kba=','. It is not - # needed or set for the -boc flag. - my $ibreak = $i; - if ( $types_to_go[$ibreak] ne ',' && $controlled_comma_style ) { - my $index = $inext_to_go[$ibreak]; - if ( $index > $ibreak && $types_to_go[$index] eq ',' ) { - $ibreak = $index; - } + # just copy old breakpoints unless $controlled_comma_style or -boc + if ( !$controlled_comma_style + && !$rOpts_break_at_old_comma_breakpoints ) + { + foreach my $ii (@i_old_breaks) { + $self->set_forced_breakpoint($ii); + } + return; + } + + # Scan for commas before and after the old breakpoints... + my @i_breaks; + my $num_after; + my $num_before; + foreach my $i (@i_old_breaks) { + my $i_break = $i; + if ( $types_to_go[$i_break] ne ',' ) { + my $index = $inext_to_go[$i_break]; + if ( $index > $i_break && $types_to_go[$index] eq ',' ) { + $i_break = $index; + $num_before++; } - $self->set_forced_breakpoint($ibreak); + } + else { $num_after++; } + push @i_breaks, $i_break; + } + + # -boc by itself can use old breaks except when there are mixed + # leading and trailing commas. In that case excess iterations + # can occur (see b878) + if ( !$controlled_comma_style + && $rOpts_break_at_old_comma_breakpoints ) + { + + my $mixed = $num_before && $num_after; + if ( !$mixed ) { + @i_breaks = @i_old_breaks; } } + + foreach my $ii (@i_breaks) { + $self->set_forced_breakpoint($ii); + } + return; } ## end sub copy_old_breakpoints -- 2.39.5