Skip to content

Commit f09c383

Browse files
fix(match): Support empty lines and comments in match expressions (closes #1956) (#2201)
* refactor(match): Extract var and remove ifBreak Match arms are never combined onto a single line, so ifBreak is not needed. * feat(match): Support empty lines between arms * feat(match): Print leading comments * feat(match): Print trailing comments
1 parent bde976c commit f09c383

5 files changed

Lines changed: 173 additions & 5 deletions

File tree

src/printer.js

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const {
5353
normalizeMagicMethodName,
5454
getNextNonSpaceNonCommentCharacterIndex,
5555
isNextLineEmpty,
56+
isPreviousLineEmpty,
5657
} = require("./util");
5758

5859
function isMinVersion(actualVersion, requiredVersion) {
@@ -2886,27 +2887,59 @@ function printNode(path, options, print) {
28862887
return path.call(print, "name");
28872888
}
28882889
case "match": {
2890+
const lastArmIndex = node.arms.length - 1;
28892891
const arms = path.map((armPath, armIdx) => {
2892+
const armNode = armPath.getValue();
2893+
2894+
const maybeLeadingComment = comments.hasLeadingComment(armNode)
2895+
? [comments.printComments(armNode.leadingComments, options), hardline]
2896+
: [];
2897+
const maybeTrailingComma =
2898+
armIdx < lastArmIndex || options.trailingCommaPHP ? "," : "";
2899+
const maybeTrailingComment = comments.hasTrailingComment(armNode)
2900+
? [
2901+
" ",
2902+
comments.printComments(
2903+
armNode.comments.filter((c) => c.trailing),
2904+
options
2905+
),
2906+
]
2907+
: [];
2908+
28902909
const conds =
2891-
armPath.getValue().conds === null
2910+
armNode.conds === null
28922911
? "default"
28932912
: armPath.map(
28942913
(condPath, condIdx) =>
28952914
[",", line, print(condPath)].slice(condIdx === 0 ? 2 : 0),
28962915
"conds"
28972916
);
28982917
const body = armPath.call(print, "body");
2918+
const maybeEmptyLineBetweenArms =
2919+
armIdx > 0 &&
2920+
isPreviousLineEmpty(options.originalText, armNode, options)
2921+
? hardline
2922+
: "";
2923+
28992924
return [
2900-
",",
2925+
"",
29012926
hardline,
2902-
group([group([conds, indent(line)]), "=> ", body]),
2927+
maybeEmptyLineBetweenArms,
2928+
...maybeLeadingComment,
2929+
group([
2930+
group([conds, indent(line)]),
2931+
"=> ",
2932+
body,
2933+
maybeTrailingComma,
2934+
...maybeTrailingComment,
2935+
]),
29032936
].slice(armIdx > 0 ? 0 : 1);
29042937
}, "arms");
29052938
return group([
29062939
"match (",
29072940
group([softline, indent(path.call(print, "cond")), softline]),
29082941
") {",
2909-
group(indent([...arms, options.trailingCommaPHP ? ifBreak(",") : ""])),
2942+
group(indent([...arms])),
29102943
" ",
29112944
softline,
29122945
"}",

tests/comments/__snapshots__/jsfmt.spec.js.snap

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4824,6 +4824,57 @@ list(
48244824
================================================================================
48254825
`;
48264826
4827+
exports[`match.php 1`] = `
4828+
====================================options=====================================
4829+
parsers: ["php"]
4830+
printWidth: 80
4831+
| printWidth
4832+
=====================================input======================================
4833+
<?php
4834+
4835+
$withComments = match($v) {
4836+
4837+
// first comment
4838+
4839+
'a' => 1,
4840+
4841+
4842+
4843+
/*
4844+
* second comment
4845+
*/
4846+
4847+
4848+
4849+
'b' => 2,
4850+
// leading comment ...
4851+
'c' => 3, /* ... and trailing comment */
4852+
'd' // fourth comment
4853+
=> 4,
4854+
default => null // final comment
4855+
};
4856+
4857+
=====================================output=====================================
4858+
<?php
4859+
4860+
$withComments = match ($v) {
4861+
// first comment
4862+
"a" => 1,
4863+
4864+
/*
4865+
* second comment
4866+
*/
4867+
"b" => 2,
4868+
// leading comment ...
4869+
"c" => 3, /* ... and trailing comment */
4870+
"d" // fourth comment
4871+
=> 4,
4872+
default => null, // final comment
4873+
};
4874+
4875+
================================================================================
4876+
`;
4877+
48274878
exports[`method.php 1`] = `
48284879
====================================options=====================================
48294880
parsers: ["php"]

tests/comments/match.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
$withComments = match($v) {
4+
5+
// first comment
6+
7+
'a' => 1,
8+
9+
10+
11+
/*
12+
* second comment
13+
*/
14+
15+
16+
17+
'b' => 2,
18+
// leading comment ...
19+
'c' => 3, /* ... and trailing comment */
20+
'd' // fourth comment
21+
=> 4,
22+
default => null // final comment
23+
};

tests/match/__snapshots__/jsfmt.spec.js.snap

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ $extraLongMatch = match($a) {
5252
'cd' => [],
5353
default => [],
5454
};
55+
56+
// Whitespace in match expressions is handled like in function/method arguments:
57+
// - none above the first arm or below the last arm
58+
// - empty lines are preserved between arms
59+
// - multiple empty lines are collapsed into one
60+
match ($a) {
61+
62+
'a' => 1,
63+
64+
65+
'b' => 2
66+
67+
};
68+
5569
=====================================output=====================================
5670
<?php
5771
@@ -124,6 +138,16 @@ $extraLongMatch = match ($a) {
124138
default => []
125139
};
126140
141+
// Whitespace in match expressions is handled like in function/method arguments:
142+
// - none above the first arm or below the last arm
143+
// - empty lines are preserved between arms
144+
// - multiple empty lines are collapsed into one
145+
match ($a) {
146+
"a" => 1,
147+
148+
"b" => 2
149+
};
150+
127151
================================================================================
128152
`;
129153

@@ -179,6 +203,20 @@ $extraLongMatch = match($a) {
179203
'cd' => [],
180204
default => [],
181205
};
206+
207+
// Whitespace in match expressions is handled like in function/method arguments:
208+
// - none above the first arm or below the last arm
209+
// - empty lines are preserved between arms
210+
// - multiple empty lines are collapsed into one
211+
match ($a) {
212+
213+
'a' => 1,
214+
215+
216+
'b' => 2
217+
218+
};
219+
182220
=====================================output=====================================
183221
<?php
184222
@@ -251,5 +289,15 @@ $extraLongMatch = match ($a) {
251289
default => [],
252290
};
253291
292+
// Whitespace in match expressions is handled like in function/method arguments:
293+
// - none above the first arm or below the last arm
294+
// - empty lines are preserved between arms
295+
// - multiple empty lines are collapsed into one
296+
match ($a) {
297+
"a" => 1,
298+
299+
"b" => 2,
300+
};
301+
254302
================================================================================
255303
`;

tests/match/match.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,17 @@
4141
=> 'some really long value in the return part of the match statement',
4242
'cd' => [],
4343
default => [],
44-
};
44+
};
45+
46+
// Whitespace in match expressions is handled like in function/method arguments:
47+
// - none above the first arm or below the last arm
48+
// - empty lines are preserved between arms
49+
// - multiple empty lines are collapsed into one
50+
match ($a) {
51+
52+
'a' => 1,
53+
54+
55+
'b' => 2
56+
57+
};

0 commit comments

Comments
 (0)