diff --git a/crates/oxc_linter/src/context/host.rs b/crates/oxc_linter/src/context/host.rs new file mode 100644 index 0000000000000..b84d91146735e --- /dev/null +++ b/crates/oxc_linter/src/context/host.rs @@ -0,0 +1,177 @@ +use oxc_semantic::Semantic; +use oxc_span::SourceType; +use std::{cell::RefCell, path::Path, rc::Rc, sync::Arc}; + +use crate::{ + config::LintConfig, + disable_directives::{DisableDirectives, DisableDirectivesBuilder}, + fixer::FixKind, + frameworks, + options::{LintOptions, LintPlugins}, + utils, FrameworkFlags, RuleWithSeverity, +}; + +use super::{plugin_name_to_prefix, LintContext}; + +/// Stores shared information about a file being linted. +/// +/// When linting a file, there are a number of shared resources that are +/// independent of the rule being linted. [`ContextHost`] stores this context +/// subset. When a lint rule is run, a [`LintContext`] with rule-specific +/// information is spawned using [`ContextHost::spawn`]. +/// +/// ## API Encapsulation +/// +/// In most cases, lint rules should be interacting with a [`LintContext`]. The +/// only current exception to this is +/// [should_run](`crate::rule::Rule::should_run`). Just before a file is linted, +/// rules are filtered out based on that method. Creating a [`LintContext`] for +/// rules that would never get run is a waste of resources, so they must use +/// [`ContextHost`]. +/// +/// ## References +/// - [Flyweight Pattern](https://en.wikipedia.org/wiki/Flyweight_pattern) +#[must_use] +#[non_exhaustive] +pub struct ContextHost<'a> { + pub(super) semantic: Rc>, + pub(super) disable_directives: DisableDirectives<'a>, + /// Whether or not to apply code fixes during linting. Defaults to + /// [`FixKind::None`] (no fixing). + /// + /// Set via the `--fix`, `--fix-suggestions`, and `--fix-dangerously` CLI + /// flags. + pub(super) fix: FixKind, + pub(super) file_path: Box, + pub(super) config: Arc, + pub(super) frameworks: FrameworkFlags, + pub(super) plugins: LintPlugins, +} + +impl<'a> ContextHost<'a> { + /// # Panics + /// If `semantic.cfg()` is `None`. + pub fn new>( + file_path: P, + semantic: Rc>, + options: LintOptions, + ) -> Self { + // We should always check for `semantic.cfg()` being `Some` since we depend on it and it is + // unwrapped without any runtime checks after construction. + assert!( + semantic.cfg().is_some(), + "`LintContext` depends on `Semantic::cfg`, Build your semantic with cfg enabled(`SemanticBuilder::with_cfg`)." + ); + + let disable_directives = + DisableDirectivesBuilder::new(semantic.source_text(), semantic.trivias().clone()) + .build(); + + let file_path = file_path.as_ref().to_path_buf().into_boxed_path(); + + Self { + semantic, + disable_directives, + fix: options.fix, + file_path, + config: Arc::new(LintConfig::default()), + frameworks: options.framework_hints, + plugins: options.plugins, + } + .sniff_for_frameworks() + } + + #[inline] + pub(crate) fn with_config(mut self, config: &Arc) -> Self { + self.config = Arc::clone(config); + self + } + + #[inline] + pub fn semantic(&self) -> &Semantic<'a> { + &self.semantic + } + + /// Path to the file being linted. + /// + /// When created from a [`LintService`](`crate::service::LintService`), this + /// will be an absolute path. + #[inline] + pub fn file_path(&self) -> &Path { + &self.file_path + } + + /// The source type of the file being linted, e.g. JavaScript, TypeScript, + /// CJS, ESM, etc. + #[inline] + pub fn source_type(&self) -> &SourceType { + self.semantic.source_type() + } + + pub(crate) fn spawn(self: Rc, rule: &RuleWithSeverity) -> LintContext<'a> { + const DIAGNOSTICS_INITIAL_CAPACITY: usize = 128; + let rule_name = rule.name(); + let plugin_name = self.map_jest(rule.plugin_name(), rule_name); + + LintContext { + parent: self, + diagnostics: RefCell::new(Vec::with_capacity(DIAGNOSTICS_INITIAL_CAPACITY)), + current_rule_name: rule_name, + current_plugin_name: plugin_name, + current_plugin_prefix: plugin_name_to_prefix(plugin_name), + #[cfg(debug_assertions)] + current_rule_fix_capabilities: rule.rule.fix(), + severity: rule.severity.into(), + } + } + + #[cfg(test)] + pub(crate) fn spawn_for_test(self: Rc) -> LintContext<'a> { + const DIAGNOSTICS_INITIAL_CAPACITY: usize = 128; + + LintContext { + parent: Rc::clone(&self), + diagnostics: RefCell::new(Vec::with_capacity(DIAGNOSTICS_INITIAL_CAPACITY)), + current_rule_name: "", + current_plugin_name: "eslint", + current_plugin_prefix: "eslint", + #[cfg(debug_assertions)] + current_rule_fix_capabilities: crate::rule::RuleFixMeta::None, + severity: oxc_diagnostics::Severity::Warning, + } + } + + fn map_jest(&self, plugin_name: &'static str, rule_name: &str) -> &'static str { + if self.plugins.has_vitest() + && plugin_name == "jest" + && utils::is_jest_rule_adapted_to_vitest(rule_name) + { + "vitest" + } else { + plugin_name + } + } + + /// Inspect the target file for clues about what frameworks are being used. + /// Should only be called once immediately after construction. + /// + /// Before invocation, `self.frameworks` contains hints obtained at the + /// project level. For example, Oxlint may (eventually) search for a + /// `package.json`` and look for relevant dependencies. This method builds + /// on top of those hints, providing a more granular understanding of the + /// frameworks in use. + fn sniff_for_frameworks(mut self) -> Self { + if self.plugins.has_test() { + // let mut test_flags = FrameworkFlags::empty(); + + let vitest_like = frameworks::has_vitest_imports(self.semantic.module_record()); + let jest_like = frameworks::is_jestlike_file(&self.file_path) + || frameworks::has_jest_imports(self.semantic.module_record()); + + self.frameworks.set(FrameworkFlags::Vitest, vitest_like); + self.frameworks.set(FrameworkFlags::Jest, jest_like); + } + + self + } +} diff --git a/crates/oxc_linter/src/context.rs b/crates/oxc_linter/src/context/mod.rs similarity index 76% rename from crates/oxc_linter/src/context.rs rename to crates/oxc_linter/src/context/mod.rs index 65100736e964c..0f8e14a8be508 100644 --- a/crates/oxc_linter/src/context.rs +++ b/crates/oxc_linter/src/context/mod.rs @@ -1,5 +1,7 @@ #![allow(rustdoc::private_intra_doc_links)] // useful for intellisense -use std::{cell::RefCell, path::Path, rc::Rc, sync::Arc}; +mod host; + +use std::{cell::RefCell, path::Path, rc::Rc}; use oxc_cfg::ControlFlowGraph; use oxc_diagnostics::{OxcDiagnostic, Severity}; @@ -10,36 +12,25 @@ use oxc_syntax::module_record::ModuleRecord; #[cfg(debug_assertions)] use crate::rule::RuleFixMeta; use crate::{ - config::LintConfig, - disable_directives::{DisableDirectives, DisableDirectivesBuilder}, + disable_directives::DisableDirectives, fixer::{FixKind, Message, RuleFix, RuleFixer}, javascript_globals::GLOBALS, AllowWarnDeny, FrameworkFlags, OxlintEnv, OxlintGlobals, OxlintSettings, }; +pub use host::ContextHost; + #[derive(Clone)] #[must_use] pub struct LintContext<'a> { - semantic: Rc>, + /// Shared context independent of the rule being linted. + parent: Rc>, /// Diagnostics reported by the linter. /// /// Contains diagnostics for all rules across all files. diagnostics: RefCell>>, - disable_directives: Rc>, - - /// Whether or not to apply code fixes during linting. Defaults to - /// [`FixKind::None`] (no fixing). - /// - /// Set via the `--fix`, `--fix-suggestions`, and `--fix-dangerously` CLI - /// flags. - fix: FixKind, - - file_path: Rc, - - config: Arc, - // states current_plugin_name: &'static str, current_plugin_prefix: &'static str, @@ -57,54 +48,11 @@ pub struct LintContext<'a> { /// } /// ``` severity: Severity, - frameworks: FrameworkFlags, } impl<'a> LintContext<'a> { const WEBSITE_BASE_URL: &'static str = "https://oxc.rs/docs/guide/usage/linter/rules"; - /// # Panics - /// If `semantic.cfg()` is `None`. - pub fn new(file_path: Box, semantic: Rc>) -> Self { - const DIAGNOSTICS_INITIAL_CAPACITY: usize = 128; - - // We should always check for `semantic.cfg()` being `Some` since we depend on it and it is - // unwrapped without any runtime checks after construction. - assert!( - semantic.cfg().is_some(), - "`LintContext` depends on `Semantic::cfg`, Build your semantic with cfg enabled(`SemanticBuilder::with_cfg`)." - ); - let disable_directives = - DisableDirectivesBuilder::new(semantic.source_text(), semantic.trivias().clone()) - .build(); - Self { - semantic, - diagnostics: RefCell::new(Vec::with_capacity(DIAGNOSTICS_INITIAL_CAPACITY)), - disable_directives: Rc::new(disable_directives), - fix: FixKind::None, - file_path: file_path.into(), - config: Arc::new(LintConfig::default()), - current_plugin_name: "eslint", - current_plugin_prefix: "eslint", - current_rule_name: "", - #[cfg(debug_assertions)] - current_rule_fix_capabilities: RuleFixMeta::None, - severity: Severity::Warning, - frameworks: FrameworkFlags::empty(), - } - } - - /// Enable/disable automatic code fixes. - pub fn with_fix(mut self, fix: FixKind) -> Self { - self.fix = fix; - self - } - - pub(crate) fn with_config(mut self, config: &Arc) -> Self { - self.config = Arc::clone(config); - self - } - pub fn with_plugin_name(mut self, plugin: &'static str) -> Self { self.current_plugin_name = plugin; self.current_plugin_prefix = plugin_name_to_prefix(plugin); @@ -122,38 +70,37 @@ impl<'a> LintContext<'a> { self } + /// Update the severity of diagnostics reported by the rule this context is + /// associated with. + #[inline] pub fn with_severity(mut self, severity: AllowWarnDeny) -> Self { self.severity = Severity::from(severity); self } - /// Set [`FrameworkFlags`], overwriting any existing flags. - pub fn with_frameworks(mut self, frameworks: FrameworkFlags) -> Self { - self.frameworks = frameworks; - self - } - - /// Add additional [`FrameworkFlags`] - pub fn and_frameworks(mut self, frameworks: FrameworkFlags) -> Self { - self.frameworks |= frameworks; - self - } - + /// Get information such as the control flow graph, bound symbols, AST, etc. + /// for the file being linted. + /// + /// Refer to [`Semantic`]'s documentation for more information. + #[inline] pub fn semantic(&self) -> &Rc> { - &self.semantic + &self.parent.semantic } + #[inline] pub fn cfg(&self) -> &ControlFlowGraph { // SAFETY: `LintContext::new` is the only way to construct a `LintContext` and we always // assert the existence of control flow so it should always be `Some`. unsafe { self.semantic().cfg().unwrap_unchecked() } } + #[inline] pub fn disable_directives(&self) -> &DisableDirectives<'a> { - &self.disable_directives + &self.parent.disable_directives } /// Source code of the file being linted. + #[inline] pub fn source_text(&self) -> &'a str { self.semantic().source_text() } @@ -165,29 +112,34 @@ impl<'a> LintContext<'a> { } /// [`SourceType`] of the file currently being linted. + #[inline] pub fn source_type(&self) -> &SourceType { self.semantic().source_type() } /// Path to the file currently being linted. + #[inline] pub fn file_path(&self) -> &Path { - &self.file_path + &self.parent.file_path } /// Plugin settings + #[inline] pub fn settings(&self) -> &OxlintSettings { - &self.config.settings + &self.parent.config.settings } + #[inline] pub fn globals(&self) -> &OxlintGlobals { - &self.config.globals + &self.parent.config.globals } /// Runtime environments turned on/off by the user. /// /// Examples of environments are `builtin`, `browser`, `node`, etc. + #[inline] pub fn env(&self) -> &OxlintEnv { - &self.config.env + &self.parent.config.env } pub fn env_contains_var(&self, var: &str) -> bool { @@ -211,7 +163,7 @@ impl<'a> LintContext<'a> { } fn add_diagnostic(&self, mut message: Message<'a>) { - if self.disable_directives.contains(self.current_rule_name, message.span()) { + if self.parent.disable_directives.contains(self.current_rule_name, message.span()) { return; } message.error = message @@ -334,7 +286,7 @@ impl<'a> LintContext<'a> { (Some(message), None) => diagnostic.with_help(message.to_owned()), _ => diagnostic, }; - if self.fix.can_apply(rule_fix.kind()) { + if self.parent.fix.can_apply(rule_fix.kind()) { let fix = rule_fix.into_fix(self.source_text()); self.add_diagnostic(Message::new(diagnostic, Some(fix))); } else { @@ -343,7 +295,7 @@ impl<'a> LintContext<'a> { } pub fn frameworks(&self) -> FrameworkFlags { - self.frameworks + self.parent.frameworks } /// AST nodes @@ -380,16 +332,6 @@ impl<'a> LintContext<'a> { pub fn jsdoc(&self) -> &JSDocFinder<'a> { self.semantic().jsdoc() } - - // #[inline] - // fn plugin_name_to_prefix(&self, plugin_name: &'static str) -> &'static str { - // let plugin_name = if self. plugin_name == "jest" && self.frameworks.contains(FrameworkFlags::Vitest) { - // "vitest" - // } else { - // plugin_name - // }; - // PLUGIN_PREFIXES.get(plugin_name).copied().unwrap_or(plugin_name) - // } } #[inline] diff --git a/crates/oxc_linter/src/lib.rs b/crates/oxc_linter/src/lib.rs index e3272067e6682..ca28492762dbc 100644 --- a/crates/oxc_linter/src/lib.rs +++ b/crates/oxc_linter/src/lib.rs @@ -23,6 +23,7 @@ pub mod table; use std::{io::Write, path::Path, rc::Rc, sync::Arc}; use config::LintConfig; +use context::ContextHost; use options::LintOptions; use oxc_diagnostics::Error; use oxc_semantic::{AstNode, Semantic}; @@ -113,22 +114,22 @@ impl Linter { self.rules.len() } - // pub fn run<'a>(&self, ctx: LintContext<'a>) -> Vec> { pub fn run<'a>(&self, path: &Path, semantic: Rc>) -> Vec> { - let ctx = self.create_ctx(path, semantic); - let semantic = Rc::clone(ctx.semantic()); + let ctx_host = + Rc::new(ContextHost::new(path, semantic, self.options).with_config(&self.config)); let rules = self .rules .iter() - .filter(|rule| rule.should_run(&ctx)) - .map(|rule| (rule, self.ctx_for_rule(&ctx, rule))) + .filter(|rule| rule.should_run(&ctx_host)) + .map(|rule| (rule, Rc::clone(&ctx_host).spawn(rule))) .collect::>(); for (rule, ctx) in &rules { rule.run_once(ctx); } + let semantic = ctx_host.semantic(); for symbol in semantic.symbols().symbol_ids() { for (rule, ctx) in &rules { rule.run_on_symbol(symbol, ctx); @@ -153,53 +154,6 @@ impl Linter { writeln!(writer, "Default: {}", table.turned_on_by_default_count).unwrap(); writeln!(writer, "Total: {}", table.total).unwrap(); } - - fn create_ctx<'a>(&self, path: &Path, semantic: Rc>) -> LintContext<'a> { - let mut ctx = LintContext::new(path.to_path_buf().into_boxed_path(), semantic) - .with_fix(self.options.fix) - .with_config(&self.config) - .with_frameworks(self.options.framework_hints); - - // set file-specific jest/vitest flags - if self.options.plugins.has_test() { - let mut test_flags = FrameworkFlags::empty(); - - if frameworks::has_vitest_imports(ctx.module_record()) { - test_flags.set(FrameworkFlags::Vitest, true); - } else if frameworks::is_jestlike_file(path) - || frameworks::has_jest_imports(ctx.module_record()) - { - test_flags.set(FrameworkFlags::Jest, true); - } - - ctx = ctx.and_frameworks(test_flags); - } - - ctx - } - - fn ctx_for_rule<'a>(&self, ctx: &LintContext<'a>, rule: &RuleWithSeverity) -> LintContext<'a> { - let rule_name = rule.name(); - let plugin_name = self.map_jest(rule.plugin_name(), rule_name); - - #[cfg(debug_assertions)] - let ctx = ctx.clone().with_rule_fix_capabilities(rule.rule.fix()); - #[cfg(not(debug_assertions))] - let ctx = ctx.clone(); - - ctx.with_plugin_name(plugin_name).with_rule_name(rule_name).with_severity(rule.severity) - } - - fn map_jest(&self, plugin_name: &'static str, rule_name: &str) -> &'static str { - if self.options.plugins.has_vitest() - && plugin_name == "jest" - && utils::is_jest_rule_adapted_to_vitest(rule_name) - { - "vitest" - } else { - plugin_name - } - } } #[cfg(test)] diff --git a/crates/oxc_linter/src/options/mod.rs b/crates/oxc_linter/src/options/mod.rs index 3461542c6bb46..2b1ef8295e820 100644 --- a/crates/oxc_linter/src/options/mod.rs +++ b/crates/oxc_linter/src/options/mod.rs @@ -6,12 +6,11 @@ use std::{convert::From, path::PathBuf}; use filter::LintFilterKind; use oxc_diagnostics::Error; -use plugins::LintPlugins; use rustc_hash::FxHashSet; pub use allow_warn_deny::AllowWarnDeny; pub use filter::{InvalidFilterKind, LintFilter}; -pub use plugins::LintPluginOptions; +pub use plugins::{LintPluginOptions, LintPlugins}; use crate::{ config::{LintConfig, OxlintConfig}, @@ -26,7 +25,7 @@ use crate::{ /// outside of this crate. /// /// [`Linter`]: crate::Linter -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone, Copy)] #[cfg_attr(test, derive(PartialEq))] pub(crate) struct LintOptions { pub fix: FixKind, diff --git a/crates/oxc_linter/src/rule.rs b/crates/oxc_linter/src/rule.rs index 2d041e4480803..4d45b793db9e6 100644 --- a/crates/oxc_linter/src/rule.rs +++ b/crates/oxc_linter/src/rule.rs @@ -7,7 +7,10 @@ use std::{ use oxc_semantic::SymbolId; -use crate::{context::LintContext, AllowWarnDeny, AstNode, FixKind, RuleEnum}; +use crate::{ + context::{ContextHost, LintContext}, + AllowWarnDeny, AstNode, FixKind, RuleEnum, +}; pub trait Rule: Sized + Default + fmt::Debug { /// Initialize from eslint json configuration @@ -39,7 +42,7 @@ pub trait Rule: Sized + Default + fmt::Debug { /// [`linter`]: crate::Linter #[expect(unused_variables)] #[inline] - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { true } } diff --git a/crates/oxc_linter/src/rules/eslint/no_unused_vars/mod.rs b/crates/oxc_linter/src/rules/eslint/no_unused_vars/mod.rs index 426a50bf05f77..974ff1a335b6f 100644 --- a/crates/oxc_linter/src/rules/eslint/no_unused_vars/mod.rs +++ b/crates/oxc_linter/src/rules/eslint/no_unused_vars/mod.rs @@ -18,7 +18,10 @@ use oxc_semantic::{AstNode, ScopeFlags, SymbolFlags, SymbolId}; use oxc_span::GetSpan; use symbol::Symbol; -use crate::{context::LintContext, rule::Rule}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, +}; #[derive(Debug, Default, Clone)] pub struct NoUnusedVars(Box); @@ -210,7 +213,7 @@ impl Rule for NoUnusedVars { self.run_on_symbol_internal(&symbol, ctx); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { // ignore .d.ts and vue files. // 1. declarations have side effects (they get merged together) // 2. vue scripts declare variables that get used in the template, which diff --git a/crates/oxc_linter/src/rules/import/no_deprecated.rs b/crates/oxc_linter/src/rules/import/no_deprecated.rs index e8642a0bf771e..10aa4b2bdd790 100644 --- a/crates/oxc_linter/src/rules/import/no_deprecated.rs +++ b/crates/oxc_linter/src/rules/import/no_deprecated.rs @@ -2,7 +2,7 @@ use oxc_diagnostics::{LabeledSpan, OxcDiagnostic}; use oxc_macros::declare_oxc_lint; // use oxc_span::{CompactStr, Span}; -use crate::{context::LintContext, rule::Rule}; +use crate::{context::{LintContext, ContextHost}, rule::Rule}; // #[derive(Debug, Error, Diagnostic)] // #[error("")] diff --git a/crates/oxc_linter/src/rules/import/no_unused_modules.rs b/crates/oxc_linter/src/rules/import/no_unused_modules.rs index 679ec96d6d5d4..8bf030d1153aa 100644 --- a/crates/oxc_linter/src/rules/import/no_unused_modules.rs +++ b/crates/oxc_linter/src/rules/import/no_unused_modules.rs @@ -1,7 +1,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule}; +use crate::{context::{LintContext, ContextHost}, rule::Rule}; fn no_exports_found(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("No exports found") diff --git a/crates/oxc_linter/src/rules/jest/expect_expect.rs b/crates/oxc_linter/src/rules/jest/expect_expect.rs index cbb5d45eaa01a..f98d35b9a51b1 100644 --- a/crates/oxc_linter/src/rules/jest/expect_expect.rs +++ b/crates/oxc_linter/src/rules/jest/expect_expect.rs @@ -288,6 +288,32 @@ fn convert_pattern(pattern: &str) -> String { format!("(?ui)^{pattern}(\\.|$)") } +#[test] +fn debug() { + use crate::tester::Tester; + + let mut pass: Vec<(&str, Option)> = vec![]; + + let mut fail = vec![]; + + let pass_vitest = vec![( + " + import { test } from 'vitest'; + test.skip(\"skipped test\", () => {}) + ", + None, + )]; + + let fail_vitest = vec![]; + + pass.extend(pass_vitest); + fail.extend(fail_vitest); + + Tester::new(ExpectExpect::NAME, pass, fail) + .with_jest_plugin(true) + .with_vitest_plugin(true) + .test(); +} #[test] fn test() { use crate::tester::Tester; diff --git a/crates/oxc_linter/src/rules/nextjs/no_typos.rs b/crates/oxc_linter/src/rules/nextjs/no_typos.rs index 39f8d96c27174..b380d668bd582 100644 --- a/crates/oxc_linter/src/rules/nextjs/no_typos.rs +++ b/crates/oxc_linter/src/rules/nextjs/no_typos.rs @@ -7,7 +7,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use phf::phf_set; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_typos_diagnostic(typo: &str, suggestion: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("{typo} may be a typo. Did you mean {suggestion}?")) @@ -47,7 +51,7 @@ const NEXTJS_DATA_FETCHING_FUNCTIONS: phf::Set<&'static str> = phf_set! { const THRESHOLD: i32 = 1; impl Rule for NoTypos { - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { let Some(path) = ctx.file_path().to_str() else { return false; }; diff --git a/crates/oxc_linter/src/rules/react/button_has_type.rs b/crates/oxc_linter/src/rules/react/button_has_type.rs index 96798206d3c7d..05e6c066eb9a5 100644 --- a/crates/oxc_linter/src/rules/react/button_has_type.rs +++ b/crates/oxc_linter/src/rules/react/button_has_type.rs @@ -10,7 +10,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, rule::Rule, utils::{get_prop_value, has_jsx_prop_ignore_case, is_create_element_call}, AstNode, @@ -152,7 +152,7 @@ impl Rule for ButtonHasType { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_boolean_value.rs b/crates/oxc_linter/src/rules/react/jsx_boolean_value.rs index 414354869e2c4..3a949bdff6152 100644 --- a/crates/oxc_linter/src/rules/react/jsx_boolean_value.rs +++ b/crates/oxc_linter/src/rules/react/jsx_boolean_value.rs @@ -8,7 +8,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, utils::get_prop_value, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + utils::get_prop_value, + AstNode, +}; fn boolean_value_diagnostic(attr: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("Value must be omitted for boolean attribute {attr:?}")) @@ -149,7 +154,7 @@ impl Rule for JsxBooleanValue { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_curly_brace_presence.rs b/crates/oxc_linter/src/rules/react/jsx_curly_brace_presence.rs index 34103935fcb0e..a03a2a6ff7cce 100644 --- a/crates/oxc_linter/src/rules/react/jsx_curly_brace_presence.rs +++ b/crates/oxc_linter/src/rules/react/jsx_curly_brace_presence.rs @@ -12,7 +12,11 @@ use oxc_semantic::NodeId; use oxc_span::{GetSpan as _, Span}; use serde_json::Value; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn jsx_curly_brace_presence_unnecessary_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Curly braces are unnecessary here.").with_label(span) @@ -350,7 +354,7 @@ impl Rule for JsxCurlyBracePresence { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_key.rs b/crates/oxc_linter/src/rules/react/jsx_key.rs index 7f23ec8ec66ea..0fff0dd6e2bf0 100644 --- a/crates/oxc_linter/src/rules/react/jsx_key.rs +++ b/crates/oxc_linter/src/rules/react/jsx_key.rs @@ -7,7 +7,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn missing_key_prop_for_element_in_array(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(r#"Missing "key" prop for element in array."#).with_label(span) @@ -68,7 +72,7 @@ impl Rule for JsxKey { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_comment_textnodes.rs b/crates/oxc_linter/src/rules/react/jsx_no_comment_textnodes.rs index bdd7d3094814a..bcd1a1a70f602 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_comment_textnodes.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_comment_textnodes.rs @@ -5,7 +5,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use regex::Regex; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn jsx_no_comment_textnodes_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Comments inside children section of tag should be placed inside braces") @@ -61,7 +65,7 @@ impl Rule for JsxNoCommentTextnodes { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_duplicate_props.rs b/crates/oxc_linter/src/rules/react/jsx_no_duplicate_props.rs index ec223c691466a..43121b67e7fac 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_duplicate_props.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_duplicate_props.rs @@ -7,7 +7,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{Atom, Span}; use rustc_hash::FxHashMap; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn jsx_no_duplicate_props_diagnostic(x0: &str, span1: Span, span2: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("No duplicate props allowed. The prop \"{x0}\" is duplicated.")) @@ -72,7 +76,7 @@ impl Rule for JsxNoDuplicateProps { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs b/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs index c31148b667c0e..e6ea70578a344 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs @@ -11,7 +11,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{CompactStr, GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn target_blank_without_noreferrer(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Using target=`_blank` without rel=`noreferrer` (which implies rel=`noopener`) is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations") @@ -241,7 +245,7 @@ impl Rule for JsxNoTargetBlank { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs index d76014bc3c548..8f9e1707abd65 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn jsx_no_undef_diagnostic(ident_name: &str, span1: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Disallow undeclared variables in JSX") @@ -72,7 +76,7 @@ impl Rule for JsxNoUndef { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs index eac0686e6b205..e6bffa4b92bad 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs @@ -10,7 +10,11 @@ use oxc_macros::declare_oxc_lint; use oxc_semantic::NodeId; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn needs_more_children(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Fragments should contain more than one child.").with_label(span) @@ -78,7 +82,7 @@ impl Rule for JsxNoUselessFragment { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/jsx_props_no_spread_multi.rs b/crates/oxc_linter/src/rules/react/jsx_props_no_spread_multi.rs index 0688956e72d75..e9bc3ebe58e33 100644 --- a/crates/oxc_linter/src/rules/react/jsx_props_no_spread_multi.rs +++ b/crates/oxc_linter/src/rules/react/jsx_props_no_spread_multi.rs @@ -6,7 +6,7 @@ use oxc_span::{Atom, Span}; use rustc_hash::FxHashMap; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, fixer::{Fix, RuleFix}, rule::Rule, utils::is_same_member_expression, @@ -122,7 +122,7 @@ impl Rule for JsxPropsNoSpreadMulti { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_children_prop.rs b/crates/oxc_linter/src/rules/react/no_children_prop.rs index 8434b258b74c6..bf4d1c86e0d3c 100644 --- a/crates/oxc_linter/src/rules/react/no_children_prop.rs +++ b/crates/oxc_linter/src/rules/react/no_children_prop.rs @@ -6,7 +6,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, utils::is_create_element_call, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + utils::is_create_element_call, + AstNode, +}; fn no_children_prop_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Avoid passing children using a prop.") @@ -86,7 +91,7 @@ impl Rule for NoChildrenProp { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_danger.rs b/crates/oxc_linter/src/rules/react/no_danger.rs index a0a39362d5425..c8e97b1cbd79a 100644 --- a/crates/oxc_linter/src/rules/react/no_danger.rs +++ b/crates/oxc_linter/src/rules/react/no_danger.rs @@ -7,7 +7,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, rule::Rule, utils::{has_jsx_prop, is_create_element_call}, AstNode, @@ -91,7 +91,7 @@ impl Rule for NoDanger { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs b/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs index 30fd07848b382..5b618278ae07f 100644 --- a/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs +++ b/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs @@ -7,7 +7,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, rule::Rule, utils::{is_es5_component, is_es6_component}, AstNode, @@ -118,7 +118,7 @@ impl Rule for NoDirectMutationState { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_find_dom_node.rs b/crates/oxc_linter/src/rules/react/no_find_dom_node.rs index 19e5aa9a33b84..27ab47f934a4d 100644 --- a/crates/oxc_linter/src/rules/react/no_find_dom_node.rs +++ b/crates/oxc_linter/src/rules/react/no_find_dom_node.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_find_dom_node_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Unexpected call to `findDOMNode`.") @@ -67,7 +71,7 @@ impl Rule for NoFindDomNode { ctx.diagnostic(no_find_dom_node_diagnostic(span)); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_is_mounted.rs b/crates/oxc_linter/src/rules/react/no_is_mounted.rs index b636b3d9f22f9..2edd5f568ca0e 100644 --- a/crates/oxc_linter/src/rules/react/no_is_mounted.rs +++ b/crates/oxc_linter/src/rules/react/no_is_mounted.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_is_mounted_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Do not use isMounted") @@ -67,7 +71,7 @@ impl Rule for NoIsMounted { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_render_return_value.rs b/crates/oxc_linter/src/rules/react/no_render_return_value.rs index 13d3f39886aed..389a90a4170d7 100644 --- a/crates/oxc_linter/src/rules/react/no_render_return_value.rs +++ b/crates/oxc_linter/src/rules/react/no_render_return_value.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_render_return_value_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Do not depend on the return value from ReactDOM.render.") @@ -82,7 +86,7 @@ impl Rule for NoRenderReturnValue { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_set_state.rs b/crates/oxc_linter/src/rules/react/no_set_state.rs index da2acc7a221ab..7e6786100c4f9 100644 --- a/crates/oxc_linter/src/rules/react/no_set_state.rs +++ b/crates/oxc_linter/src/rules/react/no_set_state.rs @@ -3,7 +3,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, utils::get_parent_component, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + utils::get_parent_component, + AstNode, +}; fn no_set_state_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Do not use setState").with_label(span) @@ -66,7 +71,7 @@ impl Rule for NoSetState { ctx.diagnostic(no_set_state_diagnostic(call_expr.callee.span())); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_string_refs.rs b/crates/oxc_linter/src/rules/react/no_string_refs.rs index 33e3237832c34..01f84be5e716f 100644 --- a/crates/oxc_linter/src/rules/react/no_string_refs.rs +++ b/crates/oxc_linter/src/rules/react/no_string_refs.rs @@ -9,7 +9,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, utils::get_parent_component, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + utils::get_parent_component, + AstNode, +}; fn this_refs_deprecated(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Using this.refs is deprecated.") @@ -125,7 +130,7 @@ impl Rule for NoStringRefs { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_unescaped_entities.rs b/crates/oxc_linter/src/rules/react/no_unescaped_entities.rs index 4c6409c77612a..1fe0a52e15803 100644 --- a/crates/oxc_linter/src/rules/react/no_unescaped_entities.rs +++ b/crates/oxc_linter/src/rules/react/no_unescaped_entities.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use phf::{phf_map, Map}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_unescaped_entities_diagnostic(span: Span, unescaped: char, escaped: &str) -> OxcDiagnostic { OxcDiagnostic::warn(format!("`{unescaped}` can be escaped with {escaped}")).with_label(span) @@ -62,7 +66,7 @@ impl Rule for NoUnescapedEntities { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/no_unknown_property.rs b/crates/oxc_linter/src/rules/react/no_unknown_property.rs index cb2618809658b..e84a906493020 100644 --- a/crates/oxc_linter/src/rules/react/no_unknown_property.rs +++ b/crates/oxc_linter/src/rules/react/no_unknown_property.rs @@ -15,7 +15,12 @@ use regex::Regex; use rustc_hash::FxHashSet; use serde::Deserialize; -use crate::{context::LintContext, rule::Rule, utils::get_jsx_attribute_name, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + utils::get_jsx_attribute_name, + AstNode, +}; fn invalid_prop_on_tag(span: Span, prop: &str, tag: &str) -> OxcDiagnostic { OxcDiagnostic::warn("Invalid property found") @@ -540,7 +545,7 @@ impl Rule for NoUnknownProperty { }); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/prefer_es6_class.rs b/crates/oxc_linter/src/rules/react/prefer_es6_class.rs index 1a9621a8e6877..e75dde1fa523e 100644 --- a/crates/oxc_linter/src/rules/react/prefer_es6_class.rs +++ b/crates/oxc_linter/src/rules/react/prefer_es6_class.rs @@ -4,7 +4,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, rule::Rule, utils::{is_es5_component, is_es6_component}, AstNode, @@ -75,7 +75,7 @@ impl Rule for PreferEs6Class { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/react_in_jsx_scope.rs b/crates/oxc_linter/src/rules/react/react_in_jsx_scope.rs index cf1ec5b99449d..7acf8334925b4 100644 --- a/crates/oxc_linter/src/rules/react/react_in_jsx_scope.rs +++ b/crates/oxc_linter/src/rules/react/react_in_jsx_scope.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn react_in_jsx_scope_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("'React' must be in scope when using JSX") @@ -59,7 +63,7 @@ impl Rule for ReactInJsxScope { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/require_render_return.rs b/crates/oxc_linter/src/rules/react/require_render_return.rs index ed2a6161060c4..5be0cdf30ed79 100644 --- a/crates/oxc_linter/src/rules/react/require_render_return.rs +++ b/crates/oxc_linter/src/rules/react/require_render_return.rs @@ -8,7 +8,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, rule::Rule, utils::{is_es5_component, is_es6_component}, AstNode, @@ -79,7 +79,7 @@ impl Rule for RequireRenderReturn { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/self_closing_comp.rs b/crates/oxc_linter/src/rules/react/self_closing_comp.rs index 88279aebafe0e..b7bb1cc273b6e 100644 --- a/crates/oxc_linter/src/rules/react/self_closing_comp.rs +++ b/crates/oxc_linter/src/rules/react/self_closing_comp.rs @@ -6,7 +6,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, globals::HTML_TAG, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + globals::HTML_TAG, + rule::Rule, + AstNode, +}; fn self_closing_comp_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Unnecessary closing tag") @@ -119,7 +124,7 @@ impl Rule for SelfClosingComp { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs b/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs index d45242006ceef..70f67a1f51c32 100644 --- a/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs +++ b/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs @@ -10,7 +10,12 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use phf::phf_set; -use crate::{context::LintContext, rule::Rule, utils::is_create_element_call, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + utils::is_create_element_call, + AstNode, +}; fn void_dom_elements_no_children_diagnostic(tag: &str, span: Span) -> OxcDiagnostic { // TODO: use imperative phrasing @@ -142,7 +147,7 @@ impl Rule for VoidDomElementsNoChildren { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs b/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs index b6ba79f200658..9be9ef7494375 100644 --- a/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs +++ b/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs @@ -9,7 +9,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{CompactStr, GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn adjacent_overload_signatures_diagnostic( fn_name: &str, @@ -320,7 +324,7 @@ impl Rule for AdjacentOverloadSignatures { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/array_type.rs b/crates/oxc_linter/src/rules/typescript/array_type.rs index fed85e6641c76..52481ca2d9f62 100644 --- a/crates/oxc_linter/src/rules/typescript/array_type.rs +++ b/crates/oxc_linter/src/rules/typescript/array_type.rs @@ -7,7 +7,10 @@ use oxc_macros::declare_oxc_lint; use oxc_semantic::AstNode; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, +}; #[derive(Debug, Default, Clone)] pub struct ArrayType(Box); @@ -136,7 +139,7 @@ impl Rule for ArrayType { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/ban_ts_comment.rs b/crates/oxc_linter/src/rules/typescript/ban_ts_comment.rs index da5a063264d02..46fb4b00c79fc 100644 --- a/crates/oxc_linter/src/rules/typescript/ban_ts_comment.rs +++ b/crates/oxc_linter/src/rules/typescript/ban_ts_comment.rs @@ -5,7 +5,10 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use regex::Regex; -use crate::{context::LintContext, rule::Rule}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, +}; fn comment(ts_comment_name: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!( @@ -213,7 +216,7 @@ impl Rule for BanTsComment { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/ban_types.rs b/crates/oxc_linter/src/rules/typescript/ban_types.rs index 81c18b79588f0..8066fc93507f7 100644 --- a/crates/oxc_linter/src/rules/typescript/ban_types.rs +++ b/crates/oxc_linter/src/rules/typescript/ban_types.rs @@ -4,7 +4,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn type_diagnostic(banned_type: &str, suggested_type: &str, span2: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!( @@ -88,7 +92,7 @@ impl Rule for BanTypes { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs b/crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs index 21de5b2389df6..d98aab866d30b 100644 --- a/crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs +++ b/crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn consistent_indexed_object_style_diagnostic(a: &str, b: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("A {a} is preferred over an {b}.")) @@ -245,7 +249,7 @@ impl Rule for ConsistentIndexedObjectStyle { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/consistent_type_definitions.rs b/crates/oxc_linter/src/rules/typescript/consistent_type_definitions.rs index ec73b01cbf4fb..5d4b8acace8f6 100644 --- a/crates/oxc_linter/src/rules/typescript/consistent_type_definitions.rs +++ b/crates/oxc_linter/src/rules/typescript/consistent_type_definitions.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn consistent_type_definitions_diagnostic( preferred_type_kind: &str, @@ -220,7 +224,7 @@ impl Rule for ConsistentTypeDefinitions { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs b/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs index 4fce9cb24a2a8..49f81db637415 100644 --- a/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs +++ b/crates/oxc_linter/src/rules/typescript/consistent_type_imports.rs @@ -14,7 +14,7 @@ use oxc_semantic::{Reference, SymbolId}; use oxc_span::{GetSpan, Span}; use crate::{ - context::LintContext, + context::{ContextHost, LintContext}, fixer::{RuleFix, RuleFixer}, rule::Rule, AstNode, @@ -268,7 +268,7 @@ impl Rule for ConsistentTypeImports { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/explicit_function_return_type.rs b/crates/oxc_linter/src/rules/typescript/explicit_function_return_type.rs index 1802c7dc8900e..4e9d4a62b7140 100644 --- a/crates/oxc_linter/src/rules/typescript/explicit_function_return_type.rs +++ b/crates/oxc_linter/src/rules/typescript/explicit_function_return_type.rs @@ -14,7 +14,7 @@ use oxc_syntax::operator::UnaryOperator; use crate::{ ast_util::outermost_paren_parent, - context::LintContext, + context::{ContextHost, LintContext}, rule::Rule, rules::eslint::array_callback_return::return_checker::{ check_statement, StatementReturnStatus, @@ -300,7 +300,7 @@ impl Rule for ExplicitFunctionReturnType { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_confusing_non_null_assertion.rs b/crates/oxc_linter/src/rules/typescript/no_confusing_non_null_assertion.rs index c629731e45e25..f20e7931a0bff 100644 --- a/crates/oxc_linter/src/rules/typescript/no_confusing_non_null_assertion.rs +++ b/crates/oxc_linter/src/rules/typescript/no_confusing_non_null_assertion.rs @@ -7,7 +7,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use oxc_syntax::operator::{AssignmentOperator, BinaryOperator}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; #[derive(Debug, Default, Clone)] pub struct NoConfusingNonNullAssertion; @@ -111,7 +115,7 @@ impl Rule for NoConfusingNonNullAssertion { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_duplicate_enum_values.rs b/crates/oxc_linter/src/rules/typescript/no_duplicate_enum_values.rs index 26ffb9c862442..cf942ed362706 100644 --- a/crates/oxc_linter/src/rules/typescript/no_duplicate_enum_values.rs +++ b/crates/oxc_linter/src/rules/typescript/no_duplicate_enum_values.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use rustc_hash::FxHashMap; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_duplicate_enum_values_diagnostic(span: Span, span1: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Disallow duplicate enum member values") @@ -67,7 +71,7 @@ impl Rule for NoDuplicateEnumValues { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_empty_interface.rs b/crates/oxc_linter/src/rules/typescript/no_empty_interface.rs index 1045900bfd094..8573c43829531 100644 --- a/crates/oxc_linter/src/rules/typescript/no_empty_interface.rs +++ b/crates/oxc_linter/src/rules/typescript/no_empty_interface.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use serde_json::Value; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_empty_interface_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("an empty interface is equivalent to `{}`").with_label(span) @@ -69,7 +73,7 @@ impl Rule for NoEmptyInterface { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_explicit_any.rs b/crates/oxc_linter/src/rules/typescript/no_explicit_any.rs index 4b0a4c921484b..b79539fcbee7e 100644 --- a/crates/oxc_linter/src/rules/typescript/no_explicit_any.rs +++ b/crates/oxc_linter/src/rules/typescript/no_explicit_any.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use serde_json::Value; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_explicit_any_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Unexpected any. Specify a different type.") @@ -114,7 +118,7 @@ impl Rule for NoExplicitAny { Self { fix_to_unknown, ignore_rest_args } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs b/crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs index cd9e1d7332553..accedc03054c2 100644 --- a/crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs +++ b/crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_extra_non_null_assertion_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("extra non-null assertion").with_label(span) @@ -63,7 +67,7 @@ impl Rule for NoExtraNonNullAssertion { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_import_type_side_effects.rs b/crates/oxc_linter/src/rules/typescript/no_import_type_side_effects.rs index f3246d24ab89b..645cc02105935 100644 --- a/crates/oxc_linter/src/rules/typescript/no_import_type_side_effects.rs +++ b/crates/oxc_linter/src/rules/typescript/no_import_type_side_effects.rs @@ -6,7 +6,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, fixer::Fix, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + fixer::Fix, + rule::Rule, + AstNode, +}; fn no_import_type_side_effects_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("TypeScript will only remove the inline type specifiers which will leave behind a side effect import at runtime.") @@ -117,7 +122,7 @@ impl Rule for NoImportTypeSideEffects { ); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_namespace.rs b/crates/oxc_linter/src/rules/typescript/no_namespace.rs index d361b62069a37..3935d3839df2d 100644 --- a/crates/oxc_linter/src/rules/typescript/no_namespace.rs +++ b/crates/oxc_linter/src/rules/typescript/no_namespace.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_namespace_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("ES2015 module syntax is preferred over namespaces.") @@ -99,7 +103,7 @@ impl Rule for NoNamespace { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_nullish_coalescing.rs b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_nullish_coalescing.rs index df59c168e1562..17875b49445e5 100644 --- a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_nullish_coalescing.rs +++ b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_nullish_coalescing.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_semantic::SymbolId; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; #[derive(Debug, Default, Clone)] pub struct NoNonNullAssertedNullishCoalescing; @@ -48,7 +52,7 @@ impl Rule for NoNonNullAssertedNullishCoalescing { ctx.diagnostic(no_non_null_asserted_nullish_coalescing_diagnostic(ts_non_null_expr.span)); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs index 796a00f3f478b..d261859cda774 100644 --- a/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs +++ b/crates/oxc_linter/src/rules/typescript/no_non_null_asserted_optional_chain.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_non_null_asserted_optional_chain_diagnostic(span: Span, span1: Span) -> OxcDiagnostic { OxcDiagnostic::warn("non-null assertions after an optional chain expression") @@ -91,7 +95,7 @@ impl Rule for NoNonNullAssertedOptionalChain { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_non_null_assertion.rs b/crates/oxc_linter/src/rules/typescript/no_non_null_assertion.rs index c251980071b8f..1e07ddedd72a7 100644 --- a/crates/oxc_linter/src/rules/typescript/no_non_null_assertion.rs +++ b/crates/oxc_linter/src/rules/typescript/no_non_null_assertion.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; #[derive(Debug, Default, Clone)] pub struct NoNonNullAssertion; @@ -37,7 +41,7 @@ impl Rule for NoNonNullAssertion { ctx.diagnostic(no_non_null_assertion_diagnostic(expr.span)); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_this_alias.rs b/crates/oxc_linter/src/rules/typescript/no_this_alias.rs index 8ba77f4927f86..298967d97a71b 100644 --- a/crates/oxc_linter/src/rules/typescript/no_this_alias.rs +++ b/crates/oxc_linter/src/rules/typescript/no_this_alias.rs @@ -8,7 +8,11 @@ use oxc_span::{CompactStr, GetSpan, Span}; use rustc_hash::FxHashSet; use serde_json::Value; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_this_alias_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Unexpected aliasing of 'this' to local variable.") @@ -153,7 +157,7 @@ impl Rule for NoThisAlias { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_unnecessary_type_constraint.rs b/crates/oxc_linter/src/rules/typescript/no_unnecessary_type_constraint.rs index 81331f5a37c70..c7073c66d17d8 100644 --- a/crates/oxc_linter/src/rules/typescript/no_unnecessary_type_constraint.rs +++ b/crates/oxc_linter/src/rules/typescript/no_unnecessary_type_constraint.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_unnecessary_type_constraint_diagnostic( generic_type: &str, @@ -68,7 +72,7 @@ impl Rule for NoUnnecessaryTypeConstraint { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_unsafe_declaration_merging.rs b/crates/oxc_linter/src/rules/typescript/no_unsafe_declaration_merging.rs index 20d8fc27e41df..5a2059ac00d05 100644 --- a/crates/oxc_linter/src/rules/typescript/no_unsafe_declaration_merging.rs +++ b/crates/oxc_linter/src/rules/typescript/no_unsafe_declaration_merging.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_semantic::SymbolId; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_unsafe_declaration_merging_diagnostic(span: Span, span1: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Unsafe declaration merging between classes and interfaces.") @@ -61,7 +65,7 @@ impl Rule for NoUnsafeDeclarationMerging { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/no_var_requires.rs b/crates/oxc_linter/src/rules/typescript/no_var_requires.rs index 3f1a593344b20..e858557000771 100644 --- a/crates/oxc_linter/src/rules/typescript/no_var_requires.rs +++ b/crates/oxc_linter/src/rules/typescript/no_var_requires.rs @@ -3,7 +3,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{ast_util::is_global_require_call, context::LintContext, rule::Rule, AstNode}; +use crate::{ + ast_util::is_global_require_call, + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn no_var_requires_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Require statement not part of import statement.") @@ -66,7 +71,7 @@ impl Rule for NoVarRequires { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/prefer_as_const.rs b/crates/oxc_linter/src/rules/typescript/prefer_as_const.rs index 9487f4eaefea8..a5123fddcff23 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_as_const.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_as_const.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn prefer_as_const_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Expected a `const` assertion instead of a literal type annotation.") @@ -82,7 +86,7 @@ impl Rule for PreferAsConst { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/prefer_enum_initializers.rs b/crates/oxc_linter/src/rules/typescript/prefer_enum_initializers.rs index 11433f70e9ba7..1edc9eb20a0c9 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_enum_initializers.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_enum_initializers.rs @@ -3,7 +3,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn prefer_enum_initializers_diagnostic( member_name: &str, @@ -59,7 +63,7 @@ impl Rule for PreferEnumInitializers { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs b/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs index 1f329e68e2b1e..d5ef6a106a2d1 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs @@ -6,7 +6,12 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, fixer::Fix, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + fixer::Fix, + rule::Rule, + AstNode, +}; fn prefer_function_type_diagnostic(suggestion: &str, span: Span) -> OxcDiagnostic { // FIXME: use imperative message phrasing @@ -397,7 +402,7 @@ impl Rule for PreferFunctionType { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/prefer_literal_enum_member.rs b/crates/oxc_linter/src/rules/typescript/prefer_literal_enum_member.rs index cdd15a08a8359..591cad430e656 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_literal_enum_member.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_literal_enum_member.rs @@ -4,7 +4,11 @@ use oxc_macros::declare_oxc_lint; use oxc_span::Span; use oxc_syntax::operator::{BinaryOperator, UnaryOperator}; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn prefer_literal_enum_member_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn( @@ -109,7 +113,7 @@ impl Rule for PreferLiteralEnumMember { ctx.diagnostic(prefer_literal_enum_member_diagnostic(decl.span)); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/prefer_namespace_keyword.rs b/crates/oxc_linter/src/rules/typescript/prefer_namespace_keyword.rs index 30107cdabb363..9da87a6996dd8 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_namespace_keyword.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_namespace_keyword.rs @@ -6,7 +6,11 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, AstNode}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, + AstNode, +}; fn prefer_namespace_keyword_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Use 'namespace' instead of 'module' to declare custom TypeScript modules.") @@ -69,7 +73,7 @@ impl Rule for PreferNamespaceKeyword { }); } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/prefer_ts_expect_error.rs b/crates/oxc_linter/src/rules/typescript/prefer_ts_expect_error.rs index c2fade16e69f0..0eb26802eefa1 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_ts_expect_error.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_ts_expect_error.rs @@ -4,7 +4,10 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, +}; fn prefer_ts_expect_error_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Enforce using `@ts-expect-error` over `@ts-ignore`") @@ -74,7 +77,7 @@ impl Rule for PreferTsExpectError { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs b/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs index 2140fc877b7ba..4a358d59dbedf 100644 --- a/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs +++ b/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs @@ -8,7 +8,10 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::{GetSpan, Span}; -use crate::{context::LintContext, rule::Rule}; +use crate::{ + context::{ContextHost, LintContext}, + rule::Rule, +}; fn triple_slash_reference_diagnostic(ref_kind: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("Do not use a triple slash reference for {ref_kind}, use `import` style instead.")) @@ -163,7 +166,7 @@ impl Rule for TripleSlashReference { } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_typescript() } } diff --git a/crates/oxc_linter/src/utils/jest.rs b/crates/oxc_linter/src/utils/jest.rs index 00dc48c9f2f80..21d6c8c5d1e56 100644 --- a/crates/oxc_linter/src/utils/jest.rs +++ b/crates/oxc_linter/src/utils/jest.rs @@ -302,14 +302,14 @@ pub fn is_equality_matcher(matcher: &KnownMemberExpressionProperty) -> bool { #[cfg(test)] mod test { - use std::{path::Path, rc::Rc}; + use std::rc::Rc; use oxc_allocator::Allocator; use oxc_parser::Parser; use oxc_semantic::SemanticBuilder; use oxc_span::SourceType; - use crate::LintContext; + use crate::{options::LintOptions, ContextHost}; #[test] fn test_is_jest_file() { @@ -320,16 +320,18 @@ mod test { let semantic_ret = SemanticBuilder::new("").with_cfg(true).build(program).semantic; let semantic_ret = Rc::new(semantic_ret); - let path = Path::new("foo.js"); - let ctx = LintContext::new(Box::from(path), Rc::clone(&semantic_ret)); + let build_ctx = |path: &'static str| { + Rc::new(ContextHost::new(path, Rc::clone(&semantic_ret), LintOptions::default())) + .spawn_for_test() + }; + + let ctx = build_ctx("foo.js"); assert!(!super::is_jest_file(&ctx)); - let path = Path::new("foo.test.js"); - let ctx = LintContext::new(Box::from(path), Rc::clone(&semantic_ret)); + let ctx = build_ctx("foo.test.js"); assert!(super::is_jest_file(&ctx)); - let path = Path::new("__tests__/foo/test.spec.js"); - let ctx = LintContext::new(Box::from(path), semantic_ret); + let ctx = build_ctx("__tests__/foo/test.spec.js"); assert!(super::is_jest_file(&ctx)); } } diff --git a/crates/oxc_linter/src/utils/react_perf.rs b/crates/oxc_linter/src/utils/react_perf.rs index 4cf51fdd7653b..ad6f29a0ea3ab 100644 --- a/crates/oxc_linter/src/utils/react_perf.rs +++ b/crates/oxc_linter/src/utils/react_perf.rs @@ -11,7 +11,7 @@ use oxc_diagnostics::OxcDiagnostic; use oxc_semantic::SymbolId; use oxc_span::Span; -use crate::{rule::Rule, AstNode, LintContext}; +use crate::{context::ContextHost, rule::Rule, AstNode, LintContext}; fn react_perf_inline_diagnostic(message: &'static str, attr_span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(message) @@ -119,7 +119,7 @@ where } } - fn should_run(&self, ctx: &LintContext) -> bool { + fn should_run(&self, ctx: &ContextHost) -> bool { ctx.source_type().is_jsx() } } diff --git a/crates/oxc_macros/src/declare_all_lint_rules.rs b/crates/oxc_macros/src/declare_all_lint_rules.rs index 879dd4626aacb..b6e429b9f42dc 100644 --- a/crates/oxc_macros/src/declare_all_lint_rules.rs +++ b/crates/oxc_macros/src/declare_all_lint_rules.rs @@ -61,7 +61,7 @@ pub fn declare_all_lint_rules(metadata: AllLintRulesMeta) -> TokenStream { let expanded = quote! { #(pub use self::#use_stmts::#struct_names;)* - use crate::{context::LintContext, rule::{Rule, RuleCategory, RuleFixMeta, RuleMeta}, AstNode}; + use crate::{context::{ContextHost, LintContext}, rule::{Rule, RuleCategory, RuleFixMeta, RuleMeta}, AstNode}; use oxc_semantic::SymbolId; #[derive(Debug, Clone)] @@ -134,7 +134,7 @@ pub fn declare_all_lint_rules(metadata: AllLintRulesMeta) -> TokenStream { } } - pub(super) fn should_run(&self, ctx: &LintContext) -> bool { + pub(super) fn should_run(&self, ctx: &ContextHost) -> bool { match self { #(Self::#struct_names(rule) => rule.should_run(ctx)),* }