From d5fb3d5d97441b290946a92861aeeb3adb6427ca Mon Sep 17 00:00:00 2001 From: Steve Hancock Date: Wed, 30 Jun 2021 06:17:48 -0700 Subject: [PATCH] Fix token type of colon introducing anonomyous sub attribute list --- lib/Perl/Tidy/Tokenizer.pm | 20 +++++++++++++++++++- local-docs/BugLog.pod | 31 ++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/Perl/Tidy/Tokenizer.pm b/lib/Perl/Tidy/Tokenizer.pm index 69a578d2..af59785f 100644 --- a/lib/Perl/Tidy/Tokenizer.pm +++ b/lib/Perl/Tidy/Tokenizer.pm @@ -3706,6 +3706,23 @@ EOM $tok_kw .= '::'; } + # Decide if 'sub :' can be the start of a sub attribute list. + # We will decide based on if the colon is followed by a + # bareword which is not a keyword. + my $sub_attribute_ok_here; + if ( $is_sub{$tok_kw} + && $expecting != OPERATOR + && $next_nonblank_token eq ':' ) + { + my ( $nn_nonblank_token, $i_nn ) = + find_next_nonblank_token( $i_next + 1, + $rtokens, $max_token_index ); + $sub_attribute_ok_here = + $nn_nonblank_token =~ /^\w/ + && $nn_nonblank_token !~ /^\d/ + && !$is_keyword{$nn_nonblank_token}; + } + # handle operator x (now we know it isn't $x=) if ( $expecting == OPERATOR && substr( $tok, 0, 1 ) eq 'x' @@ -3867,7 +3884,8 @@ EOM elsif ( ( $next_nonblank_token eq ':' ) && ( $rtokens->[ $i_next + 1 ] ne ':' ) - && ( $i_next <= $max_token_index ) # colon on same line + && ( $i_next <= $max_token_index ) # colon on same line + && !$sub_attribute_ok_here # like 'sub : lvalue' ? && label_ok() ) { diff --git a/local-docs/BugLog.pod b/local-docs/BugLog.pod index 8f1fc67b..35a916e0 100644 --- a/local-docs/BugLog.pod +++ b/local-docs/BugLog.pod @@ -2,6 +2,35 @@ =over 4 +=item B + +In the following example + + print "not " unless ref +( + map { + sub : lvalue { "a" } + } 1 + )[0] eq "CODE"; + +the colon after 'sub' was being marked as part of a label rather than the start +of an attribute list. This does not cause an error, but the space before the +':' is lost. This is fixed in this update. + +Note that something like 'sub :' can also be a label, so the tokenizer has to +look ahead to decide what to do. For example, this 'sub :' is a label: + + my $xx = 0; + sub : { + $xx++; + print "looping with label sub:, a=$xx\n"; + if ( $xx < 10 ) { goto "sub" } + } + +In this case, the goto statement needs quotes around "sub" because it is a +keyword. + +29 Jun 2021. + =item B Testing with random input parameters produced several new cases of formatting @@ -11,7 +40,7 @@ stable with the update. 28 Jun 2021. -=item B +=item B This update undoes the update c16c5ee of 20 Feb 2021, in which the value of -ci=n was limited to the value of -i=n when -xci was set. Recent -- 2.39.5