Skip to content

Commit 3f43d4c

Browse files
committed
fix(linter): accept bools as valid values for fixable (#18772)
fixes #17967 fixes #18700 closes #18011 This PR allows boolean values as valid options for meta.fixable. While this technically doesn't align exactly with eslint, it reduces some friction about getting users to migrate from exlint to oxlint, by increasing the number of plugins that are compatible.
1 parent 9862224 commit 3f43d4c

7 files changed

Lines changed: 134 additions & 2 deletions

File tree

apps/oxlint/src-js/plugins/load.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,17 @@ export function registerPlugin(
181181

182182
const { fixable } = ruleMeta;
183183
if (fixable != null) {
184-
if (fixable !== "code" && fixable !== "whitespace") {
184+
// `true` and `false` aren't valid values for `meta.fixable`, but we accept them for
185+
// backward compatibility with some ESLint plugins
186+
if (
187+
fixable !== "code" &&
188+
fixable !== "whitespace" &&
189+
fixable !== true &&
190+
fixable !== false
191+
) {
185192
throw new TypeError("Invalid `rule.meta.fixable`");
186193
}
187-
isFixable = true;
194+
isFixable = (fixable as "code" | "whitespace" | true | false) !== false;
188195
}
189196

190197
// If `schema` provided, compile schema to validator for applying schema defaults to options
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"jsPlugins": ["./plugin.ts"],
3+
"categories": {
4+
"correctness": "off"
5+
},
6+
"rules": {
7+
"fixable-boolean-plugin/no-debugger-true": "error",
8+
"fixable-boolean-plugin/no-console-false": "error"
9+
}
10+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
debugger;
2+
console.log("test");
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Exit code
2+
1
3+
4+
# stdout
5+
```
6+
x fixable-boolean-plugin(no-console-false): Console with fixable: false
7+
,-[files/index.js:2:1]
8+
1 | debugger;
9+
2 | console.log("test");
10+
: ^^^^^^^^^^^^^^^^^^^
11+
`----
12+
13+
Found 0 warnings and 1 error.
14+
Finished in Xms on 1 file with 2 rules using X threads.
15+
```
16+
17+
# stderr
18+
```
19+
WARNING: JS plugins are experimental and not subject to semver.
20+
Breaking changes are possible while JS plugins support is under development.
21+
```
22+
23+
# File altered: files/index.js
24+
```
25+
26+
console.log("test");
27+
28+
```
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"fix": true
3+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Exit code
2+
1
3+
4+
# stdout
5+
```
6+
x fixable-boolean-plugin(no-debugger-true): Debugger with fixable: true
7+
,-[files/index.js:1:1]
8+
1 | debugger;
9+
: ^^^^^^^^^
10+
2 | console.log("test");
11+
`----
12+
13+
x fixable-boolean-plugin(no-console-false): Console with fixable: false
14+
,-[files/index.js:2:1]
15+
1 | debugger;
16+
2 | console.log("test");
17+
: ^^^^^^^^^^^^^^^^^^^
18+
`----
19+
20+
Found 0 warnings and 2 errors.
21+
Finished in Xms on 1 file with 2 rules using X threads.
22+
```
23+
24+
# stderr
25+
```
26+
WARNING: JS plugins are experimental and not subject to semver.
27+
Breaking changes are possible while JS plugins support is under development.
28+
```
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { Plugin } from "#oxlint/plugin";
2+
3+
// Test backward compatibility for `meta.fixable: true` and `meta.fixable: false`
4+
// which some ESLint plugins use instead of "code" or "whitespace"
5+
const plugin: Plugin = {
6+
meta: {
7+
name: "fixable-boolean-plugin",
8+
},
9+
rules: {
10+
// Rule with fixable: true (backward compatibility)
11+
"no-debugger-true": {
12+
meta: {
13+
fixable: true as any,
14+
},
15+
create(context) {
16+
return {
17+
DebuggerStatement(node) {
18+
context.report({
19+
message: "Debugger with fixable: true",
20+
node,
21+
fix(fixer) {
22+
return fixer.remove(node);
23+
},
24+
});
25+
},
26+
};
27+
},
28+
},
29+
// Rule with fixable: false (backward compatibility)
30+
"no-console-false": {
31+
meta: {
32+
fixable: false as any,
33+
},
34+
create(context) {
35+
return {
36+
CallExpression(node) {
37+
if (
38+
node.callee.type === "MemberExpression" &&
39+
node.callee.object.type === "Identifier" &&
40+
node.callee.object.name === "console"
41+
) {
42+
context.report({
43+
message: "Console with fixable: false",
44+
node,
45+
});
46+
}
47+
},
48+
};
49+
},
50+
},
51+
},
52+
};
53+
54+
export default plugin;

0 commit comments

Comments
 (0)