Skip to content

perf(linter/no-extra-non-null-assertion): reduce node matches#22588

Merged
graphite-app[bot] merged 1 commit into
mainfrom
codex/perf-no-extra-non-null-assertion
May 19, 2026
Merged

perf(linter/no-extra-non-null-assertion): reduce node matches#22588
graphite-app[bot] merged 1 commit into
mainfrom
codex/perf-no-extra-non-null-assertion

Conversation

@camc314

@camc314 camc314 commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Restrict typescript/no-extra-non-null-assertion to run only on TSNonNullExpression nodes.
  • Move optional member/call handling to parent/chain context checks from the non-null assertion node.
  • Regenerate the linter rule runner so this rule is registered only for AstType::TSNonNullExpression.

Performance

Profiled release oxlint with only this rule enabled:

oxlint -f default --disable-nested-config \
  --disable-unicorn-plugin --disable-oxc-plugin \
  -A all -W no-extra-non-null-assertion \
  --debug=timings --threads=1 .

Full repo profile over 5 runs. The repo contains intentionally invalid fixture files, so both before and after reported Found 0 warnings and 534 errors, but timing output was still emitted and file counts matched.

Build Files Rule calls Avg rule time
main 3914 31,289 0.670 ms
this PR 3914 332 0.019 ms

This is about a 99% reduction in rule calls for this rule on the repo profile.

@github-actions github-actions Bot added the A-linter Area - Linter label May 19, 2026
@camc314 camc314 self-assigned this May 19, 2026
@camc314 camc314 marked this pull request as ready for review May 19, 2026 13:12
Copilot AI review requested due to automatic review settings May 19, 2026 13:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 optimizes the typescript/no-extra-non-null-assertion lint rule by narrowing its AST visitation to TSNonNullExpression nodes and moving optional member/call handling to checks against the node’s parent context. This fits the linter’s broader design of minimizing per-node rule dispatch overhead via targeted NODE_TYPES.

Changes:

  • Restrict rule execution to TSNonNullExpression nodes and early-return for all others.
  • Rework redundant-assertion detection to use parent/chain context (including optional member/call and paren-skipping parent lookup).
  • Regenerate the rule runner so the rule is registered only for AstType::TSNonNullExpression.

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.

File Description
crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs Reworks rule logic to run only on TSNonNullExpression and determine redundancy via parent/chain context.
crates/oxc_linter/src/generated/rule_runner_impls.rs Updates generated NODE_TYPES registration to only include TSNonNullExpression for this rule.

@codspeed-hq

codspeed-hq Bot commented May 19, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 47 skipped benchmarks1


Comparing codex/perf-no-extra-non-null-assertion (d5bdbde) with main (26a55c4)

Open in CodSpeed

Footnotes

  1. 47 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.

@camchenry camchenry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice!

@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label May 19, 2026

camc314 commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

**Summary**

- Restrict `typescript/no-extra-non-null-assertion` to run only on `TSNonNullExpression` nodes.
- Move optional member/call handling to parent/chain context checks from the non-null assertion node.
- Regenerate the linter rule runner so this rule is registered only for `AstType::TSNonNullExpression`.

**Performance**

Profiled release `oxlint` with only this rule enabled:

```bash
oxlint -f default --disable-nested-config \
  --disable-unicorn-plugin --disable-oxc-plugin \
  -A all -W no-extra-non-null-assertion \
  --debug=timings --threads=1 .
```

Full repo profile over 5 runs. The repo contains intentionally invalid fixture files, so both before and after reported `Found 0 warnings and 534 errors`, but timing output was still emitted and file counts matched.

| Build | Files | Rule calls | Avg rule time |
| --- | ---: | ---: | ---: |
| main | 3914 | 31,289 | 0.670 ms |
| this PR | 3914 | 332 | 0.019 ms |

This is about a 99% reduction in rule calls for this rule on the repo profile.
@graphite-app graphite-app Bot force-pushed the codex/perf-no-extra-non-null-assertion branch from d5bdbde to 97fe9ba Compare May 19, 2026 15:14
@graphite-app graphite-app Bot merged commit 97fe9ba into main May 19, 2026
29 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label May 19, 2026
@graphite-app graphite-app Bot deleted the codex/perf-no-extra-non-null-assertion branch May 19, 2026 15:18
Dunqing added a commit that referenced this pull request May 26, 2026
# Oxlint
### 🚀 Features

