From e9c25f2c2ab8fbed358136a7b2452709d0fec48a Mon Sep 17 00:00:00 2001 From: Steve Hancock Date: Sat, 7 Aug 2021 07:37:00 -0700 Subject: [PATCH] Fix edge case of formatting instability, b1189 --- dev-bin/run_convergence_tests.pl.data | 31 ++++++++++++ lib/Perl/Tidy/Formatter.pm | 13 +++++ local-docs/BugLog.pod | 71 ++++++++++++++++++++++++--- 3 files changed, 109 insertions(+), 6 deletions(-) diff --git a/dev-bin/run_convergence_tests.pl.data b/dev-bin/run_convergence_tests.pl.data index 6009a0b7..2d53b292 100644 --- a/dev-bin/run_convergence_tests.pl.data +++ b/dev-bin/run_convergence_tests.pl.data @@ -7029,6 +7029,37 @@ find( --paren-vertical-tightness=1 --weld-nested-containers +==> b1189.in <== +#S1 +if ($ON_EBCDIC) +{ + delete @Encode::ExtModule{ qw(euc-cn gb2312 gb12345 gbk cp936 iso-ir-165 MacChineseSimp + euc-jp iso-2022-jp 7bit-jis shiftjis MacJapanese cp932 + euc-kr ksc5601 cp949 MacKorean + big5 big5-hkscs cp950 MacChineseTrad + gb18030 big5plus euc-tw) + }; +} + +#S2 +if ($ON_EBCDIC) +{ delete @Encode::ExtModule{ + qw(euc-cn gb2312 gb12345 gbk cp936 iso-ir-165 MacChineseSimp + euc-jp iso-2022-jp 7bit-jis shiftjis MacJapanese cp932 + euc-kr ksc5601 cp949 MacKorean + big5 big5-hkscs cp950 MacChineseTrad + gb18030 big5plus euc-tw) + }; +} + +==> b1189.par <== +--block-brace-vertical-tightness=1 +--continuation-indentation=7 +--nodelete-old-newlines +--maximum-line-length=99 +--notrim-qw +--weld-nested-containers + ==> b120.in <== # Same as bug96 # State 1 diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index 587cf853..47887f95 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -8476,6 +8476,19 @@ sub weld_nested_quotes { my $is_old_weld = ( $iline_oo == $iline_io && $iline_ic == $iline_oc ); + # Fix for case b1189. If quote is marked as type 'Q' then only weld + # if the two closing tokens are on the same input line. Otherwise, + # the closing line will be output earlier in the pipeline than + # other CODE lines and welding will not actually occur. This will + # leave a half-welded structure with potential formatting + # instability. This might be fixed by adding a check for a weld on + # a closing Q token and sending it down the normal channel, but it + # would complicate the code and is potentially risky. + next + if (!$is_old_weld + && $next_type eq 'Q' + && $iline_ic != $iline_oc ); + # If welded, the line must not exceed allowed line length ( my $ok_to_weld, $maximum_text_length, $starting_lentot, my $msg ) = $self->setup_new_weld_measurements( $Kouter_opening, diff --git a/local-docs/BugLog.pod b/local-docs/BugLog.pod index 14066e48..90c55bb3 100644 --- a/local-docs/BugLog.pod +++ b/local-docs/BugLog.pod @@ -2,6 +2,65 @@ =over 4 +=item B. + +Testing with random parameters produced a case of unstable formatting involving +welding with parameter -notrim-qw. The problem was that the -notrim-qw flag +converts a qw quote into a quote with fixed leading whitespace. +The lines of these types of quotes which have no other code are are output early +in the formatting process, since they have a fixed format, so welding does not work. +In particular, the closing tokens cannot be welded if they are on a separate line. +This also holds for all types of non-qw quotes. So welding can only be done +if the first and last lines of a non-qw quote contain other code. A check for +this was added. + +For example, in the following snippet the terminal '}' is alone on a line: + + is eval(q{ + $[ = 3; + BEGIN { my $x = "foo\x{666}"; $x =~ /foo\p{Alnum}/; } + $t[3]; + } + ), "a"; + +# In the previous version this was half-welded: +# OLD: perltidy -wn -sil=0 + + is eval( q{ + $[ = 3; + BEGIN { my $x = "foo\x{666}"; $x =~ /foo\p{Alnum}/; } + $t[3]; + } + ), + "a"; + +The new check avoids welding in this case, giving + + # NEW: perltidy -wn -sil=0 + is eval( + q{ + $[ = 3; + BEGIN { my $x = "foo\x{666}"; $x =~ /foo\p{Alnum}/; } + $t[3]; + } + ), + "a"; + +Welding can still be done if the opening and closing container tokens +have other code. For example, welding can be done for the following snippet: + + is eval(q{ + $[ = 3; + BEGIN { my $x = "foo\x{666}"; $x =~ /foo\p{Alnum}/; } + $t[3]; + }), "a"; + +And welding can still be done on all qw quotes unless the -notrim-qw flag is set. + +This fixes case b1189. + +7 Aug 2021. + =item B. Testing with random parameters produced some cases of instability @@ -10,7 +69,7 @@ involved an interaction between the formatter and vertical aligner. This fixes cases b1187 and b1188. -3 Aug 2021. +3 Aug 2021, 5be949b. =item B. @@ -19,7 +78,7 @@ parameter -lp -pvt=n and a short maximum line length. This fixes case b1186. -2 Aug 2021. +2 Aug 2021, f3dbee1. =item B. @@ -28,7 +87,7 @@ parameters -wn, -vt=2, -lp and a short maximum line length. This fixes case b1185. -1 Aug 2021. +1 Aug 2021, d2ab2b7. =item B. @@ -37,7 +96,7 @@ parameters -wn, -vt=n, -lp. This update fixes the problem. This fixes case b1183. -30 Jul 2021. +30 Jul 2021, 055650b. =item B. @@ -46,7 +105,7 @@ a tripple weld with parameters -wn, -vt=n, -lp. This update fixes the problem. This fixes case b1184. -29 Jul 2021. +29 Jul 2021, 6dd53fb. =item B. @@ -56,7 +115,7 @@ problem. This fixes case b1182. -28 Jul 2021. +28 Jul 2021, 01d6c40. =item B. -- 2.39.5