Skip to content

refactor(linter/plugins): store source text in end of buffer#18714

Merged
graphite-app[bot] merged 1 commit intomainfrom
om/01-29-refactor_linter_plugins_store_source_text_in_end_of_buffer
Jan 30, 2026
Merged

refactor(linter/plugins): store source text in end of buffer#18714
graphite-app[bot] merged 1 commit intomainfrom
om/01-29-refactor_linter_plugins_store_source_text_in_end_of_buffer

Conversation

@overlookmotel
Copy link
Member

@overlookmotel overlookmotel commented Jan 30, 2026

Previously we had to store source text at start of buffers sent to JS via raw transfer.

#18376 made changes to how raw transfer deserializer handles strings, in order to support files containing a BOM. Building on that, we're now able to remove the requirement that source text be at start of the buffer entirely.

This PR changes the deserializer used in Oxlint JS plugins to accept source text being anywhere in the buffer, as long as no other strings are after it. In practice this just means that the source text must be allocated before anything else, which is easy to satisfy.

Now the source text can be allocated with just the usual safe allocator.alloc_str(source_text) method.

This change removes a ton of dodgy workarounds and unsafe code we used previously to get source text at the start of buffer. It makes the code less labyrinthine and far less likely a slip up can inadvertently introduce UB.

Note: In napi/parser, source text still is at start of the buffer, as that's simpler and more efficient when the source text is written into the buffer on JS side. This change only affects Oxlint.

@github-actions github-actions bot added A-linter Area - Linter A-parser Area - Parser A-cli Area - CLI A-ast-tools Area - AST tools A-linter-plugins Area - Linter JS plugins C-cleanup Category - technical debt or refactoring. Solution not expected to change behavior labels Jan 30, 2026
Copy link
Member Author

overlookmotel commented Jan 30, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

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.

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 30, 2026

CodSpeed Performance Report

Merging this PR will not alter performance

Comparing om/01-29-refactor_linter_plugins_store_source_text_in_end_of_buffer (2c6c42b) with main (051cfcf)1

Summary

✅ 46 untouched benchmarks
⏩ 3 skipped benchmarks2

Footnotes

  1. No successful run was found on main (b82faec) during the generation of this report, so 051cfcf was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 3 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.

@overlookmotel overlookmotel marked this pull request as ready for review January 30, 2026 00:29
Copilot AI review requested due to automatic review settings January 30, 2026 00:29
@overlookmotel overlookmotel self-assigned this Jan 30, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors how source text is stored in buffers for Oxlint JS plugins, moving it from the start to the end of the buffer. This change simplifies the code significantly by removing unsafe workarounds and making the implementation more maintainable.

Changes:

  • Refactored string deserializer to detect source text by checking if position is >= sourceStartPos (for linter) instead of < sourceEndPos
  • Updated parse function to accept source_start parameter and position source text at end of buffer
  • Removed RawTransferFileSystem and its complex unsafe file reading implementation, now using standard OsFileSystem
  • Simplified source text allocation from unsafe alloc_bytes_start to safe alloc_str
  • Added ACTIVE_SIZE and CHUNK_FOOTER_SIZE constants for better buffer size calculations
  • Removed complex allocator reset logic that was restoring data pointer to start

Reviewed changes

