diff --git a/crates/oxc_linter/src/config/mod.rs b/crates/oxc_linter/src/config/mod.rs index 90f448a50de37..69cf700e3e3a5 100644 --- a/crates/oxc_linter/src/config/mod.rs +++ b/crates/oxc_linter/src/config/mod.rs @@ -5,7 +5,7 @@ use oxc_diagnostics::{Error, FailedToOpenFileError, Report}; use rustc_hash::{FxHashMap, FxHashSet}; use serde_json::Value; -use crate::{rules::RuleEnum, AllowWarnDeny, JsxA11y, LintSettings}; +use crate::{rules::RuleEnum, settings::Nextjs, AllowWarnDeny, JsxA11y, LintSettings}; use self::errors::{ FailedToParseConfigError, FailedToParseConfigJsonError, FailedToParseRuleValueError, @@ -167,9 +167,9 @@ fn parse_settings_from_root(root_json: &Value) -> LintSettings { pub fn parse_settings(setting_value: &Value) -> LintSettings { if let Value::Object(settings_object) = setting_value { + let mut jsx_a11y_setting = JsxA11y::new(None, FxHashMap::default()); + let mut nextjs_setting = Nextjs::new(vec![]); if let Some(Value::Object(jsx_a11y)) = settings_object.get("jsx-a11y") { - let mut jsx_a11y_setting = JsxA11y::new(None, FxHashMap::default()); - if let Some(Value::Object(components)) = jsx_a11y.get("components") { let components_map: FxHashMap = components .iter() @@ -184,9 +184,20 @@ pub fn parse_settings(setting_value: &Value) -> LintSettings { jsx_a11y_setting .set_polymorphic_prop_name(Some(String::from(polymorphic_prop_name))); } + } - return LintSettings::new(jsx_a11y_setting); + if let Some(Value::Object(nextjs)) = settings_object.get("next") { + if let Some(Value::String(root_dir)) = nextjs.get("rootDir") { + nextjs_setting.set_root_dir(vec![String::from(root_dir)]); + } + if let Some(Value::Array(root_dir)) = nextjs.get("rootDir") { + nextjs_setting.set_root_dir( + root_dir.iter().map(|v| v.as_str().unwrap().to_string()).collect(), + ); + } } + + return LintSettings::new(jsx_a11y_setting, nextjs_setting); } LintSettings::default() @@ -201,9 +212,13 @@ fn parse_rule_name(name: &str) -> (&str, &str) { "typescript-eslint" => "typescript", // plugin name in RuleEnum is in snake_case "jsx-a11y" => "jsx_a11y", + "next" => "nextjs", _ => category, }; + // since next.js eslint rule starts with @next/next/ + let name = name.trim_start_matches("next/"); + (category, name) } else { ("eslint", name) diff --git a/crates/oxc_linter/src/settings.rs b/crates/oxc_linter/src/settings.rs index 6ad3ae60f7409..a32e2b8c2b7c1 100644 --- a/crates/oxc_linter/src/settings.rs +++ b/crates/oxc_linter/src/settings.rs @@ -4,17 +4,21 @@ use rustc_hash::FxHashMap; #[derive(Debug, Clone)] pub struct LintSettings { pub jsx_a11y: JsxA11y, + pub nextjs: Nextjs, } impl Default for LintSettings { fn default() -> Self { - Self { jsx_a11y: JsxA11y { polymorphic_prop_name: None, components: FxHashMap::default() } } + Self { + jsx_a11y: JsxA11y { polymorphic_prop_name: None, components: FxHashMap::default() }, + nextjs: Nextjs { root_dir: vec![] }, + } } } impl LintSettings { - pub fn new(jsx_a11y: JsxA11y) -> Self { - Self { jsx_a11y } + pub fn new(jsx_a11y: JsxA11y, nextjs: Nextjs) -> Self { + Self { jsx_a11y, nextjs } } } @@ -40,3 +44,18 @@ impl JsxA11y { self.polymorphic_prop_name = name; } } + +#[derive(Debug, Clone)] +pub struct Nextjs { + pub root_dir: Vec, +} + +impl Nextjs { + pub fn new(root_dir: Vec) -> Self { + Self { root_dir } + } + + pub fn set_root_dir(&mut self, root_dir: Vec) { + self.root_dir = root_dir; + } +} diff --git a/crates/oxc_linter/src/utils/react.rs b/crates/oxc_linter/src/utils/react.rs index bbbbf78cc0525..40a3728d31a85 100644 --- a/crates/oxc_linter/src/utils/react.rs +++ b/crates/oxc_linter/src/utils/react.rs @@ -224,7 +224,7 @@ pub fn get_element_type(context: &LintContext, element: &JSXOpeningElement) -> O return None; }; - let LintSettings { jsx_a11y } = context.settings(); + let LintSettings { jsx_a11y, .. } = context.settings(); let JsxA11y { polymorphic_prop_name, components } = jsx_a11y; if let Some(polymorphic_prop_name_value) = polymorphic_prop_name {