From 502ce80c917e3f999dd9181dc199afb01d39e32e Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Fri, 3 Feb 2023 03:40:09 +0100 Subject: [PATCH] many-to-one 0/9: Introduce RuleSelector::Linter variant We want to remove the variants denoting whole Linters from the RuleCodePrefix enum, so we have to introduce a new RuleSelector::Linter variant. --- crates/ruff/src/flake8_to_ruff/converter.rs | 17 +++-- crates/ruff/src/flake8_to_ruff/parser.rs | 12 ++-- crates/ruff/src/flake8_to_ruff/plugin.rs | 77 ++++++++++----------- crates/ruff/src/registry.rs | 2 +- crates/ruff/src/rule_selector.rs | 26 +++++-- 5 files changed, 75 insertions(+), 59 deletions(-) diff --git a/crates/ruff/src/flake8_to_ruff/converter.rs b/crates/ruff/src/flake8_to_ruff/converter.rs index 34f96ab51f..72d03471ff 100644 --- a/crates/ruff/src/flake8_to_ruff/converter.rs +++ b/crates/ruff/src/flake8_to_ruff/converter.rs @@ -6,8 +6,8 @@ use itertools::Itertools; use super::external_config::ExternalConfig; use super::plugin::Plugin; use super::{parser, plugin}; -use crate::registry::RuleCodePrefix; -use crate::rule_selector::{prefix_to_selector, RuleSelector}; +use crate::registry::Linter; +use crate::rule_selector::RuleSelector; use crate::rules::flake8_pytest_style::types::{ ParametrizeNameType, ParametrizeValuesRowType, ParametrizeValuesType, }; @@ -23,9 +23,8 @@ use crate::settings::pyproject::Pyproject; use crate::warn_user; const DEFAULT_SELECTORS: &[RuleSelector] = &[ - prefix_to_selector(RuleCodePrefix::F), - prefix_to_selector(RuleCodePrefix::E), - prefix_to_selector(RuleCodePrefix::W), + RuleSelector::Linter(Linter::Pyflakes), + RuleSelector::Linter(Linter::Pycodestyle), ]; pub fn convert( @@ -433,7 +432,7 @@ pub fn convert( /// plugins. fn resolve_select(plugins: &[Plugin]) -> HashSet { let mut select: HashSet<_> = DEFAULT_SELECTORS.iter().cloned().collect(); - select.extend(plugins.iter().map(Plugin::selector)); + select.extend(plugins.iter().map(|p| Linter::from(p).into())); select } @@ -448,7 +447,7 @@ mod tests { use super::convert; use crate::flake8_to_ruff::converter::DEFAULT_SELECTORS; use crate::flake8_to_ruff::ExternalConfig; - use crate::registry::RuleCodePrefix; + use crate::registry::Linter; use crate::rule_selector::RuleSelector; use crate::rules::pydocstyle::settings::Convention; use crate::rules::{flake8_quotes, pydocstyle}; @@ -578,7 +577,7 @@ mod tests { pydocstyle: Some(pydocstyle::settings::Options { convention: Some(Convention::Numpy), }), - ..default_options([RuleCodePrefix::D.into()]) + ..default_options([Linter::Pydocstyle.into()]) }); assert_eq!(actual, expected); @@ -602,7 +601,7 @@ mod tests { docstring_quotes: None, avoid_escape: None, }), - ..default_options([RuleCodePrefix::Q.into()]) + ..default_options([Linter::Flake8Quotes.into()]) }); assert_eq!(actual, expected); diff --git a/crates/ruff/src/flake8_to_ruff/parser.rs b/crates/ruff/src/flake8_to_ruff/parser.rs index 7086a28b33..559c348d5f 100644 --- a/crates/ruff/src/flake8_to_ruff/parser.rs +++ b/crates/ruff/src/flake8_to_ruff/parser.rs @@ -196,7 +196,7 @@ mod tests { use anyhow::Result; use super::{parse_files_to_codes_mapping, parse_prefix_codes, parse_strings}; - use crate::registry::RuleCodePrefix; + use crate::registry::{Linter, RuleCodePrefix}; use crate::rule_selector::RuleSelector; use crate::settings::types::PatternPrefixPair; @@ -296,23 +296,23 @@ mod tests { let expected: Vec = vec![ PatternPrefixPair { pattern: "t/*".to_string(), - prefix: RuleCodePrefix::D.into(), + prefix: Linter::Pydocstyle.into(), }, PatternPrefixPair { pattern: "setup.py".to_string(), - prefix: RuleCodePrefix::D.into(), + prefix: Linter::Pydocstyle.into(), }, PatternPrefixPair { pattern: "examples/*".to_string(), - prefix: RuleCodePrefix::D.into(), + prefix: Linter::Pydocstyle.into(), }, PatternPrefixPair { pattern: "docs/*".to_string(), - prefix: RuleCodePrefix::D.into(), + prefix: Linter::Pydocstyle.into(), }, PatternPrefixPair { pattern: "extra/*".to_string(), - prefix: RuleCodePrefix::D.into(), + prefix: Linter::Pydocstyle.into(), }, ]; assert_eq!(actual, expected); diff --git a/crates/ruff/src/flake8_to_ruff/plugin.rs b/crates/ruff/src/flake8_to_ruff/plugin.rs index 42b0b0d578..3283b0b280 100644 --- a/crates/ruff/src/flake8_to_ruff/plugin.rs +++ b/crates/ruff/src/flake8_to_ruff/plugin.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::anyhow; -use crate::registry::RuleCodePrefix; +use crate::registry::Linter; use crate::rule_selector::RuleSelector; #[derive(Clone, Ord, PartialOrd, Eq, PartialEq)] @@ -131,43 +131,42 @@ impl fmt::Debug for Plugin { } } -// TODO(martin): Convert into `impl From for Linter` -impl Plugin { - pub fn selector(&self) -> RuleSelector { - match self { - Plugin::Flake82020 => RuleCodePrefix::YTT.into(), - Plugin::Flake8Annotations => RuleCodePrefix::ANN.into(), - Plugin::Flake8Bandit => RuleCodePrefix::S.into(), - Plugin::Flake8BlindExcept => RuleCodePrefix::BLE.into(), - Plugin::Flake8BooleanTrap => RuleCodePrefix::FBT.into(), - Plugin::Flake8Bugbear => RuleCodePrefix::B.into(), - Plugin::Flake8Builtins => RuleCodePrefix::A.into(), - Plugin::Flake8Commas => RuleCodePrefix::COM.into(), - Plugin::Flake8Comprehensions => RuleCodePrefix::C4.into(), - Plugin::Flake8Datetimez => RuleCodePrefix::DTZ.into(), - Plugin::Flake8Debugger => RuleCodePrefix::T1.into(), - Plugin::Flake8Docstrings => RuleCodePrefix::D.into(), - Plugin::Flake8Eradicate => RuleCodePrefix::ERA.into(), - Plugin::Flake8ErrMsg => RuleCodePrefix::EM.into(), - Plugin::Flake8Executable => RuleCodePrefix::EXE.into(), - Plugin::Flake8ImplicitStrConcat => RuleCodePrefix::ISC.into(), - Plugin::Flake8ImportConventions => RuleCodePrefix::ICN.into(), - Plugin::Flake8NoPep420 => RuleCodePrefix::INP.into(), - Plugin::Flake8Pie => RuleCodePrefix::PIE.into(), - Plugin::Flake8Print => RuleCodePrefix::T2.into(), - Plugin::Flake8PytestStyle => RuleCodePrefix::PT.into(), - Plugin::Flake8Quotes => RuleCodePrefix::Q.into(), - Plugin::Flake8Return => RuleCodePrefix::RET.into(), - Plugin::Flake8Simplify => RuleCodePrefix::SIM.into(), - Plugin::Flake8TidyImports => RuleCodePrefix::TID.into(), - Plugin::Flake8TypeChecking => RuleCodePrefix::TCH.into(), - Plugin::Flake8UnusedArguments => RuleCodePrefix::ARG.into(), - Plugin::Flake8UsePathlib => RuleCodePrefix::PTH.into(), - Plugin::McCabe => RuleCodePrefix::C9.into(), - Plugin::PEP8Naming => RuleCodePrefix::N.into(), - Plugin::PandasVet => RuleCodePrefix::PD.into(), - Plugin::Pyupgrade => RuleCodePrefix::UP.into(), - Plugin::Tryceratops => RuleCodePrefix::TRY.into(), +impl From<&Plugin> for Linter { + fn from(plugin: &Plugin) -> Self { + match plugin { + Plugin::Flake82020 => Linter::Flake82020, + Plugin::Flake8Annotations => Linter::Flake8Annotations, + Plugin::Flake8Bandit => Linter::Flake8Bandit, + Plugin::Flake8BlindExcept => Linter::Flake8BlindExcept, + Plugin::Flake8BooleanTrap => Linter::Flake8BooleanTrap, + Plugin::Flake8Bugbear => Linter::Flake8Bugbear, + Plugin::Flake8Builtins => Linter::Flake8Builtins, + Plugin::Flake8Commas => Linter::Flake8Commas, + Plugin::Flake8Comprehensions => Linter::Flake8Comprehensions, + Plugin::Flake8Datetimez => Linter::Flake8Datetimez, + Plugin::Flake8Debugger => Linter::Flake8Debugger, + Plugin::Flake8Docstrings => Linter::Pydocstyle, + Plugin::Flake8Eradicate => Linter::Eradicate, + Plugin::Flake8ErrMsg => Linter::Flake8ErrMsg, + Plugin::Flake8Executable => Linter::Flake8Executable, + Plugin::Flake8ImplicitStrConcat => Linter::Flake8ImplicitStrConcat, + Plugin::Flake8ImportConventions => Linter::Flake8ImportConventions, + Plugin::Flake8NoPep420 => Linter::Flake8NoPep420, + Plugin::Flake8Pie => Linter::Flake8Pie, + Plugin::Flake8Print => Linter::Flake8Print, + Plugin::Flake8PytestStyle => Linter::Flake8PytestStyle, + Plugin::Flake8Quotes => Linter::Flake8Quotes, + Plugin::Flake8Return => Linter::Flake8Return, + Plugin::Flake8Simplify => Linter::Flake8Simplify, + Plugin::Flake8TidyImports => Linter::Flake8TidyImports, + Plugin::Flake8TypeChecking => Linter::Flake8TypeChecking, + Plugin::Flake8UnusedArguments => Linter::Flake8UnusedArguments, + Plugin::Flake8UsePathlib => Linter::Flake8UsePathlib, + Plugin::McCabe => Linter::McCabe, + Plugin::PEP8Naming => Linter::PEP8Naming, + Plugin::PandasVet => Linter::PandasVet, + Plugin::Pyupgrade => Linter::Pyupgrade, + Plugin::Tryceratops => Linter::Tryceratops, } } } @@ -334,7 +333,7 @@ pub fn infer_plugins_from_codes(selectors: &HashSet) -> Vec rules::flake8_django::rules::NonLeadingReceiverDecorator, ); -#[derive(EnumIter, Debug, PartialEq, Eq, RuleNamespace)] +#[derive(EnumIter, Debug, PartialEq, Eq, Clone, Hash, RuleNamespace)] pub enum Linter { /// [Pyflakes](https://pypi.org/project/pyflakes/) #[prefix = "F"] diff --git a/crates/ruff/src/rule_selector.rs b/crates/ruff/src/rule_selector.rs index b96fab9df6..75c733c39e 100644 --- a/crates/ruff/src/rule_selector.rs +++ b/crates/ruff/src/rule_selector.rs @@ -8,19 +8,26 @@ use serde::{Deserialize, Serialize}; use strum::IntoEnumIterator; use strum_macros::EnumIter; -use crate::registry::{Rule, RuleCodePrefix, RuleIter}; +use crate::registry::{Linter, Rule, RuleCodePrefix, RuleIter, RuleNamespace}; use crate::rule_redirects::get_redirect; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum RuleSelector { /// All rules All, + Linter(Linter), Prefix { prefix: RuleCodePrefix, redirected_from: Option<&'static str>, }, } +impl From for RuleSelector { + fn from(linter: Linter) -> Self { + Self::Linter(linter) + } +} + impl FromStr for RuleSelector { type Err = ParseError; @@ -32,6 +39,14 @@ impl FromStr for RuleSelector { Some((from, target)) => (target, Some(from)), None => (s, None), }; + + let (linter, code) = + Linter::parse_code(s).ok_or_else(|| ParseError::Unknown(s.to_string()))?; + + if code.is_empty() { + return Ok(Self::Linter(linter)); + } + Ok(Self::Prefix { prefix: RuleCodePrefix::from_str(s) .map_err(|_| ParseError::Unknown(s.to_string()))?, @@ -53,6 +68,7 @@ impl RuleSelector { pub fn short_code(&self) -> &'static str { match self { RuleSelector::All => "ALL", + RuleSelector::Linter(linter) => linter.common_prefix(), RuleSelector::Prefix { prefix, .. } => prefix.into(), } } @@ -117,14 +133,15 @@ impl IntoIterator for &RuleSelector { fn into_iter(self) -> Self::IntoIter { match self { RuleSelector::All => RuleSelectorIter::All(Rule::iter()), - RuleSelector::Prefix { prefix, .. } => RuleSelectorIter::Prefix(prefix.into_iter()), + RuleSelector::Linter(linter) => RuleSelectorIter::Vec(linter.into_iter()), + RuleSelector::Prefix { prefix, .. } => RuleSelectorIter::Vec(prefix.into_iter()), } } } pub enum RuleSelectorIter { All(RuleIter), - Prefix(std::vec::IntoIter), + Vec(std::vec::IntoIter), } impl Iterator for RuleSelectorIter { @@ -133,7 +150,7 @@ impl Iterator for RuleSelectorIter { fn next(&mut self) -> Option { match self { RuleSelectorIter::All(iter) => iter.next(), - RuleSelectorIter::Prefix(iter) => iter.next(), + RuleSelectorIter::Vec(iter) => iter.next(), } } } @@ -173,6 +190,7 @@ impl RuleSelector { pub(crate) fn specificity(&self) -> Specificity { match self { RuleSelector::All => Specificity::All, + RuleSelector::Linter(..) => Specificity::Linter, RuleSelector::Prefix { prefix, .. } => prefix.specificity(), } }