Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions apps/oxlint/src-js/plugins/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ const registeredPluginPaths = new Set<string>();
// Indexed by `ruleId`, which is passed to `lintFile`.
export const registeredRules: RuleAndContext[] = [];

// `before` hook which makes rule never run.
const neverRunBeforeHook: BeforeHook = () => false;

// Plugin details returned to Rust
interface PluginDetails {
// Plugin name
Expand Down Expand Up @@ -146,6 +149,19 @@ async function loadPluginImpl(path: string): Promise<PluginDetails> {
beforeHook = conformHookFn(beforeHook, 'before');
afterHook = conformHookFn(afterHook, 'after');

// If empty visitor, make this rule never run by substituting a `before` hook which always returns `false`.
// This means the original `before` hook won't run either.
//
// Reason for doing this is:
// In future, we may do a check on Rust side whether AST contains any nodes which rules act on,
// and if not, skip calling into JS entirely. In that case, the `before` hook won't get called.
// We can't emulate that behavior exactly, but we can at least emulate it in this simple case,
// and prevent users defining rules with *only* a `before` hook, which they expect to run on every file.
if (ObjectKeys(visitor).length === 0) {
beforeHook = neverRunBeforeHook;
afterHook = null;
}

ruleAndContext = { rule, context, visitor, beforeHook, afterHook };
} else {
ruleAndContext = { rule, context, visitor: null, beforeHook: null, afterHook: null };
Expand Down
1 change: 1 addition & 0 deletions apps/oxlint/test/fixtures/createOnce/.oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"create-once-plugin/skip-run": "error",
"create-once-plugin/before-only": "error",
"create-once-plugin/after-only": "error",
"create-once-plugin/only-hooks": "error",
"create-once-plugin/no-hooks": "error"
}
}
15 changes: 15 additions & 0 deletions apps/oxlint/test/fixtures/createOnce/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ const afterOnlyRule: Rule = {
},
};

const hooksOnlyRule: Rule = {
createOnce(context) {
return {
// Neither hook should be called, because no AST node visitor functions
before() {
context.report({ message: 'before hook: should not be output', node: SPAN });
},
after() {
context.report({ message: 'after hook: should not be output', node: SPAN });
},
};
},
};

