diff --git a/src/common/ast-path.js b/src/common/ast-path.js index cd8b725a0..5c1ed16c1 100644 --- a/src/common/ast-path.js +++ b/src/common/ast-path.js @@ -57,6 +57,10 @@ class AstPath { return this.stack.length === 1; } + get root() { + return this.stack[0]; + } + // The name of the current property is always the penultimate element of // this.stack, and always a string/number/symbol. getName() { diff --git a/src/language-yaml/print/flow-mapping-sequence.js b/src/language-yaml/print/flow-mapping-sequence.js index cf2dac3dc..3c158689b 100644 --- a/src/language-yaml/print/flow-mapping-sequence.js +++ b/src/language-yaml/print/flow-mapping-sequence.js @@ -42,24 +42,21 @@ function printFlowMapping(path, print, options) { } function printChildren(path, print, options) { - const { node } = path; - const parts = path.map( - (childPath, index) => [ + return path.map( + ({ isLast, node, next }) => [ print(), - index === node.children.length - 1 + isLast ? "" : [ ",", line, - node.children[index].position.start.line !== - node.children[index + 1].position.start.line - ? printNextEmptyLine(childPath, options.originalText) + node.position.start.line !== next.position.start.line + ? printNextEmptyLine(path, options.originalText) : "", ], ], "children" ); - return parts; } export { diff --git a/src/language-yaml/print/mapping-item.js b/src/language-yaml/print/mapping-item.js index f7d75958d..8aa23c904 100644 --- a/src/language-yaml/print/mapping-item.js +++ b/src/language-yaml/print/mapping-item.js @@ -5,7 +5,6 @@ import { group, hardline, ifBreak, - join, line, } from "../../document/builders.js"; import { @@ -19,7 +18,8 @@ import { } from "../utils.js"; import { alignWithSpaces } from "./misc.js"; -function printMappingItem(node, parentNode, path, print, options) { +function printMappingItem(path, print, options) { + const { node, parent } = path; const { key, value } = node; const isEmptyMappingKey = isEmptyNode(key); @@ -33,7 +33,7 @@ function printMappingItem(node, parentNode, path, print, options) { const spaceBeforeColon = needsSpaceInFrontOfMappingValue(node) ? " " : ""; if (isEmptyMappingValue) { - if (node.type === "flowMappingItem" && parentNode.type === "flowMapping") { + if (node.type === "flowMappingItem" && parent.type === "flowMapping") { return printedKey; } @@ -41,7 +41,7 @@ function printMappingItem(node, parentNode, path, print, options) { node.type === "mappingItem" && isAbsolutelyPrintedAsSingleLineNode(key.content, options) && !hasTrailingComment(key.content) && - (!parentNode.tag || parentNode.tag.value !== "tag:yaml.org,2002:set") + parent.tag?.value !== "tag:yaml.org,2002:set" ) { return [printedKey, spaceBeforeColon, ":"]; } @@ -60,12 +60,7 @@ function printMappingItem(node, parentNode, path, print, options) { "? ", alignWithSpaces(2, printedKey), hardline, - join( - "", - path - .map(print, "value", "leadingComments") - .map((comment) => [comment, hardline]) - ), + ...path.map(() => [print(), hardline], "value", "leadingComments"), ": ", alignWithSpaces(2, printedValue), ]; @@ -107,7 +102,7 @@ function printMappingItem(node, parentNode, path, print, options) { (hasEndComments(value) && value.content && !isNode(value.content, ["mapping", "sequence"])) || - (parentNode.type === "mapping" && + (parent.type === "mapping" && hasTrailingComment(key.content) && isInlineNode(value.content)) || (isNode(value.content, ["mapping", "sequence"]) && diff --git a/src/language-yaml/print/misc.js b/src/language-yaml/print/misc.js index 37305eb24..506310ee4 100644 --- a/src/language-yaml/print/misc.js +++ b/src/language-yaml/print/misc.js @@ -3,8 +3,7 @@ import { hasEndComments, isNextLineEmpty, isNode } from "../utils.js"; const printedEmptyLineCache = new WeakMap(); function printNextEmptyLine(path, originalText) { - const { node } = path; - const root = path.stack[0]; + const { node, root } = path; let isNextEmptyLinePrintedSet; if (printedEmptyLineCache.has(root)) { diff --git a/src/language-yaml/printer-yaml.js b/src/language-yaml/printer-yaml.js index f9638f9cc..7cabcb894 100644 --- a/src/language-yaml/printer-yaml.js +++ b/src/language-yaml/printer-yaml.js @@ -98,7 +98,6 @@ function genericPrint(path, options, print) { ]); } - const parentNode = path.getParentNode(); if (hasPrettierIgnore(path)) { parts.push( replaceEndOfLine( @@ -108,14 +107,14 @@ function genericPrint(path, options, print) { ) ); } else { - parts.push(group(printNode(node, parentNode, path, options, print))); + parts.push(group(printNode(path, options, print))); } if (hasTrailingComment(node) && !isNode(node, ["document", "documentHead"])) { parts.push( lineSuffix([ node.type === "mappingValue" && !node.content ? "" : " ", - parentNode.type === "mappingKey" && + path.parent.type === "mappingKey" && path.getParentNode(2).type === "mapping" && isInlineNode(node) ? "" @@ -132,8 +131,8 @@ function genericPrint(path, options, print) { join( hardline, path.map( - (path) => [ - isPreviousLineEmpty(options.originalText, path.node, locStart) + ({ node }) => [ + isPreviousLineEmpty(options.originalText, node, locStart) ? hardline : "", print(), @@ -148,15 +147,13 @@ function genericPrint(path, options, print) { return parts; } -function printNode(node, parentNode, path, options, print) { +function printNode(path, options, print) { + const { node } = path; switch (node.type) { case "root": { - const { children } = node; const parts = []; - path.each((childPath, index) => { - const document = children[index]; - const nextDocument = children[index + 1]; - if (index !== 0) { + path.each(({ node: document, next: nextDocument, isFirst }) => { + if (!isFirst) { parts.push(hardline); } parts.push(print()); @@ -180,16 +177,8 @@ function printNode(node, parentNode, path, options, print) { return parts; } case "document": { - const nextDocument = parentNode.children[path.getName() + 1]; const parts = []; - if ( - shouldPrintDocumentHeadEndMarker( - node, - nextDocument, - parentNode, - options - ) === "head" - ) { + if (shouldPrintDocumentHeadEndMarker(path, options) === "head") { if (node.head.children.length > 0 || node.head.endComments.length > 0) { parts.push(print("head")); } @@ -331,7 +320,7 @@ function printNode(node, parentNode, path, options, print) { return !node.content ? "" : print("content"); case "mappingItem": case "flowMappingItem": - return printMappingItem(node, parentNode, path, print, options); + return printMappingItem(path, print, options); case "flowMapping": return printFlowMapping(path, print, options); @@ -371,18 +360,14 @@ function shouldPrintDocumentEndMarker(document, nextDocument) { ); } -function shouldPrintDocumentHeadEndMarker( - document, - nextDocument, - root, - options -) { +function shouldPrintDocumentHeadEndMarker(path, options) { + const document = path.node; if ( /** * --- * preserve the first document head end marker */ - (root.children[0] === document && + (path.isFirst && /---(?:\s|$)/.test( options.originalText.slice(locStart(document), locStart(document) + 4) )) || @@ -404,6 +389,7 @@ function shouldPrintDocumentHeadEndMarker( return "head"; } + const nextDocument = path.next; if (shouldPrintDocumentEndMarker(document, nextDocument)) { return false; } diff --git a/src/language-yaml/utils.js b/src/language-yaml/utils.js index 9d5c22f6e..2adcd943f 100644 --- a/src/language-yaml/utils.js +++ b/src/language-yaml/utils.js @@ -109,10 +109,10 @@ function hasPrettierIgnore(path) { const { node } = path; if (node.type === "documentBody") { - const document = path.getParentNode(); + const documentHead = path.parent.head; return ( - hasEndComments(document.head) && - isPrettierIgnore(document.head.endComments.at(-1)) + hasEndComments(documentHead) && + isPrettierIgnore(documentHead.endComments.at(-1)) ); }