From 08b945c4473f9c27f62713da7317a8d514535d4f Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Fri, 23 Aug 2024 14:42:46 -0400 Subject: [PATCH] refactor(linter): start internal/external split of LintPluginOptions refactor(linter): start internal/external split of `LintPluginOptions` --- crates/oxc_linter/src/lib.rs | 4 +- crates/oxc_linter/src/options/mod.rs | 5 +- crates/oxc_linter/src/options/plugins.rs | 75 ++++++++++++++++++++++++ crates/oxc_linter/src/service.rs | 8 +-- 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/crates/oxc_linter/src/lib.rs b/crates/oxc_linter/src/lib.rs index 0dba9828ea99e7..91214504e26002 100644 --- a/crates/oxc_linter/src/lib.rs +++ b/crates/oxc_linter/src/lib.rs @@ -161,7 +161,7 @@ impl Linter { .with_frameworks(self.options.framework_hints); // set file-specific jest/vitest flags - if self.options.plugins.jest || self.options.plugins.vitest { + if self.options.plugins.has_test() { let mut test_flags = FrameworkFlags::empty(); if frameworks::has_vitest_imports(ctx.module_record()) { @@ -191,7 +191,7 @@ impl Linter { } fn map_jest(&self, plugin_name: &'static str, rule_name: &str) -> &'static str { - if self.options.plugins.vitest + if self.options.plugins.has_vitest() && plugin_name == "jest" && utils::is_jest_rule_adapted_to_vitest(rule_name) { diff --git a/crates/oxc_linter/src/options/mod.rs b/crates/oxc_linter/src/options/mod.rs index d3e77fb1936324..8f54003983bd5c 100644 --- a/crates/oxc_linter/src/options/mod.rs +++ b/crates/oxc_linter/src/options/mod.rs @@ -6,6 +6,7 @@ use std::{convert::From, path::PathBuf}; pub use allow_warn_deny::AllowWarnDeny; use oxc_diagnostics::Error; pub use plugins::LintPluginOptions; +use plugins::LintPlugins; use rustc_hash::FxHashSet; use crate::{ @@ -26,7 +27,7 @@ use crate::{ pub(crate) struct LintOptions { pub fix: FixKind, pub framework_hints: FrameworkFlags, - pub plugins: LintPluginOptions, + pub plugins: LintPlugins, } impl From for LintOptions { @@ -34,7 +35,7 @@ impl From for LintOptions { Self { fix: options.fix, framework_hints: options.framework_hints, - plugins: options.plugins, + plugins: options.plugins.into(), } } } diff --git a/crates/oxc_linter/src/options/plugins.rs b/crates/oxc_linter/src/options/plugins.rs index 97d464676ade49..b792ebbcf25446 100644 --- a/crates/oxc_linter/src/options/plugins.rs +++ b/crates/oxc_linter/src/options/plugins.rs @@ -1,3 +1,71 @@ +use bitflags::bitflags; + +bitflags! { + // NOTE: may be increased to a u32 if needed + #[derive(Debug, Clone, Copy, PartialEq, Hash)] + pub(crate) struct LintPlugins: u16 { + const REACT = 1 << 0; + const UNICORN = 1 << 1; + const TYPESCRIPT = 1 << 2; + const OXC = 1 << 3; + const IMPORT = 1 << 4; + const JSDOC = 1 << 5; + const JEST = 1 << 6; + const VITEST = 1 << 7; + const JSX_A11Y = 1 << 8; + const NEXTJS = 1 << 9; + const REACT_PERF = 1 << 10; + const PROMISE = 1 << 11; + const NODE = 1 << 12; + } +} +impl Default for LintPlugins { + #[inline] + fn default() -> Self { + LintPlugins::REACT | LintPlugins::UNICORN | LintPlugins::TYPESCRIPT | LintPlugins::OXC + } +} + +impl From for LintPlugins { + fn from(options: LintPluginOptions) -> Self { + let mut plugins = LintPlugins::empty(); + plugins.set(LintPlugins::REACT, options.react); + plugins.set(LintPlugins::UNICORN, options.unicorn); + plugins.set(LintPlugins::TYPESCRIPT, options.typescript); + plugins.set(LintPlugins::OXC, options.oxc); + plugins.set(LintPlugins::IMPORT, options.import); + plugins.set(LintPlugins::JSDOC, options.jsdoc); + plugins.set(LintPlugins::JEST, options.jest); + plugins.set(LintPlugins::VITEST, options.vitest); + plugins.set(LintPlugins::JSX_A11Y, options.jsx_a11y); + plugins.set(LintPlugins::NEXTJS, options.nextjs); + plugins.set(LintPlugins::REACT_PERF, options.react_perf); + plugins.set(LintPlugins::PROMISE, options.promise); + plugins.set(LintPlugins::NODE, options.node); + plugins + } +} + +impl LintPlugins { + /// Returns `true` if the Vitest plugin is enabled. + #[inline] + pub fn has_vitest(self) -> bool { + self.contains(LintPlugins::VITEST) + } + + /// Returns `true` if Jest or Vitest plugins are enabled. + #[inline] + pub fn has_test(self) -> bool { + self.intersects(LintPlugins::JEST.union(LintPlugins::VITEST)) + } + + /// Returns `true` if the import plugin is enabled. + #[inline] + pub fn has_import(self) -> bool { + self.contains(LintPlugins::IMPORT) + } +} + #[derive(Debug)] #[non_exhaustive] pub struct LintPluginOptions { @@ -138,6 +206,13 @@ mod test { } } + #[test] + fn test_default_conversion() { + let plugins = LintPlugins::default(); + let options = LintPluginOptions::default(); + assert_eq!(LintPlugins::from(options), plugins); + } + #[test] fn test_collect_empty() { let empty: &[&str] = &[]; diff --git a/crates/oxc_linter/src/service.rs b/crates/oxc_linter/src/service.rs index 152f4841e7eb80..bc6d86afa740a8 100644 --- a/crates/oxc_linter/src/service.rs +++ b/crates/oxc_linter/src/service.rs @@ -165,7 +165,7 @@ pub struct Runtime { impl Runtime { fn new(linter: Linter, options: LintServiceOptions) -> Self { - let resolver = linter.options().plugins.import.then(|| { + let resolver = linter.options().plugins.has_import().then(|| { Self::get_resolver(options.tsconfig.or_else(|| Some(options.cwd.join("tsconfig.json")))) }); Self { @@ -310,7 +310,7 @@ impl Runtime { .build_module_record(path, program); let module_record = semantic_builder.module_record(); - if self.linter.options().plugins.import { + if self.linter.options().plugins.has_import() { self.module_map.insert( path.to_path_buf().into_boxed_path(), ModuleState::Resolved(Arc::clone(&module_record)), @@ -392,7 +392,7 @@ impl Runtime { } fn init_cache_state(&self, path: &Path) -> bool { - if !self.linter.options().plugins.import { + if !self.linter.options().plugins.has_import() { return false; } @@ -447,7 +447,7 @@ impl Runtime { } fn ignore_path(&self, path: &Path) { - if self.linter.options().plugins.import { + if self.linter.options().plugins.has_import() { self.module_map.insert(path.to_path_buf().into_boxed_path(), ModuleState::Ignored); self.update_cache_state(path); }