feat(linter/eslint): implement id-match rule#22379
Conversation
|
@codex review, use the repository skill $performance-lint-rules |
|
Codex Review: Didn't find any major issues. Nice work! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Merging this PR will not alter performance
Comparing Footnotes
|
40503c6 to
6759565
Compare
There was a problem hiding this comment.
Pull request overview
Implements the ESLint id-match rule in oxc_linter, enforcing a configurable identifier naming regex (with options for class fields, properties, destructuring behavior, and declarations-only mode), and wires it into the generated rule registry + published schemas.
Changes:
- Add
eslint/id-matchrule implementation with extensive JS/TS test coverage and snapshots. - Introduce
deserialize_required_regex_optionhelper for required regex string config parsing. - Register the new rule across generated enums/runners and update configuration schema/snapshots.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tasks/website_linter/src/snapshots/schema_json.snap | Adds id-match to the website schema snapshot rule list. |
| npm/oxlint/configuration_schema.json | Adds id-match to the published configuration schema rule list. |
| crates/oxc_linter/src/utils/config.rs | Adds deserialize_required_regex_option helper for pattern deserialization. |
| crates/oxc_linter/src/snapshots/eslint_id_match.snap | Adds snapshot output for the JS/TSX coverage of id-match. |
| crates/oxc_linter/src/snapshots/eslint_id_match@ts.snap | Adds snapshot output for TS-specific coverage of id-match. |
| crates/oxc_linter/src/rules/eslint/id_match.rs | New rule implementation + unit tests and config validation tests. |
| crates/oxc_linter/src/rules.rs | Exposes the eslint::id_match module. |
| crates/oxc_linter/src/generated/rules_enum.rs | Registers EslintIdMatch in the generated rule enum/dispatch. |
| crates/oxc_linter/src/generated/rule_runner_impls.rs | Adds the rule runner node-type bitset for id-match. |
| apps/oxlint/src-js/package/config.generated.ts | Adds id-match to the generated JS config typings. |
# Oxlint ### 🚀 Features - 1ae291e linter/no-underscore-dangle: Add `allowInUsingDeclarations` option (#22483) (吴杨帆) - 0440b0f linter/eslint: Implement `id-match` rule (#22379) (Vladislav Sayapin) - 65bf119 linter: Implement react no-object-type-as-default-prop (#22481) (uhyo) - 2a6ddce linter/eslint: Implement `no-implied-eval` rule (#22391) (Vladislav Sayapin) - d3a3c1d linter: Auto detect agents from CLI and transition to the agent output format (#22068) (Jovi De Croock) - 625758a linter/vitest: Implement padding-around-after-all-blocks rule (#21788) (kapobajza) - 37680b0 linter: Implement react no-unstable-nested-components (#22248) (Jovi De Croock) - d8d9c74 linter: Implement import/newline-after-import rule (#19142) (Ryuya Yanagi) ### 🐛 Bug Fixes - 3f59e03 linter: Only call rayon/miette/tracing inits once (#21899) (Matiss Janis Aboltins) - 602dfd6 linter/promise/no-return-wrap: Detect Promise calls in all branches (#22474) (zennnnnnn11) - e182aee linter: Allow dialogs and popovers for no_autofocus (#22289) (mehm8128) - 7ffb710 linter/jest/vitest: Jest/no-standalone-expect ignores additionalTestBlockFunctions option for jest/vitest hooks (#22477) (kapobajza) - c6f2d3f linter: Add more expression support for iframe-has-title (#22460) (mehm8128) - 5747ff1 linter: Avoid enabling jest with vitest plugin (#22499) (camc314) - 863984f linter/no-find-dom-node: Run on all files (#22479) (bab) ### ⚡ Performance - 2afef79 linter: Optimize `no-loop-func` (#22491) (camchenry) - 4c9ca72 oxlint: Align walker thread count with rayon pool (#22494) (Boshen) ### 📚 Documentation - f7967c7 linter/id-match: Clarify `onlyDeclarations` config docs (#22523) (camc314) - 1e0c97f linter: Fix closing code block in documentation for `padding-around-after-all-blocks` rule. (#22513) (connorshea) - a9049fd linter: Exclude directly provide autoFocus to dialog pattern (#22510) (mehm8128) # Oxfmt ### 🐛 Bug Fixes - 8ee946f formatter/sort_imports: Use label to classify lines (#22512) (leaysgur) - 8c1da44 formatter: Normalize destructuring keys in DCR (#22478) (camc314)
This PR implements the
eslint/id-matchrule, which enforces a configured naming regex for identifiersESLint ref: https://eslint.org/docs/latest/rules/id-match
Issue: #479
Behavior Differences from ESLint
This implementation is intentionally stricter in two cases:
const { [bad_name]: x } = objand({ [bad_name]: x } = obj), because the computed key is a normal reference expression, not a binding introduced by destructuringpropertiesenabled, ordinary top-level dynamic import option keys are checked, for exampleimport("x", { bad_option: true }). Import attributes insidewith { ... }are still ignoredTypeScript
TypeScript syntax is supported on a best-effort basis for identifiers that flow through the same visited AST node kinds and transparent wrappers such as
as,satisfies, non-null assertions, and instantiation expressionsThis is not a replacement for
@typescript-eslint/naming-conventionor future tsgolint naming-convention work: oxc-project/tsgolint#186Regex Compatibility
The pattern is compiled with Rust regex syntax. JavaScript-specific regex features such as lookaround and backreferences are not supported. Unicode escapes should use Rust syntax, for example
\u{XXXX}Algorithmic Complexity
The generated rule runner limits the hot path to identifier-like AST nodes:
BindingIdentifierIdentifierReferenceIdentifierNamePrivateIdentifierLabelIdentifierEach visited identifier first runs the regex check and returns immediately when the name matches
For non-default configurations, the hot path is linear in the total length of checked identifier names, with additional ancestor/context checks only for failed regex matches
Space complexity is
O(1)beyond the compiled regex and options. The hot path does not allocate unless a diagnostic is emittedThe default pattern
^.+$matches every non-empty identifier name, soshould_runskips rule work entirely for the default configurationAI Disclosure
Claude Opus 4.7 & Codex GPT 5.5