Commit Graph

26 Commits

Author SHA1 Message Date
Boshen 1193c9dbaf chore(oxfmt): dogfood operator position at line start (#25937)
dogfood
2026-08-20 14:36:47 +00:00
overlookmotel f33248da63 refactor(linter/plugins): move and refactor handling legacy report call forms (#19239)
Follow on after #19193. Refactor.

That PR introduced support for legacy call styles for `context.report`.

Move that implementation into `report.ts`, shorten the code a little, and produce consistent object shapes. Avoid calling `convertLegacyCallArgs` in the common case that `report` is called in the modern way.
2026-02-10 23:55:44 +00:00
overlookmotel 28d8882757 refactor(linter/plugins): getMessage return messageId (#19105)
Pure refactor. Remove duplicated code at 2 x call sites for `getMessage`, and move the logic into `getMessage` itself instead.
2026-02-08 20:40:30 +00:00
overlookmotel e3dc5f6c10 feat(linter/plugins): RuleTester test suggestions (#19104)
`RuleTester` test that suggestions provided by the rule match what's expected in the test case - that code after applying each suggestion matches the test case's `output` property, and that suggestions' descriptions also match those specified in test cases.

Skip one conformance test for ESLint's `prefer-regex-literals` rule where the suggestion description in Oxlint is different from ESLint, but in a completely cosmetic way. There's no need to match it exactly. That apart, no change to conformance test results, which strongly suggests that Oxlint is treating suggestions correctly.
2026-02-08 20:33:18 +00:00
overlookmotel 726e273f60 docs(linter/plugins): improve JSDoc comment for DiagnosticReport (#19103)
Improve accuracy of a JSDoc comment.
2026-02-07 10:46:25 +00:00
overlookmotel 65c6c33512 refactor(linter/plugins): simplify fix type and validation (#19078)
Refactor. Simplify the type used to represent a fix when sending from JS to Rust.

Previously we avoided creating new objects by using the same fix object returned by `fix` function, and so were locked to ESLint's design.

That worked, but the code was excessively complicated. Fixes should be fairly rare, so this optimization is on a cold path - it's not worth it.

Simplify implementation by converting `Fix`es to a simpler type (`FixReport`) before sending to Rust.
2026-02-06 17:13:22 +00:00
overlookmotel e2d28fe9a0 feat(linter/plugins): implement suggestions (#18963)
Implement support for suggestions.

Implementation exactly matches ESLint's.

The tests demonstrate that:

* `--fix-suggestions` applies suggestions.
* `--fix` does *not* apply suggestions.
* When a rule provides multiple suggestions, only the 1st is applied.

I've also confirmed that suggestions show up correctly in VSCode (once language server supports JS plugins).
2026-02-05 11:51:51 +00:00
overlookmotel 56a614ddbb refactor(linter/plugins): move data interpolation into getMessage (#18959)
Pure refactor. Move the code for interpolating data into error messages out of `report` and into `getMessages`. This logic can now also be used for getting the fixes for suggestions in a later PR.
2026-02-05 02:24:15 +00:00
overlookmotel 28df1604bf fix(linter/plugins): allow line number passed to report to be 0 (#18642)
Similar to #18341. Loosen checks for `loc` passed to `report()`. Allow `line` to 0, if `column` is 0. In this case, treat it offset 0. `eslint-plugin-sonarjs` reports errors with `loc` like this.
2026-01-28 02:04:25 +00:00
루밀LuMir a9bfbcfc4a fix(linter): compatibility issue with DiagnosticData type in ESLint (#18396)
Hi, this is my first contribution here, so I'm not sure whether opening
a PR directly is appropriate.

If anything is wrong, please let me know!

---

In this PR, I've corrected the `DiagnosticData` type to `Record<string,
string | number | boolean | bigint | null | undefined>;`

In ESLint v9.39.2 (which uses `@eslint/core@0.17.0`), this type was
widened to `Record<string, unknown>`.

Refs:

- https://github.com/eslint/rewrite/releases/tag/core-v0.17.0
- https://github.com/eslint/rewrite/pull/298

However, in the ESLint v10.0.0 pre-release (which uses
`@eslint/core@1.0.1`), this type have been narrowed to `Record<string,
string | number | boolean | bigint | null | undefined>;`.

Refs:

- https://github.com/eslint/rewrite/releases/tag/core-v1.0.1
- https://github.com/eslint/rewrite/pull/327

If the type's intention is to ensure maximum compatibility with any
ESLint version, then `Record<string, string | number | boolean | bigint
| null | undefined>` seems the most appropriate choice here.
2026-01-22 18:09:52 +00:00
overlookmotel a3914fd542 fix(linter/plugins): allow line number passed to report to be 1 over line count (#18341)
Loosen checks for `loc` passed to `report()`. Allow `line` to be 1 larger than number of lines in source, if `column` is 0. In this case, treat it as representing the end of the file.
2026-01-21 12:18:36 +00:00
overlookmotel 4d684483e7 fix(linter/plugins): report accept out of range column indexes in loc (#18199)
ESLint's `func-call-spacing` rule sometimes reports errors with `loc` containing `column: -1`. As ESLint doesn't complain, probably other plugins do the same too.

Make the checks for validity of `loc` in `report` more relaxed, to support this behavior.
2026-01-19 04:39:05 +00:00
overlookmotel da509be78a refactor(linter/plugins): convert global properties to vars with TSDown plugin, instead of manually (#16961)
Previously we had a pattern of destructuring properties of global objects into top-level vars. e.g.:

```js
const { keys: ObjectKeys, hasOwn } = Object,
  { isArray } = Array;
```

Doing this is more performant, but it makes the code harder to read.

Instead, write code normally, and use a TSDown plugin to convert:

```js
const keys = Object.keys(obj);
```

to:

```js
import { ObjectKeys } from "../utils/globals.ts";
const keys = ObjectKeys(obj);
```

Defining all the destructured globals in a single file (`utils/globals.ts`) is advantageous for bundle size. If the TSDown plugin created top level `const ObjectKeys = Object.keys;` statements in each file, then you can end up with this in bundle as minifier doesn't de-duplicate:

```js
const ObjectKeys = Object.keys;
const ObjectKeys$1 = Object.keys;
const ObjectKeys$2 = Object.keys;
```

The globals we use have to be manually added to `utils/globals.ts`, but TSDown plugin warns when this needs to be done, and doesn't generate a broken build in the meantime.

This plugin is run in debug builds too, so that the tests will catch any bugs.
2025-12-16 17:33:37 +00:00
overlookmotel eccffcf7da fix(linter/plugins): report() accept loc with no end (#16859)
Make `Context#report` accept multiple formats for `loc` property. These are all legal in ESLint:

```
{ start: { line, column }, end: { line, column } }
{ start: { line, column }, end: null }
{ start: { line, column }, end: undefined }
{ start: { line, column } }
{ line, column }
```
2025-12-14 21:19:28 +00:00
camc314 2acd66ed42 style(all): enable eslint/curly lint rule (#16753)
built on https://github.com/oxc-project/oxc/pull/16749, we can use the linter to be consistent here
2025-12-11 14:49:48 +00:00
overlookmotel 3f3d646280 refactor(linter/plugins): imports use .ts extension (#16390)
Pure refactor. Use `.ts` extension when importing `.ts` files.
2025-12-02 14:08:49 +00:00
overlookmotel 5da1a6326d feat(linter/plugins): introduce RuleTester (#16206)
Part of #16018.

Implement `RuleTester` class for testing rules. Has same API as ESLint's `RuleTester`.

A few features not implemented yet:

* Fixes are not executed, or checked against provided `output`.
* Suggestions are not checked (we don't yet have support for suggestions in JS plugins).
* No use of config provided through `RuleTester` class constructor or via `RuleTester.setDefaultConfig`.
2025-11-30 23:51:14 +00:00
overlookmotel 1af1091195 refactor(linter/plugins): store messageId in diagnostics (#16296)
Store `messageId` in `DiagnosticReport` objects. It's not required for sending to Rust, but it is needed for rule tester (#16206).

I think it's fine to add a little code that's redundant in the main runtime, because it only has an overhead when a rule produces diagnostics, which should be an uncommon path.
2025-11-30 23:51:13 +00:00
overlookmotel 9de386dc9f refactor(linter/plugins): move placeholder replacement into own function (#16302)
Pure refactor. Move placeholder replacement into it's own function, so it can also be used by rule tester (#16206).
2025-11-30 23:51:13 +00:00
overlookmotel cf249f5594 fix(linter/plugins): fix message interpolation (#16300)
Use the same RegExp as ESLint does.
2025-11-30 18:40:01 +00:00
overlookmotel 99281bcd36 refactor(linter/plugins): remove unnecessary type assertion (#16274)
This type assertion is unnecessary. Remove it.
2025-11-29 12:42:06 +00:00
Boshen 523a30a016 style(all): apply oxfmt default options (#16091)
Embrace the defaults!

---------

Co-authored-by: Yuji Sugiura <y.sugiura.0316@gmail.com>
2025-11-25 15:56:24 +09:00
overlookmotel a72b093b05 refactor(linter/plugins): enable TS strictNullChecks (#15886)
Adapted from #15868. Enable `strictNullChecks` in TSConfig for `apps/oxlint`.

Rather than using `!` all over the place, I've added a function `assertIsNonNull`, which performs the same function. Idea is that we can later on produce a debug build where `assertIsNonNull` does an actual runtime assertion (rather than just a TS `asserts`) that the value is not `null` or `undefined`. We can use the debug build in tests, and catch any logic errors.

Unfortunately, TypeScript doesn't seem able to track side effects, so there seems to be no way to tell it "after calling `initAst()`, `ast` is always non-null". Don't want to switch to a having a `getAst` function which returns a non-null value, as that'd introduce unnecessary temp vars, and function calls, on hot paths. So this seems to be the best we can do without incurring runtime cost.
2025-11-20 15:52:49 +00:00
overlookmotel 197f074436 refactor(linter/plugins): improve Diagnostic + Suggestion types (#15643)
Improve `Diagnostic` and `Suggestion` types, by using `RequireAtLeastOne` utility type from `type-fest` package, to enforce that:

* Either `message` or `messageId` property must be provided.
* Either `node` or `loc` property must be provided.

Change to TSDown config `dts: { resolve: true }` is get it to bundle `type-fest` into the `.d.ts` file.
2025-11-12 22:19:42 +00:00
overlookmotel 24d00f42d0 fix(linter/plugins): add types for suggested fixes (#15636)
Add `Suggestion` type, and `suggest` field to `Diagnostic`.

Suggestions are not implemented yet, but this completes the interface for diagnostics defined by ESLint's docs.
2025-11-12 15:15:59 +00:00
overlookmotel d2ff4baab2 refactor(linter/plugins): move report function and diagnostic types to separate file (#15635)
Pure refactor. Move `report` function and `Diagnostic` types into a separate file. `context.ts` was getting too long.
2025-11-12 15:15:58 +00:00