From: Steve Hancock Date: Wed, 23 Aug 2023 00:27:47 +0000 (-0700) Subject: improve tokenization of --use-feature=class X-Git-Tag: 20230701.03~5 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=0adaebd13e284d73d4ec765ae80c7998c61adb1b;p=perltidy.git improve tokenization of --use-feature=class --- diff --git a/bin/perltidy b/bin/perltidy index 1067f9db..3d3dcb67 100755 --- a/bin/perltidy +++ b/bin/perltidy @@ -4937,11 +4937,30 @@ by listing them in the string B. To remove all of the default operators use =item B<-uf=s>, B<--use-feature=s> This flag tells perltidy to allow the syntax associated a pragma in string -B. Currently only the recognized values for the string are B or -string B. The default is B<--use-feature='class'>. This enables -perltidy to recognized the special words B, B, B, and -B. If this causes a conflict with other uses of these words, the -default can be turned off with B<--use-feature=' '>. +B. The current possible settings are: + +=over 4 + +=item * + +B<--use-feature='class'>. This tells perltidy to recognized the special words +B, B, B, and B as defined for this feature. + +=item * + +B<--use-feature=' '>. This tells perltidy not to treat words B, B, B, B specially. + +=item * + +B<--use-feature> not defined B<[DEFAULT]>. In this case perltidy will try to handle both the newer --use-feature 'class' syntax as well as some older overlapping uses, in particular for the keyword 'method'. + +=back + +Note that this parameter is independent of any B control lines +within a script. Perltidy does not look for or read such control lines. This +is because perltidy must be able to work on small chunks of code sent from an +editor, so it cannot assume that such lines will be within the lines being +formatted. =back diff --git a/lib/Perl/Tidy.pm b/lib/Perl/Tidy.pm index 7ccab2d6..4f51151d 100644 --- a/lib/Perl/Tidy.pm +++ b/lib/Perl/Tidy.pm @@ -3698,7 +3698,6 @@ sub generate_options { noweld-nested-containers recombine nouse-unicode-gcstring - use-feature=class valign-code valign-block-comments valign-side-comments @@ -4520,29 +4519,15 @@ EOM $rOpts->{'default-tabsize'} = 8; } - # Check and clean up any use-feature list - my $saw_use_feature_class; - if ( $rOpts->{'use-feature'} ) { - my $rseen = cleanup_word_list( $rOpts, 'use-feature' ); - $saw_use_feature_class = $rseen->{'class'}; - } - # Check and clean up any sub-alias-list - if ( - defined( $rOpts->{'sub-alias-list'} ) - && length( $rOpts->{'sub-alias-list'} ) - - || $saw_use_feature_class - ) + if ( defined( $rOpts->{'sub-alias-list'} ) + && length( $rOpts->{'sub-alias-list'} ) ) { my @forced_words; # include 'sub' for convenience if this option is used push @forced_words, 'sub'; - # use-feature=class requires method as a sub alias - push @forced_words, 'method' if ($saw_use_feature_class); - cleanup_word_list( $rOpts, 'sub-alias-list', \@forced_words ); } diff --git a/lib/Perl/Tidy/Formatter.pm b/lib/Perl/Tidy/Formatter.pm index 122edf10..f8cc0c8c 100644 --- a/lib/Perl/Tidy/Formatter.pm +++ b/lib/Perl/Tidy/Formatter.pm @@ -5346,27 +5346,46 @@ sub make_sub_matching_pattern { $ASUB_PATTERN = '^sub$'; # match anonymous sub %matches_ASUB = ( 'sub' => 1 ); + # Fix the patterns to include any sub aliases: + # Note that any 'sub-alias-list' has been preprocessed to + # be a trimmed, space-separated list which includes 'sub' + # for example, it might be 'sub method fun' + my @words; + my $sub_alias_list = $rOpts->{'sub-alias-list'}; + if ($sub_alias_list) { + @words = split /\s+/, $sub_alias_list; + } + else { + push @words, 'sub'; + } + + # Also include 'method' if necessary for '--use-feature=class': + # - if user does NOT set 'use-feature', assume 'use-feature=class': + if ( !defined( $rOpts->{'use-feature'} ) ) { + push @words, 'method'; + } + + # - if user sets 'use-feature', then only add 'method' if + # use-feature=class is set. + else { + if ( $rOpts->{'use-feature'} =~ /\bclass\b/ ) { + push @words, 'method'; + } + } + # Note (see also RT #133130): These patterns are used by # sub make_block_pattern, which is used for making most patterns. # So this sub needs to be called before other pattern-making routines. - - if ( $rOpts->{'sub-alias-list'} ) { - - # Note that any 'sub-alias-list' has been preprocessed to - # be a trimmed, space-separated list which includes 'sub' - # for example, it might be 'sub method fun' + if ( @words > 1 ) { # Two ways are provided to match an anonymous sub: # $ASUB_PATTERN - with a regex (old method, slow) # %matches_ASUB - with a hash lookup (new method, faster) - my $sub_alias_list = $rOpts->{'sub-alias-list'}; - my @words = split /\s+/, $sub_alias_list; @matches_ASUB{@words} = (1) x scalar(@words); - - $sub_alias_list =~ s/\s+/\|/g; - $SUB_PATTERN =~ s/sub/\($sub_alias_list\)/; - $ASUB_PATTERN =~ s/sub/\($sub_alias_list\)/; + my $alias_list = join '|', keys %matches_ASUB; + $SUB_PATTERN =~ s/sub/\($alias_list\)/; + $ASUB_PATTERN =~ s/sub/\($alias_list\)/; } return; } ## end sub make_sub_matching_pattern diff --git a/lib/Perl/Tidy/Tokenizer.pm b/lib/Perl/Tidy/Tokenizer.pm index 6ecc5550..6b70a76d 100644 --- a/lib/Perl/Tidy/Tokenizer.pm +++ b/lib/Perl/Tidy/Tokenizer.pm @@ -128,6 +128,7 @@ my ( %is_END_DATA_format_sub, %is_grep_alias, %is_sub, + $guess_if_method, ); # possible values of operator_expected() @@ -348,10 +349,27 @@ sub check_options { } } + # Set global flag to say if we have to guess if bareword 'method' is + # a sub when 'method' is in %is_sub. This will be true unless: + # (1) the user entered 'method' as sub alias, or + # (2) the user set --use-feature=class + # In these two cases we can assume that 'method' is a sub alias. + $guess_if_method = 1; + if ( $is_sub{'method'} ) { $guess_if_method = 0 } + #------------------------------------------------ # Update hash values for any -use-feature options #------------------------------------------------ - my $use_feature_class = $rOpts->{'use-feature'} =~ /\bclass\b/; + + my $use_feature_class = 1; + if ( $rOpts->{'use-feature'} ) { + if ( $rOpts->{'use-feature'} =~ /\bclass\b/ ) { + $guess_if_method = 0; + } + else { + $use_feature_class = 0; + } + } # These are the main updates for this option. There are additional # changes elsewhere, usually indicated with a comment 'rt145706' @@ -375,6 +393,10 @@ sub check_options { # 'method' - treated like sub using the sub-alias-list option # Note: we must not set 'method' to be a keyword to avoid problems # with older uses. + if ($use_feature_class) { + $is_sub{'method'} = 1; + $is_END_DATA_format_sub{'method'} = 1; + } # 'field' - added as a keyword, and works like 'my' $is_keyword{'field'} = $use_feature_class; @@ -4604,7 +4626,7 @@ EOM # Update for --use-feature=class (rt145706): # We have to be extra careful to avoid misparsing other uses of # 'method' in older scripts. - if ( $tok_kw eq 'method' ) { + if ( $tok_kw eq 'method' && $guess_if_method ) { if ( $expecting == OPERATOR || $next_nonblank_token !~ /^(\w|\:)/ || !$self->method_ok_here() )