Skip to content

Commit e5a78ed

Browse files
committed
refactor(formatter/sort-imports): Move SortImportsOptions to sort_imports/options.rs (#16374)
Pure refactoring.
1 parent 7374856 commit e5a78ed

File tree

12 files changed

+124
-126
lines changed

12 files changed

+124
-126
lines changed

crates/oxc_formatter/examples/sort_imports.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::{fs, path::Path};
44

55
use oxc_allocator::Allocator;
6-
use oxc_formatter::{FormatOptions, Formatter, SortImports, SortOrder, get_parse_options};
6+
use oxc_formatter::{FormatOptions, Formatter, SortImportsOptions, SortOrder, get_parse_options};
77
use oxc_parser::Parser;
88
use oxc_span::SourceType;
99
use pico_args::Arguments;
@@ -21,7 +21,7 @@ fn main() -> Result<(), String> {
2121
let ignore_case = !args.contains("--no_ignore_case");
2222
let newlines_between = !args.contains("--no_newlines_between");
2323

24-
let sort_imports_options = SortImports {
24+
let sort_imports_options = SortImportsOptions {
2525
order,
2626
partition_by_newline,
2727
partition_by_comment,

crates/oxc_formatter/src/ir_transform/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
2222
mod sort_imports;
2323

24-
pub use sort_imports::SortImportsTransform;
24+
pub use sort_imports::*;

crates/oxc_formatter/src/ir_transform/sort_imports/compute_metadata.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ use std::{borrow::Cow, path::Path};
33
use cow_utils::CowUtils;
44
use phf::phf_set;
55

6-
use crate::{
7-
ir_transform::sort_imports::{
8-
group_config::{GroupName, ImportModifier, ImportSelector},
9-
source_line::ImportLineMetadata,
10-
},
11-
options,
6+
use crate::ir_transform::sort_imports::{
7+
group_config::{GroupName, ImportModifier, ImportSelector},
8+
options::SortImportsOptions,
9+
source_line::ImportLineMetadata,
1210
};
1311

1412
/// Compute all metadata derived from import line metadata.
@@ -17,7 +15,7 @@ use crate::{
1715
pub fn compute_import_metadata<'a>(
1816
metadata: &ImportLineMetadata<'a>,
1917
groups: &[Vec<GroupName>],
20-
options: &options::SortImports,
18+
options: &SortImportsOptions,
2119
) -> (usize, Cow<'a, str>, bool) {
2220
let ImportLineMetadata {
2321
source,
@@ -347,7 +345,7 @@ enum ImportPathKind {
347345
}
348346

349347
/// Determine the path kind for an import source.
350-
fn to_path_kind(source: &str, options: &options::SortImports) -> ImportPathKind {
348+
fn to_path_kind(source: &str, options: &SortImportsOptions) -> ImportPathKind {
351349
if is_builtin(source) {
352350
return ImportPathKind::Builtin;
353351
}

crates/oxc_formatter/src/ir_transform/sort_imports/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod compute_metadata;
22
mod group_config;
3+
pub mod options;
34
mod partitioned_chunk;
45
mod sortable_imports;
56
mod source_line;
@@ -13,19 +14,18 @@ use crate::{
1314
partitioned_chunk::PartitionedChunk,
1415
source_line::SourceLine,
1516
},
16-
options,
1717
};
1818

1919
/// An IR transform that sorts import statements according to specified options.
2020
/// Heavily inspired by ESLint's `@perfectionist/sort-imports` rule.
2121
/// <https://perfectionist.dev/rules/sort-imports>
2222
pub struct SortImportsTransform {
23-
options: options::SortImports,
23+
options: options::SortImportsOptions,
2424
groups: Vec<Vec<GroupName>>,
2525
}
2626

2727
impl SortImportsTransform {
28-
pub fn new(options: options::SortImports) -> Self {
28+
pub fn new(options: options::SortImportsOptions) -> Self {
2929
// Parse string based groups into our internal representation for performance
3030
let groups = if let Some(groups) = &options.groups {
3131
parse_groups_from_strings(groups)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use std::fmt;
2+
use std::str::FromStr;
3+
4+
#[derive(Clone, Debug, Eq, PartialEq)]
5+
pub struct SortImportsOptions {
6+
/// Partition imports by newlines.
7+
/// Default is `false`.
8+
pub partition_by_newline: bool,
9+
/// Partition imports by comments.
10+
/// Default is `false`.
11+
pub partition_by_comment: bool,
12+
/// Sort side effects imports.
13+
/// Default is `false`.
14+
pub sort_side_effects: bool,
15+
/// Sort order (asc or desc).
16+
/// Default is ascending (asc).
17+
pub order: SortOrder,
18+
/// Ignore case when sorting.
19+
/// Default is `true`.
20+
pub ignore_case: bool,
21+
/// Whether to insert blank lines between different import groups.
22+
/// - `true`: Insert one blank line between groups (default)
23+
/// - `false`: No blank lines between groups
24+
///
25+
/// NOTE: Cannot be used together with `partition_by_newline: true`.
26+
pub newlines_between: bool,
27+
/// Prefixes for internal imports.
28+
/// If `None`, uses the default internal patterns.
29+
pub internal_pattern: Option<Vec<String>>,
30+
/// Groups configuration for organizing imports.
31+
/// Each inner `Vec` represents a group, and multiple group names in the same `Vec` are treated as one.
32+
/// If `None`, uses the default groups.
33+
pub groups: Option<Vec<Vec<String>>>,
34+
}
35+
36+
impl Default for SortImportsOptions {
37+
fn default() -> Self {
38+
Self {
39+
partition_by_newline: false,
40+
partition_by_comment: false,
41+
sort_side_effects: false,
42+
order: SortOrder::default(),
43+
ignore_case: true,
44+
newlines_between: true,
45+
internal_pattern: None,
46+
groups: None,
47+
}
48+
}
49+
}
50+
51+
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
52+
pub enum SortOrder {
53+
/// Sort in ascending order (A-Z).
54+
#[default]
55+
Asc,
56+
/// Sort in descending order (Z-A).
57+
Desc,
58+
}
59+
60+
impl SortOrder {
61+
pub const fn is_asc(self) -> bool {
62+
matches!(self, Self::Asc)
63+
}
64+
65+
pub const fn is_desc(self) -> bool {
66+
matches!(self, Self::Desc)
67+
}
68+
}
69+
70+
impl FromStr for SortOrder {
71+
type Err = &'static str;
72+
73+
fn from_str(s: &str) -> Result<Self, Self::Err> {
74+
match s {
75+
"asc" => Ok(Self::Asc),
76+
"desc" => Ok(Self::Desc),
77+
_ => Err("Value not supported for SortOrder. Supported values are 'asc' and 'desc'."),
78+
}
79+
}
80+
}
81+
82+
impl fmt::Display for SortOrder {
83+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84+
let s = match self {
85+
SortOrder::Asc => "ASC",
86+
SortOrder::Desc => "DESC",
87+
};
88+
f.write_str(s)
89+
}
90+
}

crates/oxc_formatter/src/ir_transform/sort_imports/partitioned_chunk.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
use crate::{
2-
ir_transform::sort_imports::{
3-
compute_metadata::compute_import_metadata,
4-
group_config::GroupName,
5-
sortable_imports::{SortSortableImports, SortableImport},
6-
source_line::SourceLine,
7-
},
8-
options,
1+
use crate::ir_transform::sort_imports::{
2+
compute_metadata::compute_import_metadata,
3+
group_config::GroupName,
4+
options::SortImportsOptions,
5+
sortable_imports::{SortSortableImports, SortableImport},
6+
source_line::SourceLine,
97
};
108

119
#[derive(Debug)]
@@ -50,7 +48,7 @@ impl<'a> PartitionedChunk<'a> {
5048
pub fn into_sorted_import_units(
5149
self,
5250
groups: &[Vec<GroupName>],
53-
options: &options::SortImports,
51+
options: &SortImportsOptions,
5452
) -> (Vec<SortableImport<'a>>, Vec<SourceLine<'a>>) {
5553
let Self::Imports(lines) = self else {
5654
unreachable!(

crates/oxc_formatter/src/ir_transform/sort_imports/sortable_imports.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::borrow::Cow;
22

33
use rustc_hash::{FxHashMap, FxHashSet};
44

5-
use crate::{ir_transform::sort_imports::source_line::SourceLine, options};
5+
use crate::ir_transform::sort_imports::{options::SortImportsOptions, source_line::SourceLine};
66

77
#[derive(Debug)]
88
pub struct SortableImport<'a> {
@@ -18,11 +18,11 @@ pub struct SortableImport<'a> {
1818
// ---
1919

2020
pub trait SortSortableImports {
21-
fn sort(&mut self, options: &options::SortImports);
21+
fn sort(&mut self, options: &SortImportsOptions);
2222
}
2323

2424
impl SortSortableImports for Vec<SortableImport<'_>> {
25-
fn sort(&mut self, options: &options::SortImports) {
25+
fn sort(&mut self, options: &SortImportsOptions) {
2626
let imports_len = self.len();
2727

2828
// Perform sorting only if needed
@@ -90,7 +90,7 @@ impl SortSortableImports for Vec<SortableImport<'_>> {
9090
fn sort_within_group(
9191
indices: &mut [usize],
9292
imports: &[SortableImport],
93-
options: &options::SortImports,
93+
options: &SortImportsOptions,
9494
) {
9595
if indices.len() < 2 {
9696
return;
@@ -148,7 +148,7 @@ fn sort_within_group(
148148
fn sort_indices_by_source(
149149
indices: &mut [usize],
150150
imports: &[SortableImport],
151-
options: &options::SortImports,
151+
options: &SortImportsOptions,
152152
) {
153153
indices.sort_by(|&a, &b| {
154154
natord::compare(&imports[a].normalized_source, &imports[b].normalized_source)

crates/oxc_formatter/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use oxc_allocator::Allocator;
1616
use oxc_ast::ast::*;
1717

1818
pub use crate::embedded_formatter::{EmbeddedFormatter, EmbeddedFormatterCallback};
19+
pub use crate::ir_transform::options::*;
1920
pub use crate::options::*;
2021
pub use crate::service::{oxfmtrc::Oxfmtrc, parse_utils::*};
2122
use crate::{

crates/oxc_formatter/src/options.rs

Lines changed: 2 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
prelude::{if_group_breaks, token},
88
printer::PrinterOptions,
99
},
10+
ir_transform::options::SortImportsOptions,
1011
write,
1112
};
1213

@@ -71,9 +72,8 @@ pub struct FormatOptions {
7172
/// Enable formatting for embedded languages (e.g., CSS, SQL, GraphQL) within template literals. Defaults to "auto".
7273
pub embedded_language_formatting: EmbeddedLanguageFormatting,
7374

74-
// TODO: `FormatOptions`? Split out as `TransformOptions`?
7575
/// Sort import statements. By default disabled.
76-
pub experimental_sort_imports: Option<SortImports>,
76+
pub experimental_sort_imports: Option<SortImportsOptions>,
7777
}
7878

7979
impl FormatOptions {
@@ -978,93 +978,3 @@ impl fmt::Display for EmbeddedLanguageFormatting {
978978
f.write_str(s)
979979
}
980980
}
981-
982-
// ---
983-
984-
#[derive(Clone, Debug, Eq, PartialEq)]
985-
pub struct SortImports {
986-
/// Partition imports by newlines.
987-
/// Default is `false`.
988-
pub partition_by_newline: bool,
989-
/// Partition imports by comments.
990-
/// Default is `false`.
991-
pub partition_by_comment: bool,
992-
/// Sort side effects imports.
993-
/// Default is `false`.
994-
pub sort_side_effects: bool,
995-
/// Sort order (asc or desc).
996-
/// Default is ascending (asc).
997-
pub order: SortOrder,
998-
/// Ignore case when sorting.
999-
/// Default is `true`.
1000-
pub ignore_case: bool,
1001-
/// Whether to insert blank lines between different import groups.
1002-
/// - `true`: Insert one blank line between groups (default)
1003-
/// - `false`: No blank lines between groups
1004-
///
1005-
/// NOTE: Cannot be used together with `partition_by_newline: true`.
1006-
pub newlines_between: bool,
1007-
/// Prefixes for internal imports.
1008-
/// If `None`, uses the default internal patterns.
1009-
pub internal_pattern: Option<Vec<String>>,
1010-
/// Groups configuration for organizing imports.
1011-
/// Each inner `Vec` represents a group, and multiple group names in the same `Vec` are treated as one.
1012-
/// If `None`, uses the default groups.
1013-
pub groups: Option<Vec<Vec<String>>>,
1014-
}
1015-
1016-
impl Default for SortImports {
1017-
fn default() -> Self {
1018-
Self {
1019-
partition_by_newline: false,
1020-
partition_by_comment: false,
1021-
sort_side_effects: false,
1022-
order: SortOrder::default(),
1023-
ignore_case: true,
1024-
newlines_between: true,
1025-
internal_pattern: None,
1026-
groups: None,
1027-
}
1028-
}
1029-
}
1030-
1031-
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
1032-
pub enum SortOrder {
1033-
/// Sort in ascending order (A-Z).
1034-
#[default]
1035-
Asc,
1036-
/// Sort in descending order (Z-A).
1037-
Desc,
1038-
}
1039-
1040-
impl SortOrder {
1041-
pub const fn is_asc(self) -> bool {
1042-
matches!(self, Self::Asc)
1043-
}
1044-
1045-
pub const fn is_desc(self) -> bool {
1046-
matches!(self, Self::Desc)
1047-
}
1048-
}
1049-
1050-
impl FromStr for SortOrder {
1051-
type Err = &'static str;
1052-
1053-
fn from_str(s: &str) -> Result<Self, Self::Err> {
1054-
match s {
1055-
"asc" => Ok(Self::Asc),
1056-
"desc" => Ok(Self::Desc),
1057-
_ => Err("Value not supported for SortOrder. Supported values are 'asc' and 'desc'."),
1058-
}
1059-
}
1060-
}
1061-
1062-
impl fmt::Display for SortOrder {
1063-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1064-
let s = match self {
1065-
SortOrder::Asc => "ASC",
1066-
SortOrder::Desc => "DESC",
1067-
};
1068-
f.write_str(s)
1069-
}
1070-
}

crates/oxc_formatter/src/service/oxfmtrc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use serde::{Deserialize, Deserializer, Serialize};
66
use crate::{
77
ArrowParentheses, AttributePosition, BracketSameLine, BracketSpacing,
88
EmbeddedLanguageFormatting, Expand, FormatOptions, IndentStyle, IndentWidth, LineEnding,
9-
LineWidth, QuoteProperties, QuoteStyle, Semicolons, SortImports, SortOrder, TrailingCommas,
9+
LineWidth, QuoteProperties, QuoteStyle, Semicolons, SortImportsOptions, SortOrder,
10+
TrailingCommas,
1011
};
1112

1213
/// Configuration options for the formatter.
@@ -370,7 +371,7 @@ impl Oxfmtrc {
370371
return Err("Invalid `sortImports` configuration: `partitionByNewline: true` and `newlinesBetween: true` cannot be used together".to_string());
371372
}
372373

373-
options.experimental_sort_imports = Some(SortImports {
374+
options.experimental_sort_imports = Some(SortImportsOptions {
374375
partition_by_newline: sort_imports_config.partition_by_newline,
375376
partition_by_comment: sort_imports_config.partition_by_comment,
376377
sort_side_effects: sort_imports_config.sort_side_effects,

0 commit comments

Comments
 (0)