Skip to content

Commit 29db060

Browse files
authored
fix(linter): detect typescript eslint alias rules (#7622)
closes #7233
1 parent 771c698 commit 29db060

6 files changed

Lines changed: 101 additions & 1 deletion

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"categories": {
3+
"correctness": "off"
4+
},
5+
"rules": {
6+
"no-magic-numbers": "error"
7+
}
8+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"plugins": ["typescript"],
3+
"categories": {
4+
"correctness": "off"
5+
},
6+
"rules": {
7+
"typescript/no-magic-numbers": "error"
8+
}
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
3+
const price = 200;
4+
const price_with_tax = price * 0.19; // taxes are expensive
5+
6+
console.debug(price_with_tax);

apps/oxlint/src/lint.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,4 +819,27 @@ mod test {
819819
assert_eq!(result.number_of_warnings, 0);
820820
assert_eq!(result.number_of_errors, 1);
821821
}
822+
823+
#[test]
824+
fn test_eslint_and_typescript_alias_rules() {
825+
let args = &[
826+
"-c",
827+
"fixtures/eslint_and_typescript_alias_rules/oxlint-eslint.json",
828+
"fixtures/eslint_and_typescript_alias_rules/test.js",
829+
];
830+
let result = test(args);
831+
assert_eq!(result.number_of_files, 1);
832+
assert_eq!(result.number_of_warnings, 0);
833+
assert_eq!(result.number_of_errors, 1);
834+
835+
let args = &[
836+
"-c",
837+
"fixtures/eslint_and_typescript_alias_rules/oxlint-typescript.json",
838+
"fixtures/eslint_and_typescript_alias_rules/test.js",
839+
];
840+
let result = test(args);
841+
assert_eq!(result.number_of_files, 1);
842+
assert_eq!(result.number_of_warnings, 0);
843+
assert_eq!(result.number_of_errors, 1);
844+
}
822845
}

crates/oxc_linter/src/config/rules.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use serde::{
1111

1212
use crate::{
1313
rules::{RuleEnum, RULES},
14-
utils::is_jest_rule_adapted_to_vitest,
14+
utils::{is_eslint_rule_adapted_to_typescript, is_jest_rule_adapted_to_vitest},
1515
AllowWarnDeny, RuleWithSeverity,
1616
};
1717

@@ -155,6 +155,10 @@ fn transform_rule_and_plugin_name<'a>(
155155
return (rule_name, "jest");
156156
}
157157

158+
if plugin_name == "typescript" && is_eslint_rule_adapted_to_typescript(rule_name) {
159+
return (rule_name, "eslint");
160+
}
161+
158162
(rule_name, plugin_name)
159163
}
160164

crates/oxc_linter/src/utils/mod.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,63 @@ const VITEST_COMPATIBLE_JEST_RULES: phf::Set<&'static str> = phf::phf_set! {
3434
"valid-expect",
3535
};
3636

37+
// List of Eslint rules that have Typescript equivalents.
38+
const TYPESCRIPT_COMPATIBLE_ESLINT_RULES: phf::Set<&'static str> = phf::phf_set! {
39+
"class-methods-use-this",
40+
"default-param-last",
41+
"init-declarations",
42+
"max-params",
43+
"no-array-constructor",
44+
"no-dupe-class-members",
45+
"no-empty-function",
46+
"no-invalid-this",
47+
"no-loop-func",
48+
"no-loss-of-precision",
49+
"no-magic-numbers",
50+
"no-redeclare",
51+
"no-restricted-imports",
52+
"no-shadow",
53+
"no-unused-expressions",
54+
"no-unused-vars",
55+
"no-use-before-define",
56+
"no-useless-constructor",
57+
58+
// these rules are equivalents, but not supported
59+
// "block-spacing",
60+
// "brace-style",
61+
// "comma-dangle",
62+
// "comma-spacing",
63+
// "func-call-spacing",
64+
// "indent",
65+
// "key-spacing",
66+
// "keyword-spacing",
67+
// "lines-around-comment",
68+
// "lines-between-class-members",
69+
// "no-extra-parens",
70+
// "no-extra-semi",
71+
// "object-curly-spacing",
72+
// "padding-line-between-statements",
73+
// "quotes",
74+
// "semi",
75+
// "space-before-blocks",
76+
// "space-before-function-paren",
77+
// "space-infix-ops",
78+
};
79+
3780
/// Check if the Jest rule is adapted to Vitest.
3881
/// Many Vitest rule are essentially ports of Jest plugin rules with minor modifications.
3982
/// For these rules, we use the corresponding jest rules with some adjustments for compatibility.
4083
pub fn is_jest_rule_adapted_to_vitest(rule_name: &str) -> bool {
4184
VITEST_COMPATIBLE_JEST_RULES.contains(rule_name)
4285
}
4386

87+
/// Check if the Eslint rule is adapted to Typescript.
88+
/// Many Typescript rule are essentially ports of Eslint plugin rules with minor modifications.
89+
/// For these rules, we use the corresponding eslint rules with some adjustments for compatibility.
90+
pub fn is_eslint_rule_adapted_to_typescript(rule_name: &str) -> bool {
91+
TYPESCRIPT_COMPATIBLE_ESLINT_RULES.contains(rule_name)
92+
}
93+
4494
pub fn read_to_string(path: &Path) -> io::Result<String> {
4595
// `simdutf8` is faster than `std::str::from_utf8` which `fs::read_to_string` uses internally
4696
let bytes = std::fs::read(path)?;

0 commit comments

Comments
 (0)