refactor(linter): move plugin options into separate struct (#5100)

Part of #5046
This commit is contained in:
DonIsaac 2024-08-23 00:01:21 +00:00
parent 9da6a21e40
commit eca6fdbffe
4 changed files with 133 additions and 86 deletions

View file

@ -157,12 +157,12 @@ impl Linter {
.with_frameworks(self.options.framework_hints);
// set file-specific jest/vitest flags
if self.options.jest_plugin || self.options.vitest_plugin {
if self.options.plugins.jest || self.options.plugins.vitest {
let mut test_flags = FrameworkFlags::empty();
if frameworks::is_jestlike_file(path) {
test_flags.set(FrameworkFlags::Jest, self.options.jest_plugin);
test_flags.set(FrameworkFlags::Vitest, self.options.vitest_plugin);
test_flags.set(FrameworkFlags::Jest, self.options.plugins.jest);
test_flags.set(FrameworkFlags::Vitest, self.options.plugins.vitest);
} else if frameworks::has_vitest_imports(ctx.module_record()) {
test_flags.set(FrameworkFlags::Vitest, true);
}
@ -186,7 +186,7 @@ impl Linter {
}
fn map_jest(&self, plugin_name: &'static str, rule_name: &str) -> &'static str {
if self.options.vitest_plugin
if self.options.plugins.vitest
&& plugin_name == "jest"
&& utils::is_jest_rule_adapted_to_vitest(rule_name)
{

View file

@ -21,18 +21,7 @@ pub struct LintOptions {
/// The kind represents the riskiest fix that the linter can apply.
pub fix: FixKind,
pub react_plugin: bool,
pub unicorn_plugin: bool,
pub typescript_plugin: bool,
pub oxc_plugin: bool,
pub import_plugin: bool,
pub jsdoc_plugin: bool,
pub jest_plugin: bool,
pub vitest_plugin: bool,
pub jsx_a11y_plugin: bool,
pub nextjs_plugin: bool,
pub react_perf_plugin: bool,
pub promise_plugin: bool,
pub plugins: LintPluginOptions,
pub framework_hints: FrameworkFlags,
}
@ -43,19 +32,7 @@ impl Default for LintOptions {
filter: vec![(AllowWarnDeny::Warn, String::from("correctness"))],
config_path: None,
fix: FixKind::None,
react_plugin: true,
unicorn_plugin: true,
typescript_plugin: true,
oxc_plugin: true,
import_plugin: false,
jsdoc_plugin: false,
jest_plugin: false,
vitest_plugin: false,
jsx_a11y_plugin: false,
nextjs_plugin: false,
react_perf_plugin: false,
promise_plugin: false,
plugins: LintPluginOptions::default(),
framework_hints: FrameworkFlags::default(),
}
}
@ -94,77 +71,151 @@ impl LintOptions {
#[must_use]
pub fn with_react_plugin(mut self, yes: bool) -> Self {
self.react_plugin = yes;
self.plugins.react = yes;
self
}
#[must_use]
pub fn with_unicorn_plugin(mut self, yes: bool) -> Self {
self.unicorn_plugin = yes;
self.plugins.unicorn = yes;
self
}
#[must_use]
pub fn with_typescript_plugin(mut self, yes: bool) -> Self {
self.typescript_plugin = yes;
self.plugins.typescript = yes;
self
}
#[must_use]
pub fn with_oxc_plugin(mut self, yes: bool) -> Self {
self.oxc_plugin = yes;
self.plugins.oxc = yes;
self
}
#[must_use]
pub fn with_import_plugin(mut self, yes: bool) -> Self {
self.import_plugin = yes;
self.plugins.import = yes;
self
}
#[must_use]
pub fn with_jsdoc_plugin(mut self, yes: bool) -> Self {
self.jsdoc_plugin = yes;
self.plugins.jsdoc = yes;
self
}
#[must_use]
pub fn with_jest_plugin(mut self, yes: bool) -> Self {
self.jest_plugin = yes;
self.plugins.jest = yes;
self
}
#[must_use]
pub fn with_vitest_plugin(mut self, yes: bool) -> Self {
self.vitest_plugin = yes;
self.plugins.vitest = yes;
self
}
#[must_use]
pub fn with_jsx_a11y_plugin(mut self, yes: bool) -> Self {
self.jsx_a11y_plugin = yes;
self.plugins.jsx_a11y = yes;
self
}
#[must_use]
pub fn with_nextjs_plugin(mut self, yes: bool) -> Self {
self.nextjs_plugin = yes;
self.plugins.nextjs = yes;
self
}
#[must_use]
pub fn with_react_perf_plugin(mut self, yes: bool) -> Self {
self.react_perf_plugin = yes;
self.plugins.react_perf = yes;
self
}
#[must_use]
pub fn with_promise_plugin(mut self, yes: bool) -> Self {
self.promise_plugin = yes;
self.plugins.promise = yes;
self
}
}
#[derive(Debug)]
#[non_exhaustive]
pub struct LintPluginOptions {
pub react: bool,
pub unicorn: bool,
pub typescript: bool,
pub oxc: bool,
pub import: bool,
pub jsdoc: bool,
pub jest: bool,
pub vitest: bool,
pub jsx_a11y: bool,
pub nextjs: bool,
pub react_perf: bool,
pub promise: bool,
}
impl Default for LintPluginOptions {
fn default() -> Self {
Self {
react: true,
unicorn: true,
typescript: true,
oxc: true,
import: false,
jsdoc: false,
jest: false,
vitest: false,
jsx_a11y: false,
nextjs: false,
react_perf: false,
promise: false,
}
}
}
impl LintPluginOptions {
/// Create a new instance with all plugins disabled.
pub fn none() -> Self {
Self {
react: false,
unicorn: false,
typescript: false,
oxc: false,
import: false,
jsdoc: false,
jest: false,
vitest: false,
jsx_a11y: false,
nextjs: false,
react_perf: false,
promise: false,
}
}
/// Create a new instance with all plugins enabled.
pub fn all() -> Self {
Self {
react: true,
unicorn: true,
typescript: true,
oxc: true,
import: true,
jsdoc: true,
jest: true,
vitest: true,
jsx_a11y: true,
nextjs: true,
react_perf: true,
promise: true,
}
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum AllowWarnDeny {
Allow, // Off
@ -348,27 +399,27 @@ impl LintOptions {
RULES
.iter()
.filter(|rule| match rule.plugin_name() {
"react" => self.react_plugin,
"unicorn" => self.unicorn_plugin,
"typescript" => self.typescript_plugin,
"import" => self.import_plugin,
"jsdoc" => self.jsdoc_plugin,
"react" => self.plugins.react,
"unicorn" => self.plugins.unicorn,
"typescript" => self.plugins.typescript,
"import" => self.plugins.import,
"jsdoc" => self.plugins.jsdoc,
"jest" => {
if self.jest_plugin {
if self.plugins.jest {
return true;
}
if self.vitest_plugin && is_jest_rule_adapted_to_vitest(rule.name()) {
if self.plugins.vitest && is_jest_rule_adapted_to_vitest(rule.name()) {
return true;
}
false
}
"vitest" => self.vitest_plugin,
"jsx_a11y" => self.jsx_a11y_plugin,
"nextjs" => self.nextjs_plugin,
"react_perf" => self.react_perf_plugin,
"oxc" => self.oxc_plugin,
"vitest" => self.plugins.vitest,
"jsx_a11y" => self.plugins.jsx_a11y,
"nextjs" => self.plugins.nextjs,
"react_perf" => self.plugins.react_perf,
"oxc" => self.plugins.oxc,
"eslint" | "tree_shaking" => true,
"promise" => self.promise_plugin,
"promise" => self.plugins.promise,
name => panic!("Unhandled plugin: {name}"),
})
.cloned()

View file

@ -134,7 +134,7 @@ pub struct Runtime {
impl Runtime {
fn new(linter: Linter, options: LintServiceOptions) -> Self {
let resolver = linter.options().import_plugin.then(|| {
let resolver = linter.options().plugins.import.then(|| {
Self::get_resolver(options.tsconfig.or_else(|| Some(options.cwd.join("tsconfig.json"))))
});
Self {
@ -278,7 +278,7 @@ impl Runtime {
.build_module_record(path.to_path_buf(), program);
let module_record = semantic_builder.module_record();
if self.linter.options().import_plugin {
if self.linter.options().plugins.import {
self.module_map.insert(
path.to_path_buf().into_boxed_path(),
ModuleState::Resolved(Arc::clone(&module_record)),
@ -360,7 +360,7 @@ impl Runtime {
}
fn init_cache_state(&self, path: &Path) -> bool {
if !self.linter.options().import_plugin {
if !self.linter.options().plugins.import {
return false;
}
@ -415,7 +415,7 @@ impl Runtime {
}
fn ignore_path(&self, path: &Path) {
if self.linter.options().import_plugin {
if self.linter.options().plugins.import {
self.module_map.insert(path.to_path_buf().into_boxed_path(), ModuleState::Ignored);
self.update_cache_state(path);
}

View file

@ -9,8 +9,8 @@ use serde::Deserialize;
use serde_json::Value;
use crate::{
fixer::FixKind, rules::RULES, AllowWarnDeny, Fixer, LintOptions, LintService,
LintServiceOptions, Linter, OxlintConfig, RuleEnum, RuleWithSeverity,
fixer::FixKind, options::LintPluginOptions, rules::RULES, AllowWarnDeny, Fixer, LintOptions,
LintService, LintServiceOptions, Linter, OxlintConfig, RuleEnum, RuleWithSeverity,
};
#[derive(Eq, PartialEq)]
@ -170,12 +170,13 @@ pub struct Tester {
/// See: [insta::Settings::set_snapshot_suffix]
snapshot_suffix: Option<&'static str>,
current_working_directory: Box<Path>,
import_plugin: bool,
jest_plugin: bool,
vitest_plugin: bool,
jsx_a11y_plugin: bool,
nextjs_plugin: bool,
react_perf_plugin: bool,
// import_plugin: bool,
// jest_plugin: bool,
// vitest_plugin: bool,
// jsx_a11y_plugin: bool,
// nextjs_plugin: bool,
// react_perf_plugin: bool,
plugins: LintPluginOptions,
}
impl Tester {
@ -198,12 +199,7 @@ impl Tester {
snapshot: String::new(),
snapshot_suffix: None,
current_working_directory,
import_plugin: false,
jest_plugin: false,
jsx_a11y_plugin: false,
nextjs_plugin: false,
react_perf_plugin: false,
vitest_plugin: false,
plugins: LintPluginOptions::none(),
}
}
@ -225,32 +221,32 @@ impl Tester {
}
pub fn with_import_plugin(mut self, yes: bool) -> Self {
self.import_plugin = yes;
self.plugins.import = yes;
self
}
pub fn with_jest_plugin(mut self, yes: bool) -> Self {
self.jest_plugin = yes;
self.plugins.jest = yes;
self
}
pub fn with_vitest_plugin(mut self, yes: bool) -> Self {
self.vitest_plugin = yes;
self.plugins.vitest = yes;
self
}
pub fn with_jsx_a11y_plugin(mut self, yes: bool) -> Self {
self.jsx_a11y_plugin = yes;
self.plugins.jsx_a11y = yes;
self
}
pub fn with_nextjs_plugin(mut self, yes: bool) -> Self {
self.nextjs_plugin = yes;
self.plugins.nextjs = yes;
self
}
pub fn with_react_perf_plugin(mut self, yes: bool) -> Self {
self.react_perf_plugin = yes;
self.plugins.react_perf = yes;
self
}
@ -350,12 +346,12 @@ impl Tester {
let rule = self.find_rule().read_json(rule_config.unwrap_or_default());
let options = LintOptions::default()
.with_fix(fix.into())
.with_import_plugin(self.import_plugin)
.with_jest_plugin(self.jest_plugin)
.with_vitest_plugin(self.vitest_plugin)
.with_jsx_a11y_plugin(self.jsx_a11y_plugin)
.with_nextjs_plugin(self.nextjs_plugin)
.with_react_perf_plugin(self.react_perf_plugin);
.with_import_plugin(self.plugins.import)
.with_jest_plugin(self.plugins.jest)
.with_vitest_plugin(self.plugins.vitest)
.with_jsx_a11y_plugin(self.plugins.jsx_a11y)
.with_nextjs_plugin(self.plugins.nextjs)
.with_react_perf_plugin(self.plugins.react_perf);
let eslint_config = eslint_config
.as_ref()
.map_or_else(OxlintConfig::default, |v| OxlintConfig::deserialize(v).unwrap());
@ -363,7 +359,7 @@ impl Tester {
.unwrap()
.with_rules(vec![RuleWithSeverity::new(rule, AllowWarnDeny::Warn)])
.with_eslint_config(eslint_config);
let path_to_lint = if self.import_plugin {
let path_to_lint = if self.plugins.import {
assert!(path.is_none(), "import plugin does not support path");
self.current_working_directory.join(&self.rule_path)
} else if let Some(path) = path {
@ -389,7 +385,7 @@ impl Tester {
return TestResult::Fixed(fix_result.fixed_code.to_string());
}
let diagnostic_path = if self.import_plugin {
let diagnostic_path = if self.plugins.import {
self.rule_path.strip_prefix(&self.current_working_directory).unwrap()
} else {
&self.rule_path