Skip to content

Commit d11f8ca

Browse files
authored
Format pattern assignment expressions. (#1394)
Format pattern assignment expressions.
1 parent 662cb5b commit d11f8ca

File tree

7 files changed

+283
-38
lines changed

7 files changed

+283
-38
lines changed

lib/src/front_end/ast_node_visitor.dart

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
170170

171171
@override
172172
Piece visitAssignedVariablePattern(AssignedVariablePattern node) {
173-
throw UnimplementedError();
173+
return tokenPiece(node.name);
174174
}
175175

176176
@override
@@ -181,11 +181,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
181181

182182
@override
183183
Piece visitAwaitExpression(AwaitExpression node) {
184-
return buildPiece((b) {
185-
b.token(node.awaitKeyword);
186-
b.space();
187-
b.visit(node.expression);
188-
});
184+
return createPrefix(node.awaitKeyword, space: true, node.expression);
189185
}
190186

191187
@override
@@ -358,10 +354,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
358354

359355
@override
360356
Piece visitConstantPattern(ConstantPattern node) {
361-
return buildPiece((b) {
362-
b.token(node.constKeyword, spaceAfter: true);
363-
b.visit(node.expression);
364-
});
357+
return createPrefix(node.constKeyword, space: true, node.expression);
365358
}
366359

367360
@override
@@ -1293,12 +1286,12 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
12931286

12941287
@override
12951288
Piece visitNullAssertPattern(NullAssertPattern node) {
1296-
throw UnimplementedError();
1289+
return createPostfix(node.pattern, node.operator);
12971290
}
12981291

12991292
@override
13001293
Piece visitNullCheckPattern(NullCheckPattern node) {
1301-
throw UnimplementedError();
1294+
return createPostfix(node.pattern, node.operator);
13021295
}
13031296

13041297
@override
@@ -1372,7 +1365,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
13721365

13731366
@override
13741367
Piece visitPatternAssignment(PatternAssignment node) {
1375-
throw UnimplementedError();
1368+
return createAssignment(node.pattern, node.equals, node.expression);
13761369
}
13771370

13781371
@override
@@ -1413,10 +1406,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
14131406

14141407
@override
14151408
Piece visitPostfixExpression(PostfixExpression node) {
1416-
return buildPiece((b) {
1417-
b.visit(node.operand);
1418-
b.token(node.operator);
1419-
});
1409+
return createPostfix(node.operand, node.operator);
14201410
}
14211411

14221412
@override
@@ -1542,7 +1532,11 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
15421532

15431533
@override
15441534
Piece visitRelationalPattern(RelationalPattern node) {
1545-
throw UnimplementedError();
1535+
return buildPiece((b) {
1536+
b.token(node.operator);
1537+
b.space();
1538+
b.visit(node.operand);
1539+
});
15461540
}
15471541

15481542
@override
@@ -1574,10 +1568,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
15741568

15751569
@override
15761570
Piece visitRestPatternElement(RestPatternElement node) {
1577-
return buildPiece((b) {
1578-
b.token(node.operator);
1579-
b.visit(node.pattern);
1580-
});
1571+
return createPrefix(node.operator, node.pattern);
15811572
}
15821573

15831574
@override
@@ -1631,10 +1622,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
16311622

16321623
@override
16331624
Piece visitSpreadElement(SpreadElement node) {
1634-
return buildPiece((b) {
1635-
b.token(node.spreadOperator);
1636-
b.visit(node.expression);
1637-
});
1625+
return createPrefix(node.spreadOperator, node.expression);
16381626
}
16391627

16401628
@override
@@ -1795,11 +1783,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
17951783

17961784
@override
17971785
Piece visitThrowExpression(ThrowExpression node) {
1798-
return buildPiece((b) {
1799-
b.token(node.throwKeyword);
1800-
b.space();
1801-
b.visit(node.expression);
1802-
});
1786+
return createPrefix(node.throwKeyword, space: true, node.expression);
18031787
}
18041788

18051789
@override
@@ -1892,11 +1876,7 @@ class AstNodeVisitor extends ThrowingAstVisitor<Piece> with PieceFactory {
18921876

18931877
@override
18941878
Piece visitWhenClause(WhenClause node) {
1895-
return buildPiece((b) {
1896-
b.token(node.whenKeyword);
1897-
b.space();
1898-
b.visit(node.expression);
1899-
});
1879+
return createPrefix(node.whenKeyword, space: true, node.expression);
19001880
}
19011881

19021882
@override

lib/src/front_end/piece_factory.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,25 @@ mixin PieceFactory {
759759
);
760760
}
761761

762+
/// Creates a [Piece] for an AST node followed by an unsplittable token.
763+
Piece createPostfix(AstNode node, Token? operator) {
764+
return buildPiece((b) {
765+
b.visit(node);
766+
b.token(operator);
767+
});
768+
}
769+
770+
/// Creates a [Piece] for an AST node preceded by an unsplittable token.
771+
///
772+
/// If [space] is `true` and there is an operator, writes a space between the
773+
/// operator and operand.
774+
Piece createPrefix(Token? operator, AstNode? node, {bool space = false}) {
775+
return buildPiece((b) {
776+
b.token(operator, spaceAfter: space);
777+
b.visit(node);
778+
});
779+
}
780+
762781
/// Creates an [AdjacentPiece] for a given record type field.
763782
Piece createRecordTypeField(RecordTypeAnnotationField node) {
764783
return createParameter(metadata: node.metadata, node.type, node.name);
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
40 columns |
2+
>>> All supported patterns.
3+
{
4+
( a && b ) = o;
5+
( a as int , b ) = o;
6+
( : inferred ) = o;
7+
[ a ! , Foo ( : b ) , ... ] = o;
8+
{ 'k' : _ , ... } = o;
9+
Foo ( prop : value , : inferred ) = o;
10+
}
11+
<<<
12+
{
13+
(a && b) = o;
14+
(a as int, b) = o;
15+
(:inferred) = o;
16+
[a!, Foo(:b), ...] = o;
17+
{'k': _, ...} = o;
18+
Foo(prop: value, :inferred) = o;
19+
}
20+
>>> Prefer to split at "=" instead of pattern.
21+
(longIdentifier && anotherOne) = longValue;
22+
<<<
23+
(longIdentifier && anotherOne) =
24+
longValue;
25+
>>> Prefer to split in value over pattern.
26+
(first, second, third, fourth, fifth) = longValueExpression + anotherOperand + aThirdOperand;
27+
<<<
28+
(first, second, third, fourth, fifth) =
29+
longValueExpression +
30+
anotherOperand +
31+
aThirdOperand;
32+
>>> Split in infix pattern.
33+
(veryLongIdentifier && anotherAlsoLongOne) = value;
34+
<<<
35+
(veryLongIdentifier &&
36+
anotherAlsoLongOne) =
37+
value;
38+
>>> Split in list pattern.
39+
[first, second, third, fourth, fifth, sixth] = value;
40+
<<<
41+
[
42+
first,
43+
second,
44+
third,
45+
fourth,
46+
fifth,
47+
sixth,
48+
] = value;
49+
>>> Split in map pattern.
50+
{first: second, third: fourth, fifth: sixth} = value;
51+
<<<
52+
{
53+
first: second,
54+
third: fourth,
55+
fifth: sixth,
56+
} = value;
57+
>>> Split in record pattern.
58+
(first, second, third, fourth, fifth, sixth) = value;
59+
<<<
60+
(
61+
first,
62+
second,
63+
third,
64+
fourth,
65+
fifth,
66+
sixth,
67+
) = value;
68+
>>> Split in object pattern.
69+
Foo(:first, :second, :third, :fourth, :fifth) = value;
70+
<<<
71+
Foo(
72+
:first,
73+
:second,
74+
:third,
75+
:fourth,
76+
:fifth,
77+
) = value;
78+
>>> Expression split in value.
79+
(first, second, third) = longValueExpression + anotherOperand + aThirdOperand;
80+
<<<
81+
(first, second, third) =
82+
longValueExpression +
83+
anotherOperand +
84+
aThirdOperand;
85+
>>> Expression split in both.
86+
(veryLongIdentifier && anotherAlsoLongOne) = longValueExpression + anotherOperand + aThirdOperand;
87+
<<<
88+
(veryLongIdentifier &&
89+
anotherAlsoLongOne) =
90+
longValueExpression +
91+
anotherOperand +
92+
aThirdOperand;
93+
>>> Block split in both.
94+
(first, second, third, fourth, fifth, sixth) = (first, second, third, fourth, fifth);
95+
<<<
96+
(
97+
first,
98+
second,
99+
third,
100+
fourth,
101+
fifth,
102+
sixth,
103+
) = (
104+
first,
105+
second,
106+
third,
107+
fourth,
108+
fifth,
109+
);
110+
>>> Expression split in pattern, block split in value.
111+
(veryLongIdentifier && anotherAlsoLongOne) = (first, second, third, fourth, fifth);
112+
<<<
113+
(veryLongIdentifier &&
114+
anotherAlsoLongOne) = (
115+
first,
116+
second,
117+
third,
118+
fourth,
119+
fifth,
120+
);
121+
>>> Expression split in pattern, block split in value.
122+
(veryLongIdentifier && anotherAlsoLongOne) = (first, second, third, fourth, fifth);
123+
<<<
124+
(veryLongIdentifier &&
125+
anotherAlsoLongOne) = (
126+
first,
127+
second,
128+
third,
129+
fourth,
130+
fifth,
131+
);
132+
>>> Block split in pattern, expression split in value.
133+
(first, second, third, fourth, fifth, sixth) = longValueExpression + anotherOperand + aThirdOperand;
134+
<<<
135+
(
136+
first,
137+
second,
138+
third,
139+
fourth,
140+
fifth,
141+
sixth,
142+
) = longValueExpression +
143+
anotherOperand +
144+
aThirdOperand;

test/pattern/other.stmt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,12 @@ switch (obj) {
113113
case const (1):
114114
case const (-foo * bar):
115115
ok;
116-
}
116+
}
117+
>>> Null-check pattern.
118+
if (o case pattern ? ) {}
119+
<<<
120+
if (o case pattern?) {}
121+
>>> Null-assert pattern.
122+
if (o case pattern ! ) {}
123+
<<<
124+
if (o case pattern!) {}

test/pattern/other_comment.stmt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,44 @@ if (obj
6565
case const (expression // comment
6666
)) {
6767
;
68-
}
68+
}
69+
>>> Before null-check.
70+
### Looks weird, but user should move comment.
71+
if (obj case pattern // c
72+
?) {;}
73+
<<<
74+
if (obj
75+
case pattern // c
76+
?) {
77+
;
78+
}
79+
>>> After null-check.
80+
### Looks weird, but user should move comment.
81+
if (obj case pattern? // c
82+
) {;}
83+
<<<
84+
if (obj
85+
case pattern? // c
86+
) {
87+
;
88+
}
89+
>>> Before null-assert.
90+
### Looks weird, but user should move comment.
91+
if (obj case pattern // c
92+
!) {;}
93+
<<<
94+
if (obj
95+
case pattern // c
96+
!) {
97+
;
98+
}
99+
>>> After null-assert.
100+
### Looks weird, but user should move comment.
101+
if (obj case pattern! // c
102+
) {;}
103+
<<<
104+
if (obj
105+
case pattern! // c
106+
) {
107+
;
108+
}

0 commit comments

Comments
 (0)