Skip to content

Conversation

Sysix
Copy link
Member

@Sysix Sysix commented Aug 28, 2025

closes #614
related #479

https://eslint.org/docs/latest/rules/no-misleading-character-class

The rule is still in nursery because of two problems:

The spans for emojis are wrong too, do not know if the rule should fix this, or the regexp parser.

@github-actions github-actions bot added A-linter Area - Linter C-enhancement Category - New feature or request labels Aug 28, 2025
Copy link
Member Author

Sysix commented Aug 28, 2025


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.

Copy link

codspeed-hq bot commented Aug 28, 2025

CodSpeed Instrumentation Performance Report

Merging #13365 will not alter performance

Comparing 08-22-feat_linter_add_eslint_no-misleading-character-class_ (8221a01) with main (57108c0)1

Summary

✅ 37 untouched

Footnotes

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

@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from f2c2e12 to c94aa23 Compare August 29, 2025 15:43
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch 2 times, most recently from a9e4981 to ef64a32 Compare August 30, 2025 14:53
@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from c94aa23 to c2a7238 Compare August 30, 2025 14:53
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch 3 times, most recently from fbc2fd9 to 9ca9dc5 Compare August 30, 2025 21:47
@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from c2a7238 to 1774721 Compare September 2, 2025 16:23
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch 2 times, most recently from 77cb235 to f0cf15f Compare September 2, 2025 16:40
@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from 1774721 to 0eaa86f Compare September 2, 2025 16:40
@graphite-app graphite-app bot force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch 2 times, most recently from 455236e to b7a07ca Compare September 2, 2025 16:57
@graphite-app graphite-app bot force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from f0cf15f to 3690db6 Compare September 2, 2025 16:57
@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from b7a07ca to d8ce816 Compare September 2, 2025 19:07
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 3690db6 to de4da11 Compare September 2, 2025 19:07
@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from d8ce816 to ca4f52f Compare September 2, 2025 19:10
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch 3 times, most recently from 6c617dc to 97cbd4f Compare September 2, 2025 20:11
@Sysix Sysix force-pushed the 08-22-fix_regex-parser_parse_simple_templateliterals_ branch from ca4f52f to 7ae6a05 Compare September 9, 2025 17:11
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 97cbd4f to 92e888e Compare September 9, 2025 17:11
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from dde3cd4 to 30a5f28 Compare September 15, 2025 18:06
@leaysgur
Copy link
Member

After checking, I think it doesn't seem to be an issue only for the regexp AST at least.

Please look at the following code.

#![expect(clippy::print_stdout)]
use oxc_allocator::Allocator;
use oxc_diagnostics::{GraphicalReportHandler, OxcDiagnostic};
use oxc_parser::Parser;
use oxc_span::SourceType;

fn main() {
    // Test cases with various Unicode characters
    let test_cases = vec![
        // Regular expressions
        r"let r1 = /[👍]/;",
        r"let r2 = /[❇️]/;",
        r"let r3 = /[🇯🇵]/;",
        r"let r4 = /[Á]/;",
        r"let r5 = /[abc]/;",
        r"let r6 = /[日本語]/;",
        r"let r7 = /[👨‍👩‍👦]/;",
        // String literals for comparison
        r#"let s1 = "[👍]";"#,
        r#"let s2 = "[❇️]";"#,
        r#"let s3 = "[🇯🇵]";"#,
        r#"let s4 = "[Á]";"#,
        r#"let s5 = "[abc]";"#,
        r#"let s6 = "[日本語]";"#,
        r#"let s7 = "[👨‍👩‍👦]";"#,
    ];

    let allocator = Allocator::default();
    let source_type = SourceType::default();

    for source_text in test_cases {
        println!("Source: {source_text}");

        let ret = Parser::new(&allocator, source_text, source_type).parse();

        // Report diagnostic for each regex literal or string literal
        for node in ret.program.body {
            use oxc_ast::ast::*;

            if let Statement::VariableDeclaration(decl) = &node {
                for declarator in &decl.declarations {
                    if let Some(init) = &declarator.init {
                        let span = match init {
                            Expression::RegExpLiteral(regex) => regex.span,
                            Expression::StringLiteral(string) => string.span,
                            _ => continue,
                        };

                        // Create a diagnostic to show how the span is rendered
                        let diagnostic = OxcDiagnostic::warn("Test span rendering")
                            .with_label(span)
                            .with_source_code((*source_text).to_string());

                        // Render the diagnostic
                        let mut output = String::new();
                        let handler = GraphicalReportHandler::new();
                        handler.render_report(&mut output, diagnostic.as_ref()).unwrap();

                        println!("{output}");
                    }
                }
            }
        }
    }
}

