@@ -6,6 +6,7 @@ import type { AstPath, Doc } from "prettier";
66import { builders } from "prettier/doc" ;
77import {
88 call ,
9+ definedKeys ,
910 each ,
1011 hasDeclarationAnnotations ,
1112 hasLeadingComments ,
@@ -42,33 +43,49 @@ export default {
4243 } ,
4344
4445 normalClassDeclaration ( path , print ) {
45- const { classExtends, classImplements, classPermits, typeParameters } =
46- path . node . children ;
47- const header = [ "class " , call ( path , print , "typeIdentifier" ) ] ;
48- if ( typeParameters ) {
49- header . push ( call ( path , print , "typeParameters" ) ) ;
50- }
51- if ( classExtends ) {
52- header . push ( indent ( [ line , call ( path , print , "classExtends" ) ] ) ) ;
53- }
54- if ( classImplements ) {
55- header . push ( indent ( [ line , call ( path , print , "classImplements" ) ] ) ) ;
46+ const { children } = path . node ;
47+ const definedClauses = definedKeys ( children , [
48+ "classExtends" ,
49+ "classImplements" ,
50+ "classPermits"
51+ ] ) ;
52+ const hasMultipleClauses = definedClauses . length > 1 ;
53+ const hasTypeParameters = children . typeParameters !== undefined ;
54+ const parts = [ "class " , call ( path , print , "typeIdentifier" ) ] ;
55+ if ( hasTypeParameters ) {
56+ const typeParameters = call ( path , print , "typeParameters" ) ;
57+ parts . push (
58+ hasMultipleClauses ? group ( indent ( typeParameters ) ) : typeParameters
59+ ) ;
5660 }
57- if ( classPermits ) {
58- header . push ( indent ( [ line , call ( path , print , "classPermits" ) ] ) ) ;
61+ if ( definedClauses . length ) {
62+ const separator = hasTypeParameters && ! hasMultipleClauses ? " " : line ;
63+ const clauses = definedClauses . flatMap ( clause => [
64+ separator ,
65+ call ( path , print , clause )
66+ ] ) ;
67+ const hasBody =
68+ children . classBody [ 0 ] . children . classBodyDeclaration !== undefined ;
69+ const clauseGroup = [
70+ hasTypeParameters && ! hasMultipleClauses ? clauses : indent ( clauses ) ,
71+ hasBody ? separator : " "
72+ ] ;
73+ parts . push ( hasMultipleClauses ? clauseGroup : group ( clauseGroup ) ) ;
74+ } else {
75+ parts . push ( " " ) ;
5976 }
60- return [ group ( header ) , " " , call ( path , print , "classBody" ) ] ;
77+ return [ group ( parts ) , call ( path , print , "classBody" ) ] ;
6178 } ,
6279
6380 classModifier : printSingle ,
6481
6582 typeParameters ( path , print ) {
66- return group ( [
83+ return [
6784 "<" ,
6885 indent ( [ softline , call ( path , print , "typeParameterList" ) ] ) ,
6986 softline ,
7087 ">"
71- ] ) ;
88+ ] ;
7289 } ,
7390
7491 typeParameterList ( path , print ) {
@@ -89,7 +106,7 @@ export default {
89106 classPermits : printClassPermits ,
90107
91108 interfaceTypeList ( path , print ) {
92- return group ( printList ( path , print , "interfaceType" ) ) ;
109+ return printList ( path , print , "interfaceType" ) ;
93110 } ,
94111
95112 classBody ( path , print ) {
@@ -199,7 +216,7 @@ export default {
199216 const { typeParameters, annotation, throws } = path . node . children ;
200217 const header : Doc [ ] = [ ] ;
201218 if ( typeParameters ) {
202- header . push ( call ( path , print , "typeParameters" ) ) ;
219+ header . push ( group ( call ( path , print , "typeParameters" ) ) ) ;
203220 }
204221 if ( annotation ) {
205222 header . push ( join ( line , map ( path , print , "annotation" ) ) ) ;
@@ -322,7 +339,7 @@ export default {
322339 : "()"
323340 ) ;
324341 return children . typeParameters
325- ? [ call ( path , print , "typeParameters" ) , " " , ...header ]
342+ ? [ group ( call ( path , print , "typeParameters" ) ) , " " , ...header ]
326343 : header ;
327344 } ,
328345
@@ -379,11 +396,21 @@ export default {
379396 } ,
380397
381398 enumDeclaration ( path , print ) {
382- const header = [ "enum" , call ( path , print , "typeIdentifier" ) ] ;
383- if ( path . node . children . classImplements ) {
384- header . push ( call ( path , print , "classImplements" ) ) ;
399+ const { children } = path . node ;
400+ const parts = [ "enum " , call ( path , print , "typeIdentifier" ) ] ;
401+ if ( children . classImplements ) {
402+ const body = children . enumBody [ 0 ] . children ;
403+ const hasBody =
404+ body . enumBodyDeclarations !== undefined ||
405+ body . enumConstantList !== undefined ;
406+ parts . push (
407+ indent ( [ line , call ( path , print , "classImplements" ) ] ) ,
408+ hasBody ? line : " "
409+ ) ;
410+ } else {
411+ parts . push ( " " ) ;
385412 }
386- return join ( " " , [ ... header , call ( path , print , "enumBody" ) ] ) ;
413+ return [ group ( parts ) , call ( path , print , "enumBody" ) ] ;
387414 } ,
388415
389416 enumBody ( path , print , options ) {
@@ -445,20 +472,40 @@ export default {
445472
446473 recordDeclaration ( path , print ) {
447474 const { children } = path . node ;
448- const header = [ "record " , call ( path , print , "typeIdentifier" ) ] ;
475+ const parts = [ "record " , call ( path , print , "typeIdentifier" ) ] ;
449476 if ( children . typeParameters ) {
450- header . push ( call ( path , print , "typeParameters" ) ) ;
477+ parts . push ( group ( call ( path , print , "typeParameters" ) ) ) ;
451478 }
452- header . push ( call ( path , print , "recordHeader" ) ) ;
479+ parts . push ( call ( path , print , "recordHeader" ) ) ;
453480 if ( children . classImplements ) {
454- header . push ( " " , call ( path , print , "classImplements" ) ) ;
481+ const hasComponents =
482+ children . recordHeader [ 0 ] . children . recordComponentList !== undefined ;
483+ const hasBody =
484+ children . recordBody [ 0 ] . children . recordBodyDeclaration !== undefined ;
485+ const classImplements = [
486+ hasComponents ? " " : line ,
487+ call ( path , print , "classImplements" )
488+ ] ;
489+ parts . push (
490+ group ( [
491+ hasComponents ? classImplements : indent ( classImplements ) ,
492+ hasBody ? line : " "
493+ ] )
494+ ) ;
495+ } else {
496+ parts . push ( " " ) ;
455497 }
456- return [ group ( header ) , " " , call ( path , print , "recordBody" ) ] ;
498+ return [ group ( parts ) , call ( path , print , "recordBody" ) ] ;
457499 } ,
458500
459501 recordHeader ( path , print ) {
460502 return path . node . children . recordComponentList
461- ? indentInParentheses ( call ( path , print , "recordComponentList" ) )
503+ ? [
504+ "(" ,
505+ indent ( [ softline , call ( path , print , "recordComponentList" ) ] ) ,
506+ softline ,
507+ ")"
508+ ]
462509 : indentInParentheses ( printDanglingComments ( path ) , { shouldBreak : true } ) ;
463510 } ,
464511
0 commit comments