diff --git a/crates/oxc_linter/src/rules/eslint/capitalized_comments.rs b/crates/oxc_linter/src/rules/eslint/capitalized_comments.rs index fd2464421a501..f98210a6cc15e 100644 --- a/crates/oxc_linter/src/rules/eslint/capitalized_comments.rs +++ b/crates/oxc_linter/src/rules/eslint/capitalized_comments.rs @@ -45,7 +45,7 @@ struct CommentConfig { ignore_consecutive_comments: bool, } -#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize)] +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, JsonSchema)] #[serde(rename_all = "lowercase")] enum CapitalizeOption { #[default] @@ -77,8 +77,11 @@ impl std::ops::Deref for CapitalizedComments { #[serde(rename_all = "camelCase")] #[expect(clippy::struct_field_names)] struct CommentConfigJson { + /// A regex pattern. Comments that match the pattern will not cause violations. ignore_pattern: Option, + /// If true, inline comments (comments in the middle of code) will be ignored. ignore_inline_comments: Option, + /// If true, consecutive comments will be ignored after the first comment. ignore_consecutive_comments: Option, } @@ -101,14 +104,30 @@ impl CommentConfigJson { } #[derive(Debug, Clone, Default, Deserialize, JsonSchema)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "camelCase", default)] struct OptionsJson { #[serde(flatten)] base: CommentConfigJson, + /// Configuration specifically for line comments (`//`). line: Option, + /// Configuration specifically for block comments (`/* */`). block: Option, } +/// Configuration schema for the rule. +/// The rule accepts a tuple array configuration: `[capitalize_option, options]` +/// +/// - First element: `"always"` (default) or `"never"` - controls whether comments should be capitalized +/// - Second element: Optional object with additional configuration properties +#[derive(Debug, Default, Clone, Deserialize, JsonSchema)] +#[serde(default)] +struct CapitalizedCommentsSchema( + /// Controls whether comments should start with an uppercase or lowercase letter. Default: "always". + CapitalizeOption, + /// Optional configuration object with additional settings. + Option, +); + declare_oxc_lint!( /// ### What it does /// @@ -137,7 +156,7 @@ declare_oxc_lint!( eslint, style, fix, - config = OptionsJson + config = CapitalizedCommentsSchema ); impl Rule for CapitalizedComments { @@ -604,7 +623,7 @@ fn test() { // lineCommentIgnorePattern /* blockCommentIgnorePattern */", Some( - serde_json::json!([ "always", { "line": { "ignorePattern": "lineCommentIgnorePattern", }, "block": { "ignorePattern": "blockCommentIgnorePattern", }, }, ]), + serde_json::json!([ "always", { "line": { "ignorePattern": "lineCommentIgnorePattern" }, "block": { "ignorePattern": "blockCommentIgnorePattern" } }]), ), ), ]; diff --git a/tasks/website_common/src/schema_markdown.rs b/tasks/website_common/src/schema_markdown.rs index 7583344768b60..4c151ac904596 100644 --- a/tasks/website_common/src/schema_markdown.rs +++ b/tasks/website_common/src/schema_markdown.rs @@ -161,7 +161,11 @@ impl Renderer { .properties .iter() .flat_map(|(key, schema)| { - let key = parent_key.map_or_else(|| key.clone(), |k| format!("{k}.{key}")); + // This is necessary to handle config options added via serde(flatten). + let key = match parent_key { + Some(parent) if !parent.is_empty() => format!("{parent}.{key}"), + _ => key.clone(), + }; let schema_object = Self::get_schema_object(schema); if let Some(subschemas) = &schema_object.subschemas {