Skip to content

fix: handle negative indices, overlapping ranges, and moved content in MagicString remove#8829

Merged
IWANABETHATGUY merged 1 commit intomainfrom
03-21-fix_magicstring_remove_issues
Mar 23, 2026
Merged

fix: handle negative indices, overlapping ranges, and moved content in MagicString remove#8829
IWANABETHATGUY merged 1 commit intomainfrom
03-21-fix_magicstring_remove_issues

Conversation

@IWANABETHATGUY
Copy link
Copy Markdown
Member

@IWANABETHATGUY IWANABETHATGUY commented Mar 21, 2026

Summary

  • Rewrote MagicString::remove to iterate by original position (chunk_by_start) instead of linked-list order, fixing incorrect behavior with moved content
  • Added support for negative indices in remove() by accepting i64 and using normalize_index (matching reset/slice pattern)
  • Fixed overlapping range removal — previously errored, now correctly handles partially/fully overlapping removes
  • Zero-length removals (e.g., remove(0, 0) or remove(9, -3) where indices resolve to the same position) are now treated as no-ops

Test plan

  • Unskipped 8 previously-skipped tests in MagicString.test.ts:
    • should treat zero-length removals as a no-op
    • should remove overlapping ranges
    • should remove overlapping ranges, redux
    • should remove modified ranges
    • should remove interior inserts
    • removes across moved content
    • should accept negative indices
    • should throw error when using negative indices with empty string
  • Updated offset underflow test expectation to match new error message

🤖 Generated with Claude Code

Copy link
Copy Markdown
Member Author

IWANABETHATGUY commented Mar 21, 2026


How to use the Graphite Merge Queue

Add the label graphite: merge-when-ready to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-21-fix_magicstring_remove_issues branch from ac73edf to c18999f Compare March 22, 2026 06:59
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-20-feat_magicstring_replace_with_regex branch 2 times, most recently from 17d8203 to 4071490 Compare March 22, 2026 13:19
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-21-fix_magicstring_remove_issues branch from c18999f to d2e3aee Compare March 22, 2026 13:19
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-20-feat_magicstring_replace_with_regex branch from 4071490 to bae62f5 Compare March 22, 2026 13:26
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-21-fix_magicstring_remove_issues branch 2 times, most recently from 04dfd4f to c701173 Compare March 22, 2026 13:31
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-20-feat_magicstring_replace_with_regex branch 2 times, most recently from 1dfc102 to 29582bb Compare March 22, 2026 14:13
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-21-fix_magicstring_remove_issues branch from ada9e2b to fcb4dbb Compare March 22, 2026 14:13
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-20-feat_magicstring_replace_with_regex branch from e6f5935 to 597cfeb Compare March 22, 2026 14:55
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-21-fix_magicstring_remove_issues branch 2 times, most recently from 80acb87 to 25da343 Compare March 22, 2026 15:00
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-20-feat_magicstring_replace_with_regex branch from 597cfeb to b458aa2 Compare March 22, 2026 15:00
@IWANABETHATGUY IWANABETHATGUY force-pushed the 03-21-fix_magicstring_remove_issues branch from 25da343 to 58ce387 Compare March 22, 2026 15:15
@IWANABETHATGUY IWANABETHATGUY marked this pull request as ready for review March 22, 2026 15:24
@IWANABETHATGUY IWANABETHATGUY requested review from hyf0 and shulaoda March 22, 2026 15:24
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 22, 2026

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 10 skipped benchmarks1


Comparing 03-21-fix_magicstring_remove_issues (9f45b12) with main (050cd43)

Open in CodSpeed

Footnotes

  1. 10 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Copy Markdown
Member

@hyf0 hyf0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any related issue or context?

@graphite-app graphite-app bot changed the base branch from 03-20-feat_magicstring_replace_with_regex to graphite-base/8829 March 23, 2026 02:49
@IWANABETHATGUY
Copy link
Copy Markdown
Member Author

IWANABETHATGUY commented Mar 23, 2026

Any related issue or context?

Probably just because the PR title is misleading, it only aligns with the JS version magic-string, and improves the test coverage. I update the pr title and description

@graphite-app graphite-app bot force-pushed the 03-21-fix_magicstring_remove_issues branch from 58ce387 to 04a7158 Compare March 23, 2026 02:53
@graphite-app graphite-app bot force-pushed the graphite-base/8829 branch from b458aa2 to 050cd43 Compare March 23, 2026 02:53
@graphite-app graphite-app bot changed the base branch from graphite-base/8829 to main March 23, 2026 02:54
@graphite-app graphite-app bot force-pushed the 03-21-fix_magicstring_remove_issues branch from 04a7158 to 9f45b12 Compare March 23, 2026 02:54
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 23, 2026

Deploy Preview for rolldown-rs ready!

Name Link
🔨 Latest commit 9f45b12
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/69c0ab56390b2f0008e489b8
😎 Deploy Preview https://deploy-preview-8829--rolldown-rs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@IWANABETHATGUY IWANABETHATGUY changed the title fix: MagicString remove issues fix: improve MagicString remove method with negative indices and overlapping ranges Mar 23, 2026
@IWANABETHATGUY IWANABETHATGUY changed the title fix: improve MagicString remove method with negative indices and overlapping ranges fix: handle negative indices, overlapping ranges, and moved content in MagicString remove Mar 23, 2026
@IWANABETHATGUY IWANABETHATGUY merged commit 7f7f9c5 into main Mar 23, 2026
33 checks passed
@IWANABETHATGUY IWANABETHATGUY deleted the 03-21-fix_magicstring_remove_issues branch March 23, 2026 03:01
@github-actions github-actions bot mentioned this pull request Mar 23, 2026
shulaoda added a commit that referenced this pull request Mar 23, 2026
## [1.0.0-rc.11] - 2026-03-23

### 🚀 Features