Copilot reviewed 11 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tasks/ast_tools/src/generators/raw_transfer.rs Updated string deserializer to check pos >= sourceStartPos for linter; added CHUNK_FOOTER_SIZE constant and ACTIVE_SIZE calculation
napi/parser/src/generated/raw_transfer_constants.rs Added CHUNK_FOOTER_SIZE constant
napi/parser/src-js/generated/constants.js Added ACTIVE_SIZE constant for buffer size calculations
crates/oxc_linter/src/lint_runner.rs Removed file_system parameter, now always uses OsFileSystem
crates/oxc_linter/src/lib.rs Simplified source text allocation to use alloc_str instead of unsafe alloc_bytes_start
crates/oxc_allocator/src/pool/fixed_size.rs Removed complex data pointer restoration logic from reset method
crates/oxc_allocator/src/generated/fixed_size_constants.rs Added CHUNK_FOOTER_SIZE constant
crates/oxc_allocator/src/from_raw_parts.rs Added compile-time check to verify CHUNK_FOOTER_SIZE matches expected value
apps/oxlint/src/lint.rs Removed file_system parameter from lint_files call and removed associated configuration logic
apps/oxlint/src/js_plugins/raw_fs.rs Deleted entire file - no longer needed with new approach
apps/oxlint/src/js_plugins/parse.rs Updated to accept source_start parameter, position source text at end, and set allocator cursor accordingly
apps/oxlint/src/js_plugins/mod.rs Removed RawTransferFileSystem export
apps/oxlint/src/generated/raw_transfer_constants.rs Added CHUNK_FOOTER_SIZE constant
apps/oxlint/src-js/package/parse.ts Calculate sourceStartPos as ACTIVE_SIZE - maxSourceByteLen and pass to parseRawSync
apps/oxlint/src-js/generated/deserialize.js Removed sourceEndPos variable; updated string detection to use pos >= sourceStartPos
apps/oxlint/src-js/generated/constants.ts Added ACTIVE_SIZE constant
apps/oxlint/src-js/bindings.d.ts Updated parseRawSync signature to include sourceStart parameter
apps/oxlint/Cargo.toml Removed unused simdutf8 dependency
Cargo.lock Updated to reflect removed simdutf8 dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@overlookmotel overlookmotel force-pushed the om/01-29-refactor_linter_plugins_store_source_text_in_end_of_buffer branch from 71058c7 to 2c6c42b Compare January 30, 2026 00:44
@overlookmotel
Copy link
Member Author

I wrote this shameful hacky code originally, so I think I know it better than anyone. So merging without review.

@graphite-app graphite-app bot added the 0-merge Merge with Graphite Merge Queue label Jan 30, 2026
@graphite-app
Copy link
Contributor

graphite-app bot commented Jan 30, 2026

Merge activity

Previously we had to store source text at start of buffers sent to JS via raw transfer.

#18376 made changes to how raw transfer deserializer handles strings, in order to support files containing a BOM. Building on that, we're now able to remove the requirement that source text be at start of the buffer entirely.

This PR changes the deserializer used in Oxlint JS plugins to accept source text being anywhere in the buffer, *as long as no other strings are after it*. In practice this just means that the source text must be allocated before anything else, which is easy to satisfy.

Now the source text can be allocated with just the usual safe `allocator.alloc_str(source_text)` method.

This change removes a ton of dodgy workarounds and unsafe code we used previously to get source text at the start of buffer. It makes the code less labyrinthine and far less likely a slip up can inadvertently introduce UB.

Note: In `napi/parser`, source text still *is* at start of the buffer, as that's simpler and more efficient when the source text is written into the buffer on JS side. This change only affects Oxlint.
@graphite-app graphite-app bot force-pushed the om/01-29-refactor_linter_plugins_store_source_text_in_end_of_buffer branch from 2c6c42b to e39a983 Compare January 30, 2026 00:52
graphite-app bot pushed a commit that referenced this pull request Jan 30, 2026
Remove several unsafe and potentially dangerous methods from `Allocator`. These methods were only required in order to support writing source text into start of allocator chunk, instead of bumping downwards in the usual way.

#18714 has removed the need for source text to be at start of allocator chunks, so we can now remove these methods.

This is a breaking change, but the docs stated that use of these methods was inadvisable, so hopefully no-one is depending on them.

https://github.com/oxc-project/oxc/blob/b82faec35c486c0fcdb8a242a626554d2c99a310/crates/oxc_allocator/src/lib.rs#L24-L25
@graphite-app graphite-app bot merged commit e39a983 into main Jan 30, 2026
23 checks passed
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Jan 30, 2026
@graphite-app graphite-app bot deleted the om/01-29-refactor_linter_plugins_store_source_text_in_end_of_buffer branch January 30, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ast-tools Area - AST tools A-cli Area - CLI A-linter Area - Linter A-linter-plugins Area - Linter JS plugins A-parser Area - Parser C-cleanup Category - technical debt or refactoring. Solution not expected to change behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants