From f7c675d187d6fae5199c8242e7767926ad4b703e Mon Sep 17 00:00:00 2001 From: camc314 <18101008+camc314@users.noreply.github.com> Date: Mon, 7 Jul 2025 13:33:06 +0000 Subject: [PATCH] refactor(linter): rename `LintPlugins` to `BuiltinLintPlugins` (#12116) this is a simple LSP rename from `LintPlugins` to `BuiltinLintPlugins` to reduce the diff on #12117 --- apps/oxlint/src/command/lint.rs | 50 +++++----- .../oxc_linter/src/config/config_builder.rs | 94 ++++++++++-------- crates/oxc_linter/src/config/config_store.rs | 37 ++++---- crates/oxc_linter/src/config/mod.rs | 4 +- crates/oxc_linter/src/config/overrides.rs | 11 ++- crates/oxc_linter/src/config/oxlintrc.rs | 18 ++-- crates/oxc_linter/src/config/plugins.rs | 95 ++++++++++--------- crates/oxc_linter/src/context/host.rs | 4 +- crates/oxc_linter/src/lib.rs | 4 +- crates/oxc_linter/src/tester.rs | 24 ++--- tasks/website/src/linter/rules/doc_page.rs | 8 +- 11 files changed, 188 insertions(+), 161 deletions(-) diff --git a/apps/oxlint/src/command/lint.rs b/apps/oxlint/src/command/lint.rs index ada97b898c822..e0e1408776afb 100644 --- a/apps/oxlint/src/command/lint.rs +++ b/apps/oxlint/src/command/lint.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use bpaf::Bpaf; -use oxc_linter::{AllowWarnDeny, FixKind, LintPlugins}; +use oxc_linter::{AllowWarnDeny, BuiltinLintPlugins, FixKind}; use crate::output_formatter::OutputFormat; @@ -327,24 +327,24 @@ impl OverrideToggle { } impl EnablePlugins { - pub fn apply_overrides(&self, plugins: &mut LintPlugins) { - self.react_plugin.inspect(|yes| plugins.set(LintPlugins::REACT, yes)); - self.unicorn_plugin.inspect(|yes| plugins.set(LintPlugins::UNICORN, yes)); - self.oxc_plugin.inspect(|yes| plugins.set(LintPlugins::OXC, yes)); - self.typescript_plugin.inspect(|yes| plugins.set(LintPlugins::TYPESCRIPT, yes)); - self.import_plugin.inspect(|yes| plugins.set(LintPlugins::IMPORT, yes)); - self.jsdoc_plugin.inspect(|yes| plugins.set(LintPlugins::JSDOC, yes)); - self.jest_plugin.inspect(|yes| plugins.set(LintPlugins::JEST, yes)); - self.vitest_plugin.inspect(|yes| plugins.set(LintPlugins::VITEST, yes)); - self.jsx_a11y_plugin.inspect(|yes| plugins.set(LintPlugins::JSX_A11Y, yes)); - self.nextjs_plugin.inspect(|yes| plugins.set(LintPlugins::NEXTJS, yes)); - self.react_perf_plugin.inspect(|yes| plugins.set(LintPlugins::REACT_PERF, yes)); - self.promise_plugin.inspect(|yes| plugins.set(LintPlugins::PROMISE, yes)); - self.node_plugin.inspect(|yes| plugins.set(LintPlugins::NODE, yes)); + pub fn apply_overrides(&self, plugins: &mut BuiltinLintPlugins) { + self.react_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::REACT, yes)); + self.unicorn_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::UNICORN, yes)); + self.oxc_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::OXC, yes)); + self.typescript_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::TYPESCRIPT, yes)); + self.import_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::IMPORT, yes)); + self.jsdoc_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::JSDOC, yes)); + self.jest_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::JEST, yes)); + self.vitest_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::VITEST, yes)); + self.jsx_a11y_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::JSX_A11Y, yes)); + self.nextjs_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::NEXTJS, yes)); + self.react_perf_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::REACT_PERF, yes)); + self.promise_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::PROMISE, yes)); + self.node_plugin.inspect(|yes| plugins.set(BuiltinLintPlugins::NODE, yes)); // Without this, jest plugins adapted to vitest will not be enabled. if self.vitest_plugin.is_enabled() && self.jest_plugin.is_not_set() { - plugins.set(LintPlugins::JEST, true); + plugins.set(BuiltinLintPlugins::JEST, true); } } } @@ -381,29 +381,30 @@ pub struct InlineConfigOptions { #[cfg(test)] mod plugins { - use oxc_linter::LintPlugins; + use oxc_linter::BuiltinLintPlugins; use super::{EnablePlugins, OverrideToggle}; #[test] fn test_override_default() { - let mut plugins = LintPlugins::default(); + let mut plugins = BuiltinLintPlugins::default(); let enable = EnablePlugins::default(); enable.apply_overrides(&mut plugins); - assert_eq!(plugins, LintPlugins::default()); + assert_eq!(plugins, BuiltinLintPlugins::default()); } #[test] fn test_overrides() { - let mut plugins = LintPlugins::default(); + let mut plugins = BuiltinLintPlugins::default(); let enable = EnablePlugins { react_plugin: OverrideToggle::Enable, unicorn_plugin: OverrideToggle::Disable, ..EnablePlugins::default() }; - let expected = - LintPlugins::default().union(LintPlugins::REACT).difference(LintPlugins::UNICORN); + let expected = BuiltinLintPlugins::default() + .union(BuiltinLintPlugins::REACT) + .difference(BuiltinLintPlugins::UNICORN); enable.apply_overrides(&mut plugins); assert_eq!(plugins, expected); @@ -411,10 +412,11 @@ mod plugins { #[test] fn test_override_vitest() { - let mut plugins = LintPlugins::default(); + let mut plugins = BuiltinLintPlugins::default(); let enable = EnablePlugins { vitest_plugin: OverrideToggle::Enable, ..EnablePlugins::default() }; - let expected = LintPlugins::default() | LintPlugins::VITEST | LintPlugins::JEST; + let expected = + BuiltinLintPlugins::default() | BuiltinLintPlugins::VITEST | BuiltinLintPlugins::JEST; enable.apply_overrides(&mut plugins); assert_eq!(plugins, expected); diff --git a/crates/oxc_linter/src/config/config_builder.rs b/crates/oxc_linter/src/config/config_builder.rs index 49d8676fb083b..48ea93610bd0c 100644 --- a/crates/oxc_linter/src/config/config_builder.rs +++ b/crates/oxc_linter/src/config/config_builder.rs @@ -10,7 +10,9 @@ use oxc_span::{CompactStr, format_compact_str}; use crate::{ AllowWarnDeny, LintConfig, LintFilter, LintFilterKind, Oxlintrc, RuleCategory, RuleEnum, - config::{ESLintRule, LintPlugins, OxlintOverrides, OxlintRules, overrides::OxlintOverride}, + config::{ + BuiltinLintPlugins, ESLintRule, OxlintOverrides, OxlintRules, overrides::OxlintOverride, + }, external_linter::ExternalLinter, rules::RULES, }; @@ -31,7 +33,7 @@ pub struct ConfigStoreBuilder { impl Default for ConfigStoreBuilder { fn default() -> Self { - Self { rules: Self::warn_correctness(LintPlugins::default()), ..Self::empty() } + Self { rules: Self::warn_correctness(BuiltinLintPlugins::default()), ..Self::empty() } } } @@ -55,7 +57,7 @@ impl ConfigStoreBuilder { /// /// You can think of this as `oxlint -W all -W nursery`. pub fn all() -> Self { - let config = LintConfig { plugins: LintPlugins::all(), ..LintConfig::default() }; + let config = LintConfig { plugins: BuiltinLintPlugins::all(), ..LintConfig::default() }; let overrides = OxlintOverrides::default(); let categories: OxlintCategories = OxlintCategories::default(); let rules = RULES.iter().map(|rule| (rule.clone(), AllowWarnDeny::Warn)).collect(); @@ -183,7 +185,7 @@ impl ConfigStoreBuilder { /// [`with_filters`]: ConfigStoreBuilder::with_filters /// [`and_plugins`]: ConfigStoreBuilder::and_plugins #[inline] - pub fn with_plugins(mut self, plugins: LintPlugins) -> Self { + pub fn with_plugins(mut self, plugins: BuiltinLintPlugins) -> Self { self.config.plugins = plugins; self } @@ -198,13 +200,13 @@ impl ConfigStoreBuilder { /// See [`ConfigStoreBuilder::with_plugins`] for details on how plugin configuration affects your /// rules. #[inline] - pub fn and_plugins(mut self, plugins: LintPlugins, enabled: bool) -> Self { + pub fn and_plugins(mut self, plugins: BuiltinLintPlugins, enabled: bool) -> Self { self.config.plugins.set(plugins, enabled); self } #[inline] - pub fn plugins(&self) -> LintPlugins { + pub fn plugins(&self) -> BuiltinLintPlugins { self.config.plugins } @@ -268,13 +270,13 @@ impl ConfigStoreBuilder { let mut plugins = self.config.plugins; // we need to include some jest rules when vitest is enabled, see [`VITEST_COMPATIBLE_JEST_RULES`] - if plugins.contains(LintPlugins::VITEST) { - plugins = plugins.union(LintPlugins::JEST); + if plugins.contains(BuiltinLintPlugins::VITEST) { + plugins = plugins.union(BuiltinLintPlugins::JEST); } RULES .iter() - .filter(|rule| plugins.contains(LintPlugins::from(rule.plugin_name()))) + .filter(|rule| plugins.contains(BuiltinLintPlugins::from(rule.plugin_name()))) .cloned() .collect() } @@ -306,8 +308,8 @@ impl ConfigStoreBuilder { let mut plugins = self.plugins(); // Apply the same Vitest->Jest logic as in get_all_rules() - if plugins.contains(LintPlugins::VITEST) { - plugins = plugins.union(LintPlugins::JEST); + if plugins.contains(BuiltinLintPlugins::VITEST) { + plugins = plugins.union(BuiltinLintPlugins::JEST); } let mut rules: Vec<_> = self @@ -320,14 +322,14 @@ impl ConfigStoreBuilder { } /// Warn for all correctness rules in the given set of plugins. - fn warn_correctness(plugins: LintPlugins) -> FxHashMap { + fn warn_correctness(plugins: BuiltinLintPlugins) -> FxHashMap { RULES .iter() .filter(|rule| { // NOTE: this logic means there's no way to disable ESLint // correctness rules. I think that's fine for now. rule.category() == RuleCategory::Correctness - && plugins.contains(LintPlugins::from(rule.plugin_name())) + && plugins.contains(BuiltinLintPlugins::from(rule.plugin_name())) }) .map(|rule| (rule.clone(), AllowWarnDeny::Warn)) .collect() @@ -431,7 +433,7 @@ mod test { #[test] fn test_builder_default() { let builder = ConfigStoreBuilder::default(); - assert_eq!(builder.plugins(), LintPlugins::default()); + assert_eq!(builder.plugins(), BuiltinLintPlugins::default()); // populated with all correctness-level ESLint rules at a "warn" severity assert!(!builder.rules.is_empty()); @@ -450,7 +452,7 @@ mod test { #[test] fn test_builder_empty() { let builder = ConfigStoreBuilder::empty(); - assert_eq!(builder.plugins(), LintPlugins::default()); + assert_eq!(builder.plugins(), BuiltinLintPlugins::default()); assert!(builder.rules.is_empty()); } @@ -555,7 +557,7 @@ mod test { let builder = ConfigStoreBuilder::default(); let initial_rule_count = builder.rules.len(); - let builder = builder.and_plugins(LintPlugins::IMPORT, true); + let builder = builder.and_plugins(BuiltinLintPlugins::IMPORT, true); assert_eq!( initial_rule_count, builder.rules.len(), @@ -566,18 +568,18 @@ mod test { #[test] fn test_rules_after_plugin_removal() { // sanity check: the plugin we're removing is, in fact, enabled by default. - assert!(LintPlugins::default().contains(LintPlugins::TYPESCRIPT)); + assert!(BuiltinLintPlugins::default().contains(BuiltinLintPlugins::TYPESCRIPT)); - let mut desired_plugins = LintPlugins::default(); - desired_plugins.set(LintPlugins::TYPESCRIPT, false); + let mut desired_plugins = BuiltinLintPlugins::default(); + desired_plugins.set(BuiltinLintPlugins::TYPESCRIPT, false); let linter = ConfigStoreBuilder::default().with_plugins(desired_plugins).build(); for (rule, _) in linter.base.rules.iter() { let name = rule.name(); let plugin = rule.plugin_name(); assert_ne!( - LintPlugins::from(plugin), - LintPlugins::TYPESCRIPT, + BuiltinLintPlugins::from(plugin), + BuiltinLintPlugins::TYPESCRIPT, "{plugin}/{name} is in the rules list after typescript plugin has been disabled" ); } @@ -593,35 +595,39 @@ mod test { // ========================================================================================== // Enable eslint plugin. Since it's already enabled, this does nothing. - assert!(initial_plugins.contains(LintPlugins::ESLINT)); // sanity check that eslint is + assert!(initial_plugins.contains(BuiltinLintPlugins::ESLINT)); // sanity check that eslint is // enabled - let builder = builder.and_plugins(LintPlugins::ESLINT, true); + let builder = builder.and_plugins(BuiltinLintPlugins::ESLINT, true); assert_eq!(initial_plugins, builder.plugins()); // Disable import plugin. Since it's not already enabled, this is also a no-op. - assert!(!builder.plugins().contains(LintPlugins::IMPORT)); // sanity check that it's not + assert!(!builder.plugins().contains(BuiltinLintPlugins::IMPORT)); // sanity check that it's not // already enabled - let builder = builder.and_plugins(LintPlugins::IMPORT, false); + let builder = builder.and_plugins(BuiltinLintPlugins::IMPORT, false); assert_eq!(initial_plugins, builder.plugins()); // Enable import plugin. Since it's not already enabled, this turns it on. - let builder = builder.and_plugins(LintPlugins::IMPORT, true); - assert_eq!(LintPlugins::default().union(LintPlugins::IMPORT), builder.plugins()); + let builder = builder.and_plugins(BuiltinLintPlugins::IMPORT, true); + assert_eq!( + BuiltinLintPlugins::default().union(BuiltinLintPlugins::IMPORT), + builder.plugins() + ); assert_ne!(initial_plugins, builder.plugins()); // Turn import back off, resetting plugins to the initial state - let builder = builder.and_plugins(LintPlugins::IMPORT, false); + let builder = builder.and_plugins(BuiltinLintPlugins::IMPORT, false); assert_eq!(initial_plugins, builder.plugins()); // ========================================================================================== // Test ConfigStoreBuilder::with_plugins, which _does_ override plugins // ========================================================================================== - let builder = builder.with_plugins(LintPlugins::ESLINT); - assert_eq!(LintPlugins::ESLINT, builder.plugins()); + let builder = builder.with_plugins(BuiltinLintPlugins::ESLINT); + assert_eq!(BuiltinLintPlugins::ESLINT, builder.plugins()); - let expected_plugins = - LintPlugins::ESLINT.union(LintPlugins::TYPESCRIPT).union(LintPlugins::NEXTJS); + let expected_plugins = BuiltinLintPlugins::ESLINT + .union(BuiltinLintPlugins::TYPESCRIPT) + .union(BuiltinLintPlugins::NEXTJS); let builder = builder.with_plugins(expected_plugins); assert_eq!(expected_plugins, builder.plugins()); } @@ -838,7 +844,7 @@ mod test { "#, ); // Check that default plugins are correctly set - assert_eq!(default_config.plugins(), LintPlugins::default()); + assert_eq!(default_config.plugins(), BuiltinLintPlugins::default()); // Test 2: Parent config with explicitly specified plugins let parent_config = config_store_from_str( @@ -848,13 +854,19 @@ mod test { } "#, ); - assert_eq!(parent_config.plugins(), LintPlugins::REACT | LintPlugins::TYPESCRIPT); + assert_eq!( + parent_config.plugins(), + BuiltinLintPlugins::REACT | BuiltinLintPlugins::TYPESCRIPT + ); // Test 3: Child config that extends parent without specifying plugins // Should inherit parent's plugins let child_no_plugins_config = config_store_from_path("fixtures/extends_config/plugins/child_no_plugins.json"); - assert_eq!(child_no_plugins_config.plugins(), LintPlugins::REACT | LintPlugins::TYPESCRIPT); + assert_eq!( + child_no_plugins_config.plugins(), + BuiltinLintPlugins::REACT | BuiltinLintPlugins::TYPESCRIPT + ); // Test 4: Child config that extends parent and specifies additional plugins // Should have parent's plugins plus its own @@ -862,7 +874,7 @@ mod test { config_store_from_path("fixtures/extends_config/plugins/child_with_plugins.json"); assert_eq!( child_with_plugins_config.plugins(), - LintPlugins::REACT | LintPlugins::TYPESCRIPT | LintPlugins::JEST + BuiltinLintPlugins::REACT | BuiltinLintPlugins::TYPESCRIPT | BuiltinLintPlugins::JEST ); // Test 5: Empty plugins array should result in empty plugins @@ -873,7 +885,7 @@ mod test { } "#, ); - assert_eq!(empty_plugins_config.plugins(), LintPlugins::empty()); + assert_eq!(empty_plugins_config.plugins(), BuiltinLintPlugins::empty()); // Test 6: Extending multiple config files with plugins let config = config_store_from_str( @@ -886,8 +898,8 @@ mod test { } "#, ); - assert!(config.plugins().contains(LintPlugins::JEST)); - assert!(config.plugins().contains(LintPlugins::REACT)); + assert!(config.plugins().contains(BuiltinLintPlugins::JEST)); + assert!(config.plugins().contains(BuiltinLintPlugins::REACT)); // Test 7: Adding more plugins to extended configs let config = config_store_from_str( @@ -903,7 +915,7 @@ mod test { ); assert_eq!( config.plugins(), - LintPlugins::JEST | LintPlugins::REACT | LintPlugins::TYPESCRIPT + BuiltinLintPlugins::JEST | BuiltinLintPlugins::REACT | BuiltinLintPlugins::TYPESCRIPT ); // Test 8: Extending a config with a plugin is the same as adding it directly @@ -941,7 +953,7 @@ mod test { } "#, ); - assert_eq!(config.plugins(), LintPlugins::default()); + assert_eq!(config.plugins(), BuiltinLintPlugins::default()); assert!(config.rules().is_empty()); } diff --git a/crates/oxc_linter/src/config/config_store.rs b/crates/oxc_linter/src/config/config_store.rs index 7874717a07cdb..7f7b97407d229 100644 --- a/crates/oxc_linter/src/config/config_store.rs +++ b/crates/oxc_linter/src/config/config_store.rs @@ -5,7 +5,9 @@ use std::{ use rustc_hash::FxHashMap; -use super::{LintConfig, LintPlugins, categories::OxlintCategories, overrides::OxlintOverrides}; +use super::{ + BuiltinLintPlugins, LintConfig, categories::OxlintCategories, overrides::OxlintOverrides, +}; use crate::{ AllowWarnDeny, rules::{RULES, RuleEnum}, @@ -69,7 +71,7 @@ impl Config { } } - pub fn plugins(&self) -> LintPlugins { + pub fn plugins(&self) -> BuiltinLintPlugins { self.base.config.plugins } @@ -118,13 +120,13 @@ impl Config { let mut rules = self .base_rules .iter() - .filter(|(rule, _)| plugins.contains(LintPlugins::from(rule.plugin_name()))) + .filter(|(rule, _)| plugins.contains(BuiltinLintPlugins::from(rule.plugin_name()))) .cloned() .collect::>(); let all_rules = RULES .iter() - .filter(|rule| plugins.contains(LintPlugins::from(rule.plugin_name()))) + .filter(|rule| plugins.contains(BuiltinLintPlugins::from(rule.plugin_name()))) .cloned() .collect::>(); @@ -198,7 +200,7 @@ impl ConfigStore { &self.base.base.rules } - pub fn plugins(&self) -> LintPlugins { + pub fn plugins(&self) -> BuiltinLintPlugins { self.base.base.config.plugins } @@ -234,7 +236,7 @@ mod test { use super::{ConfigStore, OxlintOverrides}; use crate::{ - AllowWarnDeny, LintPlugins, RuleEnum, + AllowWarnDeny, BuiltinLintPlugins, RuleEnum, config::{ LintConfig, OxlintEnv, OxlintGlobals, OxlintSettings, categories::OxlintCategories, config_store::Config, @@ -369,7 +371,7 @@ mod test { #[test] fn test_add_plugins() { let base_config = LintConfig { - plugins: LintPlugins::IMPORT, + plugins: BuiltinLintPlugins::IMPORT, env: OxlintEnv::default(), settings: OxlintSettings::default(), globals: OxlintGlobals::default(), @@ -387,26 +389,29 @@ mod test { Config::new(vec![], OxlintCategories::default(), base_config, overrides), FxHashMap::default(), ); - assert_eq!(store.base.base.config.plugins, LintPlugins::IMPORT); + assert_eq!(store.base.base.config.plugins, BuiltinLintPlugins::IMPORT); let app = store.resolve("other.mjs".as_ref()).config; - assert_eq!(app.plugins, LintPlugins::IMPORT); + assert_eq!(app.plugins, BuiltinLintPlugins::IMPORT); let app = store.resolve("App.jsx".as_ref()).config; - assert_eq!(app.plugins, LintPlugins::IMPORT | LintPlugins::REACT); + assert_eq!(app.plugins, BuiltinLintPlugins::IMPORT | BuiltinLintPlugins::REACT); let app = store.resolve("App.ts".as_ref()).config; - assert_eq!(app.plugins, LintPlugins::IMPORT | LintPlugins::TYPESCRIPT); + assert_eq!(app.plugins, BuiltinLintPlugins::IMPORT | BuiltinLintPlugins::TYPESCRIPT); let app = store.resolve("App.tsx".as_ref()).config; - assert_eq!(app.plugins, LintPlugins::IMPORT | LintPlugins::REACT | LintPlugins::TYPESCRIPT); + assert_eq!( + app.plugins, + BuiltinLintPlugins::IMPORT | BuiltinLintPlugins::REACT | BuiltinLintPlugins::TYPESCRIPT + ); } #[test] fn test_add_env() { let base_config = LintConfig { env: OxlintEnv::default(), - plugins: LintPlugins::ESLINT, + plugins: BuiltinLintPlugins::ESLINT, settings: OxlintSettings::default(), globals: OxlintGlobals::default(), path: None, @@ -433,7 +438,7 @@ mod test { fn test_replace_env() { let base_config = LintConfig { env: OxlintEnv::from_iter(["es2024".into()]), - plugins: LintPlugins::ESLINT, + plugins: BuiltinLintPlugins::ESLINT, settings: OxlintSettings::default(), globals: OxlintGlobals::default(), path: None, @@ -460,7 +465,7 @@ mod test { fn test_add_globals() { let base_config = LintConfig { env: OxlintEnv::default(), - plugins: LintPlugins::ESLINT, + plugins: BuiltinLintPlugins::ESLINT, settings: OxlintSettings::default(), globals: OxlintGlobals::default(), path: None, @@ -490,7 +495,7 @@ mod test { fn test_replace_globals() { let base_config = LintConfig { env: OxlintEnv::default(), - plugins: LintPlugins::ESLINT, + plugins: BuiltinLintPlugins::ESLINT, settings: OxlintSettings::default(), globals: from_json!({ "React": "readonly", diff --git a/crates/oxc_linter/src/config/mod.rs b/crates/oxc_linter/src/config/mod.rs index 4cac7ced47d9f..b204e14569dc0 100644 --- a/crates/oxc_linter/src/config/mod.rs +++ b/crates/oxc_linter/src/config/mod.rs @@ -17,13 +17,13 @@ pub use env::OxlintEnv; pub use globals::{GlobalValue, OxlintGlobals}; pub use overrides::OxlintOverrides; pub use oxlintrc::Oxlintrc; -pub use plugins::LintPlugins; +pub use plugins::BuiltinLintPlugins; pub use rules::{ESLintRule, OxlintRules}; pub use settings::{OxlintSettings, jsdoc::JSDocPluginSettings}; #[derive(Debug, Default, Clone)] pub struct LintConfig { - pub(crate) plugins: LintPlugins, + pub(crate) plugins: BuiltinLintPlugins, pub(crate) settings: OxlintSettings, /// Environments enable and disable collections of global variables. pub(crate) env: OxlintEnv, diff --git a/crates/oxc_linter/src/config/overrides.rs b/crates/oxc_linter/src/config/overrides.rs index fab21d083a45b..e8a5cf3e56012 100644 --- a/crates/oxc_linter/src/config/overrides.rs +++ b/crates/oxc_linter/src/config/overrides.rs @@ -7,7 +7,7 @@ use std::{ use schemars::{JsonSchema, r#gen, schema::Schema}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de}; -use crate::{LintPlugins, OxlintEnv, OxlintGlobals, config::OxlintRules}; +use crate::{BuiltinLintPlugins, OxlintEnv, OxlintGlobals, config::OxlintRules}; // nominal wrapper required to add JsonSchema impl #[derive(Debug, Default, Clone, Deserialize, Serialize)] @@ -82,7 +82,7 @@ pub struct OxlintOverride { /// Optionally change what plugins are enabled for this override. When /// omitted, the base config's plugins are used. #[serde(default)] - pub plugins: Option, + pub plugins: Option, #[serde(default)] pub rules: OxlintRules, @@ -196,14 +196,17 @@ mod test { "plugins": [], })) .unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::empty())); + assert_eq!(config.plugins, Some(BuiltinLintPlugins::empty())); let config: OxlintOverride = from_value(json!({ "files": ["*.tsx"], "plugins": ["typescript", "react"], })) .unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::REACT | LintPlugins::TYPESCRIPT)); + assert_eq!( + config.plugins, + Some(BuiltinLintPlugins::REACT | BuiltinLintPlugins::TYPESCRIPT) + ); } #[test] diff --git a/crates/oxc_linter/src/config/oxlintrc.rs b/crates/oxc_linter/src/config/oxlintrc.rs index fbac6e9c5a54c..599a6e81fea48 100644 --- a/crates/oxc_linter/src/config/oxlintrc.rs +++ b/crates/oxc_linter/src/config/oxlintrc.rs @@ -13,7 +13,8 @@ use crate::utils::read_to_string; use super::{ categories::OxlintCategories, env::OxlintEnv, globals::OxlintGlobals, - overrides::OxlintOverrides, plugins::LintPlugins, rules::OxlintRules, settings::OxlintSettings, + overrides::OxlintOverrides, plugins::BuiltinLintPlugins, rules::OxlintRules, + settings::OxlintSettings, }; /// Oxlint Configuration File @@ -63,7 +64,7 @@ use super::{ #[serde(default)] #[non_exhaustive] pub struct Oxlintrc { - pub plugins: Option, + pub plugins: Option, pub categories: OxlintCategories, /// Example /// @@ -234,7 +235,7 @@ mod test { #[test] fn test_oxlintrc_de_plugins_empty_array() { let config: Oxlintrc = serde_json::from_value(json!({ "plugins": [] })).unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::empty())); + assert_eq!(config.plugins, Some(BuiltinLintPlugins::empty())); } #[test] @@ -246,17 +247,20 @@ mod test { #[test] fn test_oxlintrc_specifying_plugins_will_override() { let config: Oxlintrc = serde_json::from_str(r#"{ "plugins": ["react", "oxc"] }"#).unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::REACT.union(LintPlugins::OXC))); + assert_eq!(config.plugins, Some(BuiltinLintPlugins::REACT.union(BuiltinLintPlugins::OXC))); let config: Oxlintrc = serde_json::from_str(r#"{ "plugins": ["typescript", "unicorn"] }"#).unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::TYPESCRIPT.union(LintPlugins::UNICORN))); + assert_eq!( + config.plugins, + Some(BuiltinLintPlugins::TYPESCRIPT.union(BuiltinLintPlugins::UNICORN)) + ); let config: Oxlintrc = serde_json::from_str(r#"{ "plugins": ["typescript", "unicorn", "react", "oxc", "import", "jsdoc", "jest", "vitest", "jsx-a11y", "nextjs", "react-perf", "promise", "node"] }"#).unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::all())); + assert_eq!(config.plugins, Some(BuiltinLintPlugins::all())); let config: Oxlintrc = serde_json::from_str(r#"{ "plugins": ["typescript", "@typescript-eslint"] }"#).unwrap(); - assert_eq!(config.plugins, Some(LintPlugins::TYPESCRIPT)); + assert_eq!(config.plugins, Some(BuiltinLintPlugins::TYPESCRIPT)); } #[test] diff --git a/crates/oxc_linter/src/config/plugins.rs b/crates/oxc_linter/src/config/plugins.rs index b95a1784e498b..44383898b0298 100644 --- a/crates/oxc_linter/src/config/plugins.rs +++ b/crates/oxc_linter/src/config/plugins.rs @@ -9,7 +9,7 @@ use serde::{ bitflags! { // NOTE: may be increased to a u32 if needed #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] - pub struct LintPlugins: u16 { + pub struct BuiltinLintPlugins: u16 { /// Not really a plugin. Included for completeness. const ESLINT = 0; /// `eslint-plugin-react`, plus `eslint-plugin-react-hooks` @@ -40,121 +40,122 @@ bitflags! { const NODE = 1 << 12; } } -impl Default for LintPlugins { + +impl Default for BuiltinLintPlugins { #[inline] fn default() -> Self { - LintPlugins::UNICORN | LintPlugins::TYPESCRIPT | LintPlugins::OXC + BuiltinLintPlugins::UNICORN | BuiltinLintPlugins::TYPESCRIPT | BuiltinLintPlugins::OXC } } -impl LintPlugins { +impl BuiltinLintPlugins { /// Returns `true` if the Vitest plugin is enabled. #[inline] pub fn has_vitest(self) -> bool { - self.contains(LintPlugins::VITEST) + self.contains(BuiltinLintPlugins::VITEST) } /// Returns `true` if the Jest plugin is enabled. #[inline] pub fn has_jest(self) -> bool { - self.contains(LintPlugins::JEST) + self.contains(BuiltinLintPlugins::JEST) } /// Returns `true` if Jest or Vitest plugins are enabled. #[inline] pub fn has_test(self) -> bool { - self.intersects(LintPlugins::JEST.union(LintPlugins::VITEST)) + self.intersects(BuiltinLintPlugins::JEST.union(BuiltinLintPlugins::VITEST)) } /// Returns `true` if the import plugin is enabled. #[inline] pub fn has_import(self) -> bool { - self.contains(LintPlugins::IMPORT) + self.contains(BuiltinLintPlugins::IMPORT) } } -impl From<&str> for LintPlugins { +impl From<&str> for BuiltinLintPlugins { fn from(value: &str) -> Self { match value { - "react" | "react-hooks" | "react_hooks" => LintPlugins::REACT, - "unicorn" => LintPlugins::UNICORN, + "react" | "react-hooks" | "react_hooks" => BuiltinLintPlugins::REACT, + "unicorn" => BuiltinLintPlugins::UNICORN, "typescript" | "typescript-eslint" | "typescript_eslint" | "@typescript-eslint" => { - LintPlugins::TYPESCRIPT + BuiltinLintPlugins::TYPESCRIPT } // deepscan for backwards compatibility. Those rules have been moved into oxc - "oxc" | "deepscan" => LintPlugins::OXC, + "oxc" | "deepscan" => BuiltinLintPlugins::OXC, // import-x has the same rules but better performance - "import" | "import-x" => LintPlugins::IMPORT, - "jsdoc" => LintPlugins::JSDOC, - "jest" => LintPlugins::JEST, - "vitest" => LintPlugins::VITEST, - "jsx-a11y" | "jsx_a11y" => LintPlugins::JSX_A11Y, - "nextjs" => LintPlugins::NEXTJS, - "react-perf" | "react_perf" => LintPlugins::REACT_PERF, - "promise" => LintPlugins::PROMISE, - "node" => LintPlugins::NODE, + "import" | "import-x" => BuiltinLintPlugins::IMPORT, + "jsdoc" => BuiltinLintPlugins::JSDOC, + "jest" => BuiltinLintPlugins::JEST, + "vitest" => BuiltinLintPlugins::VITEST, + "jsx-a11y" | "jsx_a11y" => BuiltinLintPlugins::JSX_A11Y, + "nextjs" => BuiltinLintPlugins::NEXTJS, + "react-perf" | "react_perf" => BuiltinLintPlugins::REACT_PERF, + "promise" => BuiltinLintPlugins::PROMISE, + "node" => BuiltinLintPlugins::NODE, // "eslint" is not really a plugin, so it's 'empty'. This has the added benefit of // making it the default value. - _ => LintPlugins::empty(), + _ => BuiltinLintPlugins::empty(), } } } -impl From for &'static str { - fn from(value: LintPlugins) -> Self { +impl From for &'static str { + fn from(value: BuiltinLintPlugins) -> Self { match value { - LintPlugins::REACT => "react", - LintPlugins::UNICORN => "unicorn", - LintPlugins::TYPESCRIPT => "typescript", - LintPlugins::OXC => "oxc", - LintPlugins::IMPORT => "import", - LintPlugins::JSDOC => "jsdoc", - LintPlugins::JEST => "jest", - LintPlugins::VITEST => "vitest", - LintPlugins::JSX_A11Y => "jsx-a11y", - LintPlugins::NEXTJS => "nextjs", - LintPlugins::REACT_PERF => "react-perf", - LintPlugins::PROMISE => "promise", - LintPlugins::NODE => "node", + BuiltinLintPlugins::REACT => "react", + BuiltinLintPlugins::UNICORN => "unicorn", + BuiltinLintPlugins::TYPESCRIPT => "typescript", + BuiltinLintPlugins::OXC => "oxc", + BuiltinLintPlugins::IMPORT => "import", + BuiltinLintPlugins::JSDOC => "jsdoc", + BuiltinLintPlugins::JEST => "jest", + BuiltinLintPlugins::VITEST => "vitest", + BuiltinLintPlugins::JSX_A11Y => "jsx-a11y", + BuiltinLintPlugins::NEXTJS => "nextjs", + BuiltinLintPlugins::REACT_PERF => "react-perf", + BuiltinLintPlugins::PROMISE => "promise", + BuiltinLintPlugins::NODE => "node", _ => "", } } } -impl> FromIterator for LintPlugins { +impl> FromIterator for BuiltinLintPlugins { fn from_iter>(iter: T) -> Self { iter.into_iter() .map(|plugin| plugin.as_ref().into()) - .fold(LintPlugins::empty(), LintPlugins::union) + .fold(BuiltinLintPlugins::empty(), BuiltinLintPlugins::union) } } -impl<'de> Deserialize<'de> for LintPlugins { +impl<'de> Deserialize<'de> for BuiltinLintPlugins { fn deserialize>(deserializer: D) -> Result { struct LintPluginsVisitor; impl<'de> de::Visitor<'de> for LintPluginsVisitor { - type Value = LintPlugins; + type Value = BuiltinLintPlugins; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a list of plugin names") } fn visit_str(self, value: &str) -> Result { - Ok(LintPlugins::from(value)) + Ok(BuiltinLintPlugins::from(value)) } fn visit_string(self, v: String) -> Result where E: de::Error, { - Ok(LintPlugins::from(v.as_str())) + Ok(BuiltinLintPlugins::from(v.as_str())) } fn visit_seq(self, mut seq: A) -> Result where A: de::SeqAccess<'de>, { - let mut plugins = LintPlugins::empty(); + let mut plugins = BuiltinLintPlugins::empty(); loop { // serde_json::from_str will provide an &str, while // serde_json::from_value provides a String. The former is @@ -182,14 +183,14 @@ impl<'de> Deserialize<'de> for LintPlugins { } } -impl Serialize for LintPlugins { +impl Serialize for BuiltinLintPlugins { fn serialize(&self, serializer: S) -> Result { let vec: Vec<&str> = self.iter().map(Into::into).collect(); vec.serialize(serializer) } } -impl JsonSchema for LintPlugins { +impl JsonSchema for BuiltinLintPlugins { fn schema_name() -> String { "LintPlugins".to_string() } diff --git a/crates/oxc_linter/src/context/host.rs b/crates/oxc_linter/src/context/host.rs index 44a8d888a98d0..122bd235c3645 100644 --- a/crates/oxc_linter/src/context/host.rs +++ b/crates/oxc_linter/src/context/host.rs @@ -6,7 +6,7 @@ use oxc_span::{SourceType, Span}; use crate::{ AllowWarnDeny, FrameworkFlags, - config::{LintConfig, LintPlugins}, + config::{BuiltinLintPlugins, LintConfig}, disable_directives::{DisableDirectives, DisableDirectivesBuilder, RuleCommentType}, fixer::{Fix, FixKind, Message, PossibleFixes}, frameworks, @@ -131,7 +131,7 @@ impl<'a> ContextHost<'a> { } #[inline] - pub fn plugins(&self) -> &LintPlugins { + pub fn plugins(&self) -> &BuiltinLintPlugins { &self.config.plugins } diff --git a/crates/oxc_linter/src/lib.rs b/crates/oxc_linter/src/lib.rs index dd83afb192efe..18c75ef97263e 100644 --- a/crates/oxc_linter/src/lib.rs +++ b/crates/oxc_linter/src/lib.rs @@ -29,8 +29,8 @@ use oxc_semantic::{AstNode, Semantic}; pub use crate::{ config::{ - Config, ConfigBuilderError, ConfigStore, ConfigStoreBuilder, ESLintRule, LintPlugins, - Oxlintrc, + BuiltinLintPlugins, Config, ConfigBuilderError, ConfigStore, ConfigStoreBuilder, + ESLintRule, Oxlintrc, }, context::LintContext, external_linter::{ diff --git a/crates/oxc_linter/src/tester.rs b/crates/oxc_linter/src/tester.rs index b3046f18aea77..fe269565b9429 100644 --- a/crates/oxc_linter/src/tester.rs +++ b/crates/oxc_linter/src/tester.rs @@ -14,8 +14,8 @@ use serde::Deserialize; use serde_json::{Value, json}; use crate::{ - AllowWarnDeny, ConfigStore, ConfigStoreBuilder, LintPlugins, LintService, LintServiceOptions, - Linter, Oxlintrc, RuleEnum, + AllowWarnDeny, BuiltinLintPlugins, ConfigStore, ConfigStoreBuilder, LintService, + LintServiceOptions, Linter, Oxlintrc, RuleEnum, fixer::{FixKind, Fixer}, options::LintOptions, rules::RULES, @@ -232,7 +232,7 @@ pub struct Tester { /// See: [insta::Settings::set_snapshot_suffix] snapshot_suffix: Option<&'static str>, current_working_directory: Box, - plugins: LintPlugins, + plugins: BuiltinLintPlugins, } impl Tester { @@ -259,7 +259,7 @@ impl Tester { snapshot: String::new(), snapshot_suffix: None, current_working_directory, - plugins: LintPlugins::default(), + plugins: BuiltinLintPlugins::default(), } } @@ -304,37 +304,37 @@ impl Tester { } pub fn with_import_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::IMPORT, yes); + self.plugins.set(BuiltinLintPlugins::IMPORT, yes); self } pub fn with_jest_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::JEST, yes); + self.plugins.set(BuiltinLintPlugins::JEST, yes); self } pub fn with_vitest_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::VITEST, yes); + self.plugins.set(BuiltinLintPlugins::VITEST, yes); self } pub fn with_jsx_a11y_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::JSX_A11Y, yes); + self.plugins.set(BuiltinLintPlugins::JSX_A11Y, yes); self } pub fn with_nextjs_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::NEXTJS, yes); + self.plugins.set(BuiltinLintPlugins::NEXTJS, yes); self } pub fn with_react_perf_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::REACT_PERF, yes); + self.plugins.set(BuiltinLintPlugins::REACT_PERF, yes); self } pub fn with_node_plugin(mut self, yes: bool) -> Self { - self.plugins.set(LintPlugins::NODE, yes); + self.plugins.set(BuiltinLintPlugins::NODE, yes); self } @@ -514,7 +514,7 @@ impl Tester { ) .unwrap() }) - .with_plugins(self.plugins.union(LintPlugins::from(self.plugin_name))) + .with_plugins(self.plugins.union(BuiltinLintPlugins::from(self.plugin_name))) .with_rule(rule, AllowWarnDeny::Warn) .build(), FxHashMap::default(), diff --git a/tasks/website/src/linter/rules/doc_page.rs b/tasks/website/src/linter/rules/doc_page.rs index a379bd7875110..f6f1ad129ab4c 100644 --- a/tasks/website/src/linter/rules/doc_page.rs +++ b/tasks/website/src/linter/rules/doc_page.rs @@ -6,7 +6,7 @@ use std::{ path::PathBuf, }; -use oxc_linter::{LintPlugins, table::RuleTableRow}; +use oxc_linter::{BuiltinLintPlugins, table::RuleTableRow}; use schemars::{ JsonSchema, SchemaGenerator, schema::{InstanceType, Schema, SchemaObject, SingleOrVec}, @@ -164,8 +164,8 @@ fn rule_source(rule: &RuleTableRow) -> String { /// - Example: `eslint` => true /// - Example: `jest` => false fn is_default_plugin(plugin: &str) -> bool { - let plugin = LintPlugins::from(plugin); - LintPlugins::default().contains(plugin) + let plugin = BuiltinLintPlugins::from(plugin); + BuiltinLintPlugins::default().contains(plugin) } /// Returns the normalized plugin name. @@ -173,7 +173,7 @@ fn is_default_plugin(plugin: &str) -> bool { /// - Example: `eslint` -> `eslint` /// - Example: `jsx_a11y` -> `jsx-a11y` fn get_normalized_plugin_name(plugin: &str) -> &str { - LintPlugins::from(plugin).into() + BuiltinLintPlugins::from(plugin).into() } fn how_to_use(rule: &RuleTableRow) -> String {