Skip to content

Print string literals from raw source to preserve escapes - #68

Merged
NullVoxPopuli merged 1 commit into
mainfrom
nvp/print-literal-raw
Jun 30, 2026
Merged

Print string literals from raw source to preserve escapes#68
NullVoxPopuli merged 1 commit into
mainfrom
nvp/print-literal-raw

Conversation

@NullVoxPopuli

Copy link
Copy Markdown
Owner

Summary

The Literal/StringLiteral case printed the cooked node.value wrapped in quotes, destroying escape sequences. Round-tripping any string with an escape produced corrupt/invalid output:

'\nmessage'   ->   '<real newline>message'   // syntax error: newline in a single-quoted string

\t, \uXXXX, and escaped quotes were corrupted the same way. This is what mangled real files like assert('\n…', args.style) when a codemod reprinted them.

Change

Return node.raw / node.extra.raw (the exact original source — escapes and quote style intact) when present. Fall back to JSON.stringify(value) for synthesized nodes that have no raw, so those are still safely quoted and escaped.

Tests

  • print.test.js: escape preservation via raw; synthesized fallback escaping.
  • parse-print-gjs.test.js: round-trip of '\nLine "two"\té'.
  • Full suite: 215 passing. oxlint + oxfmt --check + publint clean.

🤖 Generated with Claude Code

The Literal/StringLiteral case emitted the cooked `node.value` wrapped in
quotes, so escape sequences were destroyed: `'\n'` printed as a real
newline, breaking the (single-quoted) literal, and `\t`, `\uXXXX`, and
escaped quotes were likewise corrupted. Round-tripping any file with an
escaped string (e.g. `assert('\nmessage', ...)`) produced invalid output.

Return `node.raw` (the exact source) when present; fall back to
`JSON.stringify(value)` for synthesized nodes that have no raw, so those
are still quoted and escaped correctly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🏎️ Benchmark Comparison

Benchmark Control (p50) Experiment (p50) Δ
🟡 gts small 277.77 µs 273.85 µs -1.4%
🔴 gts medium 37.04 ms 41.10 ms +11.0%
🟡 gts large 104.17 ms 102.46 ms -1.6%
🟡 gjs small 233.39 µs 235.76 µs +1.0%
🟢 gjs medium 53.23 ms 47.72 ms -10.3%
🟡 gjs large 165.76 ms 169.81 ms +2.4%
🟢 hbs small 82.02 µs 52.56 µs -35.9%
🔴 hbs medium 18.23 ms 21.30 ms +16.8%
hbs large 57.20 ms 57.25 ms +0.1%

🟢 faster · 🔴 slower · 🟡 within 5% · ⚪ within 1%

Full mitata output
clk: ~2.83 GHz
cpu: AMD EPYC 9V74 80-Core Processor
runtime: node 22.23.0 (x64-linux)

benchmark                   avg (min … max) p75 / p99    (min … top 1%)
------------------------------------------- -------------------------------
gts small (control)          452.92 µs/iter 297.57 µs █                    
                      (251.40 µs … 9.45 ms)   4.01 ms █                    
                    ( 36.76 kb …   2.96 mb) 186.98 kb █▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

gts small (experiment)       432.94 µs/iter 294.54 µs █                    
                      (249.45 µs … 8.39 ms)   3.77 ms █                    
                    ( 46.83 kb …   2.33 mb) 188.49 kb █▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

                             ┌                                            ┐
                             ┌─┬                                          ╷
         gts small (control) │ │──────────────────────────────────────────┤
                             └─┴                                          ╵
                             ┌─┬                                       ╷
      gts small (experiment) │ │───────────────────────────────────────┤
                             └─┴                                       ╵
                             └                                            ┘
                             249.45 µs           2.13 ms            4.01 ms

summary
  gts small (experiment)
   1.05x faster than gts small (control)

------------------------------------------- -------------------------------
gts medium (experiment)       43.55 ms/iter  42.60 ms █     █  █           
                      (35.91 ms … 62.87 ms)  50.48 ms █   ▅ █▅ █      ▅   ▅
                    ( 47.68 kb …  13.09 mb)   4.12 mb █▁▁▁█▁██▁█▁▁▁▁▁▁█▁▁▁█

gts medium (control)          41.70 ms/iter  41.60 ms    █                 
                      (34.52 ms … 67.82 ms)  48.58 ms ▅▅▅█▅    ▅▅  ▅      ▅
                    (789.19 kb …  12.40 mb)   3.99 mb █████▁▁▁▁██▁▁█▁▁▁▁▁▁█

                             ┌                                            ┐
                                 ╷        ┌───────────┬                   ╷
     gts medium (experiment)     ├────────┤           │───────────────────┤
                                 ╵        └───────────┴                   ╵
                             ╷    ┌──────────────┬                   ╷
        gts medium (control) ├────┤              │───────────────────┤
                             ╵    └──────────────┴                   ╵
                             └                                            ┘
                             34.52 ms           42.50 ms           50.48 ms

summary
  gts medium (control)
   1.04x faster than gts medium (experiment)

------------------------------------------- -------------------------------
gts large (control)          119.68 ms/iter 111.92 ms  █                   
                     (99.22 ms … 229.97 ms) 148.04 ms  ██ █                
                    (  7.63 mb …  19.99 mb)   8.77 mb ███▁██▁█▁▁▁▁▁▁▁▁▁▁▁▁█

gts large (experiment)       119.88 ms/iter 114.91 ms █                    
                     (99.93 ms … 254.15 ms) 132.09 ms █                    
                    (  8.38 mb …   9.49 mb)   8.86 mb █▇▇▁▇▇▁▁▁▇▁▁▇▁▁▁▁▁▁▁▇

                             ┌                                            ┐
                             ╷ ┌────────────────┬                         ╷
         gts large (control) ├─┤                │─────────────────────────┤
                             ╵ └────────────────┴                         ╵
                              ┌─────────────────┬          ╷
      gts large (experiment)  │                 │──────────┤
                              └─────────────────┴          ╵
                             └                                            ┘
                             99.22 ms          123.63 ms          148.04 ms

summary
  gts large (control)
   1x faster than gts large (experiment)

------------------------------------------- -------------------------------
gjs small (experiment)       398.30 µs/iter 262.54 µs █                    
                      (204.84 µs … 9.45 ms)   4.00 ms █                    
                    ( 68.57 kb …   2.35 mb) 179.34 kb █▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

gjs small (control)          415.42 µs/iter 258.66 µs █                    
                      (205.70 µs … 8.60 ms)   4.49 ms █                    
                    ( 58.17 kb …   2.38 mb) 181.36 kb █▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

                             ┌                                            ┐
                             ┌─┬                                     ╷
      gjs small (experiment) │ │─────────────────────────────────────┤
                             └─┴                                     ╵
                             ┌─┬                                          ╷
         gjs small (control) │ │──────────────────────────────────────────┤
                             └─┴                                          ╵
                             └                                            ┘
                             204.84 µs           2.35 ms            4.49 ms

summary
  gjs small (experiment)
   1.04x faster than gjs small (control)

------------------------------------------- -------------------------------
gjs medium (control)          51.10 ms/iter  53.96 ms                █     
                      (44.17 ms … 57.35 ms)  57.00 ms ▅  ▅▅▅        ▅█    ▅
                    (  3.70 mb …  15.13 mb)   5.33 mb █▁▁███▁▁▁▁▁▁▁▁██▁▁▁▁█

gjs medium (experiment)       60.87 ms/iter  51.44 ms  █                   
                     (43.02 ms … 137.62 ms) 105.45 ms ████                 
                    (  3.70 mb …  13.70 mb)   5.52 mb ████▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁█

                             ┌                                            ┐
                              ╷ ┌──┬─┐ ╷
        gjs medium (control)  ├─┤  │ ├─┤
                              ╵ └──┴─┘ ╵
                             ╷┌───────────┬                               ╷
     gjs medium (experiment) ├┤           │───────────────────────────────┤
                             ╵└───────────┴                               ╵
                             └                                            ┘
                             43.02 ms          74.24 ms           105.45 ms

summary
  gjs medium (control)
   1.19x faster than gjs medium (experiment)

------------------------------------------- -------------------------------
gjs large (experiment)       184.05 ms/iter 176.11 ms  █                   
                    (163.80 ms … 317.76 ms) 193.12 ms ▅█▅▅▅▅ ▅▅▅          ▅
                    (  9.24 mb …  22.17 mb)  10.59 mb ██████▁███▁▁▁▁▁▁▁▁▁▁█

gjs large (control)          181.80 ms/iter 174.75 ms   █                  
                    (162.44 ms … 321.45 ms) 179.22 ms ▅▅█▅▅       ▅▅ ▅▅   ▅
                    (  7.81 mb …  21.13 mb)  10.65 mb █████▁▁▁▁▁▁▁██▁██▁▁▁█

                             ┌                                            ┐
                               ╷  ┌──────────────────────────┬            ╷
      gjs large (experiment)   ├──┤                          │────────────┤
                               ╵  └──────────────────────────┴            ╵
                             ╷  ┌─────────────────────╷──┬
         gjs large (control) ├──┤                     ┤  │
                             ╵  └─────────────────────╵──┴
                             └                                            ┘
                             162.44 ms         177.78 ms          193.12 ms

summary
  gjs large (control)
   1.01x faster than gjs large (experiment)

------------------------------------------- -------------------------------
hbs small (control)           84.62 µs/iter  82.93 µs             █        
                     (77.07 µs … 121.06 µs)  86.45 µs   █         █        
                    ( 21.29 kb …  21.32 kb)  21.30 kb ███▁▁▁▁▁▁█▁██▁▁▁▁█▁▁█

hbs small (experiment)       104.04 µs/iter  54.58 µs █                    
                      (49.91 µs … 10.27 ms)   2.87 ms █                    
                    ( 16.10 kb …   2.87 mb)  98.58 kb █▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

                             ┌                                            ┐
                             ┌┬
         hbs small (control) ││
                             └┴
                             ┌┬                                           ╷
      hbs small (experiment) ││───────────────────────────────────────────┤
                             └┴                                           ╵
                             └                                            ┘
                             49.91 µs            1.46 ms            2.87 ms

summary
  hbs small (control)
   1.23x faster than hbs small (experiment)

------------------------------------------- -------------------------------
hbs medium (experiment)       22.81 ms/iter  25.16 ms ██   █        █      
                      (17.51 ms … 44.75 ms)  29.72 ms ███  ██       █      
                    (  3.12 mb …   4.55 mb)   3.83 mb ███▁▁██▁▁███▁███▁▁▁▁█

hbs medium (control)          23.22 ms/iter  23.36 ms █▄                   
                      (17.46 ms … 64.20 ms)  32.16 ms ██                   
                    (  3.24 mb …   4.75 mb)   3.98 mb ██▅▁▁▅▁██▁▁▅▁▁▁▁▁█▁▁▅

                             ┌                                            ┐
                             ╷ ┌─────────────┬───────┐             ╷
     hbs medium (experiment) ├─┤             │       ├─────────────┤
                             ╵ └─────────────┴───────┘             ╵
                             ╷┌────────────────┬                          ╷
        hbs medium (control) ├┤                │──────────────────────────┤
                             ╵└────────────────┴                          ╵
                             └                                            ┘
                             17.46 ms           24.81 ms           32.16 ms

summary
  hbs medium (experiment)
   1.02x faster than hbs medium (control)

------------------------------------------- -------------------------------
hbs large (control)           71.27 ms/iter  63.03 ms █ █                  
                     (50.10 ms … 151.09 ms) 114.48 ms █ █ █                
                    (891.50 kb …  13.96 mb)   6.54 mb █▁███▁▁▁▁▁▁█▁▁▁▁▁▁▁▁█

hbs large (experiment)        69.58 ms/iter  59.01 ms ▂  █                 
                     (50.94 ms … 181.80 ms)  97.43 ms █▅ █                 
                    (  1.16 mb …  13.45 mb)   6.28 mb ██▁█▁▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇

                             ┌                                            ┐
                             ┌──────────────┬                             ╷
         hbs large (control) │              │─────────────────────────────┤
                             └──────────────┴                             ╵
                              ┌────────────┬                  ╷
      hbs large (experiment)  │            │──────────────────┤
                              └────────────┴                  ╵
                             └                                            ┘
                             50.10 ms          82.29 ms           114.48 ms

summary
  hbs large (experiment)
   1.02x faster than hbs large (control)

@NullVoxPopuli NullVoxPopuli added the bug Something isn't working label Jun 30, 2026
@NullVoxPopuli
NullVoxPopuli merged commit cae5022 into main Jun 30, 2026
4 checks passed
@NullVoxPopuli
NullVoxPopuli deleted the nvp/print-literal-raw branch June 30, 2026 17:55
@github-actions github-actions Bot mentioned this pull request Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant