From: Steve Hancock Date: Tue, 3 Oct 2023 14:30:51 +0000 (-0700) Subject: improve error check for unexpected 'elsif' and 'else' (c272) X-Git-Tag: 20230912.03~10 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=53f3a0113a7b51b3cc8d1429b28a67ab75287a93;p=perltidy.git improve error check for unexpected 'elsif' and 'else' (c272) --- diff --git a/lib/Perl/Tidy/Tokenizer.pm b/lib/Perl/Tidy/Tokenizer.pm index 364a0e9c..94b0a97c 100644 --- a/lib/Perl/Tidy/Tokenizer.pm +++ b/lib/Perl/Tidy/Tokenizer.pm @@ -41,6 +41,9 @@ use constant DEVEL_MODE => 0; use constant EMPTY_STRING => q{}; use constant SPACE => q{ }; +# Parent sequence number of tree of containers; must be 1 +use constant SEQ_ROOT => 1; + # Decimal values of some ascii characters for quick checks use constant ORD_TAB => 9; use constant ORD_SPACE => 32; @@ -1715,7 +1718,7 @@ sub prepare_for_a_new_file { $total_depth = 0; $rtotal_depth = []; $rcurrent_sequence_number = []; - $next_sequence_number = 2; # The value 1 is reserved for SEQ_ROOT + $next_sequence_number = SEQ_ROOT + 1; $rparen_type = []; $rparen_semicolon_count = []; @@ -4289,35 +4292,50 @@ EOM $statement_type = $tok; } - # Check for misplaced 'elsif' and 'else', but allow isolated - # else or elsif blocks to be formatted. This is indicated - # by a last noblank token of ';' + # Check for unexpected 'elsif' elsif ( $tok eq 'elsif' ) { if ( - $last_nonblank_token ne ';' ## !~ /^(if|elsif|unless)$/ - && !$is_if_elsif_unless{$last_nonblank_block_type} + !$is_if_elsif_unless{$last_nonblank_block_type} + + # Allow isolated blocks of any kind during editing + # by checking for a last noblank token of ';' and no + # sequence numbers having been issued (c272). The check + # on sequence number is not perfect but good enough. + && !( + $last_nonblank_token eq ';' + && $next_sequence_number == SEQ_ROOT + 1 + ) + ) { $self->warning( "expecting '$tok' to follow one of 'if|elsif|unless'\n"); } } + + # Check for unexpected 'else' elsif ( $tok eq 'else' ) { # patched for SWITCH/CASE if ( - $last_nonblank_token ne ';' ## !~ /^(if|elsif|unless|case|when)$/ - && !$is_if_elsif_unless_case_when{$last_nonblank_block_type} + !$is_if_elsif_unless_case_when{$last_nonblank_block_type} # patch to avoid an unwanted error message for # the case of a parenless 'case' (RT 105484): # switch ( 1 ) { case x { 2 } else { } } ## !~ /^(if|elsif|unless|case|when)$/ && !$is_if_elsif_unless_case_when{$statement_type} + + # Allow isolated blocks of any kind during editing (c272) + && !( + $last_nonblank_token eq ';' + && $next_sequence_number == SEQ_ROOT + 1 + ) + ) { $self->warning( diff --git a/t/snippets/expect/lop.def b/t/snippets/expect/lop.def index bd1edbd5..7a3fbc47 100644 --- a/t/snippets/expect/lop.def +++ b/t/snippets/expect/lop.def @@ -16,6 +16,10 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: elsif ($statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} diff --git a/t/snippets/expect/lop.lop b/t/snippets/expect/lop.lop index 4c564808..ed978e38 100644 --- a/t/snippets/expect/lop.lop +++ b/t/snippets/expect/lop.lop @@ -16,6 +16,10 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: elsif ( $statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} diff --git a/t/snippets/lop.in b/t/snippets/lop.in index c889168b..2ee4456d 100644 --- a/t/snippets/lop.in +++ b/t/snippets/lop.in @@ -16,6 +16,10 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: -elsif ( $statement_type =~ /^sub\b/ +elsif ($statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} diff --git a/t/snippets/packing_list.txt b/t/snippets/packing_list.txt index de698c3a..12afe1e2 100644 --- a/t/snippets/packing_list.txt +++ b/t/snippets/packing_list.txt @@ -400,6 +400,8 @@ ../snippets28.t ame.ame ../snippets28.t ame.def ../snippets28.t git124.def +../snippets28.t c269.c269 +../snippets28.t c269.def ../snippets3.t ce_wn1.ce_wn ../snippets3.t ce_wn1.def ../snippets3.t colin.colin @@ -540,5 +542,3 @@ ../snippets9.t rt98902.def ../snippets9.t rt98902.rt98902 ../snippets9.t rt99961.def -../snippets28.t c269.c269 -../snippets28.t c269.def diff --git a/t/snippets20.t b/t/snippets20.t index d5a80730..a348b57d 100644 --- a/t/snippets20.t +++ b/t/snippets20.t @@ -179,9 +179,13 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: -elsif ( $statement_type =~ /^sub\b/ +elsif ($statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} ---------- 'outdent' => <<'----------', @@ -663,9 +667,13 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: elsif ($statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} #19........... }, }; diff --git a/t/snippets21.t b/t/snippets21.t index 3ed043e0..82245651 100644 --- a/t/snippets21.t +++ b/t/snippets21.t @@ -126,9 +126,13 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: -elsif ( $statement_type =~ /^sub\b/ +elsif ($statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} ---------- 'nib' => <<'----------', @@ -335,9 +339,13 @@ lc( $self->mime_attr('content-type') || $self->{MIH_DefaultType} || 'text/plain' ); +if (1) { ... } + # Padding can also remove spaces; here the space after the '(' is lost: elsif ( $statement_type =~ /^sub\b/ || $paren_type[$paren_depth] =~ /^sub\b/ ) +{ +} #1........... },