And the result is as follows.

image

Even the string literal isn't reported correctly.

Perhaps there's a problem on the oxc-miette side...?

@camc314
Copy link
Contributor

camc314 commented Sep 16, 2025

Perhaps there's a problem on the oxc-miette side...?

this seems likley, when rendering the span i guess it doesn't understand that the emojis are amoji sequences

@camc314
Copy link
Contributor

camc314 commented Sep 16, 2025

Let's fix the spans later

@camc314 camc314 self-assigned this Sep 16, 2025
@Sysix Sysix changed the base branch from main to graphite-base/13365 September 16, 2025 16:50
@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 30a5f28 to 85540a1 Compare September 16, 2025 16:50
@Sysix Sysix changed the base branch from graphite-base/13365 to 09-16-chore_deps_update_oxc-miette_to_v2.5.0 September 16, 2025 16:50
@Sysix
Copy link
Member Author

Sysix commented Sep 16, 2025

Thanks for the fix! Updated the PR

@Sysix Sysix force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 85540a1 to 108badd Compare September 16, 2025 16:59
@Sysix Sysix force-pushed the 09-16-chore_deps_update_oxc-miette_to_v2.5.0 branch from c9eba6d to b116b2c Compare September 16, 2025 16:59
@camc314 camc314 changed the base branch from 09-16-chore_deps_update_oxc-miette_to_v2.5.0 to graphite-base/13365 September 18, 2025 07:56
@camc314 camc314 force-pushed the graphite-base/13365 branch from b116b2c to b1029ea Compare September 18, 2025 07:56
@camc314 camc314 force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 108badd to 6da84c6 Compare September 18, 2025 07:56
@camc314 camc314 changed the base branch from graphite-base/13365 to main September 18, 2025 07:56
@camc314
Copy link
Contributor

camc314 commented Sep 18, 2025

I moved this to directly target main. I'll get miette fixed first, then we can bump it and fix the spans

@camc314 camc314 force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 6da84c6 to 6fcb3ac Compare September 18, 2025 07:58
@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label Sep 18, 2025
Copy link
Contributor

camc314 commented Sep 18, 2025

Merge activity

closes #614
related #479

https://eslint.org/docs/latest/rules/no-misleading-character-class

The rule is still in nursery because of two problems:
- #13660
- #13436

The spans for emojis are wrong too, do not know if the rule should fix this, or the regexp parser.
@graphite-app graphite-app bot force-pushed the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch from 6fcb3ac to 8221a01 Compare September 18, 2025 08:04
@graphite-app graphite-app bot merged commit 8221a01 into main Sep 18, 2025
25 checks passed
@graphite-app graphite-app bot deleted the 08-22-feat_linter_add_eslint_no-misleading-character-class_ branch September 18, 2025 08:08
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Sep 18, 2025
This was referenced Sep 19, 2025
camc314 added a commit that referenced this pull request Sep 23, 2025
## [1.17.0] - 2025-09-23

### 🚀 Features

