From 7d42e79d9dc09c64466a2c515282e89bf9f302e7 Mon Sep 17 00:00:00 2001 From: Cyrille David Date: Mon, 3 Feb 2020 20:44:24 +0100 Subject: [PATCH] refactoring(glimmer): Extract utils from printer (#7528) * Extract isWhitespaceNode * Refactor isParentOfType to isParentOfSomeType * Introduce isNodeOfSomeType * Replace isNextNodeOfType with isNextNodeOfSomeType * Move utils to utils file * Sort utils * Refactor isPrettierIgnoreNode function to use util * Extract hasPrettierIgnore to utils * Apply review feedback * Apply review suggestions * Add getSiblingNode --- src/language-handlebars/printer-glimmer.js | 103 ++++----------------- src/language-handlebars/utils.js | 78 ++++++++++++++-- 2 files changed, 90 insertions(+), 91 deletions(-) diff --git a/src/language-handlebars/printer-glimmer.js b/src/language-handlebars/printer-glimmer.js index 1c7d666e9..5a25cb3ae 100644 --- a/src/language-handlebars/printer-glimmer.js +++ b/src/language-handlebars/printer-glimmer.js @@ -11,7 +11,16 @@ const { ifBreak } = require("../document").builders; -const { isGlimmerComponent } = require("./utils"); +const { + getNextNode, + getPreviousNode, + hasPrettierIgnore, + isGlimmerComponent, + isNextNodeOfSomeType, + isParentOfSomeType, + isPreviousNodeOfSomeType, + isWhitespaceNode +} = require("./utils"); // http://w3c.github.io/html/single-page.html#void-elements const voidTags = [ @@ -177,12 +186,13 @@ function print(path, options, print) { const opening = isEscaped ? "{{{" : "{{"; const closing = isEscaped ? "}}}" : "}}"; - const leading = - isParentOfType(path, "AttrNode") || - isParentOfType(path, "ConcatStatement") || - isParentOfType(path, "ElementNode") - ? [opening, indent(softline)] - : [opening]; + const leading = isParentOfSomeType(path, [ + "AttrNode", + "ConcatStatement", + "ElementNode" + ]) + ? [opening, indent(softline)] + : [opening]; return group( concat([...leading, printPathParams(path, print), softline, closing]) @@ -253,10 +263,7 @@ function print(path, options, print) { ); trailingLineBreaksCount = 0; } else { - if ( - isNextNodeOfType(path, "ElementNode") || - isNextNodeOfType(path, "BlockStatement") - ) { + if (isNextNodeOfSomeType(path, ["BlockStatement", "ElementNode"])) { trailingLineBreaksCount = Math.max(trailingLineBreaksCount, 1); } @@ -298,7 +305,7 @@ function print(path, options, print) { } else { if ( trailingLineBreaksCount === 0 && - isNextNodeOfType(path, "MustacheStatement") + isNextNodeOfSomeType(path, ["MustacheStatement"]) ) { trailingSpace = " "; } @@ -480,57 +487,6 @@ function printCloseBlock(path, print) { return concat(["{{/", path.call(print, "path"), "}}"]); } -function isWhitespaceNode(node) { - return node.type === "TextNode" && !/\S/.test(node.chars); -} - -function isParentOfType(path, nodeType) { - const p = path.getParentNode(0); - return p && p.type === nodeType; -} - -function getPreviousNode(path, lookBack = 1) { - const node = path.getValue(); - const parentNode = path.getParentNode(0); - - const children = parentNode && (parentNode.children || parentNode.body); - if (children) { - const nodeIndex = children.indexOf(node); - if (nodeIndex > 0) { - const previousNode = children[nodeIndex - lookBack]; - return previousNode; - } - } -} - -function getNextNode(path) { - const node = path.getValue(); - const parentNode = path.getParentNode(0); - - const children = parentNode.children || parentNode.body; - if (children) { - const nodeIndex = children.indexOf(node); - if (nodeIndex < children.length) { - const nextNode = children[nodeIndex + 1]; - return nextNode; - } - } -} - -function isPreviousNodeOfSomeType(path, types) { - const previousNode = getPreviousNode(path); - - if (previousNode) { - return types.some(type => previousNode.type === type); - } - return false; -} - -function isNextNodeOfType(path, type) { - const nextNode = getNextNode(path); - return nextNode && nextNode.type === type; -} - function clean(ast, newObj) { delete newObj.loc; delete newObj.selfClosing; @@ -568,15 +524,6 @@ function generateHardlines(number = 0, max = 0) { return new Array(Math.min(number, max)).fill(hardline); } -function hasPrettierIgnore(path) { - const n = path.getValue(); - const previousPreviousNode = getPreviousNode(path, 2); - const isIgnoreNode = isPrettierIgnoreNode(n); - const isCoveredByIgnoreNode = isPrettierIgnoreNode(previousPreviousNode); - - return isIgnoreNode || isCoveredByIgnoreNode; -} - /* istanbul ignore next https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/compiler/lib/location.ts#L5-L29 */ @@ -608,18 +555,6 @@ function locationToOffset(source, line, column) { } } -function isPrettierIgnoreNode(node) { - if (!node) { - return false; - } - - const isMustacheComment = node.type === "MustacheCommentStatement"; - const containsPrettierIgnore = - typeof node.value === "string" && node.value.trim() === "prettier-ignore"; - - return isMustacheComment && containsPrettierIgnore; -} - module.exports = { print, massageAstNode: clean diff --git a/src/language-handlebars/utils.js b/src/language-handlebars/utils.js index 799c32e2e..f75853bc7 100644 --- a/src/language-handlebars/utils.js +++ b/src/language-handlebars/utils.js @@ -1,16 +1,80 @@ "use strict"; +function isUppercase(string) { + return string.toUpperCase() === string; +} + function isGlimmerComponent(node) { - if (node.type !== "ElementNode") { - return false; - } + return ( + isNodeOfSomeType(node, ["ElementNode"]) && + typeof node.tag === "string" && + (isUppercase(node.tag[0]) || node.tag.includes(".")) + ); +} - const tagFirstChar = node.tag && node.tag[0]; - const isLocal = node.tag.includes("."); +function isWhitespaceNode(node) { + return isNodeOfSomeType(node, ["TextNode"]) && !/\S/.test(node.chars); +} - return tagFirstChar.toUpperCase() === tagFirstChar || isLocal; +function isNodeOfSomeType(node, types) { + return node && types.some(type => node.type === type); +} + +function isParentOfSomeType(path, types) { + const parentNode = path.getParentNode(0); + return isNodeOfSomeType(parentNode, types); +} + +function isPreviousNodeOfSomeType(path, types) { + const previousNode = getPreviousNode(path); + return isNodeOfSomeType(previousNode, types); +} + +function isNextNodeOfSomeType(path, types) { + const nextNode = getNextNode(path); + return isNodeOfSomeType(nextNode, types); +} + +function getSiblingNode(path, offset) { + const node = path.getValue(); + const parentNode = path.getParentNode(0) || {}; + const children = parentNode.children || parentNode.body || []; + const index = children.indexOf(node); + return index !== -1 && children[index + offset]; +} + +function getPreviousNode(path, lookBack = 1) { + return getSiblingNode(path, -lookBack); +} + +function getNextNode(path) { + return getSiblingNode(path, 1); +} + +function isPrettierIgnoreNode(node) { + return ( + isNodeOfSomeType(node, ["MustacheCommentStatement"]) && + typeof node.value === "string" && + node.value.trim() === "prettier-ignore" + ); +} + +function hasPrettierIgnore(path) { + const node = path.getValue(); + const previousPreviousNode = getPreviousNode(path, 2); + return ( + isPrettierIgnoreNode(node) || isPrettierIgnoreNode(previousPreviousNode) + ); } module.exports = { - isGlimmerComponent + getNextNode, + getPreviousNode, + hasPrettierIgnore, + isGlimmerComponent, + isNextNodeOfSomeType, + isNodeOfSomeType, + isParentOfSomeType, + isPreviousNodeOfSomeType, + isWhitespaceNode };