Skip to content

Commit 480b449

Browse files
authored
Format object patterns, const constructors, and constant expressions. (#1171)
The latter two were already implemented as part of keeping the existing switch tests passing, but this adds tests for their splitting and other behavior. For object patterns, I had to decide whether to split them like collections (like other patterns) or like argument lists (which they mirror). I went collection-like because they will appear mixed with other patterns. Also, if we migrate to a consistent flutter-like style at some point, it will be one less thing to change. Let me know what you think.
1 parent 034118d commit 480b449

File tree

5 files changed

+379
-0
lines changed

5 files changed

+379
-0
lines changed

lib/src/source_visitor.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,38 @@ class SourceVisitor extends ThrowingAstVisitor {
22892289
token(node.literal);
22902290
}
22912291

2292+
@override
2293+
void visitObjectPattern(ObjectPattern node) {
2294+
// Even though object patterns syntactically resemble constructor or
2295+
// function calls, we format them like collections (or like argument lists
2296+
// with trailing commas). In other words, like this:
2297+
//
2298+
// case Foo(
2299+
// first: 1,
2300+
// second: 2,
2301+
// third: 3
2302+
// ):
2303+
// body;
2304+
//
2305+
// Not like:
2306+
//
2307+
// case Foo(
2308+
// first: 1,
2309+
// second: 2,
2310+
// third: 3):
2311+
// body;
2312+
//
2313+
// This is less consistent with the corresponding expression form, but is
2314+
// more consistent with all of the other delimited patterns -- list, map,
2315+
// and record -- which have collection-like formatting.
2316+
// TODO(rnystrom): If we move to consistently using collection-like
2317+
// formatting for all argument lists, then this will all be consistent and
2318+
// this comment should be removed.
2319+
visit(node.type);
2320+
_visitCollectionLiteral(
2321+
node.leftParenthesis, node.fields, node.rightParenthesis);
2322+
}
2323+
22922324
@override
22932325
void visitOnClause(OnClause node) {
22942326
_visitCombinator(node.onKeyword, node.superclassConstraints);

test/comments/patterns.stmt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,68 @@ if (obj
307307
second
308308
)) {
309309
;
310+
}
311+
>>> empty object pattern block comment
312+
if (obj case Foo( /* comment */ )) {;}
313+
<<<
314+
if (obj case Foo(/* comment */)) {
315+
;
316+
}
317+
>>> empty object pattern line comment (looks weird, but user should move comment)
318+
if (obj case Foo( // comment
319+
)) {;}
320+
<<<
321+
if (obj
322+
case Foo(
323+
// comment
324+
)) {
325+
;
326+
}
327+
>>> object line comment between arguments
328+
if (obj case Foo( first , // comment
329+
second)){;}
330+
<<<
331+
if (obj
332+
case Foo(
333+
first, // comment
334+
second
335+
)) {
336+
;
337+
}
338+
>>> empty const constructor line comment (looks weird, but user should move comment)
339+
if (obj case const Foo( // comment
340+
)) {;}
341+
<<<
342+
if (obj
343+
case const Foo(// comment
344+
)) {
345+
;
346+
}
347+
>>> const constructor line comment between arguments
348+
if (obj case const Foo( first , // comment
349+
second)){;}
350+
<<<
351+
if (obj
352+
case const Foo(
353+
first, // comment
354+
second)) {
355+
;
356+
}
357+
>>> after "(" in parenthesized constant
358+
if (obj case const ( // comment
359+
expression)){;}
360+
<<<
361+
if (obj
362+
case const ( // comment
363+
expression)) {
364+
;
365+
}
366+
>>> after expression in parenthesized constant (looks weird, but user should move comment)
367+
if (obj case const ( expression // comment
368+
)){;}
369+
<<<
370+
if (obj
371+
case const (expression // comment
372+
)) {
373+
;
310374
}

test/splitting/arguments.stmt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,16 @@ fn(
346346
argument,
347347
name: argument,
348348
argument,
349+
);
350+
>>> preserve line breaks in trailing comma argument list with line comment
351+
function(// yeah
352+
first, second, third,
353+
fourth, fifth,
354+
sixth,);
355+
<<<
356+
function(
357+
// yeah
358+
first, second, third,
359+
fourth, fifth,
360+
sixth,
349361
);

test/splitting/patterns.stmt

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,4 +496,221 @@ if (obj
496496
element
497497
)) {
498498
;
499+
}
500+
>>> split constant constructor in pattern
501+
if (obj case const Foo(element, element, element, element)) {;}
502+
<<<
503+
if (obj
504+
case const Foo(element, element,
505+
element, element)) {
506+
;
507+
}
508+
>>> single-element objects with trailing commas split
509+
if (obj case Foo(:pattern,)) {;}
510+
<<<
511+
if (obj
512+
case Foo(
513+
:pattern,
514+
)) {
515+
;
516+
}
517+
>>> split single-element object
518+
if (obj case Foo(longFieldName: longObjectFieldValu)) {;}
519+
<<<
520+
if (obj
521+
case Foo(
522+
longFieldName: longObjectFieldValu
523+
)) {
524+
;
525+
}
526+
>>> split field at name
527+
if (obj case Foo(longFieldName: veryLongObjectFieldValue)) {;}
528+
<<<
529+
if (obj
530+
case Foo(
531+
longFieldName:
532+
veryLongObjectFieldValue
533+
)) {
534+
;
535+
}
536+
>>> split single-element object with inferred name
537+
if (obj case Foo(:var veryLongInferredFieldName_____)) {;}
538+
<<<
539+
if (obj
540+
case Foo(
541+
:var veryLongInferredFieldName_____
542+
)) {
543+
;
544+
}
545+
>>> split before inferred field name
546+
if (obj case Foo(:var firstLongInferredFieldName, :var secondLongInferredName)) {;}
547+
<<<
548+
if (obj
549+
case Foo(
550+
:var firstLongInferredFieldName,
551+
:var secondLongInferredName
552+
)) {
553+
;
554+
}
555+
>>> don't split between name and list subpattern
556+
if (obj case Foo(longFieldName: [first, second, third])) {;}
557+
<<<
558+
if (obj
559+
case Foo(
560+
longFieldName: [
561+
first,
562+
second,
563+
third
564+
]
565+
)) {
566+
;
567+
}
568+
>>> don't split between name and map subpattern
569+
if (obj case Foo(longFieldName: {first: 1, second: 2})) {;}
570+
<<<
571+
if (obj
572+
case Foo(
573+
longFieldName: {
574+
first: 1,
575+
second: 2
576+
}
577+
)) {
578+
;
579+
}
580+
>>> don't split between name and record subpattern
581+
if (obj case Foo(longFieldName: (first: 1, second: 2))) {;}
582+
<<<
583+
if (obj
584+
case Foo(
585+
longFieldName: (
586+
first: 1,
587+
second: 2
588+
)
589+
)) {
590+
;
591+
}
592+
>>> don't split between name and constant list
593+
if (obj case Foo(longFieldName: const [first, second, third])) {;}
594+
<<<
595+
if (obj
596+
case Foo(
597+
longFieldName: const [
598+
first,
599+
second,
600+
third
601+
]
602+
)) {
603+
;
604+
}
605+
>>> don't split between name and constant map
606+
if (obj case Foo(longFieldName: const {first: 1, second: 2})) {;}
607+
<<<
608+
if (obj
609+
case Foo(
610+
longFieldName: const {
611+
first: 1,
612+
second: 2
613+
}
614+
)) {
615+
;
616+
}
617+
>>> don't split between name and const record
618+
if (obj case Foo(longFieldName: const (first: 1, second: 2))) {;}
619+
<<<
620+
if (obj
621+
case Foo(
622+
longFieldName: const (
623+
first: 1,
624+
second: 2
625+
)
626+
)) {
627+
;
628+
}
629+
>>> if any field splits, all do
630+
if (obj case Foo(first, second, third, fourth, fifth)) {;}
631+
<<<
632+
if (obj
633+
case Foo(
634+
first,
635+
second,
636+
third,
637+
fourth,
638+
fifth
639+
)) {
640+
;
641+
}
642+
>>> don't force outer object to split
643+
if (obj case Foo(Bar(a: 1, b: 2))) {;}
644+
<<<
645+
if (obj case Foo(Bar(a: 1, b: 2))) {
646+
;
647+
}
648+
>>> don't force outer record to split
649+
if (obj case (Foo(a: 1), Bar(b: 2))) {;}
650+
<<<
651+
if (obj case (Foo(a: 1), Bar(b: 2))) {
652+
;
653+
}
654+
>>> nested split object
655+
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,
656+
eleventh: 11))) {;}
657+
<<<
658+
if (obj
659+
case Foo(
660+
first: 1,
661+
Bar(second: 2, third: 3, four: 4),
662+
fifth: 5,
663+
Baz(
664+
sixth: 6,
665+
seventh: 7,
666+
eighth: 8,
667+
nine: 9,
668+
tenth: 10,
669+
eleventh: 11
670+
)
671+
)) {
672+
;
673+
}
674+
>>> preserve newlines in objects containing a line comment
675+
if (obj case Foo(
676+
// yeah
677+
a:1,b:2,c:3,
678+
d:4,e:5,f:6,
679+
)) {;}
680+
<<<
681+
if (obj
682+
case Foo(
683+
// yeah
684+
a: 1, b: 2, c: 3,
685+
d: 4, e: 5, f: 6,
686+
)) {
687+
;
688+
}
689+
>>> split in type argument
690+
if (obj case LongClassName<First, Second>()) {;}
691+
<<<
692+
if (obj
693+
case LongClassName<First,
694+
Second>()) {
695+
;
696+
}
697+
>>> split in type argument and body
698+
if (obj case LongClassName<First, Second, Third>(first: 1, second: 2, third: 3)) {;}
699+
<<<
700+
if (obj
701+
case LongClassName<First, Second,
702+
Third>(
703+
first: 1,
704+
second: 2,
705+
third: 3
706+
)) {
707+
;
708+
}
709+
>>> split in parenthesized constant expression
710+
if (obj case const(longArgument + anotherArgument)) {;}
711+
<<<
712+
if (obj
713+
case const (longArgument +
714+
anotherArgument)) {
715+
;
499716
}

0 commit comments

Comments
 (0)