Skip to content

feat: internal Rust napi parser + merge eslint-plugin-runner into @rslint/core#1035

Open
fansenze wants to merge 4 commits into
mainfrom
feat/eslint-parser-napi-20260530
Open

feat: internal Rust napi parser + merge eslint-plugin-runner into @rslint/core#1035
fansenze wants to merge 4 commits into
mainfrom
feat/eslint-parser-napi-20260530

Conversation

@fansenze
Copy link
Copy Markdown
Contributor

@fansenze fansenze commented May 30, 2026

Summary

Replaces eslint-plugin-runner's npm parser + 2138-line hand-written JS tokenizer with an internal Rust napi parser, and merges the runner into @rslint/core so the native .node ships inside the existing @rslint/{platform} subpackages — no new published packages.

Parser — an internal Rust NAPI crate exposing parse() → ESTree-JSON AST + a parser-driven columnar token stream + ESLint-shape comments (UTF-16 offsets). Tokens are parser-driven (regex/division/JSX/TS disambiguation resolved by the parser, not heuristics), so the hand-written JS tokenizer is removed.

Merge into @rslint/core

  • runner src (24 files) → src/eslint-plugin/; tests (491) → tests/eslint-plugin/
  • thin native-loader.ts resolves the platform .node from @rslint/{platform} (mirrors how bin/rslint.cjs locates the Go binary) + dev fallback + musl detection
  • hybrid build: tsgo for the library surface + an rslib sub-build for the worker → dist/eslint-plugin/
  • native .node distributed inside @rslint/{platform} (napi targets 3 → 8) via a dedicated release CI matrix
  • removed the @rslint/eslint-plugin-runner package

Verification — 491 tests green, tsgo typecheck clean, hybrid build passes, native-parser dev/prod load + token differential verified locally. The multi-platform napi cross-build release CI is new and pending validation on Actions.

Related Links

N/A

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

fansenze added 3 commits May 30, 2026 20:16
Add an internal Rust NAPI crate that parses JS/TS/JSX into ESTree JSON +
ESLint-shape comments (UTF-16 offsets), and switch the runtime's parse path
from the npm parser to it.

- the crate: parse() with Rust-side lang derivation, recovering semantics, a
  source-size guard, and catch_unwind on the #[napi] boundary.
- ecma-language-plugin: parseSync -> native parse; lang derivation moved Rust-side.
- normalize-ast: rebuild RegExp/BigInt Literal.value (JSON transfer cannot carry them).
- rust-toolchain pinned; generated .node/index.js are gitignored.

The full runtime suite passes. The tokenizer is still the JS implementation at
this point; replacing it with Rust is the next milestone.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request replaces the hand-written JS tokenizer and the npm oxc-parser dependency with a new native Rust napi crate, crates/rslint-estree, which leverages oxc's parser-driven token stream. The former @rslint/eslint-plugin-runner package is merged directly into @rslint/core under packages/rslint/src/eslint-plugin. On the JS side, SourceCode now lazily rebuilds the token array from the columnar data sent from Rust. The review feedback highlights a bug in the language promotion logic where TypeScript definition files (.d.ts) are incorrectly promoted to .tsx when JSX is enabled, and suggests guarding against this by checking !st.is_typescript_definition().

Comment thread crates/rslint-toolkit/src/parse.rs
@fansenze fansenze force-pushed the feat/eslint-parser-napi-20260530 branch from 31f590a to f32a009 Compare May 30, 2026 12:29
@fansenze fansenze changed the title feat: internal Rust napi parser (@rslint/estree) + merge eslint-plugin-runner into @rslint/core feat: internal Rust napi parser + merge eslint-plugin-runner into @rslint/core May 30, 2026
@fansenze fansenze force-pushed the feat/eslint-parser-napi-20260530 branch 7 times, most recently from 25c1c48 to a157695 Compare May 31, 2026 01:28
- migrate runner (24 src + 491 tests) into src/eslint-plugin & tests/eslint-plugin
- hybrid build: tsgo library surface + rslib worker sub-build into dist/eslint-plugin/
- publish the napi parser as @rslint/toolkit + per-platform subpackages; @rslint/core depends on it at runtime and loads the .node via the napi default loader
- napi targets 3->8 + release CI matrix
- remove @rslint/eslint-plugin-runner package
@fansenze fansenze force-pushed the feat/eslint-parser-napi-20260530 branch from a157695 to 325088b Compare May 31, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant