Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions crates/oxc_linter/src/context/host.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{
borrow::Cow,
cell::{Cell, RefCell},
ffi::OsStr,
path::Path,
rc::Rc,
sync::Arc,
Expand Down Expand Up @@ -141,6 +142,8 @@ pub struct ContextHost<'a> {
pub(super) fix: FixKind,
/// Path to the file being linted.
pub(super) file_path: Box<Path>,
/// Extension of the file being linted.
file_extension: Option<Box<OsStr>>,
/// Global linter configuration, such as globals to include and the target
/// environments, and other settings.
pub(super) config: Arc<LintConfig>,
Expand Down Expand Up @@ -171,13 +174,15 @@ impl<'a> ContextHost<'a> {
);

let file_path = file_path.as_ref().to_path_buf().into_boxed_path();
let file_extension = file_path.extension().map(|ext| ext.to_owned().into_boxed_os_str());

Self {
sub_hosts,
current_sub_host_index: Cell::new(0),
diagnostics: RefCell::new(Vec::with_capacity(DIAGNOSTICS_INITIAL_CAPACITY)),
fix: options.fix,
file_path,
file_extension,
config,
frameworks: options.framework_hints,
}
Expand Down Expand Up @@ -231,6 +236,12 @@ impl<'a> ContextHost<'a> {
&self.file_path
}

/// Extension of the file currently being linted, without the leading dot.
#[inline]
pub fn file_extension(&self) -> Option<&OsStr> {
self.file_extension.as_deref()
}

/// The source type of the file being linted, e.g. JavaScript, TypeScript,
/// CJS, ESM, etc.
#[inline]
Expand Down
8 changes: 7 additions & 1 deletion crates/oxc_linter/src/context/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![expect(rustdoc::private_intra_doc_links)] // useful for intellisense

use std::{ops::Deref, path::Path, rc::Rc};
use std::{ffi::OsStr, ops::Deref, path::Path, rc::Rc};

use javascript_globals::GLOBALS;

Expand Down Expand Up @@ -141,6 +141,12 @@ impl<'a> LintContext<'a> {
&self.parent.file_path
}

/// Extension of the file currently being linted, without the leading dot.
#[inline]
pub fn file_extension(&self) -> Option<&OsStr> {
self.parent.file_extension()
}

/// Plugin settings
#[inline]
pub fn settings(&self) -> &OxlintSettings {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_unused_labels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl Rule for NoUnusedLabels {
}

fn should_run(&self, ctx: &crate::context::ContextHost) -> bool {
ctx.file_path().extension().is_some_and(|ext| ext != "svelte")
ctx.file_extension().is_some_and(|ext| ext != "svelte")
}
}

Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_linter/src/rules/eslint/no_unused_vars/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,7 @@ impl Rule for NoUnusedVars {
// we can't detect
!ctx.source_type().is_typescript_definition()
&& !ctx
.file_path()
.extension()
.file_extension()
.is_some_and(|ext| ext == "vue" || ext == "svelte" || ext == "astro")
}
}
Expand Down
6 changes: 2 additions & 4 deletions crates/oxc_linter/src/rules/jest/no_large_snapshots.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{ops::Deref, path::Path};
use std::ops::Deref;

use lazy_regex::Regex;
use oxc_ast::{
Expand Down Expand Up @@ -170,9 +170,7 @@ impl Rule for NoLargeSnapshots {
}

fn run_once(&self, ctx: &LintContext) {
let is_snap = ctx.file_path().to_str().is_some_and(|p| {
Path::new(p).extension().is_some_and(|ext| ext.eq_ignore_ascii_case("snap"))
});
let is_snap = ctx.file_extension().is_some_and(|ext| ext.eq_ignore_ascii_case("snap"));

if is_snap {
for node in ctx.nodes().iter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl Rule for JsxFilenameExtension {
}

fn run_once(&self, ctx: &LintContext) {
let file_extension = ctx.file_path().extension().and_then(OsStr::to_str).unwrap_or("");
let file_extension = ctx.file_extension().and_then(OsStr::to_str).unwrap_or("");
let has_ext_allowed = self.extensions.contains(&CompactStr::new(file_extension));

if !has_ext_allowed {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::path::Path;

use oxc_ast::{AstKind, ast::*};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
Expand Down Expand Up @@ -262,7 +260,7 @@ impl Rule for OnlyExportComponents {
};

let should_scan = {
let ext = Path::new(filename).extension().and_then(|e| e.to_str());
let ext = ctx.file_extension();
matches!(ext, Some(e) if e.eq_ignore_ascii_case("tsx") || e.eq_ignore_ascii_case("jsx"))
|| (self.check_js && matches!(ext, Some(e) if e.eq_ignore_ascii_case("js")))
};
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/react/rules_of_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl Rule for RulesOfHooks {
// disable this rule in vue/nuxt and svelte(kit) files
// react hook can be build in only `.ts` files,
// but `useX` functions are popular and can be false positive in other frameworks
!ctx.file_path().extension().is_some_and(|ext| ext == "vue" || ext == "svelte")
!ctx.file_extension().is_some_and(|ext| ext == "vue" || ext == "svelte")
}

fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_linter/src/rules/unicorn/no_empty_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ impl Rule for NoEmptyFile {
}

fn should_run(&self, ctx: &ContextHost) -> bool {
ctx.file_path().extension().is_some_and(|ext| {
!LINT_PARTIAL_LOADER_EXTENSIONS.contains(&ext.to_string_lossy().as_ref())
})
ctx.file_extension()
.is_some_and(|ext| !LINT_PARTIAL_LOADER_EXTENSIONS.iter().any(|e| *e == ext))
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/vue/max_props.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl Rule for MaxProps {
}

fn should_run(&self, ctx: &crate::context::ContextHost) -> bool {
ctx.file_path().extension().is_some_and(|ext| ext == "vue")
ctx.file_extension().is_some_and(|ext| ext == "vue")
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/vue/no_multiple_slot_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl Rule for NoMultipleSlotArgs {
}

fn should_run(&self, ctx: &crate::context::ContextHost) -> bool {
ctx.file_path().extension().is_some_and(|ext| ext == "vue")
ctx.file_extension().is_some_and(|ext| ext == "vue")
&& ctx.frameworks_options() != FrameworkOptions::VueSetup
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ declare_oxc_lint!(

impl Rule for NoRequiredPropWithDefault {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let is_vue = ctx.file_path().extension().is_some_and(|ext| ext == "vue");
let is_vue = ctx.file_extension().is_some_and(|ext| ext == "vue");
if is_vue {
self.run_on_vue(node, ctx);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl Rule for RequireDefaultExport {

fn should_run(&self, ctx: &ContextHost) -> bool {
// only on vue files
if ctx.file_path().extension().is_none_or(|ext| ext != "vue") {
if ctx.file_extension().is_none_or(|ext| ext != "vue") {
return false;
}

Expand Down
Loading