Summary
The suppression scanners use one case mode per command frame. A nested case command replaces the outer case state; its terminator clears that state, so a later outer case-pattern closer is mistaken for the enclosing command-substitution closer. A genuine adjacent comment is missed.
Review evidence: #1650 (comment).
Reproduction steps
Run this shell source in zsh, then feed its full contents and a changed-line patch for line2 through tracker scanPatch. The review also identifies the corresponding transitions in the local and trusted workflow AWK scanners; verify parity during the fix.
v=$(case y in x) case z in z) :;; esac;;
y)#nolint
printf hi;; esac)
printf %s "$v"
Expected behavior
The shell prints hi. Line2 is a real comment and requires metadata plus a tracking record from each scanner.
Actual behavior
The tracker returns0records after the marker is given valid metadata. The inner case overwrites the scalar mode; the inner esac clears it instead of restoring the outer case. This is separate from ordinary-word esac handling being corrected in PR1650.
Logs and output
zsh parse exit: 0
zsh execution exit: 0
zsh stdout: hi
tracker expected records: 1
tracker actual records: 0
Proposed scope and acceptance criteria
Targetv1.9.0, medium coordinated grammar work. Recursive case syntax needs a per-command-frame stack and an AWK serialization design; one saved outer mode does not support recursion. PR1650's bounded operator/expansion correction does not add this grammar.
Version / commit
Reviewed3650a227b39e13eb76f3fd3051d2e7829fb077c7; reproduced5971cbacb5818e9163c355e81175b14bf2149721.
Environment
macOS with bundled Bash/sh and zsh, Node.js. The exact snippets below parse and print hi in zsh; bundled older Bash/sh reject these unparenthesized case-in-substitution forms. Do not generalize this evidence to all shell versions. Tracker scanPatch uses a read-only mocked full-file API with a changed-line patch; no external issue writes occur in the reproduction.
Summary
The suppression scanners use one case mode per command frame. A nested case command replaces the outer case state; its terminator clears that state, so a later outer case-pattern closer is mistaken for the enclosing command-substitution closer. A genuine adjacent comment is missed.
Review evidence: #1650 (comment).
Reproduction steps
Run this shell source in zsh, then feed its full contents and a changed-line patch for line2 through tracker scanPatch. The review also identifies the corresponding transitions in the local and trusted workflow AWK scanners; verify parity during the fix.
Expected behavior
The shell prints
hi. Line2 is a real comment and requires metadata plus a tracking record from each scanner.Actual behavior
The tracker returns0records after the marker is given valid metadata. The inner case overwrites the scalar mode; the inner esac clears it instead of restoring the outer case. This is separate from ordinary-word esac handling being corrected in PR1650.
Logs and output
Proposed scope and acceptance criteria
Targetv1.9.0, medium coordinated grammar work. Recursive case syntax needs a per-command-frame stack and an AWK serialization design; one saved outer mode does not support recursion. PR1650's bounded operator/expansion correction does not add this grammar.
Version / commit
Reviewed3650a227b39e13eb76f3fd3051d2e7829fb077c7; reproduced5971cbacb5818e9163c355e81175b14bf2149721.
Environment
macOS with bundled Bash/sh and zsh, Node.js. The exact snippets below parse and print
hiin zsh; bundled older Bash/sh reject these unparenthesized case-in-substitution forms. Do not generalize this evidence to all shell versions. Tracker scanPatch uses a read-only mocked full-file API with a changed-line patch; no external issue writes occur in the reproduction.