Commit Graph

21 Commits

Author SHA1 Message Date
overlookmotel 0861d9a5c8 fix(linter/plugins): remove getters from Context (#20115)
Fix an incompatibility with `eslint-plugin-jsdoc`. It relies on properties of `context` being values rather than getters:

https://github.com/gajus/eslint-plugin-jsdoc/blob/26276d428631a2625575607cba7875dab6797091/src/buildForbidRuleDefinition.js#L86-L103

When `options` property is a getter, this code throws an error because it attempts to define a property with both `value` and `get` in its descriptor.

This PR replaces the `id` and `options` getters with value properties.

The getters were there to prevent the `Context` object from being mutated by rule code, and allow the object to be frozen, as it is in ESLint. But each rule gets its own `Context` object, so if it chooses to mutate it, it only harms itself, and can't impact other rules/plugins. In ESLint, trying to alter the frozen `Context` object would be a hard error, so it's doubtful that any ESLint plugins do this anyway.

This is no real downside to this change for us, so we might as well make the change, and fix `eslint-plugin-jsdoc` and any other plugins which may depend on ESLint's behavior here.
2026-03-08 17:27:52 +00:00
camc314 d4b0324ac2 refactor(oxlint): enable useUnknownInCatchVariables tsconfig setting (#19141) 2026-02-09 13:54:38 +00:00
overlookmotel 9de9385fd1 refactor(linter/plugins): rename oxlint/plugin to oxlint/plugins (#18792)
Part of #18610.

Our intent is to move `definePlugin`, `defineRule`, and `eslintCompatPlugin` to a separate package `@oxlint/plugins` (plural to avoid confusion with naming convention for plugins `oxlint-plugin-xxx`).

So rename the current entry point which exports these functions from `oxlint/plugin` to `oxlint/plugins` (plural).
2026-02-01 13:23:14 +00:00
overlookmotel 2e1fbc2238 fix(linter/plugins): implement context.parserPath (#18644)
Closes #18119. Implement `context.parserPath`. It evaluates to `undefined`, same as what ESLint does by default.
2026-01-28 02:26:55 +00:00
camc314 81eb6fa9db refactor(linter): split entry points for custom plugins/config/types (#18601)
This is technically breaking (only for types), but custom plugins are experimental.

The ruletester/defineRule/definePlugin are re-exported but with a `@deprecated` tag which I think is a good enough trade off

I want to avoid users bringing in a ton of custom plugin code when doing `import { defineConfig } from 'oxlint'`
2026-01-27 00:58:08 +00:00
overlookmotel 3a0a190d2c fix(linter/plugins)!: prevent access to cwd in createOnce (#18081)
Supporting JS plugins in LSP requires that different workspaces have a different value for `Context#cwd`.

As a first step, prevent accessing `cwd` property, or calling `getCwd` method in `createOnce`. Later on, we can make `cwd` a dynamic property.
2026-01-16 15:49:07 +00:00
overlookmotel d44c6316bc style(linter/plugins): shorten code with destructuring (#16446)
Pure style change.

Came across these while testing ESLint's `prefer-destructuring` rule running as a JS plugin.
2025-12-03 14:20:59 +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 690abec235 test(linter/plugins): use subpath imports (#15920)
Shorten imports in test fixtures using [subpath imports](https://nodejs.org/docs/latest-v24.x/api/packages.html#subpath-imports).

Before:

```ts
import type { Plugin } from '../../../dist/index.js';
```

After:

```ts
import type { Plugin } from '#oxlint';
```
2025-11-21 11:44:25 +00:00
overlookmotel 4e844c1927 test(linter/plugins): add tests for new Context methods (#15656)
Add test coverage for methods and getters on `Context` added in #15606 and #15632. I neglected to add tests in those PRs. Disgraceful.
2025-11-12 23:56:03 +00:00
overlookmotel def251dee0 test(linter/plugins): remove unused imports from fixtures (#15655)
Pure refactor to tests. These imports are no longer used. Remove them.
2025-11-12 23:49:48 +00:00
overlookmotel 6957fb9a39 fix(linter/plugins): do not allow access to Context#id in createOnce (#15489)
Revert #15447. It's easy to allow `Context#id` to be accessed in `createOnce` when running rule in Oxlint, but not possible to do in ESLint compat mode with current API, because `id` isn't a property of the rule, so `defineRule` doesn't know it.

We could support it by making `definePlugin` compulsory for ESLint interop, and get it to set `id` property on `Context` objects properly.

But that's a bit tricky, so just disable access for now. It's probably not very useful anyway - a rule should know what its own name is!
2025-11-08 14:46:46 +00:00
overlookmotel c4c29a3d14 test(linter/plugins): fix test snapshots on Windows (#15451)
Follow-on after #15424. Fix the snapshots on Windows. I missed one slash!

Also, convert paths wrapped in quotes e.g. `file path: '/path/to/oxc/apps/oxlint/test/fixtures/blah/files/foo.js'`.

I've had to hack one fixture (`createOnce`) to get diagnostics to be printed in same order on all platforms. Otherwise they get printed out of order on Windows: https://github.com/oxc-project/oxc/actions/runs/19180329507/job/54835252163?pr=15451#step:8:419.

Presumably this is because on Windows the file path `D:\...` is sorted after `Cannot access`, whereas on Mac/Linux, file path `/` is sorted before `Cannot access`. However, I'm unclear why the prefixes `before hook:`, `after hook:` etc aren't included in sorting. If they were, this problem wouldn't arise.
2025-11-07 21:32:30 +00:00
overlookmotel 981cbc59c9 refactor(linter/plugins): allow accessing context.id in createOnce (#15447)
Previously we blocked accessing `context.id` (rule name) in `createOnce`. There's no need to be so restrictive, as it's a static value, and not file-specific. Relax this restriction.
2025-11-07 19:43:56 +00:00
overlookmotel 075079cc9c test(linter/plugins): improve reliability of replacing paths in output (#15424)
When replacing absolute paths in fixture snapshots, replace paths anywhere in the output, rather than only in certain specified patterns.

Additionally, introduce `<fixtures>` and `<fixture>` replacements to shorten paths in snapshots.

```diff
- File path: <root>/apps/oxlint/test/fixtures/fixture_name/files/1.js
+ File path: <fixture>/files/1.js
- File path: <root>/apps/oxlint/test/fixtures
+ File path: <fixtures>
```

This allows removing the `relativePath` helper function from some test plugins, outputting paths (e.g. `cwd`) anywhere, and generally will avoid problems with snapshots being system-dependent, and dependent on directory layout of fixtures.

Also, amend ESLint `stdout` output in snapshots to align all rule names, to reduce churn in snapshots, and avoid mismatches between local and CI (presumably due to differences in terminal width).

```diff
- filename: <fixture>/files/1.js                              define-plugin-plugin/create-once
- filename: <fixture>/files/long_filename.js                              define-plugin-plugin/create-once
- filename: <fixture>/files/very_long_filename.js                              define-plugin-plugin/create-once
+ filename: <fixture>/files/1.js                                 define-plugin-plugin/create-once
+ filename: <fixture>/files/long_filename.js                     define-plugin-plugin/create-once
+ filename: <fixture>/files/very_long_filename.js                define-plugin-plugin/create-once
```
2025-11-07 12:28:48 +00:00
overlookmotel fde753e023 fix(linter/plugins): block access to context.settings in createOnce (#15394)
Follow-on after #14724. Prevent accessing `context.settings` in `createOnce`. Settings are per-file, so they shouldn't be available in `createOnce`.
2025-11-06 17:33:57 +00:00
overlookmotel 96663fbaab fix(linter/plugins): do not call before hook if empty visitor (#14401)
If rule is defined using `createOnce`, and it returns an empty visitor (`before` / `after` hooks only), then don't run the hooks - the rule is a no-op.

Reason this is important is forward-compatibility with an optimization we could make where we calculate on Rust side whether AST contains any nodes that rules act on, and if it doesn't, skip calling into JS entirely. In that case, the `before` hook wouldn't run on those files.

We can't emulate that behavior entirely, but we can at least avoid users creating rules which *only* contain a `before` hook, and then finding that when we apply that optimization later on, it stops behaving as expected.

i.e. we make the `before` hook never be called for a rule defined like this:

```js
export default {
  createOnce(context) {
    return {
      before() {
        if (content.filename.endsWith('.tsx') {
          context.report({ message: 'No TSX!', node: context.sourceCode.ast });
        }
      },
    };
  },
};
```
2025-10-07 09:43:21 +00:00
overlookmotel a2914fe8d8 feat(linter/plugins): add loc field getter to all AST nodes (#14355)
Add `loc` to all AST nodes.

`loc` is computed lazily, as it's quite an expensive operation - because it requires searching the source text for line breaks and building a translation table.

We can consider making `loc` a "real" property once we have a faster translation table built on Rust side.
2025-10-05 14:02:12 +00:00
overlookmotel 5505a86121 feat(linter/plugins): include range field in AST (#14321)
Add `range` field to AST nodes, using the support for `range` in raw transfer added in #14319.

Use `range` field rather than `start` + `end` in nodes passed to `context.report` and fixer methods - for closer alignment with ESLint.
2025-10-04 15:47:47 +00:00
overlookmotel bdf901033e feat(linter/plugins): add SourceCode API (#14281)
Add support for ESLint's `SourceCode` API. At present the only method on `SourceCode` is `getText`. More methods will be added in further PRs to follow.
2025-10-01 16:36:28 +00:00
overlookmotel a9b603eb24 test(linter/plugins): convert all plugins in tests to TS (#14200)
Convert all plugins in test fixtures to TS, so can check the types work correctly.
2025-09-28 18:17:49 +01:00