Skip to content
Draft
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
71 changes: 17 additions & 54 deletions crates/oxc_linter/src/rules/eslint/sort_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde::{Deserialize};

use crate::{AstNode, context::LintContext, rule::Rule};
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};

#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Deserialize)]
pub struct SortKeys(Box<SortKeysConfig>);

#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
/// Sorting order for keys. Accepts "asc" for ascending or "desc" for descending.
pub enum SortOrder {
Expand All @@ -24,7 +28,7 @@ pub enum SortOrder {
Asc,
}

#[derive(Debug, Clone, JsonSchema)]
#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct SortKeysOptions {
/// Whether the sort comparison is case-sensitive (A < a when true).
Expand All @@ -49,19 +53,10 @@ impl Default for SortKeysOptions {
}
}

#[derive(Debug, Default, Clone, JsonSchema)]
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(default)]
pub struct SortKeysConfig(SortOrder, SortKeysOptions);

impl SortKeys {
fn sort_order(&self) -> &SortOrder {
&(*self.0).0
}
fn options(&self) -> &SortKeysOptions {
&(*self.0).1
}
}

fn sort_properties_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Object keys should be sorted").with_label(span)
}
Expand Down Expand Up @@ -102,50 +97,18 @@ declare_oxc_lint!(

impl Rule for SortKeys {
fn from_configuration(value: serde_json::Value) -> Self {
let Some(config_array) = value.as_array() else {
return Self::default();
};

let sort_order = if config_array.is_empty() {
SortOrder::Asc
} else {
config_array[0].as_str().map_or(SortOrder::Asc, |s| match s {
"desc" => SortOrder::Desc,
_ => SortOrder::Asc,
})
};

let config = if config_array.len() > 1 {
config_array[1].as_object().unwrap()
} else {
&serde_json::Map::new()
};

let case_sensitive =
config.get("caseSensitive").and_then(serde_json::Value::as_bool).unwrap_or(true);
let natural = config.get("natural").and_then(serde_json::Value::as_bool).unwrap_or(false);
let min_keys = config
.get("minKeys")
.and_then(serde_json::Value::as_u64)
.map_or(2, |n| n.try_into().unwrap_or(2));
let allow_line_separated_groups = config
.get("allowLineSeparatedGroups")
.and_then(serde_json::Value::as_bool)
.unwrap_or(false);

Self(Box::new(SortKeysConfig(
sort_order,
SortKeysOptions { case_sensitive, natural, min_keys, allow_line_separated_groups },
)))
serde_json::from_value::<DefaultRuleConfig<SortKeys>>(value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we can use serde_json::from_value::<SortKeys>(value) here, so the change to DefaultRuleConfig is unnecessary?

.unwrap_or_default()
.into_inner()
}

fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if let AstKind::ObjectExpression(dec) = node.kind() {
let options = self.options();
let SortKeysConfig(sort_order, options) = &*self.0;

if dec.properties.len() < options.min_keys {
return;
}
let sort_order = self.sort_order().clone();

let mut property_groups: Vec<Vec<String>> = vec![vec![]];

Expand Down Expand Up @@ -194,7 +157,7 @@ impl Rule for SortKeys {
alphanumeric_sort(group);
}

if sort_order == SortOrder::Desc {
if sort_order == &SortOrder::Desc {
group.reverse();
}
}
Expand Down Expand Up @@ -277,7 +240,7 @@ impl Rule for SortKeys {
} else {
alphanumeric_sort(&mut sorted_keys);
}
if sort_order == SortOrder::Desc {
if sort_order == &SortOrder::Desc {
sorted_keys.reverse();
}

Expand Down