- 10da26b linter: `no-misleading-character-class` add suggestions for
regex literal (#22681) (Sysix)
- b84941e linter/vue: Implement no-expose-after-await rule (#22675)
(bab)
- 98b98c1 linter/vue: Implement no-computed-properties-in-data rule
(#22674) (bab)
- 868e2e8 linter: Add suggestion for `no-misleading-character-class`
(#22631) (Sysix)
- 2d4c919 oxlint: Support `vite-plus/resolveConfig` for vite.config.ts
(#22456) (leaysgur)
- 2a60012 linter/vue: Implement require-render-return rule (#22613)
(bab)
- 9f227fd linter/vue: Implement no-deprecated-props-default-this rule
(#21892) (bab)
- 9cd28b3 linter: Add debug option to print files to be linted (#22546)
(camchenry)
- 87f065e linter/vue: Implement return-in-emits-validator rule (#21935)
(bab)
- ea0380c linter/unicorn: Implement `import-style` rule (#22173) (Hao
Chen)
- dde40fe linter/vue: Implement no-watch-after-await rule (#22006) (bab)
- a735eb0 linter/vue: Implement valid-next-tick rule (#22531) (bab)
- 6dc615d linter/vue: Implement no-shared-component-data rule (#21842)
(bab)
- a656418 linter/vue: Implement valid-define-options rule (#22107) (bab)
- bb6f1b2 linter/vue: Implement require-slots-as-functions rule (#22244)
(bab)
- 5fa4774 linter/n: Implement `callback-return` rule (#22470) (Mikhail
Baev)

### 🐛 Bug Fixes

- 52bd016 linter: Respect allow unused disable directives in LSP
(#22715) (camc314)
- fa7c463 semantic: Correct TS enum member symbol spans (#22689)
(camc314)
- ed445ba linter: Respect flags overrides for `RegExp(/regex/i, "u")`
(#22678) (Sysix)
- 26b9396 semantic: Resolve parameter decorators outside parameter scope
(#22623) (camc314)
- 203952d linter: `no-misleading-character-class` fix
`is_unicode_code_point_escape` check (#22655) (Sysix)
- 2f64d3d linter: `no-misleading-character-class` own diagnostic for
surrogate pairs without u flag (#22654) (Sysix)
- 0c6ebc2 linter/eslint/no-lone-blocks: Do not flag empty loops (#22649)
(Mikhail Baev)
- 2a7562e linter/no-focused-tests: Mark fixer as a suggestion (#22645)
(camc314)
- dbe644f linter: Respect args none for unused rest parameters (#22627)
(camc314)
- d0211b0 linter: Allow undefined in DummyRuleMap index (#22626)
(camc314)
- 36fc0ec oxlint/lsp: "ignore this" actions merge with existing
directive (#22604) (Sysix)
- f7f370e linter/vitest/prefer-expect-type-of: Recommend `toBeTypeOf`
instead of `expectTypeOf` (#22612) (Mikhail Baev)
- 77063e5 linter/consistent-indexed-object-style: Preserve interface
modifiers in fixes (#22579) (camc314)
- 4f33aa7 linter: Treat `TSGlobalDeclaration` as ambient in
`has_ambient_typescript_ancestor` (#22577) (camc314)

### ⚡ Performance

- c22938d linter/no-async-endpoint-handlers: Populate node types
(#22601) (camc314)
- 607486e linter/no-negated-condition: Populate node types (#22602)
(camc314)
- 4dcaa59 linter/consistent-type-imports: Populate node types (#22600)
(camc314)
- 5bd3b25 linter/no-unused-vars: Avoid cloned ancestor iterator (#22598)
(camc314)
- 97fe9ba linter/no-extra-non-null-assertion: Reduce node matches
(#22588) (camc314)
- ae98296 linter/consistent-indexed-object-style: Populate node types
(#22578) (camc314)
# Oxfmt
### 🚀 Features

- 16b8058 oxfmt: Support `vite-plus/resolveConfig` for vite.config.ts
(#22454) (leaysgur)

### 🐛 Bug Fixes

- 5a26479 formatter: Preserve import phases (#22692) (Cameron)

### ⚡ Performance

- 78cf83f formatter: Pre-size output buffer using source text length
(#22594) (Dunqing)

Co-authored-by: Dunqing <[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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants