Skip to content

Commit d16df93

Browse files
committed
feat(linter): support disable directives for type aware rules (#14052)
fixes #13941
1 parent fa3712d commit d16df93

17 files changed

+770
-146
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Test file for disable directives with type-aware rules
2+
const myPromise = new Promise(() => {})
3+
4+
// Test oxlint-disable-next-line
5+
// oxlint-disable-next-line typescript/no-floating-promises
6+
myPromise
7+
8+
// Test eslint-disable-next-line with @typescript-eslint prefix
9+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
10+
myPromise
11+
12+
// Test oxlint-disable/enable block
13+
/* oxlint-disable typescript/no-floating-promises */
14+
myPromise
15+
myPromise
16+
/* oxlint-enable typescript/no-floating-promises */
17+
18+
// This should still report an error (no disable directive)
19+
myPromise
20+
21+
// Test with different rule name formats
22+
// oxlint-disable-next-line no-floating-promises
23+
myPromise
24+
25+
// eslint-disable-next-line typescript-eslint/no-floating-promises
26+
myPromise
27+
28+
// Test disable-line variant
29+
myPromise // oxlint-disable-line typescript/no-floating-promises
30+
31+
// Multiple promises in one block
32+
/* eslint-disable @typescript-eslint/no-floating-promises */
33+
Promise.resolve(1)
34+
Promise.resolve(2)
35+
Promise.resolve(3)
36+
/* eslint-enable @typescript-eslint/no-floating-promises */
37+
38+
// Should report error
39+
Promise.resolve(4)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2020",
4+
"module": "esnext",
5+
"strict": true,
6+
"esModuleInterop": true,
7+
"skipLibCheck": true,
8+
"forceConsistentCasingInFileNames": true
9+
}
10+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Test unused disable directives with type-aware rules
2+
const myPromise = new Promise(() => {})
3+
4+
// This disable directive is USED (suppresses the error below)
5+
// oxlint-disable-next-line typescript/no-floating-promises
6+
myPromise
7+
8+
// This disable directive is UNUSED (no error to suppress)
9+
// oxlint-disable-next-line typescript/no-floating-promises
10+
console.log("hello")
11+
12+
// This disable directive is UNUSED (wrong rule name)
13+
// oxlint-disable-next-line typescript/no-unsafe-assignment
14+
myPromise
15+
16+
// This disable directive is USED
17+
/* eslint-disable @typescript-eslint/no-floating-promises */
18+
myPromise
19+
/* eslint-enable @typescript-eslint/no-floating-promises */
20+
21+
// This disable directive is UNUSED (no floating promise here)
22+
/* eslint-disable @typescript-eslint/no-floating-promises */
23+
const x = 1 + 2
24+
/* eslint-enable @typescript-eslint/no-floating-promises */

apps/oxlint/src/lint.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,18 @@ impl CliRunner {
373373
None
374374
};
375375

376-
if let Err(err) = lint_runner.lint_files(&files_to_lint, tx_error, file_system) {
377-
print_and_flush_stdout(stdout, &err);
378-
return CliRunResult::TsGoLintError;
376+
match lint_runner.lint_files(&files_to_lint, tx_error.clone(), file_system) {
377+
Ok(lint_runner) => {
378+
lint_runner.report_unused_directives(report_unused_directives, &tx_error);
379+
}
380+
Err(err) => {
381+
print_and_flush_stdout(stdout, &err);
382+
return CliRunResult::TsGoLintError;
383+
}
379384
}
380385

386+
drop(tx_error);
387+
381388
let diagnostic_result = diagnostic_service.run(stdout);
382389

383390
if let Some(end) = output_formatter.lint_command_info(&LintCommandInfo {
@@ -1298,4 +1305,24 @@ mod test {
12981305
let args = &["--type-aware", "test.svelte"];
12991306
Tester::new().with_cwd("fixtures/tsgolint".into()).test_and_snapshot(args);
13001307
}
1308+
1309+
#[cfg(not(target_endian = "big"))]
1310+
#[test]
1311+
fn test_tsgolint_unused_disable_directives() {
1312+
// Test that unused disable directives are reported with type-aware rules
1313+
let args = &["--type-aware", "--report-unused-disable-directives", "unused.ts"];
1314+
Tester::new()
1315+
.with_cwd("fixtures/tsgolint_disable_directives".into())
1316+
.test_and_snapshot(args);
1317+
}
1318+
1319+
#[cfg(not(target_endian = "big"))]
1320+
#[test]
1321+
fn test_tsgolint_disable_directives() {
1322+
// Test that disable directives work with type-aware rules
1323+
let args = &["--type-aware", "test.ts"];
1324+
Tester::new()
1325+
.with_cwd("fixtures/tsgolint_disable_directives".into())
1326+
.test_and_snapshot(args);
1327+
}
13011328
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
source: apps/oxlint/src/tester.rs
3+
---
4+
##########
5+
arguments: --type-aware --report-unused-disable-directives unused.ts
6+
working directory: fixtures/tsgolint_disable_directives
7+
----------
8+
9+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
10+
,-[unused.ts:6:1]
11+
5 | // oxlint-disable-next-line typescript/no-floating-promises
12+
6 | myPromise
13+
: ^^^^^^^^^
14+
7 |
15+
`----
16+
help: Consider using this expression or removing it
17+
18+
! Unused eslint-disable directive (no problems were reported).
19+
,-[unused.ts:9:3]
20+
8 | // This disable directive is UNUSED (no error to suppress)
21+
9 | // oxlint-disable-next-line typescript/no-floating-promises
22+
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
10 | console.log("hello")
24+
`----
25+
26+
! Unused eslint-disable directive (no problems were reported).
27+
,-[unused.ts:13:3]
28+
12 | // This disable directive is UNUSED (wrong rule name)
29+
13 | // oxlint-disable-next-line typescript/no-unsafe-assignment
30+
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
14 | myPromise
32+
`----
33+
34+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
35+
,-[unused.ts:14:1]
36+
13 | // oxlint-disable-next-line typescript/no-unsafe-assignment
37+
14 | myPromise
38+
: ^^^^^^^^^
39+
15 |
40+
`----
41+
help: Consider using this expression or removing it
42+
43+
! typescript-eslint(no-floating-promises): Promises must be awaited.
44+
,-[unused.ts:14:1]
45+
13 | // oxlint-disable-next-line typescript/no-unsafe-assignment
46+
14 | myPromise
47+
: ^^^^^^^^^
48+
15 |
49+
`----
50+
help: The promise must end with a call to .catch, or end with a call to .then with a rejection handler, or be explicitly marked as ignored with the `void` operator.
51+
52+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
53+
,-[unused.ts:18:1]
54+
17 | /* eslint-disable @typescript-eslint/no-floating-promises */
55+
18 | myPromise
56+
: ^^^^^^^^^
57+
19 | /* eslint-enable @typescript-eslint/no-floating-promises */
58+
`----
59+
help: Consider using this expression or removing it
60+
61+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html\eslint(no-unused-vars)]8;;\: Variable 'x' is declared but never used. Unused variables should start with a '_'.
62+
,-[unused.ts:23:7]
63+
22 | /* eslint-disable @typescript-eslint/no-floating-promises */
64+
23 | const x = 1 + 2
65+
: |
66+
: `-- 'x' is declared here
67+
24 | /* eslint-enable @typescript-eslint/no-floating-promises */
68+
`----
69+
help: Consider removing this declaration.
70+
71+
! Unused eslint-disable directive (no problems were reported).
72+
,-[unused.ts:24:3]
73+
23 | const x = 1 + 2
74+
24 | /* eslint-enable @typescript-eslint/no-floating-promises */
75+
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76+
`----
77+
78+
Found 8 warnings and 0 errors.
79+
Finished in <variable>ms on 1 file with 103 rules using 1 threads.
80+
----------
81+
CLI result: LintSucceeded
82+
----------
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
source: apps/oxlint/src/tester.rs
3+
---
4+
##########
5+
arguments: --type-aware test.ts
6+
working directory: fixtures/tsgolint_disable_directives
7+
----------
8+
9+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
10+
,-[test.ts:6:1]
11+
5 | // oxlint-disable-next-line typescript/no-floating-promises
12+
6 | myPromise
13+
: ^^^^^^^^^
14+
7 |
15+
`----
16+
help: Consider using this expression or removing it
17+
18+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
19+
,-[test.ts:10:1]
20+
9 | // eslint-disable-next-line @typescript-eslint/no-floating-promises
21+
10 | myPromise
22+
: ^^^^^^^^^
23+
11 |
24+
`----
25+
help: Consider using this expression or removing it
26+
27+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
28+
,-[test.ts:14:1]
29+
13 | /* oxlint-disable typescript/no-floating-promises */
30+
14 | myPromise
31+
: ^^^^^^^^^
32+
15 | myPromise
33+
`----
34+
help: Consider using this expression or removing it
35+
36+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
37+
,-[test.ts:15:1]
38+
14 | myPromise
39+
15 | myPromise
40+
: ^^^^^^^^^
41+
16 | /* oxlint-enable typescript/no-floating-promises */
42+
`----
43+
help: Consider using this expression or removing it
44+
45+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
46+
,-[test.ts:19:1]
47+
18 | // This should still report an error (no disable directive)
48+
19 | myPromise
49+
: ^^^^^^^^^
50+
20 |
51+
`----
52+
help: Consider using this expression or removing it
53+
54+
! typescript-eslint(no-floating-promises): Promises must be awaited.
55+
,-[test.ts:19:1]
56+
18 | // This should still report an error (no disable directive)
57+
19 | myPromise
58+
: ^^^^^^^^^
59+
20 |
60+
`----
61+
help: The promise must end with a call to .catch, or end with a call to .then with a rejection handler, or be explicitly marked as ignored with the `void` operator.
62+
63+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
64+
,-[test.ts:23:1]
65+
22 | // oxlint-disable-next-line no-floating-promises
66+
23 | myPromise
67+
: ^^^^^^^^^
68+
24 |
69+
`----
70+
help: Consider using this expression or removing it
71+
72+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
73+
,-[test.ts:26:1]
74+
25 | // eslint-disable-next-line typescript-eslint/no-floating-promises
75+
26 | myPromise
76+
: ^^^^^^^^^
77+
27 |
78+
`----
79+
help: Consider using this expression or removing it
80+
81+
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-expressions.html\eslint(no-unused-expressions)]8;;\: Expected expression to be used
82+
,-[test.ts:29:1]
83+
28 | // Test disable-line variant
84+
29 | myPromise // oxlint-disable-line typescript/no-floating-promises
85+
: ^^^^^^^^^
86+
30 |
87+
`----
88+
help: Consider using this expression or removing it
89+
90+
! typescript-eslint(no-floating-promises): Promises must be awaited.
91+
,-[test.ts:39:1]
92+
38 | // Should report error
93+
39 | Promise.resolve(4)
94+
: ^^^^^^^^^^^^^^^^^^
95+
`----
96+
help: The promise must end with a call to .catch, or end with a call to .then with a rejection handler, or be explicitly marked as ignored with the `void` operator.
97+
98+
Found 10 warnings and 0 errors.
99+
Finished in <variable>ms on 1 file with 103 rules using 1 threads.
100+
----------
101+
CLI result: LintSucceeded
102+
----------

0 commit comments

Comments
 (0)