]> git.donarmstrong.com Git - perltidy.git/commitdiff
Fix problem parsing anonymous subs with attribute lists
authorSteve Hancock <perltidy@users.sourceforge.net>
Thu, 15 Apr 2021 18:09:40 +0000 (11:09 -0700)
committerSteve Hancock <perltidy@users.sourceforge.net>
Thu, 15 Apr 2021 18:09:40 +0000 (11:09 -0700)
lib/Perl/Tidy/Tokenizer.pm
local-docs/BugLog.pod

index b1fe0741a5ec5709fb71a09829f8be64d4101e81..ee8cf0f0a6d6a56aefbc6731f26e572af8136ae8 100644 (file)
@@ -7163,6 +7163,8 @@ sub scan_identifier_do {
         my $id_scan_state   = $rinput_hash->{id_scan_state};
         my $max_token_index = $rinput_hash->{max_token_index};
 
+        my $i_entry = $i;
+
         # Determine the CALL TYPE
         # 1=sub
         # 2=(
@@ -7236,9 +7238,9 @@ sub scan_identifier_do {
             $proto = $1;
             $attrs = $2;
 
-       # Append the prototype to the starting token if it is 'sub' or
-       # 'prototype'.  This is not necessary but for compatibility with previous
-       # versions when the -csc flag is used:
+            # Append the prototype to the starting token if it is 'sub' or
+            # 'prototype'.  This is not necessary but for compatibility with
+            # previous versions when the -csc flag is used:
             if ( $proto && ( $match || $call_type == PROTOTYPE_CALL ) ) {
                 $tok .= $proto;
             }
@@ -7251,7 +7253,12 @@ sub scan_identifier_do {
             }
 
             $match ||= 1;
+
+            # Patch part #1 to fixes cases b994 and b1053:
+            # Mark an anonymous sub keyword without prototype as type 'k', i.e.
+            #    'sub : lvalue { ...'
             $type = 'i';
+            if ( $tok eq 'sub' && !$proto ) { $type = 'k' }
         }
 
         if ($match) {
@@ -7281,6 +7288,19 @@ sub scan_identifier_do {
                     $max_token_index );
                 if ($error) { warning("Possibly invalid sub\n") }
 
+            # Patch part #2 to fixes cases b994 and b1053:
+            # Do not let spaces be part of the token of an anonymous sub keyword
+            # which we marked as type 'k' above...i.e. for something like:
+            #    'sub : lvalue { ...'
+            # Back up and let it be parsed as a blank
+                if (   $type eq 'k'
+                    && $attrs
+                    && $i > $i_entry
+                    && substr( $rtokens->[$i], 0, 1 ) eq ' ' )
+                {
+                    $i--;
+                }
+
                 # check for multiple definitions of a sub
                 ( $next_nonblank_token, my $i_next ) =
                   find_next_nonblank_token_on_this_line( $i, $rtokens,
@@ -7327,8 +7347,11 @@ sub scan_identifier_do {
             # of the sub so the next opening brace can be labeled.
             # Setting 'statement_type' causes any ':'s to introduce
             # attributes.
-            elsif ( $next_nonblank_token eq ':' ) {
-                $statement_type = $tok if ( $call_type == SUB_CALL );
+            elsif ( $next_nonblank_token eq ':') { 
+                if ( $call_type == SUB_CALL ) {
+                    $statement_type =
+                      substr( $tok, 0, 3 ) eq 'sub' ? $tok : 'sub';
+                }
             }
 
             # if we stopped before an open paren ...
@@ -7343,9 +7366,12 @@ sub scan_identifier_do {
                 if ( !$saw_opening_paren ) {
                     $id_scan_state = 'sub';    # we must come back to get proto
                 }
-                $statement_type = $tok if ( $call_type == SUB_CALL );
+                if ( $call_type == SUB_CALL ) {
+                    $statement_type =
+                      substr( $tok, 0, 3 ) eq 'sub' ? $tok : 'sub';
+                }
             }
-            elsif ($next_nonblank_token) {     # EOF technically ok
+            elsif ($next_nonblank_token) {    # EOF technically ok
                 $subname = "" unless defined($subname);
                 warning(
 "expecting ':' or ';' or '{' after definition or declaration of sub '$subname' but saw '$next_nonblank_token'\n"
index 846cac82785753e823c9c0e394c8ea474e0f82b3..6b28c1307560da5620768f7e3a4ced647f0ccff7 100644 (file)
@@ -3,6 +3,30 @@
 
 =over 4
 
+=item B<Fix problem parsing anonymous subs with attribute lists>
+
+Random testing produced case b994 with unstable formatting:
+
+    do
+    sub :
+    lvalue
+    {
+    return;
+    }
+
+when run with parameters:
+
+    --continuation-indentation=0
+    --ignore-old-breakpoints
+    --maximum-line-length=7
+    --opening-anonymous-sub-brace-on-new-line
+
+The line 'sub :' was being correctly parsed but the following opening block
+brace was not correctly marked as an anonymous sub brace.  This fixes cases
+b994 and b1053.
+
+15 Apr 2021.
+
 =item B<Correct brace types mismarked by tokenizer>
 
 Testing with random parameters produced a case in which a brace following an