- magicString replace with regex (#8802) by @IWANABETHATGUY
- support `output.sourcemapExcludeSources` option (#8828) by @sapphi-red
- support `getIndentString` in MagicString (#8775) by @IWANABETHATGUY
- MagicString ignoreList support (#8773) by @IWANABETHATGUY

### 🐛 Bug Fixes

- types: remove `pluginName` from `MinimalPluginContext` (#8864) by @sapphi-red
- do not report eval?.() as direct eval (#8860) by @IWANABETHATGUY
- handle negative indices, overlapping ranges, and moved content in MagicString remove (#8829) by @IWANABETHATGUY
- enable arbitrary_precision for serde_json to fix JSON float parsing (#8848) by @elderapo
- resolve TypeScript lint errors (#8841) by @Boshen
- avoid panic on multi-byte UTF-8 chars in hash placeholder iterator (#8790) by @shulaoda
- ci: skip failing vite build watch raw query test (#8840) by @Boshen
- ci: use step-level env override to unset VITE_PLUS_CLI_BIN in vite tests (#8838) by @Boshen
- ci: move vite tests into CI workflow by @Boshen
- ci: unset all VITE_PLUS_* env vars in vite-tests workflow (#8837) by @Boshen
- test: skip watch CLI tests on Windows (#8830) by @Boshen
- ci: unset VITE_PLUS_CLI_BIN in vite-tests workflow (#8832) by @Boshen
- remove redundant bare side-effect imports in entry/facade chunks (#8804) by @h-a-n-a
- magicString prepend issues (#8797) by @IWANABETHATGUY
- ci: use `vpx` instead of `vp exec` for `pkg-pr-new` (#8827) by @Boshen
- set `order` for callable plugins (#8815) by @sapphi-red
- handle reversed slice ranges with moved content (#8750) by @IWANABETHATGUY
- update emnapi to latest to avoid version mismatch (#8781) by @sapphi-red
- external.md on Windows OS (#8780) by @bddjr
- align MagicString length/isEmpty with reference magic-string (#8776) by @IWANABETHATGUY

### 🚜 Refactor

- extract canonical_ref_resolving_namespace helper (#8836) by @Boshen

### 📚 Documentation

- improve external examples for cross-platform correctness (#8786) by @hyf0-agent
- update reference to transform function in plugin API documentation (#8778) by @zOadT

### ⚡ Performance

- reduce timing of `dervie_entries_aware_chunk_name` (#8847) by @AliceLanniste
- bench: remove redundant sourcemap benchmark cases (#8825) by @Boshen
- reduce intermediate allocations in `collapse_sourcemaps` (#8821) by @Boshen
- enable parallel AST cloning on macOS (#8814) by @Boshen

### 🧪 Testing

- watch: use polling watcher and retry for watch error test (#8772) by @sapphi-red

### ⚙️ Miscellaneous Tasks

- justfile: skip setup-vite-plus if vp is already installed (#8862) by @Boshen
- add expectWarning option to test config (#8861) by @IWANABETHATGUY
- justfile: support windows for `just setup` (#8846) by @AliceLanniste
- deps: update rust crates (#8852) by @renovate[bot]
- deps: update endbug/version-check action to v3 (#8855) by @renovate[bot]
- deps: update github-actions (#8853) by @renovate[bot]
- deps: update dependency vitepress to v2.0.0-alpha.17 (#8854) by @renovate[bot]
- deps: update npm packages (#8851) by @renovate[bot]
- bench: use mimalloc as global allocator in bench crate (#8844) by @IWANABETHATGUY
- reuse native build artifact in node-validation job (#8826) by @Boshen
- speed up CodSpeed benchmark build by disabling LTO (#8824) by @Boshen
- remove redundant critcmp benchmark job (#8823) by @Boshen
- deps: update rust crate oxc_sourcemap to v6.1.0 (#8785) by @renovate[bot]
- node: migrate oxlint and oxfmt to Vite+ (#8813) by @Boshen
- revert namespace runners for release build jobs (#8820) by @Boshen
- migrate runners to namespace (#8819) by @Boshen
- test: relax test utils path assertion to support git worktrees (#8816) by @younggglcy
- rename `examples/lazy` to `examples/lazy-compilation` (#8789) by @shulaoda
- improve "needs reproduction" wording by @Boshen
- deps: update dependency oxlint-tsgolint to v0.17.1 (#8807) by @renovate[bot]
- enable 7 previously-skipped MagicString tests (#8771) by @IWANABETHATGUY
- upgrade oxc to 0.121.0 (#8784) by @shulaoda
- increase Windows dev drive size from 12GB to 20GB (#8779) by @Copilot

### ❤️ New Contributors

* @elderapo made their first contribution in [#8848](#8848)
* @younggglcy made their first contribution in [#8816](#8816)
* @bddjr made their first contribution in [#8780](#8780)
* @zOadT made their first contribution in [#8778](#8778)

Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
This was referenced Mar 23, 2026
shulaoda added a commit that referenced this pull request Mar 23, 2026
## [1.0.0-rc.11] - 2026-03-23

### 🚀 Features

- magicString replace with regex (#8802) by @IWANABETHATGUY
- support `output.sourcemapExcludeSources` option (#8828) by @sapphi-red
- support `getIndentString` in MagicString (#8775) by @IWANABETHATGUY
- MagicString ignoreList support (#8773) by @IWANABETHATGUY

### 🐛 Bug Fixes

- forward test filters through vp run (#8870) by @younggglcy
- types: remove `pluginName` from `MinimalPluginContext` (#8864) by @sapphi-red
- do not report eval?.() as direct eval (#8860) by @IWANABETHATGUY
- handle negative indices, overlapping ranges, and moved content in MagicString remove (#8829) by @IWANABETHATGUY
- enable arbitrary_precision for serde_json to fix JSON float parsing (#8848) by @elderapo
- resolve TypeScript lint errors (#8841) by @Boshen
- avoid panic on multi-byte UTF-8 chars in hash placeholder iterator (#8790) by @shulaoda
- ci: skip failing vite build watch raw query test (#8840) by @Boshen
- ci: use step-level env override to unset VITE_PLUS_CLI_BIN in vite tests (#8838) by @Boshen
- ci: move vite tests into CI workflow by @Boshen
- ci: unset all VITE_PLUS_* env vars in vite-tests workflow (#8837) by @Boshen
- test: skip watch CLI tests on Windows (#8830) by @Boshen
- ci: unset VITE_PLUS_CLI_BIN in vite-tests workflow (#8832) by @Boshen
- remove redundant bare side-effect imports in entry/facade chunks (#8804) by @h-a-n-a
- magicString prepend issues (#8797) by @IWANABETHATGUY
- ci: use `vpx` instead of `vp exec` for `pkg-pr-new` (#8827) by @Boshen
- set `order` for callable plugins (#8815) by @sapphi-red
- handle reversed slice ranges with moved content (#8750) by @IWANABETHATGUY
- update emnapi to latest to avoid version mismatch (#8781) by @sapphi-red
- external.md on Windows OS (#8780) by @bddjr
- align MagicString length/isEmpty with reference magic-string (#8776) by @IWANABETHATGUY

### 🚜 Refactor

- extract canonical_ref_resolving_namespace helper (#8836) by @Boshen

### 📚 Documentation

- improve external examples for cross-platform correctness (#8786) by @hyf0-agent
- update reference to transform function in plugin API documentation (#8778) by @zOadT

### ⚡ Performance

- reduce timing of `dervie_entries_aware_chunk_name` (#8847) by @AliceLanniste
- bench: remove redundant sourcemap benchmark cases (#8825) by @Boshen
- reduce intermediate allocations in `collapse_sourcemaps` (#8821) by @Boshen
- enable parallel AST cloning on macOS (#8814) by @Boshen

### 🧪 Testing

- watch: use polling watcher and retry for watch error test (#8772) by @sapphi-red

### ⚙️ Miscellaneous Tasks

- deps: update dependency @oxc-project/types to v0.122.0 (#8873) by @renovate[bot]
- publish-to-npm: use correct vp pm publish (#8871) by @shulaoda
- justfile: skip setup-vite-plus if vp is already installed (#8862) by @Boshen
- add expectWarning option to test config (#8861) by @IWANABETHATGUY
- justfile: support windows for `just setup` (#8846) by @AliceLanniste
- deps: update rust crates (#8852) by @renovate[bot]
- deps: update endbug/version-check action to v3 (#8855) by @renovate[bot]
- deps: update github-actions (#8853) by @renovate[bot]
- deps: update dependency vitepress to v2.0.0-alpha.17 (#8854) by @renovate[bot]
- deps: update npm packages (#8851) by @renovate[bot]
- bench: use mimalloc as global allocator in bench crate (#8844) by @IWANABETHATGUY
- reuse native build artifact in node-validation job (#8826) by @Boshen
- speed up CodSpeed benchmark build by disabling LTO (#8824) by @Boshen
- remove redundant critcmp benchmark job (#8823) by @Boshen
- deps: update rust crate oxc_sourcemap to v6.1.0 (#8785) by @renovate[bot]
- node: migrate oxlint and oxfmt to Vite+ (#8813) by @Boshen
- revert namespace runners for release build jobs (#8820) by @Boshen
- migrate runners to namespace (#8819) by @Boshen
- test: relax test utils path assertion to support git worktrees (#8816) by @younggglcy
- rename `examples/lazy` to `examples/lazy-compilation` (#8789) by @shulaoda
- improve "needs reproduction" wording by @Boshen
- deps: update dependency oxlint-tsgolint to v0.17.1 (#8807) by @renovate[bot]
- enable 7 previously-skipped MagicString tests (#8771) by @IWANABETHATGUY
- upgrade oxc to 0.121.0 (#8784) by @shulaoda
- increase Windows dev drive size from 12GB to 20GB (#8779) by @Copilot

### ❤️ New Contributors

* @younggglcy made their first contribution in [#8870](#8870)
* @elderapo made their first contribution in [#8848](#8848)
* @bddjr made their first contribution in [#8780](#8780)
* @zOadT made their first contribution in [#8778](#8778)

---------

Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants