mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(linter): remove with_rule_name from the tight loop (#3335)
This commit is contained in:
parent
e4b3a3c06a
commit
8383b6e046
3 changed files with 32 additions and 24 deletions
|
|
@ -12,19 +12,20 @@ use crate::{
|
||||||
ESLintConfig, ESLintEnv, ESLintGlobals, ESLintSettings,
|
ESLintConfig, ESLintEnv, ESLintGlobals, ESLintSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct LintContext<'a> {
|
pub struct LintContext<'a> {
|
||||||
semantic: Rc<Semantic<'a>>,
|
semantic: Rc<Semantic<'a>>,
|
||||||
|
|
||||||
diagnostics: RefCell<Vec<Message<'a>>>,
|
diagnostics: RefCell<Vec<Message<'a>>>,
|
||||||
|
|
||||||
disable_directives: DisableDirectives<'a>,
|
disable_directives: Rc<DisableDirectives<'a>>,
|
||||||
|
|
||||||
/// Whether or not to apply code fixes during linting.
|
/// Whether or not to apply code fixes during linting.
|
||||||
fix: bool,
|
fix: bool,
|
||||||
|
|
||||||
current_rule_name: &'static str,
|
current_rule_name: &'static str,
|
||||||
|
|
||||||
file_path: Box<Path>,
|
file_path: Rc<Path>,
|
||||||
|
|
||||||
eslint_config: Arc<ESLintConfig>,
|
eslint_config: Arc<ESLintConfig>,
|
||||||
}
|
}
|
||||||
|
|
@ -36,10 +37,10 @@ impl<'a> LintContext<'a> {
|
||||||
Self {
|
Self {
|
||||||
semantic: Rc::clone(semantic),
|
semantic: Rc::clone(semantic),
|
||||||
diagnostics: RefCell::new(vec![]),
|
diagnostics: RefCell::new(vec![]),
|
||||||
disable_directives,
|
disable_directives: Rc::new(disable_directives),
|
||||||
fix: false,
|
fix: false,
|
||||||
current_rule_name: "",
|
current_rule_name: "",
|
||||||
file_path,
|
file_path: file_path.into(),
|
||||||
eslint_config: Arc::new(ESLintConfig::default()),
|
eslint_config: Arc::new(ESLintConfig::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -99,15 +100,16 @@ impl<'a> LintContext<'a> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[must_use]
|
||||||
pub fn with_rule_name(&mut self, name: &'static str) {
|
pub fn with_rule_name(mut self, name: &'static str) -> Self {
|
||||||
self.current_rule_name = name;
|
self.current_rule_name = name;
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Diagnostics */
|
/* Diagnostics */
|
||||||
|
|
||||||
pub fn into_message(self) -> Vec<Message<'a>> {
|
pub fn into_message(self) -> Vec<Message<'a>> {
|
||||||
self.diagnostics.into_inner()
|
self.diagnostics.borrow().iter().cloned().collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_diagnostic(&self, message: Message<'a>) {
|
fn add_diagnostic(&self, message: Message<'a>) {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::borrow::Cow;
|
||||||
use oxc_diagnostics::OxcDiagnostic;
|
use oxc_diagnostics::OxcDiagnostic;
|
||||||
use oxc_span::Span;
|
use oxc_span::Span;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Fix<'a> {
|
pub struct Fix<'a> {
|
||||||
pub content: Cow<'a, str>,
|
pub content: Cow<'a, str>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
@ -25,6 +25,7 @@ pub struct FixResult<'a> {
|
||||||
pub messages: Vec<Message<'a>>,
|
pub messages: Vec<Message<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Message<'a> {
|
pub struct Message<'a> {
|
||||||
pub error: OxcDiagnostic,
|
pub error: OxcDiagnostic,
|
||||||
pub start: u32,
|
pub start: u32,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ fn size_asserts() {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Linter {
|
pub struct Linter {
|
||||||
rules: Vec<(/* rule name */ &'static str, RuleEnum)>,
|
rules: Vec<RuleEnum>,
|
||||||
options: LintOptions,
|
options: LintOptions,
|
||||||
eslint_config: Arc<ESLintConfig>,
|
eslint_config: Arc<ESLintConfig>,
|
||||||
}
|
}
|
||||||
|
|
@ -69,13 +69,12 @@ impl Linter {
|
||||||
/// Returns `Err` if there are any errors parsing the configuration file.
|
/// Returns `Err` if there are any errors parsing the configuration file.
|
||||||
pub fn from_options(options: LintOptions) -> Result<Self, Error> {
|
pub fn from_options(options: LintOptions) -> Result<Self, Error> {
|
||||||
let (rules, eslint_config) = options.derive_rules_and_config()?;
|
let (rules, eslint_config) = options.derive_rules_and_config()?;
|
||||||
let rules = rules.into_iter().map(|rule| (rule.name(), rule)).collect();
|
|
||||||
Ok(Self { rules, options, eslint_config: Arc::new(eslint_config) })
|
Ok(Self { rules, options, eslint_config: Arc::new(eslint_config) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_rules(mut self, rules: Vec<RuleEnum>) -> Self {
|
pub fn with_rules(mut self, rules: Vec<RuleEnum>) -> Self {
|
||||||
self.rules = rules.into_iter().map(|rule| (rule.name(), rule)).collect();
|
self.rules = rules;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,34 +100,40 @@ impl Linter {
|
||||||
|
|
||||||
pub fn run<'a>(&self, ctx: LintContext<'a>) -> Vec<Message<'a>> {
|
pub fn run<'a>(&self, ctx: LintContext<'a>) -> Vec<Message<'a>> {
|
||||||
let semantic = Rc::clone(ctx.semantic());
|
let semantic = Rc::clone(ctx.semantic());
|
||||||
let mut ctx = ctx.with_fix(self.options.fix).with_eslint_config(&self.eslint_config);
|
|
||||||
|
|
||||||
for (rule_name, rule) in &self.rules {
|
let ctx = ctx.with_fix(self.options.fix).with_eslint_config(&self.eslint_config);
|
||||||
ctx.with_rule_name(rule_name);
|
let rules = self
|
||||||
rule.run_once(&ctx);
|
.rules
|
||||||
|
.iter()
|
||||||
|
.map(|rule| (rule, ctx.clone().with_rule_name(rule.name())))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for (rule, ctx) in &rules {
|
||||||
|
rule.run_once(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
for symbol in semantic.symbols().iter() {
|
for symbol in semantic.symbols().iter() {
|
||||||
for (rule_name, rule) in &self.rules {
|
for (rule, ctx) in &rules {
|
||||||
ctx.with_rule_name(rule_name);
|
rule.run_on_symbol(symbol, ctx);
|
||||||
rule.run_on_symbol(symbol, &ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for node in semantic.nodes().iter() {
|
for node in semantic.nodes().iter() {
|
||||||
for (rule_name, rule) in &self.rules {
|
for (rule, ctx) in &rules {
|
||||||
ctx.with_rule_name(rule_name);
|
rule.run(node, ctx);
|
||||||
rule.run(node, &ctx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.into_message()
|
rules.into_iter().flat_map(|(_, ctx)| ctx.into_message()).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Panics
|
/// # Panics
|
||||||
pub fn print_rules<W: Write>(writer: &mut W) {
|
pub fn print_rules<W: Write>(writer: &mut W) {
|
||||||
let default_rules =
|
let default_rules = Linter::default()
|
||||||
Linter::default().rules.into_iter().map(|(name, _)| name).collect::<FxHashSet<&str>>();
|
.rules
|
||||||
|
.into_iter()
|
||||||
|
.map(|rule| rule.name())
|
||||||
|
.collect::<FxHashSet<&str>>();
|
||||||
|
|
||||||
let rules_by_category = RULES.iter().fold(
|
let rules_by_category = RULES.iter().fold(
|
||||||
FxHashMap::default(),
|
FxHashMap::default(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue