mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(linter): move LintPlugins from LintOptions to LintConfig (#6932)
Pure refactor. Moves plugin settings from linter options (which control the linter's behavior on a global level) and linter config ("which may or may not get adjusted on each file).
This commit is contained in:
parent
1691cab507
commit
8f1460eba3
10 changed files with 58 additions and 34 deletions
|
|
@ -7,8 +7,7 @@ use oxc_span::CompactStr;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{ESLintRule, OxlintRules},
|
config::{ESLintRule, LintPlugins, OxlintRules},
|
||||||
options::LintPlugins,
|
|
||||||
rules::RULES,
|
rules::RULES,
|
||||||
AllowWarnDeny, FixKind, FrameworkFlags, LintConfig, LintFilter, LintFilterKind, LintOptions,
|
AllowWarnDeny, FixKind, FrameworkFlags, LintConfig, LintFilter, LintFilterKind, LintOptions,
|
||||||
Linter, Oxlintrc, RuleCategory, RuleEnum, RuleWithSeverity,
|
Linter, Oxlintrc, RuleCategory, RuleEnum, RuleWithSeverity,
|
||||||
|
|
@ -35,8 +34,11 @@ impl LinterBuilder {
|
||||||
/// You can think of this as `oxlint -A all`.
|
/// You can think of this as `oxlint -A all`.
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
let options = LintOptions::default();
|
let options = LintOptions::default();
|
||||||
let cache = RulesCache::new(options.plugins);
|
let config = LintConfig::default();
|
||||||
Self { rules: FxHashSet::default(), options, config: LintConfig::default(), cache }
|
let rules = FxHashSet::default();
|
||||||
|
let cache = RulesCache::new(config.plugins);
|
||||||
|
|
||||||
|
Self { rules, options, config, cache }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Warn on all rules in all plugins and categories, including those in `nursery`.
|
/// Warn on all rules in all plugins and categories, including those in `nursery`.
|
||||||
|
|
@ -44,15 +46,16 @@ impl LinterBuilder {
|
||||||
///
|
///
|
||||||
/// You can think of this as `oxlint -W all -W nursery`.
|
/// You can think of this as `oxlint -W all -W nursery`.
|
||||||
pub fn all() -> Self {
|
pub fn all() -> Self {
|
||||||
let options = LintOptions { plugins: LintPlugins::all(), ..LintOptions::default() };
|
let options = LintOptions::default();
|
||||||
let cache = RulesCache::new(options.plugins);
|
let config = LintConfig { plugins: LintPlugins::all(), ..LintConfig::default() };
|
||||||
|
let cache = RulesCache::new(config.plugins);
|
||||||
Self {
|
Self {
|
||||||
rules: RULES
|
rules: RULES
|
||||||
.iter()
|
.iter()
|
||||||
.map(|rule| RuleWithSeverity { rule: rule.clone(), severity: AllowWarnDeny::Warn })
|
.map(|rule| RuleWithSeverity { rule: rule.clone(), severity: AllowWarnDeny::Warn })
|
||||||
.collect(),
|
.collect(),
|
||||||
options,
|
options,
|
||||||
config: LintConfig::default(),
|
config,
|
||||||
cache,
|
cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,11 +79,11 @@ impl LinterBuilder {
|
||||||
let Oxlintrc { plugins, settings, env, globals, categories, rules: oxlintrc_rules } =
|
let Oxlintrc { plugins, settings, env, globals, categories, rules: oxlintrc_rules } =
|
||||||
oxlintrc;
|
oxlintrc;
|
||||||
|
|
||||||
let config = LintConfig { settings, env, globals };
|
let config = LintConfig { plugins, settings, env, globals };
|
||||||
let options = LintOptions { plugins, ..Default::default() };
|
let options = LintOptions::default();
|
||||||
let rules =
|
let rules =
|
||||||
if start_empty { FxHashSet::default() } else { Self::warn_correctness(plugins) };
|
if start_empty { FxHashSet::default() } else { Self::warn_correctness(plugins) };
|
||||||
let cache = RulesCache::new(options.plugins);
|
let cache = RulesCache::new(config.plugins);
|
||||||
let mut builder = Self { rules, options, config, cache };
|
let mut builder = Self { rules, options, config, cache };
|
||||||
|
|
||||||
if !categories.is_empty() {
|
if !categories.is_empty() {
|
||||||
|
|
@ -128,7 +131,7 @@ impl LinterBuilder {
|
||||||
/// [`and_plugins`]: LinterBuilder::and_plugins
|
/// [`and_plugins`]: LinterBuilder::and_plugins
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_plugins(mut self, plugins: LintPlugins) -> Self {
|
pub fn with_plugins(mut self, plugins: LintPlugins) -> Self {
|
||||||
self.options.plugins = plugins;
|
self.config.plugins = plugins;
|
||||||
self.cache.set_plugins(plugins);
|
self.cache.set_plugins(plugins);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
@ -139,14 +142,14 @@ impl LinterBuilder {
|
||||||
/// rules.
|
/// rules.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn and_plugins(mut self, plugins: LintPlugins, enabled: bool) -> Self {
|
pub fn and_plugins(mut self, plugins: LintPlugins, enabled: bool) -> Self {
|
||||||
self.options.plugins.set(plugins, enabled);
|
self.config.plugins.set(plugins, enabled);
|
||||||
self.cache.set_plugins(self.options.plugins);
|
self.cache.set_plugins(self.config.plugins);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn plugins(&self) -> LintPlugins {
|
pub fn plugins(&self) -> LintPlugins {
|
||||||
self.options.plugins
|
self.config.plugins
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ mod categories;
|
||||||
mod env;
|
mod env;
|
||||||
mod globals;
|
mod globals;
|
||||||
mod oxlintrc;
|
mod oxlintrc;
|
||||||
|
mod plugins;
|
||||||
mod rules;
|
mod rules;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
|
||||||
|
|
@ -9,6 +10,7 @@ pub use self::{
|
||||||
env::OxlintEnv,
|
env::OxlintEnv,
|
||||||
globals::OxlintGlobals,
|
globals::OxlintGlobals,
|
||||||
oxlintrc::Oxlintrc,
|
oxlintrc::Oxlintrc,
|
||||||
|
plugins::LintPlugins,
|
||||||
rules::ESLintRule,
|
rules::ESLintRule,
|
||||||
rules::OxlintRules,
|
rules::OxlintRules,
|
||||||
settings::{jsdoc::JSDocPluginSettings, OxlintSettings},
|
settings::{jsdoc::JSDocPluginSettings, OxlintSettings},
|
||||||
|
|
@ -16,6 +18,7 @@ pub use self::{
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct LintConfig {
|
pub(crate) struct LintConfig {
|
||||||
|
pub(crate) plugins: LintPlugins,
|
||||||
pub(crate) settings: OxlintSettings,
|
pub(crate) settings: OxlintSettings,
|
||||||
/// Environments enable and disable collections of global variables.
|
/// Environments enable and disable collections of global variables.
|
||||||
pub(crate) env: OxlintEnv,
|
pub(crate) env: OxlintEnv,
|
||||||
|
|
@ -25,7 +28,12 @@ pub(crate) struct LintConfig {
|
||||||
|
|
||||||
impl From<Oxlintrc> for LintConfig {
|
impl From<Oxlintrc> for LintConfig {
|
||||||
fn from(config: Oxlintrc) -> Self {
|
fn from(config: Oxlintrc) -> Self {
|
||||||
Self { settings: config.settings, env: config.env, globals: config.globals }
|
Self {
|
||||||
|
plugins: config.plugins,
|
||||||
|
settings: config.settings,
|
||||||
|
env: config.env,
|
||||||
|
globals: config.globals,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
categories::OxlintCategories, env::OxlintEnv, globals::OxlintGlobals, rules::OxlintRules,
|
categories::OxlintCategories, env::OxlintEnv, globals::OxlintGlobals, plugins::LintPlugins,
|
||||||
settings::OxlintSettings,
|
rules::OxlintRules, settings::OxlintSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{options::LintPlugins, utils::read_to_string};
|
use crate::utils::read_to_string;
|
||||||
|
|
||||||
/// Oxlint Configuration File
|
/// Oxlint Configuration File
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ use oxc_span::SourceType;
|
||||||
use std::{cell::RefCell, path::Path, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, path::Path, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::LintConfig,
|
config::{LintConfig, LintPlugins},
|
||||||
disable_directives::{DisableDirectives, DisableDirectivesBuilder},
|
disable_directives::{DisableDirectives, DisableDirectivesBuilder},
|
||||||
fixer::{FixKind, Message},
|
fixer::{FixKind, Message},
|
||||||
frameworks,
|
frameworks,
|
||||||
options::{LintOptions, LintPlugins},
|
options::LintOptions,
|
||||||
utils, FrameworkFlags, RuleWithSeverity,
|
utils, FrameworkFlags, RuleWithSeverity,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -68,6 +68,7 @@ impl<'a> ContextHost<'a> {
|
||||||
file_path: P,
|
file_path: P,
|
||||||
semantic: Rc<Semantic<'a>>,
|
semantic: Rc<Semantic<'a>>,
|
||||||
options: LintOptions,
|
options: LintOptions,
|
||||||
|
config: Arc<LintConfig>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
const DIAGNOSTICS_INITIAL_CAPACITY: usize = 512;
|
const DIAGNOSTICS_INITIAL_CAPACITY: usize = 512;
|
||||||
|
|
||||||
|
|
@ -82,6 +83,7 @@ impl<'a> ContextHost<'a> {
|
||||||
DisableDirectivesBuilder::new().build(semantic.source_text(), semantic.comments());
|
DisableDirectivesBuilder::new().build(semantic.source_text(), semantic.comments());
|
||||||
|
|
||||||
let file_path = file_path.as_ref().to_path_buf().into_boxed_path();
|
let file_path = file_path.as_ref().to_path_buf().into_boxed_path();
|
||||||
|
let plugins = config.plugins;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
semantic,
|
semantic,
|
||||||
|
|
@ -89,17 +91,25 @@ impl<'a> ContextHost<'a> {
|
||||||
diagnostics: RefCell::new(Vec::with_capacity(DIAGNOSTICS_INITIAL_CAPACITY)),
|
diagnostics: RefCell::new(Vec::with_capacity(DIAGNOSTICS_INITIAL_CAPACITY)),
|
||||||
fix: options.fix,
|
fix: options.fix,
|
||||||
file_path,
|
file_path,
|
||||||
config: Arc::new(LintConfig::default()),
|
config,
|
||||||
frameworks: options.framework_hints,
|
frameworks: options.framework_hints,
|
||||||
plugins: options.plugins,
|
plugins,
|
||||||
}
|
}
|
||||||
.sniff_for_frameworks()
|
.sniff_for_frameworks()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the linter configuration for this context.
|
/// Set the linter configuration for this context.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(dead_code)] // will be used in up-stack PR
|
||||||
pub fn with_config(mut self, config: &Arc<LintConfig>) -> Self {
|
pub fn with_config(mut self, config: &Arc<LintConfig>) -> Self {
|
||||||
|
let plugins = config.plugins;
|
||||||
self.config = Arc::clone(config);
|
self.config = Arc::clone(config);
|
||||||
|
|
||||||
|
if self.plugins != plugins {
|
||||||
|
self.plugins = plugins;
|
||||||
|
return self.sniff_for_frameworks();
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@ use utils::iter_possible_jest_call_node;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
builder::LinterBuilder,
|
builder::LinterBuilder,
|
||||||
config::Oxlintrc,
|
config::{LintPlugins, Oxlintrc},
|
||||||
context::LintContext,
|
context::LintContext,
|
||||||
fixer::FixKind,
|
fixer::FixKind,
|
||||||
frameworks::FrameworkFlags,
|
frameworks::FrameworkFlags,
|
||||||
options::{AllowWarnDeny, InvalidFilterKind, LintFilter, LintFilterKind, LintPlugins},
|
options::{AllowWarnDeny, InvalidFilterKind, LintFilter, LintFilterKind},
|
||||||
rule::{RuleCategory, RuleFixMeta, RuleMeta, RuleWithSeverity},
|
rule::{RuleCategory, RuleFixMeta, RuleMeta, RuleWithSeverity},
|
||||||
service::{LintService, LintServiceOptions},
|
service::{LintService, LintServiceOptions},
|
||||||
};
|
};
|
||||||
|
|
@ -115,7 +115,7 @@ impl Linter {
|
||||||
|
|
||||||
pub fn run<'a>(&self, path: &Path, semantic: Rc<Semantic<'a>>) -> Vec<Message<'a>> {
|
pub fn run<'a>(&self, path: &Path, semantic: Rc<Semantic<'a>>) -> Vec<Message<'a>> {
|
||||||
let ctx_host =
|
let ctx_host =
|
||||||
Rc::new(ContextHost::new(path, semantic, self.options).with_config(&self.config));
|
Rc::new(ContextHost::new(path, semantic, self.options, Arc::clone(&self.config)));
|
||||||
|
|
||||||
let rules = self
|
let rules = self
|
||||||
.rules
|
.rules
|
||||||
|
|
@ -126,7 +126,7 @@ impl Linter {
|
||||||
let semantic = ctx_host.semantic();
|
let semantic = ctx_host.semantic();
|
||||||
|
|
||||||
let should_run_on_jest_node =
|
let should_run_on_jest_node =
|
||||||
self.options.plugins.has_test() && ctx_host.frameworks().is_test();
|
self.config.plugins.has_test() && ctx_host.frameworks().is_test();
|
||||||
|
|
||||||
// IMPORTANT: We have two branches here for performance reasons:
|
// IMPORTANT: We have two branches here for performance reasons:
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::RuleCategory;
|
use crate::RuleCategory;
|
||||||
|
|
||||||
use super::{plugins::LintPlugins, AllowWarnDeny};
|
use super::AllowWarnDeny;
|
||||||
|
use crate::LintPlugins;
|
||||||
use std::{borrow::Cow, fmt};
|
use std::{borrow::Cow, fmt};
|
||||||
|
|
||||||
/// Enables, disables, and sets the severity of lint rules.
|
/// Enables, disables, and sets the severity of lint rules.
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
mod allow_warn_deny;
|
mod allow_warn_deny;
|
||||||
mod filter;
|
mod filter;
|
||||||
mod plugins;
|
|
||||||
|
|
||||||
pub use allow_warn_deny::AllowWarnDeny;
|
pub use allow_warn_deny::AllowWarnDeny;
|
||||||
pub use filter::{InvalidFilterKind, LintFilter, LintFilterKind};
|
pub use filter::{InvalidFilterKind, LintFilter, LintFilterKind};
|
||||||
pub use plugins::LintPlugins;
|
|
||||||
|
|
||||||
use crate::{fixer::FixKind, FrameworkFlags};
|
use crate::{fixer::FixKind, FrameworkFlags};
|
||||||
|
|
||||||
|
|
@ -14,5 +12,4 @@ use crate::{fixer::FixKind, FrameworkFlags};
|
||||||
pub(crate) struct LintOptions {
|
pub(crate) struct LintOptions {
|
||||||
pub fix: FixKind,
|
pub fix: FixKind,
|
||||||
pub framework_hints: FrameworkFlags,
|
pub framework_hints: FrameworkFlags,
|
||||||
pub plugins: LintPlugins,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use serde::Deserialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fixer::FixKind, options::LintPlugins, rules::RULES, AllowWarnDeny, Fixer, LintService,
|
fixer::FixKind, rules::RULES, AllowWarnDeny, Fixer, LintPlugins, LintService,
|
||||||
LintServiceOptions, LinterBuilder, Oxlintrc, RuleEnum, RuleWithSeverity,
|
LintServiceOptions, LinterBuilder, Oxlintrc, RuleEnum, RuleWithSeverity,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ pub fn is_equality_matcher(matcher: &KnownMemberExpressionProperty) -> bool {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::rc::Rc;
|
use std::{rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
use oxc_allocator::Allocator;
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
|
|
@ -322,8 +322,13 @@ mod test {
|
||||||
let semantic_ret = Rc::new(semantic_ret);
|
let semantic_ret = Rc::new(semantic_ret);
|
||||||
|
|
||||||
let build_ctx = |path: &'static str| {
|
let build_ctx = |path: &'static str| {
|
||||||
Rc::new(ContextHost::new(path, Rc::clone(&semantic_ret), LintOptions::default()))
|
Rc::new(ContextHost::new(
|
||||||
.spawn_for_test()
|
path,
|
||||||
|
Rc::clone(&semantic_ret),
|
||||||
|
LintOptions::default(),
|
||||||
|
Arc::default(),
|
||||||
|
))
|
||||||
|
.spawn_for_test()
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctx = build_ctx("foo.js");
|
let ctx = build_ctx("foo.js");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue