@@ -18,6 +18,7 @@ const {
1818} = require ( "./utils" ) ;
1919const docBuilders = require ( "../doc" ) . builders ;
2020const {
21+ conditionalGroup,
2122 breakParent,
2223 concat,
2324 dedent,
@@ -58,44 +59,15 @@ function genericPrint(path, options, print) {
5859 : "" ;
5960
6061 return concat ( [
61- hasLeadingComments ( node )
62- ? concat ( [
63- ( node . type === "sequence" || node . type === "mapping" ) &&
64- ( parentParentNode =>
65- parentParentNode . type === "mappingItem" &&
66- isImplicitMappingItem ( parentParentNode , path . getParentNode ( 2 ) ) ) (
67- path . getParentNode ( 1 )
68- ) &&
69- ! ( tag || anchor )
70- ? hardline
71- : "" ,
72- join ( hardline , path . map ( print , "leadingComments" ) ) ,
73- hardline
74- ] )
62+ node . type !== "mappingValue" && hasLeadingComments ( node )
63+ ? concat ( [ join ( hardline , path . map ( print , "leadingComments" ) ) , hardline ] )
7564 : "" ,
7665 tag ,
7766 tag && anchor ? " " : "" ,
7867 anchor ,
7968 ( node . type === "sequence" || node . type === "mapping" ) &&
8069 node . middleComments . length === 0
81- ? tag ||
82- anchor ||
83- ( parentNode . type !== "documentBody" &&
84- parentNode . type !== "sequenceItem" &&
85- node . leadingComments . length === 0 &&
86- ! (
87- parentNode . type === "mappingValue" &&
88- ( parentParentNode =>
89- parentParentNode . type === "mappingItem" &&
90- hasTrailingComments ( parentParentNode . key . node ) ) (
91- path . getParentNode ( 1 )
92- )
93- ) &&
94- ! ( parentParentNode =>
95- parentParentNode . type === "mappingItem" &&
96- ! isImplicitMappingItem ( parentParentNode , path . getParentNode ( 2 ) ) ) (
97- path . getParentNode ( 1 )
98- ) )
70+ ? tag || anchor
9971 ? hardline
10072 : ""
10173 : tag || anchor
@@ -118,9 +90,9 @@ function genericPrint(path, options, print) {
11890 ? lineSuffix (
11991 concat ( [
12092 " " ,
121- isSingleLineNode ( node ) &&
122- parentNode . type === "mappingValue " &&
123- path . getParentNode ( 1 ) . type === "mappingItem"
93+ parentNode . type === "mappingKey" &&
94+ path . getParentNode ( 2 ) . type === "mapping " &&
95+ isInlineNode ( node )
12496 ? ""
12597 : breakParent ,
12698 join ( hardline , path . map ( print , "trailingComments" ) )
@@ -281,50 +253,84 @@ function _print(node, parentNode, path, options, print) {
281253 case "sequenceItem" :
282254 return concat ( [ "- " , align ( 2 , path . call ( print , "node" ) ) ] ) ;
283255 case "mappingKey" :
284- return isImplicitMappingItem ( parentNode , path . getParentNode ( 1 ) )
285- ? path . call ( print , "node" )
286- : concat ( [ "? " , align ( 2 , path . call ( print , "node" ) ) ] ) ;
256+ return path . call ( print , "node" ) ;
287257 case "mappingValue" :
288- return isImplicitMappingItem ( parentNode , path . getParentNode ( 1 ) )
289- ? concat ( [
290- concat ( [
291- needsSpaceInFrontOfMappingValue ( parentNode ) ? " " : "" ,
292- ":"
293- ] ) ,
294- ( doc => ( node . node . type === "sequence" ? doc : indent ( doc ) ) ) (
295- concat ( [
296- node . node . type === "null"
297- ? ""
298- : hasTrailingComments ( parentNode . key . node ) &&
299- ! isBlockValue ( node . node )
300- ? hardline
301- : isInlineNode ( node . node )
302- ? line
303- : " " ,
304- path . call ( print , "node" )
305- ] )
306- )
307- ] )
308- : concat ( [
309- ":" ,
310- node . node . type === "null" ? "" : " " ,
311- align ( 2 , path . call ( print , "node" ) )
312- ] ) ;
258+ return path . call ( print , "node" ) ;
313259 case "mapping" :
314260 return join ( hardline , path . map ( print , "children" ) ) ;
315261 case "mappingItem" :
316262 case "flowMappingItem" : {
317- return ( node . type === "flowMappingItem" || node . type === "mappingItem" ) &&
318- node . key . type === "null" &&
319- node . value . type === "null"
320- ? concat ( [ ":" , line ] )
321- : join (
322- isImplicitMappingItem ( node , parentNode ) ? "" : hardline ,
323- [
324- node . key . type === "null" ? "" : path . call ( print , "key" ) ,
325- node . value . type === "null" ? "" : path . call ( print , "value" )
326- ] . filter ( doc => doc !== "" )
327- ) ;
263+ if ( node . key . type === "null" && node . value . type === "null" ) {
264+ return concat ( [ ":" , line ] ) ;
265+ }
266+
267+ const key = path . call ( print , "key" ) ;
268+ const value = path . call ( print , "value" ) ;
269+
270+ if ( node . value . type === "null" ) {
271+ return node . type === "flowMappingItem" &&
272+ path . getParentNode ( ) . type !== "flowSequence"
273+ ? key
274+ : concat ( [ "? " , align ( 2 , key ) ] ) ;
275+ }
276+
277+ if ( node . key . type === "null" ) {
278+ return concat ( [
279+ ":" ,
280+ node . value . node . type === "null" ? "" : " " ,
281+ align ( 2 , value )
282+ ] ) ;
283+ }
284+
285+ const groupId = Symbol ( "mappingKey" ) ;
286+
287+ const forceExplicitKey =
288+ hasLeadingComments ( node . value ) ||
289+ ( node . key . type !== "null" && ! isInlineNode ( node . key . node ) ) ;
290+ return forceExplicitKey
291+ ? concat ( [
292+ "? " ,
293+ align ( 2 , key ) ,
294+ hardline ,
295+ join (
296+ "" ,
297+ path
298+ . map ( print , "value" , "leadingComments" )
299+ . map ( comment => concat ( [ comment , hardline ] ) )
300+ ) ,
301+ ": " ,
302+ align ( 2 , value )
303+ ] )
304+ : conditionalGroup ( [
305+ concat ( [
306+ group (
307+ concat ( [ ifBreak ( "? " ) , group ( align ( 2 , key ) , { id : groupId } ) ] )
308+ ) ,
309+ ifBreak (
310+ concat ( [ hardline , ": " , align ( 2 , value ) ] ) ,
311+ indent (
312+ concat ( [
313+ needsSpaceInFrontOfMappingValue ( node ) ? " " : "" ,
314+ ":" ,
315+ hasLeadingComments ( node . value . node ) ||
316+ ( parentNode . type === "mapping" &&
317+ hasTrailingComments ( node . key . node ) &&
318+ isInlineNode ( node . value . node ) ) ||
319+ ( ( node . value . node . type === "mapping" ||
320+ node . value . node . type === "sequence" ) &&
321+ node . value . node . tag . type === "null" &&
322+ node . value . node . anchor . type === "null" )
323+ ? hardline
324+ : node . value . node . type === "null"
325+ ? ""
326+ : line ,
327+ value
328+ ] )
329+ ) ,
330+ { groupId }
331+ )
332+ ] )
333+ ] ) ;
328334 }
329335 case "flowMapping" :
330336 case "flowSequence" : {
@@ -394,82 +400,6 @@ function _print(node, parentNode, path, options, print) {
394400 }
395401}
396402
397- /**
398- * (implicit: indent)
399- *
400- * key:
401- * value
402- *
403- * (explicit: align 2)
404- *
405- * ? key
406- * : value
407- */
408- function isImplicitMappingItem ( node , parentNode ) {
409- /**
410- * { : value }
411- */
412- if ( node . key . type === "null" ) {
413- return false ;
414- }
415-
416- /**
417- * ? key
418- *
419- * [ ? key ]
420- *
421- * { key }
422- */
423- if ( node . value . type === "null" ) {
424- return parentNode . type === "flowMapping" ;
425- }
426-
427- /**
428- * ? !!tag key
429- * : value
430- */
431- if (
432- "tag" in node . key . node &&
433- ( node . key . node . tag . type !== "null" || node . key . node . anchor . type !== "null" )
434- ) {
435- return false ;
436- }
437-
438- /**
439- * ? # comment
440- * key
441- * : value
442- */
443- if ( hasLeadingComments ( node . key . node ) ) {
444- return false ;
445- }
446-
447- /**
448- * ? key
449- * # comment
450- * : value
451- */
452- if ( hasLeadingComments ( node . value ) ) {
453- return false ;
454- }
455-
456- return isSingleLineNode ( node . key . node ) ;
457- }
458-
459- function isSingleLineNode ( node ) {
460- switch ( node . type ) {
461- case "alias" :
462- return true ;
463- case "plain" :
464- return ! node . value . includes ( "\n" ) ;
465- case "quoteDouble" :
466- case "quoteSingle" :
467- return node . position . start . line === node . position . end . line ;
468- default :
469- return false ;
470- }
471- }
472-
473403function isInlineNode ( node ) {
474404 switch ( node . type ) {
475405 case "plain" :
0 commit comments