Skip to content

Commit 50e1248

Browse files
authored
Format object patterns. (#1385)
1 parent 4289ff6 commit 50e1248

File tree

4 files changed

+242
-1
lines changed

4 files changed

+242
-1
lines changed

lib/src/ast_extensions.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ extension PatternExtensions on DartPattern {
393393
elements.canSplit(rightBracket),
394394
MapPattern(:var elements, :var rightBracket) =>
395395
elements.canSplit(rightBracket),
396+
ObjectPattern(:var fields, :var rightParenthesis) ||
396397
RecordPattern(:var fields, :var rightParenthesis) =>
397398
fields.canSplit(rightParenthesis),
398399
_ => false,

lib/src/front_end/ast_node_visitor.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,14 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
12721272

12731273
@override
12741274
Piece visitObjectPattern(ObjectPattern node) {
1275-
throw UnimplementedError();
1275+
return buildPiece((b) {
1276+
b.visit(node.type);
1277+
b.add(createCollection(
1278+
node.leftParenthesis,
1279+
node.fields,
1280+
node.rightParenthesis,
1281+
));
1282+
});
12761283
}
12771284

12781285
@override

test/pattern/object.stmt

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
40 columns |
2+
>>> Single-element objects with trailing comma removed.
3+
if (obj case Foo(:pattern,)) {;}
4+
<<<
5+
if (obj case Foo(:pattern)) {
6+
;
7+
}
8+
>>> Split single-element object.
9+
if (obj case Foo(longFieldName: veryLongObjectFieldValue)) {;}
10+
<<<
11+
if (obj case Foo(
12+
longFieldName: veryLongObjectFieldValue,
13+
)) {
14+
;
15+
}
16+
>>> Split all fields, if any field splits.
17+
if (obj case Foo(first, second, third, fourth, fifth)) {;}
18+
<<<
19+
if (obj case Foo(
20+
first,
21+
second,
22+
third,
23+
fourth,
24+
fifth,
25+
)) {
26+
;
27+
}
28+
>>> Split single-element object with inferred name.
29+
if (obj case Foo(:var veryLongInferredFieldName_____)) {;}
30+
<<<
31+
if (obj case Foo(
32+
:var veryLongInferredFieldName_____,
33+
)) {
34+
;
35+
}
36+
>>> Split multiple inferred fields.
37+
if (obj case Foo(:var firstLongInferredFieldName, :var secondLongInferredName)) {;}
38+
<<<
39+
if (obj case Foo(
40+
:var firstLongInferredFieldName,
41+
:var secondLongInferredName,
42+
)) {
43+
;
44+
}
45+
>>> Split with list subpattern.
46+
if (obj case Foo(longFieldName: [first, second, third])) {;}
47+
<<<
48+
if (obj case Foo(
49+
longFieldName: [first, second, third],
50+
)) {
51+
;
52+
}
53+
>>> Split with a split list subpattern.
54+
if (obj case Foo(longFieldName: [firstlooooooong, secondlooooooong, thirdlooooooong])) {;}
55+
<<<
56+
if (obj case Foo(
57+
longFieldName: [
58+
firstlooooooong,
59+
secondlooooooong,
60+
thirdlooooooong,
61+
],
62+
)) {
63+
;
64+
}
65+
>>> Don't split between name and constant list.
66+
if (obj case Foo(longFieldName: const [first, second, third])) {;}
67+
<<<
68+
if (obj case Foo(
69+
longFieldName: const [
70+
first,
71+
second,
72+
third,
73+
],
74+
)) {
75+
;
76+
}
77+
>>> Split with map subpattern.
78+
if (obj case Foo(longFieldName: {first: 1, second: 2})) {;}
79+
<<<
80+
if (obj case Foo(
81+
longFieldName: {first: 1, second: 2},
82+
)) {
83+
;
84+
}
85+
>>> Split with a split map subpattern.
86+
if (obj case Foo(longFieldName: {firstlooooooong: 1, secondlooooooong: 2})) {;}
87+
<<<
88+
if (obj case Foo(
89+
longFieldName: {
90+
firstlooooooong: 1,
91+
secondlooooooong: 2,
92+
},
93+
)) {
94+
;
95+
}
96+
>>> Don't split between name and constant map.
97+
if (obj case Foo(longFieldName: const {first: 1, second: 2})) {;}
98+
<<<
99+
if (obj case Foo(
100+
longFieldName: const {
101+
first: 1,
102+
second: 2,
103+
},
104+
)) {
105+
;
106+
}
107+
>>> Split with record subpattern.
108+
if (obj case Foo(longFieldName: (first: 1, second: 2))) {;}
109+
<<<
110+
if (obj case Foo(
111+
longFieldName: (first: 1, second: 2),
112+
)) {
113+
;
114+
}
115+
>>> Split with split record subpattern.
116+
if (obj case Foo(longFieldName: (firstlooooooong: 1, secondlooooooong: 2))) {;}
117+
<<<
118+
if (obj case Foo(
119+
longFieldName: (
120+
firstlooooooong: 1,
121+
secondlooooooong: 2,
122+
),
123+
)) {
124+
;
125+
}
126+
>>> Don't split between name and const record.
127+
if (obj case Foo(longFieldName: const (first: 1, second: 2))) {;}
128+
<<<
129+
if (obj case Foo(
130+
longFieldName: const (
131+
first: 1,
132+
second: 2,
133+
),
134+
)) {
135+
;
136+
}
137+
>>> Nested object doesn't force outer object to split.
138+
if (obj case Foo(Bar(a: 1, b: 2))) {;}
139+
<<<
140+
if (obj case Foo(Bar(a: 1, b: 2))) {
141+
;
142+
}
143+
>>> Multiple objects doesn't force outer object to split.
144+
if (obj case (Foo(a: 1), Bar(b: 2))) {;}
145+
<<<
146+
if (obj case (Foo(a: 1), Bar(b: 2))) {
147+
;
148+
}
149+
>>> Deeply nested split object.
150+
if (obj case Foo(first: 1, Bar(second: 2, third: 3, four: 4), fifth: 5, Baz(sixth: 6, seventh: 7, eighth: 8, nine: 9, tenth: 10,
151+
eleventh: 11))) {;}
152+
<<<
153+
if (obj case Foo(
154+
first: 1,
155+
Bar(second: 2, third: 3, four: 4),
156+
fifth: 5,
157+
Baz(
158+
sixth: 6,
159+
seventh: 7,
160+
eighth: 8,
161+
nine: 9,
162+
tenth: 10,
163+
eleventh: 11,
164+
),
165+
)) {
166+
;
167+
}
168+
>>> Split in type argument.
169+
if (obj case LongClassName<First, Second>()) {;}
170+
<<<
171+
### TODO(tall): It formats like this if there's no elements. Similarly with lists, maps etc.
172+
if (obj
173+
case LongClassName<
174+
First,
175+
Second
176+
>()) {
177+
;
178+
}
179+
>>> Split in type argument and body.
180+
if (obj case LongClassName<First, Second, Third>(first: 1, second: 2, third: 3)) {;}
181+
<<<
182+
if (obj case LongClassName<
183+
First,
184+
Second,
185+
Third
186+
>(first: 1, second: 2, third: 3)) {
187+
;
188+
}

test/pattern/object_comment.stmt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
40 columns |
2+
>>> Keep line comment when split.
3+
if (obj case Foo(
4+
// yeah
5+
a:1,b:2,c:3,
6+
d:4,e:5,f:6,
7+
)) {;}
8+
<<<
9+
if (obj case Foo(
10+
// yeah
11+
a: 1,
12+
b: 2,
13+
c: 3,
14+
d: 4,
15+
e: 5,
16+
f: 6,
17+
)) {
18+
;
19+
}
20+
>>> Empty object pattern with block comment.
21+
if (obj case Foo( /* comment */ )) {;}
22+
<<<
23+
if (obj case Foo(/* comment */)) {
24+
;
25+
}
26+
>>> Empty object pattern with line comment.
27+
if (obj case Foo( // comment
28+
)) {;}
29+
<<<
30+
### Weird, but users rarely write this.
31+
if (obj case Foo(
32+
// comment
33+
)) {
34+
;
35+
}
36+
>>> Line comment between arguments in object.
37+
if (obj case Foo( first , // comment
38+
second)){;}
39+
<<<
40+
if (obj case Foo(
41+
first, // comment
42+
second,
43+
)) {
44+
;
45+
}

0 commit comments

Comments
 (0)