- f47f978 linter/plugins: Add `definePlugin` API (#14008)
(overlookmotel)
- 3e117c6 linter/plugins: Add `defineRule` API (#13945) (overlookmotel)
- 2dc8adb linter/plugins: Add `createOnce` API (#13944) (overlookmotel)
- bef8753 linter/plugins: ESTree-compatible AST for JS plugins (#13942)
(overlookmotel)
- 55c2e11 editor: Add `oxc.fmt.experimental` flag (#13923) (Sysix)
- a21ff54 language_server: Introduce `ServerFormatter` (#13700) (Sysix)
- a14aa79 npm/oxlint: Convert to ES modules (#13876) (Boshen)
- 15eb326 linter: Add `vue/no-required-prop-with-default` rule (#13613)
(yefan)
- 5d3ba00 linter: Add `vue/require-typed-ref` rule (#13857) (yefan)
- b52389a node: Bump `engines` field to require Node.js 20.19.0+ for ESM
support (#13879) (Copilot)
- 8221a01 linter: Add `eslint/no-misleading-character-class` (#13365)
(Sysix)
- c75ae8c linter/plugins: Add options to `Context` (#13810)
(overlookmotel)
- 53d04dd linter: Convert `oxlint` to NAPI app (#13723) (overlookmotel)

### 🐛 Bug Fixes

- 1f4be38 napi/parser: Generate `.d.mts` extension for types (#14038)
(Daniel Roe)
- a018756 linter/plugins: Pin `tsdown` dependency to 0.15.1 (#14005)
(overlookmotel)
- b8790c2 language_server: Output correct position for parser & semantic
errors (#14010) (Sysix)
- 4d3c6e1 linter: Support let-chains in codegen node type detection
(#14006) (camc314)
- a34918a linter/plugins: Avoid lint warnings compiling WASM or
big-endian (#13968) (overlookmotel)
- 27022ab linter/switch-case-braces: Add support for string including
colon on case expression (#13687) (Lukinoh)
- dd3843f linter: Set package version in `package.json` (#13890)
(overlookmotel)
- fa866b3 linter: Sort optimized/unoptimized diagnostics before
comparison (#13850) (camc314)
- fac7624 linter/plugins: Improve error for no JS plugins (#13858)
(overlookmotel)

### 🚜 Refactor

- bb040bc parser, linter: Replace `.mjs` files with `.js` (#14045)
(overlookmotel)
- b353750 linter/plugins: Remove unnecessary `Serialize` derives
(#14031) (overlookmotel)
- 0d48511 linter/plugins: Improve handling `Context` method calls in
`createOnce` (#14032) (overlookmotel)
- 36ac0fb language_server: Don't create `mpsc` channel (#14011) (Sysix)
- 2e9ae3f linter: Make disable directives own the rule name (#13987)
(camc314)
- 6bc7664 oxlint: Run oxlint before tsgolint (#13519) (camc314)
- 0c93f33 language_server: Use minimal text edit for `ServerFormatter`
(#13960) (Sysix)
- 823cb57 langauge_server: Move `Backend` into own file (#13955) (Sysix)
- dc700f5 language_server: Introduce `LSPFileSystem` (#13731) (Sysix)
- 42e2c1d linter: Remove `Rc` from `DisableDirectives` (#13924)
(camc314)
- ac3e9e9 napi/parser: Move JS code into `src-js` directory (#13899)
(overlookmotel)
- e90bfe3 linter: Remove double reference in unicorn/error-message
(#13916) (camc314)
- 83791a0 linter: Remove double reference in vue/jsx-no-undef (#13915)
(camc314)
- ebd22de linter: Remove double reference in vue/require-typed-ref
(#13914) (camc314)
- 873e231 language_server: Move `needs_linter_restart` to `ServerLinter`
(#13834) (Sysix)
- 7e0d736 linter/plugins: Rename `--experimental-js-plugins` to
`--js-plugins` (#13860) (overlookmotel)
- 6245c8c linter/plugins: Make `Context` properties getters (#13809)
(overlookmotel)
- a2342a6 linter/plugins: Import named in tests (#13807) (overlookmotel)

### 📚 Documentation

- 601c876 linter: Add comment explaining why Mimalloc is feature-gated
(#14037) (overlookmotel)

### ⚡ Performance

- 4d04c6e linter/plugins: Flatten `LintFileResult` fields (#14033)
(overlookmotel)
- 06363e0 linter: Add node type codegen support for `match node.kind()`
(#13736) (camchenry)
- a79af0a linter: Replace `for (... of ...)` loops (#13913)
(overlookmotel)
- b53292d linter: Use unstable sort where possible (#13818) (sapphi-red)

### 🎨 Styling

- 8083740 linter: Import `Serialize` at top level (#14030)
(overlookmotel)

### 🧪 Testing

- b807b6f language_server: Skip formatter test on windows (#13986)
(Sysix)
- 2600858 language_server: Add Tester for ServerFormatter (#13969)
(Sysix)
- 37aadf0 language_server: Add `test_and_snapshot_multiple_file`
(#13966) (Sysix)
- ad14a41 editor: Fix test setup (#13929) (Sysix)
- f51240e linter/plugins: Tests for different import styles (#13859)
(overlookmotel)
- 407c95e linter/plugins: Check `this` is undefined in visit functions
(#13811) (overlookmotel)
- f023a22 linter/plugins: Include stack trace in plugin loading errors
(#13808) (overlookmotel)

### 💼 Other

- 0630d68 linter: Build `oxlint` locally with Mimalloc in release mode
(#14034) (overlookmotel)

Co-authored-by: camc314 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linter Area - Linter C-enhancement Category - New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat(linter): eslint/no-misleading-character-class
3 participants