const noHooksRule: Rule = {
createOnce(context) {
return {
Expand All @@ -139,6 +153,7 @@ const plugin: Plugin = {
'skip-run': skipRunRule,
'before-only': beforeOnlyRule,
'after-only': afterOnlyRule,
'only-hooks': hooksOnlyRule,
'no-hooks': noHooksRule,
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
x Error running JS plugin.
| File path: <root>/apps/oxlint/test/fixtures/custom_plugin_lint_after_hook_error/files/index.js
| Error: Whoops!
| at after (<root>/apps/oxlint/test/fixtures/custom_plugin_lint_after_hook_error/plugin.ts:12:19)
| at after (<root>/apps/oxlint/test/fixtures/custom_plugin_lint_after_hook_error/plugin.ts:13:19)

Found 0 warnings and 1 error.
Finished in Xms on 1 file using X threads.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const plugin: Plugin = {
error: {
createOnce(_context) {
return {
Program(_program) {},
after() {
throw new Error('Whoops!');
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const plugin: Plugin = {
before() {
throw new Error('Whoops!');
},
Program(_program) {},
};
},
},
Expand Down
30 changes: 1 addition & 29 deletions apps/oxlint/test/fixtures/definePlugin/output.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,6 @@
: ^
`----

x define-plugin-plugin(create-once-hooks-only): before hook:
| filename: files/1.js
,-[files/1.js:1:1]
1 | let a, b;
: ^
`----

x define-plugin-plugin(create-once-hooks-only): after hook:
| filename: files/1.js
,-[files/1.js:1:1]
1 | let a, b;
: ^
`----

x define-plugin-plugin(create): ident visit fn "a":
| filename: files/1.js
,-[files/1.js:1:5]
Expand Down Expand Up @@ -186,20 +172,6 @@
: ^
`----

x define-plugin-plugin(create-once-hooks-only): before hook:
| filename: files/2.js
,-[files/2.js:1:1]
1 | let c, d;
: ^
`----

x define-plugin-plugin(create-once-hooks-only): after hook:
| filename: files/2.js
,-[files/2.js:1:1]
1 | let c, d;
: ^
`----

x define-plugin-plugin(create): ident visit fn "c":
| filename: files/2.js
,-[files/2.js:1:5]
Expand Down Expand Up @@ -286,7 +258,7 @@
: ^
`----

Found 0 warnings and 39 errors.
Found 0 warnings and 35 errors.
Finished in Xms on 2 files using X threads.
```

Expand Down
1 change: 1 addition & 0 deletions apps/oxlint/test/fixtures/definePlugin/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ const createOnceAfterOnlyRule: Rule = {
const createOnceHooksOnlyRule: Rule = {
createOnce(context) {
return {
// Neither hook should be called, because no AST node visitor functions
before() {
context.report({
message: 'before hook:\n' +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,6 @@
: ^
`----

x define-plugin-and-rule-plugin(create-once-hooks-only): before hook:
| filename: files/1.js
,-[files/1.js:1:1]
1 | let a, b;
: ^
`----

x define-plugin-and-rule-plugin(create-once-hooks-only): after hook:
| filename: files/1.js
,-[files/1.js:1:1]
1 | let a, b;
: ^
`----

x define-plugin-and-rule-plugin(create): ident visit fn "a":
| filename: files/1.js
,-[files/1.js:1:5]
Expand Down Expand Up @@ -186,20 +172,6 @@
: ^
`----

x define-plugin-and-rule-plugin(create-once-hooks-only): before hook:
| filename: files/2.js
,-[files/2.js:1:1]
1 | let c, d;
: ^
`----

x define-plugin-and-rule-plugin(create-once-hooks-only): after hook:
| filename: files/2.js
,-[files/2.js:1:1]
1 | let c, d;
: ^
`----

x define-plugin-and-rule-plugin(create): ident visit fn "c":
| filename: files/2.js
,-[files/2.js:1:5]
Expand Down Expand Up @@ -286,7 +258,7 @@
: ^
`----

Found 0 warnings and 39 errors.
Found 0 warnings and 35 errors.
Finished in Xms on 2 files using X threads.
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ const createOnceAfterOnlyRule = defineRule({
const createOnceHooksOnlyRule = defineRule({
createOnce(context) {
return {
// Neither hook should be called, because no AST node visitor functions
before() {
context.report({
message: 'before hook:\n' +
Expand Down
30 changes: 1 addition & 29 deletions apps/oxlint/test/fixtures/defineRule/output.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,6 @@
: ^
`----

x define-rule-plugin(create-once-hooks-only): before hook:
| filename: files/1.js
,-[files/1.js:1:1]
1 | let a, b;
: ^
`----

x define-rule-plugin(create-once-hooks-only): after hook:
| filename: files/1.js
,-[files/1.js:1:1]
1 | let a, b;
: ^
`----

x define-rule-plugin(create): ident visit fn "a":
| filename: files/1.js
,-[files/1.js:1:5]
Expand Down Expand Up @@ -186,20 +172,6 @@
: ^
`----

x define-rule-plugin(create-once-hooks-only): before hook:
| filename: files/2.js
,-[files/2.js:1:1]
1 | let c, d;
: ^
`----

x define-rule-plugin(create-once-hooks-only): after hook:
| filename: files/2.js
,-[files/2.js:1:1]
1 | let c, d;
: ^
`----

x define-rule-plugin(create): ident visit fn "c":
| filename: files/2.js
,-[files/2.js:1:5]
Expand Down Expand Up @@ -286,7 +258,7 @@
: ^
`----

Found 0 warnings and 39 errors.
Found 0 warnings and 35 errors.
Finished in Xms on 2 files using X threads.
```

Expand Down
1 change: 1 addition & 0 deletions apps/oxlint/test/fixtures/defineRule/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ const createOnceAfterOnlyRule = defineRule({
const createOnceHooksOnlyRule = defineRule({
createOnce(context) {
return {
// Neither hook should be called, because no AST node visitor functions
before() {
context.report({
message: 'before hook:\n' +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const SPAN: Node = {
const createOnceRule: Rule = {
createOnce(context) {
return {
Program(_program) {},
after() {
context.report({
message: 'after:\n' +
Expand Down
Loading