Skip to content

Commit 90a38fd

Browse files
committed
fix(formatter): ensure match expression with trailing comments on conditions is idempotent
Signed-off-by: azjezz <[email protected]>
1 parent 7c7561c commit 90a38fd

File tree

5 files changed

+96
-4
lines changed

5 files changed

+96
-4
lines changed

crates/formatter/src/internal/format/expression.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -901,12 +901,23 @@ impl<'arena> Format<'arena> for MatchExpressionArm<'arena> {
901901
fn format(&'arena self, f: &mut FormatterState<'_, 'arena>) -> Document<'arena> {
902902
wrap!(f, self, MatchExpressionArm, {
903903
let len = self.conditions.len();
904+
905+
let must_break = self
906+
.conditions
907+
.iter()
908+
.take(len.saturating_sub(1))
909+
.any(|condition| f.has_comment(condition.span(), CommentFlags::Trailing | CommentFlags::Line));
910+
904911
let mut contents = vec![in f.arena];
905912
for (i, condition) in self.conditions.iter().enumerate() {
906913
contents.push(condition.format(f));
907914
if i != (len - 1) {
908915
contents.push(Document::String(","));
909-
contents.push(Document::Line(Line::default()));
916+
contents.push(if must_break {
917+
Document::Line(Line::hard())
918+
} else {
919+
Document::Line(Line::default())
920+
});
910921
} else if f.settings.trailing_comma && i > 0 {
911922
contents.push(Document::IfBreak(IfBreak::then(f.arena, Document::String(","))));
912923
}
@@ -917,18 +928,19 @@ impl<'arena> Format<'arena> for MatchExpressionArm<'arena> {
917928
group_id,
918929
vec![
919930
in f.arena;
920-
Document::Line(Line::default()),
931+
if must_break { Document::Line(Line::hard()) } else { Document::Line(Line::default()) },
921932
format_token(f, self.arrow, "=> "),
922933
],
923934
)));
924935

925936
Document::Group(
926937
Group::new(vec![
927938
in f.arena;
928-
Document::Group(Group::new(contents)),
939+
Document::Group(Group::new(contents).with_break(must_break)),
929940
self.expression.format(f),
930941
])
931-
.with_id(group_id),
942+
.with_id(group_id)
943+
.with_break(must_break),
932944
)
933945
})
934946
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
class DoctrineExtractor
4+
{
5+
/**
6+
* Gets the corresponding built-in PHP type.
7+
*/
8+
private function getTypeIdentifier(string $doctrineType): null|TypeIdentifier
9+
{
10+
return match ($doctrineType) {
11+
Types::SMALLINT, Types::INTEGER => TypeIdentifier::INT,
12+
Types::FLOAT => TypeIdentifier::FLOAT,
13+
Types::BIGINT, Types::STRING, Types::TEXT, Types::GUID, Types::DECIMAL => TypeIdentifier::STRING,
14+
Types::BOOLEAN => TypeIdentifier::BOOL,
15+
Types::BLOB, Types::BINARY => TypeIdentifier::RESOURCE,
16+
'object', // DBAL < 4
17+
Types::DATE_MUTABLE,
18+
Types::DATETIME_MUTABLE,
19+
Types::DATETIMETZ_MUTABLE,
20+
'vardatetime',
21+
Types::TIME_MUTABLE,
22+
Types::DATE_IMMUTABLE,
23+
Types::DATETIME_IMMUTABLE,
24+
Types::DATETIMETZ_IMMUTABLE,
25+
Types::TIME_IMMUTABLE,
26+
Types::DATEINTERVAL,
27+
=> TypeIdentifier::OBJECT,
28+
'array', // DBAL < 4
29+
'json_array', // DBAL < 3
30+
Types::SIMPLE_ARRAY,
31+
=> TypeIdentifier::ARRAY,
32+
default => null,
33+
};
34+
}
35+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
class DoctrineExtractor
4+
{
5+
/**
6+
* Gets the corresponding built-in PHP type.
7+
*/
8+
private function getTypeIdentifier(string $doctrineType): ?TypeIdentifier
9+
{
10+
return match ($doctrineType) {
11+
Types::SMALLINT,
12+
Types::INTEGER => TypeIdentifier::INT,
13+
Types::FLOAT => TypeIdentifier::FLOAT,
14+
Types::BIGINT,
15+
Types::STRING,
16+
Types::TEXT,
17+
Types::GUID,
18+
Types::DECIMAL => TypeIdentifier::STRING,
19+
Types::BOOLEAN => TypeIdentifier::BOOL,
20+
Types::BLOB,
21+
Types::BINARY => TypeIdentifier::RESOURCE,
22+
'object', // DBAL < 4
23+
Types::DATE_MUTABLE,
24+
Types::DATETIME_MUTABLE,
25+
Types::DATETIMETZ_MUTABLE,
26+
'vardatetime',
27+
Types::TIME_MUTABLE,
28+
Types::DATE_IMMUTABLE,
29+
Types::DATETIME_IMMUTABLE,
30+
Types::DATETIMETZ_IMMUTABLE,
31+
Types::TIME_IMMUTABLE,
32+
Types::DATEINTERVAL => TypeIdentifier::OBJECT,
33+
'array', // DBAL < 4
34+
'json_array', // DBAL < 3
35+
Types::SIMPLE_ARRAY => TypeIdentifier::ARRAY,
36+
default => null,
37+
};
38+
}
39+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FormatSettings {
2+
null_type_hint: NullTypeHint::NullPipe,
3+
space_around_concatenation_binary_operator: false,
4+
..FormatSettings::default()
5+
}

crates/formatter/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ test_case!(align_run_breaking);
223223
test_case!(align_modifier_breaking);
224224
test_case!(inline_block_comments_in_arguments);
225225
test_case!(idempotent_chain_with_array);
226+
test_case!(match_idempotency);
226227

227228
// A special test case for regressions in the Psl codebase
228229
test_case!(psl_regressions);

0 commit comments

Comments
 (0)