From 737ea7a32d336a0bf6b49fe542c87f4d2146a511 Mon Sep 17 00:00:00 2001 From: Steve Hancock Date: Wed, 13 Jan 2021 20:30:02 -0800 Subject: [PATCH] Fix error in guessing if divide or pattern --- lib/Perl/Tidy/Formatter.pm | 22 +++++++++++++-- local-docs/BugLog.pod | 56 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index 256ccd84..a5339bfd 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -6687,6 +6687,11 @@ sub weld_nested_containers { # 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; + + my $is_one_line_weld; + + my $iline_oc = $outer_closing->[_LINE_INDEX_]; + if ( !$touch_previous_pair ) { # If this pair is not adjacent to the previous pair (skipped or @@ -6704,6 +6709,20 @@ sub weld_nested_containers { $ci_level * $rOpts_continuation_indentation; } + # An existing one-line weld is a line in which + # (1) the containers are all on one line, and + # (2) the line does not exceed the allowable length, and + # (3) there are no good line breaks (comma or semicolon). + # This flag is used to avoid creating blinkers. + if ( $iline_oo == $iline_oc && $excess_length_to_K->($Klast) <= 0 ) + { + my $rtype_count = + $self->[_rtype_count_by_seqno_]->{$inner_seqno}; + $is_one_line_weld = 1 + unless ( $rtype_count + && ( $rtype_count->{','} || $rtype_count->{';'} ) ); + } + # DO-NOT-WELD RULE 1: # Do not weld something that looks like the start of a two-line # function call, like this: <> @@ -6727,7 +6746,6 @@ sub weld_nested_containers { # $top_label->set_text( gettext( # "Unable to create personal directory - check permissions.") ); - my $iline_oc = $outer_closing->[_LINE_INDEX_]; my $token_oo = $outer_opening->[_TOKEN_]; if ( $iline_oc == $iline_oo + 1 && $iline_io == $iline_ic @@ -6775,7 +6793,7 @@ sub weld_nested_containers { # $_[0]->(); # } ); - if ( $iline_ic == $iline_io ) { + if ( !$is_one_line_weld && $iline_ic == $iline_io ) { my $token_oo = $outer_opening->[_TOKEN_]; $do_not_weld ||= $token_oo eq '('; diff --git a/local-docs/BugLog.pod b/local-docs/BugLog.pod index 3fa7aca5..adacec39 100644 --- a/local-docs/BugLog.pod +++ b/local-docs/BugLog.pod @@ -2,6 +2,57 @@ =over 4 +=item B + +In random testing with convergence a 'blinker' (oscillating states) was found +for the following script + + sub _prompt { + + print $_[0]; + return ( + readline + (*{$_[1]})!~ + /^q/i) + ; # Return false if user types 'q' + + } + +with the following specific parameters: + + --maximum-line-length=32 + --indent-columns=6 + --continuation-indentation=7 + --weld-nested-containers + --extended-continuation-indentation + --noadd-whitespace + +The other state was + + sub _prompt { + + print $_[0]; + return ( + readline( + *{ + $_ + [ + 1 + ] + } + )!~/^q/i + ) + ; # Return false if user types 'q' + + } + +All of the listed parameters are required to cause this, but the main cause +is the very large continuation indentation and short line length. Welding +was being turned on and off in this case. Normally welding is not done if +all containers are on a single line, but an exception was made to detect +a situation like this and keep the welded string together. Updated 13 Jan 2021. + + =item B A syntax error was produced in random testing when perltidy was fed @@ -22,8 +73,7 @@ The formatted result is now sub _DR () { pi2 / 360 } sub _RD () { 360 / pi2 } -This update was made 13 Jan 2021. - +This update was made 13 Jan 2021, a50ecf8. =item B @@ -49,7 +99,7 @@ run with the following parameters caused an oscillation between two states. An unusual feature which contributed to the problem is the very large ci value. This is fixed in a patch made 12 Jan -2021. +2021, 9a97dba. =back -- 2.39.5