Skip to content

Commit

Permalink
feat(linter): add support for same rule name but different plugin nam…
Browse files Browse the repository at this point in the history
…es (#1992)

e.g.

```
{
  "rules": {
    "semi": "off",
    "@typescript-eslint/semi": "error"
  }
}
```

closes #1975
  • Loading branch information
Boshen authored Jan 11, 2024
1 parent b7ea4e5 commit fb5d0a7
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 20 deletions.
6 changes: 6 additions & 0 deletions crates/oxc_cli/fixtures/typescript_eslint/eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"rules": {
"no-loss-of-precision": "off",
"@typescript-eslint/no-loss-of-precision": "error"
}
}
1 change: 1 addition & 0 deletions crates/oxc_cli/fixtures/typescript_eslint/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9007199254740993 // no-loss-of-precision
13 changes: 13 additions & 0 deletions crates/oxc_cli/src/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,19 @@ mod test {
assert_eq!(result.number_of_errors, 0);
}

#[test]
fn typescript_eslint() {
let args = &[
"-c",
"fixtures/typescript_eslint/eslintrc.json",
"fixtures/typescript_eslint/test.js",
];
let result = test(args);
assert_eq!(result.number_of_files, 1);
assert_eq!(result.number_of_warnings, 1);
assert_eq!(result.number_of_errors, 0);
}

#[test]
fn lint_vue_file() {
let args = &["fixtures/vue/debugger.vue"];
Expand Down
63 changes: 44 additions & 19 deletions crates/oxc_linter/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,41 +68,66 @@ impl ESLintConfig {
})
}

#[allow(clippy::option_if_let_else)]
pub fn override_rules(
&self,
rules_to_override: &mut FxHashSet<RuleEnum>,
rules_for_override: &mut FxHashSet<RuleEnum>,
all_rules: &[RuleEnum],
) {
use itertools::Itertools;
let mut rules_to_replace = vec![];
let mut rules_to_remove = vec![];

for rule_to_configure in &self.rules {
let (plugin_name, rule_name) =
(&rule_to_configure.plugin_name, &rule_to_configure.rule_name);
if let Some(rule) = rules_to_override
.iter()
.find(|r| r.plugin_name() == plugin_name && r.name() == rule_name)
{
match rule_to_configure.severity {
AllowWarnDeny::Warn | AllowWarnDeny::Deny => {
rules_to_replace.push(rule.read_json(rule_to_configure.config.clone()));
// Rules can have the same name but different plugin names
let lookup = self.rules.iter().into_group_map_by(|r| r.rule_name.as_str());

for (name, rule_configs) in &lookup {
match rule_configs.len() {
0 => unreachable!(),
1 => {
let rule_config = &rule_configs[0];
let rule_name = &rule_config.rule_name;
let plugin_name = &rule_config.plugin_name;
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == rule_name) {
match rule_config.severity {
AllowWarnDeny::Warn | AllowWarnDeny::Deny => {
rules_to_replace.push(rule.read_json(rule_config.config.clone()));
}
AllowWarnDeny::Allow => {
rules_to_remove.push(rule.clone());
}
}
} else if let Some(rule) = all_rules
.iter()
.find(|r| r.plugin_name() == plugin_name && r.name() == rule_name)
{
rules_to_replace.push(rule.read_json(rule_config.config.clone()));
}
AllowWarnDeny::Allow => {
rules_to_remove.push(rule.clone());
}
_ => {
// For overlapping rule names, use the "error" one
// "no-loss-of-precision": "off",
// "@typescript-eslint/no-loss-of-precision": "error"
if let Some(rule_config) =
rule_configs.iter().find(|r| r.severity.is_warn_deny())
{
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == *name) {
rules_to_replace.push(rule.read_json(rule_config.config.clone()));
}
} else if rule_configs.iter().all(|r| r.severity.is_allow()) {
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == *name) {
rules_to_remove.push(rule.clone());
}
}
}
} else if let Some(rule) =
all_rules.iter().find(|r| r.plugin_name() == plugin_name && r.name() == rule_name)
{
rules_to_replace.push(rule.read_json(rule_to_configure.config.clone()));
}
}

for rule in rules_to_remove {
rules_to_override.remove(&rule);
rules_for_override.remove(&rule);
}
for rule in rules_to_replace {
rules_to_override.replace(rule);
rules_for_override.replace(rule);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion crates/oxc_linter/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,13 @@ pub enum AllowWarnDeny {
}

impl AllowWarnDeny {
pub fn is_enabled(self) -> bool {
pub fn is_warn_deny(self) -> bool {
self != Self::Allow
}

pub fn is_allow(self) -> bool {
self == Self::Allow
}
}

impl TryFrom<&str> for AllowWarnDeny {
Expand Down

0 comments on commit fb5d0a7

Please sign in to comment.