You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Range formatting appends a stray token outside the range when the range starts with a comment in an arrow-function body #19795
Range formatting appends a stray token outside the requested range when the range starts with a comment inside an arrow-function body. Two shapes, two different outcomes — one produces code that no longer parses, the other produces valid-but-wrong code.
This is the same symptom as #12964 (closed, fixed for 2.8 by #13173). That issue's own repro no longer reproduces on 3.8.4 — I verified it — but the two shapes below do. So this looks like variants the fix did not cover rather than a regression of the same input.
Reproduction
import*asprettierfrom"prettier";// A — arrow passed as a call argumentconstA="beforeEach(() => {\n // c\n a();\n});\n";console.log(awaitprettier.format(A,{parser: "babel",rangeStart: 19,rangeEnd: 32}));// B — arrow assigned to a constconstB="const f = () => {\n // c\n a();\n};\n";console.log(awaitprettier.format(B,{parser: "babel",rangeStart: 18,rangeEnd: 31}));
In both cases the range covers the comment line plus the statement after it.
Actual output
A — the closing }); becomes };);, which is not parseable:
beforeEach(()=>{// ca();};);
Re-formatting that output fails with Unexpected token, expected "," (4:2).
B — the closing }; becomes };; — an extra empty statement:
constf=()=>{// ca();};;
This one does parse, which makes it the quieter of the two: a caller that validates range-format output by re-parsing it will accept the corrupted result.
Expected output
Input unchanged in both cases — the code inside the range is already formatted, and nothing outside the range should be touched.
Notes on the trigger
The comment must be the first line of the range. Moving it later in the range, or shrinking the range to the comment alone, avoids the bug.
A plain function f() { … } declaration is unaffected; only arrow-function bodies reproduce.
Both shapes reproduce with default options and with printWidth: 100, tabWidth: 2, semi: true, singleQuote: false, trailingComma: "all".
Why this bites
We use range formatting in a CI gate that checks whether the lines changed by a PR are formatted. Because the stray token always lands outside the requested range, the gate compared the source against corrupted output and reported correctly formatted code as unformatted — with nothing the author could fix. Worse, the obvious remedy (write the range-format output back to the file) corrupts the source; that happened to us once and was caught by a type check rather than by the formatter.
We have since worked around it by comparing only the lines the author actually changed, so this is not urgent for us — but the "valid but wrong" shape (B) seems worth fixing regardless, since it survives an output-parses-fine sanity check.
Activity