mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(linter): add support for same rule name but different plugin names (#1992)
e.g.
```
{
"rules": {
"semi": "off",
"@typescript-eslint/semi": "error"
}
}
```
closes #1975
This commit is contained in:
parent
b7ea4e53fb
commit
fb5d0a740c
5 changed files with 70 additions and 21 deletions
6
crates/oxc_cli/fixtures/typescript_eslint/eslintrc.json
Normal file
6
crates/oxc_cli/fixtures/typescript_eslint/eslintrc.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"rules": {
|
||||
"no-loss-of-precision": "off",
|
||||
"@typescript-eslint/no-loss-of-precision": "error"
|
||||
}
|
||||
}
|
||||
1
crates/oxc_cli/fixtures/typescript_eslint/test.js
Normal file
1
crates/oxc_cli/fixtures/typescript_eslint/test.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
9007199254740993 // no-loss-of-precision
|
||||
|
|
@ -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"];
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
AllowWarnDeny::Allow => {
|
||||
rules_to_remove.push(rule.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()));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue