Sitelet https://github.com/starkware-libs/cairo/commit/294280cada47401a1e47f50f17176fc05051e231
Skip to content

Commit 294280c

Browse files
committed
bugfix(formatter): Sort merged items via compare_names.
1 parent c81c58a commit 294280c

4 files changed

Lines changed: 44 additions & 21 deletions

File tree

‎crates/cairo-lang-formatter/src/formatter_impl.rs‎

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,20 @@ struct UseTree {
3232
}
3333

3434
/// Represents a terminal node in a `UseTree`, corresponding to a specific `use` path.
35-
#[derive(Default, Debug, Clone)]
35+
#[derive(Default, Debug, Clone, PartialEq, Eq)]
3636
struct Leaf {
3737
name: String,
3838
alias: Option<String>,
3939
}
40+
impl std::fmt::Display for Leaf {
41+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42+
if let Some(alias) = &self.alias {
43+
write!(f, "{} as {alias}", self.name)
44+
} else {
45+
write!(f, "{}", self.name)
46+
}
47+
}
48+
}
4049

4150
impl UseTree {
4251
/// Inserts a path into the `UseTree`, creating nested entries as needed.
@@ -64,17 +73,7 @@ impl UseTree {
6473
}
6574

6675
/// Merge and organize the `use` paths in a hierarchical structure.
67-
pub fn create_merged_use_items(self, allow_duplicate_uses: bool) -> Vec<String> {
68-
let mut leaf_paths: Vec<String> = self
69-
.leaves
70-
.into_iter()
71-
.map(
72-
|Leaf { name, alias }| {
73-
if let Some(alias) = alias { format!("{name} as {alias}") } else { name }
74-
},
75-
)
76-
.collect();
77-
76+
pub fn create_merged_use_items(mut self, allow_duplicate_uses: bool) -> Vec<String> {
7877
let mut nested_paths = vec![];
7978
for (segment, subtree) in self.children {
8079
let subtree_merged_use_items = subtree.create_merged_use_items(allow_duplicate_uses);
@@ -84,15 +83,16 @@ impl UseTree {
8483
}
8584

8685
if !allow_duplicate_uses {
87-
leaf_paths.sort();
88-
leaf_paths.dedup();
86+
self.leaves.sort_by(|a, b| {
87+
compare_names(&a.name, &b.name).then_with(|| a.alias.cmp(&b.alias))
88+
});
89+
self.leaves.dedup();
8990
}
90-
91-
match leaf_paths.len() {
92-
0 => {}
93-
1 if nested_paths.is_empty() => return leaf_paths,
94-
1 => nested_paths.extend(leaf_paths),
95-
_ => nested_paths.push(format!("{{{}}}", leaf_paths.join(", "))),
91+
match self.leaves.as_slice() {
92+
[] => {}
93+
[leaf] if nested_paths.is_empty() => return vec![leaf.to_string()],
94+
[leaf] => nested_paths.push(leaf.to_string()),
95+
leaves => nested_paths.push(format!("{{{}}}", leaves.iter().format(", "))),
9696
}
9797

9898
nested_paths
@@ -1347,9 +1347,13 @@ fn compare_use_paths<'a>(a: &UsePath<'a>, b: &UsePath<'a>, db: &dyn Database) ->
13471347
}
13481348
}
13491349

1350-
/// Compares two names, with special handling for "super" and "crate".
1350+
/// Compares two names, with special handling for the glob `*` (first), `self` (first) and
1351+
/// `super`/`crate` (last) — matching the ordering of `compare_use_paths`.
13511352
fn compare_names(a: &str, b: &str) -> Ordering {
13521353
match (a, b) {
1354+
("*", "*") => Ordering::Equal,
1355+
("*", _) => Ordering::Less,
1356+
(_, "*") => Ordering::Greater,
13531357
("super" | "crate", "super" | "crate") => a.cmp(b),
13541358
("self", "self") => Ordering::Equal,
13551359
("super" | "crate", _) | (_, "self") => Ordering::Greater,

‎crates/cairo-lang-formatter/src/test.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,17 @@ use crate::{FormatterConfig, get_formatted_file};
143143
true,
144144
true
145145
)]
146+
// Merge enabled, module-level sorting disabled: merged braces must still honor the
147+
// `self`-first convention.
148+
#[test_case(
149+
"test_data/cairo_files/use_merge_no_sort.cairo",
150+
"test_data/expected_results/use_merge_no_sort.cairo",
151+
false,
152+
false,
153+
false,
154+
true,
155+
false
156+
)]
146157
fn format_and_compare_file(
147158
unformatted_filename: &str,
148159
expected_filename: &str,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use a::z;
2+
use a::self;
3+
use a::b;
4+
use c::x;
5+
use c::*;
6+
use c::self;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
use a::{self, b, z};
2+
use c::{*, self, x};

0 commit comments

Comments
 (0)