From 8dae4abf41e1ccec3515e8acea159505bbd55f33 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sun, 17 Jul 2022 16:10:06 +0800 Subject: [PATCH] Switch print/embed to async (#13104) --- changelog_unreleased/api/12574.md | 1 + changelog_unreleased/api/12740.md | 2 +- changelog_unreleased/api/12748.md | 59 +++++- docs/plugins.md | 37 ++-- src/common/ast-path.js | 103 +++++++-- src/language-css/embed.js | 4 +- src/language-css/printer-postcss.js | 75 +++---- src/language-graphql/printer-graphql.js | 195 ++++++++++-------- src/language-handlebars/printer-glimmer.js | 88 ++++---- src/language-html/embed.js | 34 +-- src/language-html/print/children.js | 20 +- src/language-html/print/element.js | 12 +- src/language-html/print/tag.js | 8 +- src/language-html/printer-html.js | 6 +- src/language-html/syntax-vue.js | 10 +- src/language-js/embed/css.js | 6 +- src/language-js/embed/graphql.js | 6 +- src/language-js/embed/html.js | 6 +- src/language-js/embed/markdown.js | 4 +- src/language-js/print/angular.js | 28 +-- src/language-js/print/array.js | 25 ++- src/language-js/print/assignment.js | 40 ++-- src/language-js/print/binaryish.js | 22 +- src/language-js/print/block.js | 12 +- src/language-js/print/call-arguments.js | 22 +- src/language-js/print/call-expression.js | 16 +- src/language-js/print/class.js | 53 ++--- src/language-js/print/decorators.js | 12 +- src/language-js/print/flow.js | 91 ++++---- src/language-js/print/function-parameters.js | 8 +- src/language-js/print/function.js | 82 ++++---- src/language-js/print/html-binding.js | 8 +- src/language-js/print/interface.js | 10 +- src/language-js/print/jsx.js | 76 +++---- src/language-js/print/member-chain.js | 30 +-- src/language-js/print/member.js | 10 +- src/language-js/print/misc.js | 25 ++- src/language-js/print/module.js | 50 ++--- src/language-js/print/object.js | 16 +- src/language-js/print/property.js | 10 +- src/language-js/print/statement.js | 8 +- src/language-js/print/template-literal.js | 18 +- src/language-js/print/ternary.js | 32 +-- src/language-js/print/type-annotation.js | 51 ++--- src/language-js/print/type-parameters.js | 27 ++- src/language-js/print/typescript.js | 126 +++++------ src/language-js/printer-estree-json.js | 16 +- src/language-js/printer-estree.js | 156 +++++++------- src/language-js/utils/index.js | 18 +- src/language-markdown/embed.js | 6 +- src/language-markdown/printer-markdown.js | 61 +++--- src/language-yaml/print/block.js | 4 +- .../print/flow-mapping-sequence.js | 14 +- src/language-yaml/print/mapping-item.js | 13 +- src/language-yaml/printer-yaml.js | 64 +++--- src/main/ast-to-doc.js | 17 +- src/main/core.js | 6 +- src/main/multiparser.js | 12 +- src/main/parser.js | 7 +- src/utils/front-matter/print.js | 8 +- .../__snapshots__/jsfmt.spec.js.snap | 40 ---- .../plugins/embed-async-parser/jsfmt.spec.js | 10 - .../with-aync-parser-code-block.md | 7 - 63 files changed, 1117 insertions(+), 926 deletions(-) delete mode 100644 tests/format/misc/plugins/embed-async-parser/__snapshots__/jsfmt.spec.js.snap delete mode 100644 tests/format/misc/plugins/embed-async-parser/jsfmt.spec.js delete mode 100644 tests/format/misc/plugins/embed-async-parser/with-aync-parser-code-block.md diff --git a/changelog_unreleased/api/12574.md b/changelog_unreleased/api/12574.md index af75fe135..c5723ed4d 100644 --- a/changelog_unreleased/api/12574.md +++ b/changelog_unreleased/api/12574.md @@ -2,6 +2,7 @@ - `prettier.format()` returns `Promise` - `prettier.formatWithCursor()` returns `Promise<{formatted: string, cursorOffset: number}>` +- `prettier.formatAST()` returns `Promise` - `prettier.check()` returns `Promise` - `prettier.getSupportInfo()` returns `Promise` - `prettier.resolveConfig.sync` is removed diff --git a/changelog_unreleased/api/12740.md b/changelog_unreleased/api/12740.md index 47f57bb2b..a596abee2 100644 --- a/changelog_unreleased/api/12740.md +++ b/changelog_unreleased/api/12740.md @@ -1,4 +1,4 @@ -#### [Breaking] standalone version export style changed (#12740 by @fisker) +#### [BREAKING] standalone version export style changed (#12740 by @fisker) The `esm/standalone.mjs` entry has changed export style from default export to named export. diff --git a/changelog_unreleased/api/12748.md b/changelog_unreleased/api/12748.md index 6f3943463..03904afe7 100644 --- a/changelog_unreleased/api/12748.md +++ b/changelog_unreleased/api/12748.md @@ -1,7 +1,60 @@ -#### [HIGHLIGHT] Support plugin with async parse function (#12748 by @fisker) +#### [HIGHLIGHT] Support plugin with async parse function (#12748, #13104 by @fisker) [`parse` function](https://prettier.io/docs/en/plugins.html#parsers) in plugin can return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) now. - +In order to support async parser, we introduced several breaking changes to the plugin system: -Note: Since [`embed` functions in plugin](https://prettier.io/docs/en/plugins.html#optional-embed) are still sync, plugins with async parser can't be used to format embed code. +The third argument of the [`print`](https://prettier.io/docs/en/plugins.html#print) method of plugin printers (the `print` callback) returns `Promise` now. + +```diff +export const printers = { + "dance-ast": { +- print(path, options, print) { +- return [print("key"), ": ", print("value")]; ++ async print(path, options, print) { ++ return [await print("key"), ": ", await print("value")]; + }, + }, +} +``` + +The `print` and `textToDoc` arguments of the [`embed`](https://prettier.io/docs/en/plugins.html#optional-embed) method of plugin printers returns `Promise` now. + +```diff +export const printers = { + "dance-ast": { +- embed(path, print, textToDoc, options) { ++ async embed(path, print, textToDoc, options) { + const { text } = path.getValue(); +- const doc = textToDoc(text, {...options, parser: "meriyah"}); ++ const doc = await textToDoc(text, {...options, parser: "meriyah"}); + return [doc, hardline]; + }, + }, +} +``` + +`Promise`s returned in callback of `AstPath#{each,map}()`(aka `path`) are `await`ed. + +```js +path.map((path, index) => Promise.resolve(index)); + +/* Prettier stable */ +// -> [Promise<0>, Promise<1>] + +/* Prettier main */ +// -> Promise<[0, 1]> +``` + +Note: Due to limitation of `AstPath`, plugin should not try to call `print()` or `textToDoc()` in parallel, it may cause unexpected result. + +```js +/* BAD */ +const [key, value] = await Promise.all( + ["key", "value"].map((property) => print(property)) +); +return [key, ": ", value]; + +/* GOOD */ +return [await print("key"), ": ", await print("key")]; +``` diff --git a/docs/plugins.md b/docs/plugins.md index e38dd0ab8..289802cb6 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -196,8 +196,10 @@ function print( path: AstPath, options: object, // Recursively print a child node - print: (selector?: string | number | Array | AstPath) => Doc -): Doc; + print: ( + selector?: string | number | Array | AstPath + ) => Promise +): Promise; ``` The `print` function is passed the following parameters: @@ -209,18 +211,18 @@ The `print` function is passed the following parameters: Here’s a simplified example to give an idea of what a typical implementation of `print` looks like: ```js -const { - builders: { group, indent, join, line, softline }, -} = require("prettier").doc; +import { doc } from "prettier"; -function print(path, options, print) { +const { group, indent, join, line, softline } = doc.builders; + +async function print(path, options, print) { const node = path.getValue(); switch (node.type) { case "list": return group([ "(", - indent([softline, join(line, path.map(print, "elements"))]), + indent([softline, join(line, await path.map(print, "elements"))]), softline, ")", ]); @@ -228,7 +230,13 @@ function print(path, options, print) { case "pair": return group([ "(", - indent([softline, print("left"), line, ". ", print("right")]), + indent([ + softline, + await print("left"), + line, + ". ", + await print("right"), + ]), softline, ")", ]); @@ -252,13 +260,15 @@ function embed( // Path to the current AST node path: AstPath, // Print a node with the current printer - print: (selector?: string | number | Array | AstPath) => Doc, + print: ( + selector?: string | number | Array | AstPath + ) => Promise, // Parse and print some text using a different parser. // You should set `options.parser` to specify which parser to use. - textToDoc: (text: string, options: object) => Doc, + textToDoc: (text: string, options: object) => Promise, // Current options options: object -): Doc | null; +): Promise; ``` The `embed` function acts like the `print` function, except that it is passed an additional `textToDoc` function, which can be used to render a doc using a different plugin. The `embed` function returns a Doc or a falsy value. If a falsy value is returned, the `print` function is called with the current `path`. If a Doc is returned, that Doc is used in printing and the `print` function is not called. @@ -452,9 +462,10 @@ function isPreviousLineEmpty(text: string, node: N, locStart: (node: N) => nu Since plugins can be resolved using relative paths, when working on one you can do: ```js -const prettier = require("prettier"); +import * as prettier from "prettier"; + const code = "(add 1 2)"; -prettier.format(code, { +await prettier.format(code, { parser: "lisp", plugins: ["."], }); diff --git a/src/common/ast-path.js b/src/common/ast-path.js index eef2b6402..1d3405711 100644 --- a/src/common/ast-path.js +++ b/src/common/ast-path.js @@ -15,6 +15,24 @@ function getNodeStackIndexHelper(stack, count) { return -1; } +const isThenable = (object) => typeof object?.then === "function"; +const tryFinally = (fn, onSettled) => { + let result; + try { + result = fn(); + } catch (error) { + onSettled(); + throw error; + } + + if (isThenable(result)) { + return result.finally(onSettled); + } + + onSettled(); + return result; +}; + class AstPath { constructor(value) { this.stack = [value]; @@ -62,17 +80,25 @@ class AstPath { value = value[name]; stack.push(name, value); } - const result = callback(this); - stack.length = length; - return result; + + return tryFinally( + () => callback(this), + () => { + stack.length = length; + } + ); } callParent(callback, count = 0) { const stackIndex = getNodeStackIndexHelper(this.stack, count + 1); const parentValues = this.stack.splice(stackIndex + 1); - const result = callback(this); - this.stack.push(...parentValues); - return result; + + return tryFinally( + () => callback(this), + () => { + this.stack.push(...parentValues); + } + ); } // Similar to AstPath.prototype.call, except that the value obtained by @@ -89,24 +115,55 @@ class AstPath { stack.push(name, value); } - for (let i = 0; i < value.length; ++i) { - stack.push(i, value[i]); - callback(this, i, value); - stack.length -= 2; - } + const iteratee = (index) => + tryFinally( + () => { + stack.push(index, value[index]); + return callback(this, index, value); + }, + () => { + stack.length -= 2; + } + ); - stack.length = length; + return tryFinally( + () => { + let promise; + + for (let index = 0; index < value.length; index++) { + if (promise) { + promise = promise.then(() => iteratee(index)); + continue; + } + + const result = iteratee(index); + + if (isThenable(result)) { + promise = result; + } + } + + return promise; + }, + () => { + stack.length = length; + } + ); } // Similar to AstPath.prototype.each, except that the results of the // callback function invocations are stored in an array and returned at // the end of the iteration. map(callback, ...names) { - const result = []; - this.each((path, index, value) => { - result[index] = callback(path, index, value); + const results = []; + const maybePromise = this.each((path, index, value) => { + const result = callback(path, index, value); + results[index] = result; + return result; }, ...names); - return result; + return isThenable(maybePromise) + ? maybePromise.then(() => Promise.all(results)) + : results; } /** @@ -116,12 +173,14 @@ class AstPath { try(callback) { const { stack } = this; const stackBackup = [...stack]; - try { - return callback(); - } finally { - stack.length = 0; - stack.push(...stackBackup); - } + + return tryFinally( + () => callback(), + () => { + stack.length = 0; + stack.push(...stackBackup); + } + ); } /** diff --git a/src/language-css/embed.js b/src/language-css/embed.js index f4bb7b80b..4464ac536 100644 --- a/src/language-css/embed.js +++ b/src/language-css/embed.js @@ -1,11 +1,11 @@ import { hardline } from "../document/builders.js"; import printFrontMatter from "../utils/front-matter/print.js"; -function embed(path, print, textToDoc /*, options */) { +async function embed(path, print, textToDoc /*, options */) { const node = path.getValue(); if (node.type === "front-matter") { - const doc = printFrontMatter(node, textToDoc); + const doc = await printFrontMatter(node, textToDoc); return doc ? [doc, hardline] : ""; } } diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index 0a67b421c..ad5bd85cf 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -78,7 +78,7 @@ function shouldPrintComma(options) { return options.trailingComma === "es5" || options.trailingComma === "all"; } -function genericPrint(path, options, print) { +async function genericPrint(path, options, print) { const node = path.getValue(); /* istanbul ignore if */ @@ -94,7 +94,7 @@ function genericPrint(path, options, print) { case "front-matter": return [node.raw, hardline]; case "css-root": { - const nodes = printNodeSequence(path, options, print); + const nodes = await printNodeSequence(path, options, print); const after = node.raws.after.trim(); return [ @@ -112,7 +112,7 @@ function genericPrint(path, options, print) { } case "css-rule": { return [ - print("selector"), + await print("selector"), node.important ? " !important" : "", node.nodes ? [ @@ -125,7 +125,10 @@ function genericPrint(path, options, print) { : "", "{", node.nodes.length > 0 - ? indent([hardline, printNodeSequence(path, options, print)]) + ? indent([ + hardline, + await printNodeSequence(path, options, print), + ]) : "", hardline, "}", @@ -144,8 +147,8 @@ function genericPrint(path, options, print) { typeof node.value === "string" && /^ *$/.test(node.value); let value = hasComposesNode(node) - ? removeLines(print("value")) - : print("value"); + ? removeLines(await print("value")) + : await print("value"); if (!isColon && lastLineHasInlineComment(trimmedBetween)) { value = indent([hardline, dedent(value)]); @@ -158,7 +161,7 @@ function genericPrint(path, options, print) { trimmedBetween, node.extend || isValueAllSpace ? "" : " ", options.parser === "less" && node.extend && node.selector - ? ["extend(", print("selector"), ")"] + ? ["extend(", await print("selector"), ")"] : "", value, node.raws.important @@ -179,7 +182,7 @@ function genericPrint(path, options, print) { node.nodes ? [ " {", - indent([softline, printNodeSequence(path, options, print)]), + indent([softline, await printNodeSequence(path, options, print)]), softline, "}", ] @@ -202,7 +205,7 @@ function genericPrint(path, options, print) { if (options.parser === "less") { if (node.mixin) { return [ - print("selector"), + await print("selector"), node.important ? " !important" : "", isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";", ]; @@ -211,7 +214,7 @@ function genericPrint(path, options, print) { if (node.function) { return [ node.name, - print("params"), + await print("params"), isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";", ]; } @@ -221,14 +224,14 @@ function genericPrint(path, options, print) { "@", node.name, ": ", - node.value ? print("value") : "", + node.value ? await print("value") : "", node.raws.between.trim() ? node.raws.between.trim() + " " : "", node.nodes ? [ "{", indent([ node.nodes.length > 0 ? softline : "", - printNodeSequence(path, options, print), + await printNodeSequence(path, options, print), ]), softline, "}", @@ -267,14 +270,14 @@ function genericPrint(path, options, print) { ? hardline : " " : " ", - print("params"), + await print("params"), ] : "", - node.selector ? indent([" ", print("selector")]) : "", + node.selector ? indent([" ", await print("selector")]) : "", node.value ? group([ " ", - print("value"), + await print("value"), isSCSSControlDirectiveNode(node, options) ? hasParensAroundNode(node) ? " " @@ -300,7 +303,7 @@ function genericPrint(path, options, print) { "{", indent([ node.nodes.length > 0 ? softline : "", - printNodeSequence(path, options, print), + await printNodeSequence(path, options, print), ]), softline, "}", @@ -314,19 +317,19 @@ function genericPrint(path, options, print) { // postcss-media-query-parser case "media-query-list": { const parts = []; - path.each((childPath) => { + await path.each(async (childPath) => { const node = childPath.getValue(); if (node.type === "media-query" && node.value === "") { return; } - parts.push(print()); + parts.push(await print()); }, "nodes"); return group(indent(join(line, parts))); } case "media-query": { return [ - join(" ", path.map(print, "nodes")), + join(" ", await path.map(print, "nodes")), isLastNode(path, node) ? "" : ",", ]; } @@ -337,7 +340,7 @@ function genericPrint(path, options, print) { if (!node.nodes) { return node.value; } - return ["(", ...path.map(print, "nodes"), ")"]; + return ["(", ...(await path.map(print, "nodes")), ")"]; } case "media-feature": { return maybeToLowerCase( @@ -375,12 +378,12 @@ function genericPrint(path, options, print) { ? line : hardline, ], - path.map(print, "nodes") + await path.map(print, "nodes") ), ]); } case "selector-selector": { - return group(indent(path.map(print, "nodes"))); + return group(indent(await path.map(print, "nodes"))); } case "selector-comment": { return node.value; @@ -465,7 +468,7 @@ function genericPrint(path, options, print) { return [ maybeToLowerCase(node.value), isNonEmptyArray(node.nodes) - ? ["(", join(", ", path.map(print, "nodes")), ")"] + ? ["(", join(", ", await path.map(print, "nodes")), ")"] : "", ]; } @@ -534,7 +537,7 @@ function genericPrint(path, options, print) { isInlineValueCommentNode(node) ); - const printed = path.map(print, "groups"); + const printed = await path.map(print, "groups"); const parts = []; const insideURLFunction = insideValueFunctionNode(path, "url"); @@ -870,14 +873,14 @@ function genericPrint(path, options, print) { node.groups[0].groups[0].value.startsWith("data:"))) ) { return [ - node.open ? print("open") : "", - join(",", path.map(print, "groups")), - node.close ? print("close") : "", + node.open ? await print("open") : "", + join(",", await path.map(print, "groups")), + node.close ? await print("close") : "", ]; } if (!node.open) { - const printed = path.map(print, "groups"); + const printed = await path.map(print, "groups"); const res = []; for (let i = 0; i < printed.length; i++) { @@ -902,15 +905,15 @@ function genericPrint(path, options, print) { const printed = group( [ - node.open ? print("open") : "", + node.open ? await print("open") : "", indent([ softline, join( [line], - path.map((childPath, index) => { + await path.map(async (childPath, index) => { const child = childPath.getValue(); const isLast = index === node.groups.length - 1; - const printed = [print(), isLast ? "" : ","]; + const printed = [await print(), isLast ? "" : ","]; // Key/Value pair in open paren already indented if ( @@ -954,7 +957,7 @@ function genericPrint(path, options, print) { : "" ), softline, - node.close ? print("close") : "", + node.close ? await print("close") : "", ], { shouldBreak, @@ -969,7 +972,7 @@ function genericPrint(path, options, print) { insideAtRuleNode(path, "supports") && isMediaAndSupportsKeywords(node) ? " " : "", - print("group"), + await print("group"), ]; } case "value-paren": { @@ -1030,9 +1033,9 @@ function genericPrint(path, options, print) { } } -function printNodeSequence(path, options, print) { +async function printNodeSequence(path, options, print) { const parts = []; - path.each((pathChild, i, nodes) => { + await path.each(async (pathChild, i, nodes) => { const prevNode = nodes[i - 1]; if ( prevNode && @@ -1044,7 +1047,7 @@ function printNodeSequence(path, options, print) { options.originalText.slice(locStart(childNode), locEnd(childNode)) ); } else { - parts.push(print()); + parts.push(await print()); } if (i !== nodes.length - 1) { diff --git a/src/language-graphql/printer-graphql.js b/src/language-graphql/printer-graphql.js index c9be434af..aa43f167e 100644 --- a/src/language-graphql/printer-graphql.js +++ b/src/language-graphql/printer-graphql.js @@ -11,7 +11,7 @@ import { isNextLineEmpty, isNonEmptyArray } from "../common/util.js"; import { insertPragma } from "./pragma.js"; import { locStart, locEnd } from "./loc.js"; -function genericPrint(path, options, print) { +async function genericPrint(path, options, print) { const node = path.getValue(); if (!node) { return ""; @@ -24,8 +24,8 @@ function genericPrint(path, options, print) { switch (node.kind) { case "Document": { const parts = []; - path.each((pathChild, index, definitions) => { - parts.push(print()); + await path.each(async (pathChild, index, definitions) => { + parts.push(await print()); if (index !== definitions.length - 1) { parts.push(hardline); if ( @@ -42,7 +42,7 @@ function genericPrint(path, options, print) { const hasName = Boolean(node.name); return [ hasOperation ? node.operation : "", - hasOperation && hasName ? [" ", print("name")] : "", + hasOperation && hasName ? [" ", await print("name")] : "", hasOperation && !hasName && isNonEmptyArray(node.variableDefinitions) ? " " : "", @@ -53,22 +53,22 @@ function genericPrint(path, options, print) { softline, join( [ifBreak("", ", "), softline], - path.map(print, "variableDefinitions") + await path.map(print, "variableDefinitions") ), ]), softline, ")", ]) : "", - printDirectives(path, print, node), + await printDirectives(path, print, node), node.selectionSet ? (!hasOperation && !hasName ? "" : " ") : "", - print("selectionSet"), + await print("selectionSet"), ]; } case "FragmentDefinition": { return [ "fragment ", - print("name"), + await print("name"), isNonEmptyArray(node.variableDefinitions) ? group([ "(", @@ -76,7 +76,7 @@ function genericPrint(path, options, print) { softline, join( [ifBreak("", ", "), softline], - path.map(print, "variableDefinitions") + await path.map(print, "variableDefinitions") ), ]), softline, @@ -84,10 +84,10 @@ function genericPrint(path, options, print) { ]) : "", " on ", - print("typeCondition"), - printDirectives(path, print, node), + await print("typeCondition"), + await printDirectives(path, print, node), " ", - print("selectionSet"), + await print("selectionSet"), ]; } case "SelectionSet": { @@ -95,7 +95,10 @@ function genericPrint(path, options, print) { "{", indent([ hardline, - join(hardline, printSequence(path, options, print, "selections")), + join( + hardline, + await printSequence(path, options, print, "selections") + ), ]), hardline, "}", @@ -103,8 +106,8 @@ function genericPrint(path, options, print) { } case "Field": { return group([ - node.alias ? [print("alias"), ": "] : "", - print("name"), + node.alias ? [await print("alias"), ": "] : "", + await print("name"), node.arguments.length > 0 ? group([ "(", @@ -112,16 +115,16 @@ function genericPrint(path, options, print) { softline, join( [ifBreak("", ", "), softline], - printSequence(path, options, print, "arguments") + await printSequence(path, options, print, "arguments") ), ]), softline, ")", ]) : "", - printDirectives(path, print, node), + await printDirectives(path, print, node), node.selectionSet ? " " : "", - print("selectionSet"), + await print("selectionSet"), ]); } case "Name": { @@ -158,14 +161,14 @@ function genericPrint(path, options, print) { return "null"; } case "Variable": { - return ["$", print("name")]; + return ["$", await print("name")]; } case "ListValue": { return group([ "[", indent([ softline, - join([ifBreak("", ", "), softline], path.map(print, "values")), + join([ifBreak("", ", "), softline], await path.map(print, "values")), ]), softline, "]", @@ -177,7 +180,7 @@ function genericPrint(path, options, print) { options.bracketSpacing && node.fields.length > 0 ? " " : "", indent([ softline, - join([ifBreak("", ", "), softline], path.map(print, "fields")), + join([ifBreak("", ", "), softline], await path.map(print, "fields")), ]), softline, ifBreak( @@ -189,13 +192,13 @@ function genericPrint(path, options, print) { } case "ObjectField": case "Argument": { - return [print("name"), ": ", print("value")]; + return [await print("name"), ": ", await print("value")]; } case "Directive": { return [ "@", - print("name"), + await print("name"), node.arguments.length > 0 ? group([ "(", @@ -203,7 +206,7 @@ function genericPrint(path, options, print) { softline, join( [ifBreak("", ", "), softline], - printSequence(path, options, print, "arguments") + await printSequence(path, options, print, "arguments") ), ]), softline, @@ -219,32 +222,35 @@ function genericPrint(path, options, print) { case "VariableDefinition": { return [ - print("variable"), + await print("variable"), ": ", - print("type"), - node.defaultValue ? [" = ", print("defaultValue")] : "", - printDirectives(path, print, node), + await print("type"), + node.defaultValue ? [" = ", await print("defaultValue")] : "", + await printDirectives(path, print, node), ]; } case "ObjectTypeExtension": case "ObjectTypeDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", node.kind === "ObjectTypeExtension" ? "extend " : "", "type ", - print("name"), + await print("name"), node.interfaces.length > 0 - ? [" implements ", ...printInterfaces(path, options, print)] + ? [" implements ", ...(await printInterfaces(path, options, print))] : "", - printDirectives(path, print, node), + await printDirectives(path, print, node), node.fields.length > 0 ? [ " {", indent([ hardline, - join(hardline, printSequence(path, options, print, "fields")), + join( + hardline, + await printSequence(path, options, print, "fields") + ), ]), hardline, "}", @@ -255,9 +261,9 @@ function genericPrint(path, options, print) { case "FieldDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", - print("name"), + await print("name"), node.arguments.length > 0 ? group([ "(", @@ -265,7 +271,7 @@ function genericPrint(path, options, print) { softline, join( [ifBreak("", ", "), softline], - printSequence(path, options, print, "arguments") + await printSequence(path, options, print, "arguments") ), ]), softline, @@ -273,18 +279,18 @@ function genericPrint(path, options, print) { ]) : "", ": ", - print("type"), - printDirectives(path, print, node), + await print("type"), + await printDirectives(path, print, node), ]; } case "DirectiveDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", "directive ", "@", - print("name"), + await print("name"), node.arguments.length > 0 ? group([ "(", @@ -292,7 +298,7 @@ function genericPrint(path, options, print) { softline, join( [ifBreak("", ", "), softline], - printSequence(path, options, print, "arguments") + await printSequence(path, options, print, "arguments") ), ]), softline, @@ -301,26 +307,29 @@ function genericPrint(path, options, print) { : "", node.repeatable ? " repeatable" : "", " on ", - join(" | ", path.map(print, "locations")), + join(" | ", await path.map(print, "locations")), ]; } case "EnumTypeExtension": case "EnumTypeDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", node.kind === "EnumTypeExtension" ? "extend " : "", "enum ", - print("name"), - printDirectives(path, print, node), + await print("name"), + await printDirectives(path, print, node), node.values.length > 0 ? [ " {", indent([ hardline, - join(hardline, printSequence(path, options, print, "values")), + join( + hardline, + await printSequence(path, options, print, "values") + ), ]), hardline, "}", @@ -331,40 +340,43 @@ function genericPrint(path, options, print) { case "EnumValueDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", - print("name"), - printDirectives(path, print, node), + await print("name"), + await printDirectives(path, print, node), ]; } case "InputValueDefinition": { return [ - print("description"), + await print("description"), node.description ? (node.description.block ? hardline : line) : "", - print("name"), + await print("name"), ": ", - print("type"), - node.defaultValue ? [" = ", print("defaultValue")] : "", - printDirectives(path, print, node), + await print("type"), + node.defaultValue ? [" = ", await print("defaultValue")] : "", + await printDirectives(path, print, node), ]; } case "InputObjectTypeExtension": case "InputObjectTypeDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", node.kind === "InputObjectTypeExtension" ? "extend " : "", "input ", - print("name"), - printDirectives(path, print, node), + await print("name"), + await printDirectives(path, print, node), node.fields.length > 0 ? [ " {", indent([ hardline, - join(hardline, printSequence(path, options, print, "fields")), + join( + hardline, + await printSequence(path, options, print, "fields") + ), ]), hardline, "}", @@ -376,7 +388,7 @@ function genericPrint(path, options, print) { case "SchemaExtension": { return [ "extend schema", - printDirectives(path, print, node), + await printDirectives(path, print, node), ...(node.operationTypes.length > 0 ? [ " {", @@ -384,7 +396,7 @@ function genericPrint(path, options, print) { hardline, join( hardline, - printSequence(path, options, print, "operationTypes") + await printSequence(path, options, print, "operationTypes") ), ]), hardline, @@ -395,17 +407,17 @@ function genericPrint(path, options, print) { } case "SchemaDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", "schema", - printDirectives(path, print, node), + await printDirectives(path, print, node), " {", node.operationTypes.length > 0 ? indent([ hardline, join( hardline, - printSequence(path, options, print, "operationTypes") + await printSequence(path, options, print, "operationTypes") ), ]) : "", @@ -415,27 +427,30 @@ function genericPrint(path, options, print) { } case "OperationTypeDefinition": { - return [print("operation"), ": ", print("type")]; + return [await print("operation"), ": ", await print("type")]; } case "InterfaceTypeExtension": case "InterfaceTypeDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", node.kind === "InterfaceTypeExtension" ? "extend " : "", "interface ", - print("name"), + await print("name"), node.interfaces.length > 0 - ? [" implements ", ...printInterfaces(path, options, print)] + ? [" implements ", ...(await printInterfaces(path, options, print))] : "", - printDirectives(path, print, node), + await printDirectives(path, print, node), node.fields.length > 0 ? [ " {", indent([ hardline, - join(hardline, printSequence(path, options, print, "fields")), + join( + hardline, + await printSequence(path, options, print, "fields") + ), ]), hardline, "}", @@ -445,36 +460,40 @@ function genericPrint(path, options, print) { } case "FragmentSpread": { - return ["...", print("name"), printDirectives(path, print, node)]; + return [ + "...", + await print("name"), + await printDirectives(path, print, node), + ]; } case "InlineFragment": { return [ "...", - node.typeCondition ? [" on ", print("typeCondition")] : "", - printDirectives(path, print, node), + node.typeCondition ? [" on ", await print("typeCondition")] : "", + await printDirectives(path, print, node), " ", - print("selectionSet"), + await print("selectionSet"), ]; } case "UnionTypeExtension": case "UnionTypeDefinition": { return group([ - print("description"), + await print("description"), node.description ? hardline : "", group([ node.kind === "UnionTypeExtension" ? "extend " : "", "union ", - print("name"), - printDirectives(path, print, node), + await print("name"), + await printDirectives(path, print, node), node.types.length > 0 ? [ " =", ifBreak("", " "), indent([ ifBreak([line, " "]), - join([line, "| "], path.map(print, "types")), + join([line, "| "], await path.map(print, "types")), ]), ] : "", @@ -485,21 +504,21 @@ function genericPrint(path, options, print) { case "ScalarTypeExtension": case "ScalarTypeDefinition": { return [ - print("description"), + await print("description"), node.description ? hardline : "", node.kind === "ScalarTypeExtension" ? "extend " : "", "scalar ", - print("name"), - printDirectives(path, print, node), + await print("name"), + await printDirectives(path, print, node), ]; } case "NonNullType": { - return [print("type"), "!"]; + return [await print("type"), "!"]; } case "ListType": { - return ["[", print("type"), "]"]; + return ["[", await print("type"), "]"]; } default: @@ -508,12 +527,12 @@ function genericPrint(path, options, print) { } } -function printDirectives(path, print, node) { +async function printDirectives(path, print, node) { if (node.directives.length === 0) { return ""; } - const printed = join(line, path.map(print, "directives")); + const printed = join(line, await path.map(print, "directives")); if ( node.kind === "FragmentDefinition" || @@ -526,8 +545,8 @@ function printDirectives(path, print, node) { } function printSequence(path, options, print, property) { - return path.map((path, index, sequence) => { - const printed = print(); + return path.map(async (path, index, sequence) => { + const printed = await print(); if ( index < sequence.length - 1 && @@ -554,11 +573,11 @@ function printComment(commentPath) { throw new Error("Not a comment: " + JSON.stringify(comment)); } -function printInterfaces(path, options, print) { +async function printInterfaces(path, options, print) { const node = path.getNode(); const parts = []; const { interfaces } = node; - const printed = path.map((node) => print(node), "interfaces"); + const printed = await path.map((node) => print(node), "interfaces"); for (let index = 0; index < interfaces.length; index++) { const interfaceNode = interfaces[index]; diff --git a/src/language-handlebars/printer-glimmer.js b/src/language-handlebars/printer-glimmer.js index 9592bc64c..d42ab1cc4 100644 --- a/src/language-handlebars/printer-glimmer.js +++ b/src/language-handlebars/printer-glimmer.js @@ -31,7 +31,7 @@ const NEWLINES_TO_PRESERVE_MAX = 2; // Formatter based on @glimmerjs/syntax's built-in test formatter: // https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/syntax/lib/generation/print.ts -function print(path, options, print) { +async function print(path, options, print) { const node = path.getValue(); /* istanbul ignore if*/ @@ -49,11 +49,11 @@ function print(path, options, print) { case "Block": case "Program": case "Template": { - return group(path.map(print, "body")); + return group(await path.map(print, "body")); } case "ElementNode": { - const startingTag = group(printStartingTag(path, print)); + const startingTag = group(await printStartingTag(path, print)); const escapeNextElementNode = options.htmlWhitespaceSensitivity === "ignore" && @@ -74,7 +74,7 @@ function print(path, options, print) { if (options.htmlWhitespaceSensitivity === "ignore") { return [ startingTag, - indent(printChildren(path, options, print)), + indent(await printChildren(path, options, print)), hardline, indent(endingTag), escapeNextElementNode, @@ -83,7 +83,7 @@ function print(path, options, print) { return [ startingTag, - indent(group(printChildren(path, options, print))), + indent(group(await printChildren(path, options, print))), indent(endingTag), escapeNextElementNode, ]; @@ -101,30 +101,30 @@ function print(path, options, print) { if (isElseIf) { return [ - printElseIfBlock(path, print), - printProgram(path, print, options), - printInverse(path, print, options), + await printElseIfBlock(path, print), + await printProgram(path, print, options), + await printInverse(path, print, options), ]; } return [ - printOpenBlock(path, print), + await printOpenBlock(path, print), group([ - printProgram(path, print, options), - printInverse(path, print, options), - printCloseBlock(path, print, options), + await printProgram(path, print, options), + await printInverse(path, print, options), + await printCloseBlock(path, print, options), ]), ]; } case "ElementModifierStatement": { - return group(["{{", printPathAndParams(path, print), "}}"]); + return group(["{{", await printPathAndParams(path, print), "}}"]); } case "MustacheStatement": { return group([ printOpeningMustache(node), - printPathAndParams(path, print), + await printPathAndParams(path, print), printClosingMustache(node), ]); } @@ -132,7 +132,7 @@ function print(path, options, print) { case "SubExpression": { return group([ "(", - printSubExpressionPathAndParams(path, print), + await printSubExpressionPathAndParams(path, print), softline, ")", ]); @@ -162,7 +162,7 @@ function print(path, options, print) { ).quote : ""; - const valueDoc = print("value"); + const valueDoc = await print("value"); return [ node.name, @@ -178,10 +178,10 @@ function print(path, options, print) { } case "Hash": { - return join(line, path.map(print, "pairs")); + return join(line, await path.map(print, "pairs")); } case "HashPair": { - return [node.key, "=", print("value")]; + return [node.key, "=", await print("value")]; } case "TextNode": { /* if `{{my-component}}` (or any text containing "{{") @@ -423,7 +423,7 @@ function sortByLoc(a, b) { return locStart(a) - locStart(b); } -function printStartingTag(path, print) { +async function printStartingTag(path, print) { const node = path.getValue(); const types = ["attributes", "modifiers", "comments"].filter((property) => @@ -432,9 +432,9 @@ function printStartingTag(path, print) { const attributes = types.flatMap((type) => node[type]).sort(sortByLoc); for (const attributeType of types) { - path.each((attributePath) => { + await path.each(async (attributePath) => { const index = attributes.indexOf(attributePath.getValue()); - attributes.splice(index, 1, [line, print()]); + attributes.splice(index, 1, [line, await print()]); }, attributeType); } @@ -452,8 +452,8 @@ function printChildren(path, options, print) { return ""; } - return path.map((childPath, childIndex) => { - const printedChild = print(); + return path.map(async (childPath, childIndex) => { + const printedChild = await print(); if (childIndex === 0 && options.htmlWhitespaceSensitivity === "ignore") { return [softline, printedChild]; @@ -523,15 +523,15 @@ function printInverseBlockClosingMustache(node) { return [strip, closing]; } -function printOpenBlock(path, print) { +async function printOpenBlock(path, print) { const node = path.getValue(); const openingMustache = printOpeningBlockOpeningMustache(node); const closingMustache = printOpeningBlockClosingMustache(node); - const attributes = [printPath(path, print)]; + const attributes = [await printPath(path, print)]; - const params = printParams(path, print); + const params = await printParams(path, print); if (params) { attributes.push(line, params); } @@ -558,18 +558,18 @@ function printElseBlock(node, options) { ]; } -function printElseIfBlock(path, print) { +async function printElseIfBlock(path, print) { const parentNode = path.getParentNode(1); return [ printInverseBlockOpeningMustache(parentNode), "else if ", - printParams(path, print), + await printParams(path, print), printInverseBlockClosingMustache(parentNode), ]; } -function printCloseBlock(path, print, options) { +async function printCloseBlock(path, print, options) { const node = path.getValue(); if (options.htmlWhitespaceSensitivity === "ignore") { @@ -580,14 +580,14 @@ function printCloseBlock(path, print, options) { return [ escape, printClosingBlockOpeningMustache(node), - print("path"), + await print("path"), printClosingBlockClosingMustache(node), ]; } return [ printClosingBlockOpeningMustache(node), - print("path"), + await print("path"), printClosingBlockClosingMustache(node), ]; } @@ -612,14 +612,14 @@ function blockStatementHasElse(node) { return isNodeOfSomeType(node, ["BlockStatement"]) && node.inverse; } -function printProgram(path, print, options) { +async function printProgram(path, print, options) { const node = path.getValue(); if (blockStatementHasOnlyWhitespaceInProgram(node)) { return ""; } - const program = print("program"); + const program = await print("program"); if (options.htmlWhitespaceSensitivity === "ignore") { return indent([hardline, program]); @@ -628,10 +628,10 @@ function printProgram(path, print, options) { return indent(program); } -function printInverse(path, print, options) { +async function printInverse(path, print, options) { const node = path.getValue(); - const inverse = print("inverse"); + const inverse = await print("inverse"); const printed = options.htmlWhitespaceSensitivity === "ignore" ? [hardline, inverse] @@ -730,9 +730,9 @@ function needsOppositeQuote(path) { /* SubExpression print helpers */ -function printSubExpressionPathAndParams(path, print) { - const printed = printPath(path, print); - const params = printParams(path, print); +async function printSubExpressionPathAndParams(path, print) { + const printed = await printPath(path, print); + const params = await printParams(path, print); if (!params) { return printed; @@ -743,9 +743,9 @@ function printSubExpressionPathAndParams(path, print) { /* misc. print helpers */ -function printPathAndParams(path, print) { - const p = printPath(path, print); - const params = printParams(path, print); +async function printPathAndParams(path, print) { + const p = await printPath(path, print); + const params = await printParams(path, print); if (!params) { return p; @@ -758,17 +758,17 @@ function printPath(path, print) { return print("path"); } -function printParams(path, print) { +async function printParams(path, print) { const node = path.getValue(); const parts = []; if (node.params.length > 0) { - const params = path.map(print, "params"); + const params = await path.map(print, "params"); parts.push(...params); } if (node.hash && node.hash.pairs.length > 0) { - const hash = print("hash"); + const hash = await print("hash"); parts.push(hash); } diff --git a/src/language-html/embed.js b/src/language-html/embed.js index cce5b770c..30affc4ab 100644 --- a/src/language-html/embed.js +++ b/src/language-html/embed.js @@ -35,7 +35,7 @@ import { } from "./utils/index.js"; import getNodeContent from "./get-node-content.js"; -function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { +async function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { const isKeyMatched = (patterns) => new RegExp(patterns.join("|")).test(node.fullName); const getValue = () => unescapeQuoteEntities(node.value); @@ -95,7 +95,7 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { const value = getValue(); if (!value.includes("{{")) { return printExpand( - attributeTextToDoc(value, { + await attributeTextToDoc(value, { parser: "css", __isHTMLStyleAttribute: true, }) @@ -137,7 +137,7 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { ? "__vue_ts_event_binding" : "__vue_event_binding"; return printMaybeHug( - attributeTextToDoc(value, { + await attributeTextToDoc(value, { parser, }) ); @@ -145,13 +145,13 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { if (isKeyMatched(vueExpressionBindingPatterns)) { return printMaybeHug( - attributeTextToDoc(getValue(), { parser: "__vue_expression" }) + await attributeTextToDoc(getValue(), { parser: "__vue_expression" }) ); } if (isKeyMatched(jsExpressionBindingPatterns)) { return printMaybeHug( - attributeTextToDoc(getValue(), { parser: "__js_expression" }) + await attributeTextToDoc(getValue(), { parser: "__js_expression" }) ); } } @@ -189,11 +189,15 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { const ngI18nPatterns = ["^i18n(-.+)?$"]; if (isKeyMatched(ngStatementBindingPatterns)) { - return printMaybeHug(ngTextToDoc(getValue(), { parser: "__ng_action" })); + return printMaybeHug( + await ngTextToDoc(getValue(), { parser: "__ng_action" }) + ); } if (isKeyMatched(ngExpressionBindingPatterns)) { - return printMaybeHug(ngTextToDoc(getValue(), { parser: "__ng_binding" })); + return printMaybeHug( + await ngTextToDoc(getValue(), { parser: "__ng_binding" }) + ); } if (isKeyMatched(ngI18nPatterns)) { @@ -206,7 +210,7 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { if (isKeyMatched(ngDirectiveBindingPatterns)) { return printMaybeHug( - ngTextToDoc(getValue(), { parser: "__ng_directive" }) + await ngTextToDoc(getValue(), { parser: "__ng_directive" }) ); } @@ -224,7 +228,7 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { "{{", indent([ line, - ngTextToDoc(part, { + await ngTextToDoc(part, { parser: "__ng_interpolation", __isInHtmlInterpolation: true, // to avoid unexpected `}}` }), @@ -245,7 +249,7 @@ function printEmbeddedAttributeValue(node, htmlTextToDoc, options) { return null; } -function embed(path, print, textToDoc, options) { +async function embed(path, print, textToDoc, options) { const node = path.getValue(); switch (node.type) { @@ -265,7 +269,7 @@ function embed(path, print, textToDoc, options) { let isEmpty = /^\s*$/.test(content); let doc = ""; if (!isEmpty) { - doc = textToDoc( + doc = await textToDoc( htmlTrimPreserveIndentation(content), { parser, __embeddedInHtml: true }, { stripTrailingHardline: true } @@ -275,7 +279,7 @@ function embed(path, print, textToDoc, options) { return [ printOpeningTagPrefix(node, options), - group(printOpeningTag(path, options, print)), + group(await printOpeningTag(path, options, print)), isEmpty ? "" : hardline, doc, isEmpty ? "" : hardline, @@ -310,7 +314,7 @@ function embed(path, print, textToDoc, options) { return [ breakParent, printOpeningTagPrefix(node, options), - textToDoc(value, textToDocOptions, { + await textToDoc(value, textToDocOptions, { stripTrailingHardline: true, }), printClosingTagSuffix(node, options), @@ -334,7 +338,7 @@ function embed(path, print, textToDoc, options) { return [ indent([ line, - textToDoc(node.value, textToDocOptions, { + await textToDoc(node.value, textToDocOptions, { stripTrailingHardline: true, }), ]), @@ -378,7 +382,7 @@ function embed(path, print, textToDoc, options) { } } - const embeddedAttributeValueDoc = printEmbeddedAttributeValue( + const embeddedAttributeValueDoc = await printEmbeddedAttributeValue( node, (code, opts) => // strictly prefer single quote to avoid unnecessary html entity escape diff --git a/src/language-html/print/children.js b/src/language-html/print/children.js index 2e5bf1e60..6fd0c3e8a 100644 --- a/src/language-html/print/children.js +++ b/src/language-html/print/children.js @@ -110,14 +110,14 @@ function printBetweenLine(prevNode, nextNode) { : softline; } -function printChildren(path, options, print) { +async function printChildren(path, options, print) { const node = path.getValue(); if (forceBreakChildren(node)) { return [ breakParent, - ...path.map((childPath) => { + ...(await path.map(async (childPath) => { const childNode = childPath.getValue(); const prevBetweenLine = !childNode.prev ? "" @@ -129,14 +129,14 @@ function printChildren(path, options, print) { prevBetweenLine, forceNextEmptyLine(childNode.prev) ? hardline : "", ], - printChild(childPath, options, print), + await printChild(childPath, options, print), ]; - }, "children"), + }, "children")), ]; } const groupIds = node.children.map(() => Symbol("")); - return path.map((childPath, childIndex) => { + return path.map(async (childPath, childIndex) => { const childNode = childPath.getValue(); if (isTextLikeNode(childNode)) { @@ -144,9 +144,13 @@ function printChildren(path, options, print) { const prevBetweenLine = printBetweenLine(childNode.prev, childNode); if (prevBetweenLine) { if (forceNextEmptyLine(childNode.prev)) { - return [hardline, hardline, printChild(childPath, options, print)]; + return [ + hardline, + hardline, + await printChild(childPath, options, print), + ]; } - return [prevBetweenLine, printChild(childPath, options, print)]; + return [prevBetweenLine, await printChild(childPath, options, print)]; } } return printChild(childPath, options, print); @@ -201,7 +205,7 @@ function printChildren(path, options, print) { ...prevParts, group([ ...leadingParts, - group([printChild(childPath, options, print), ...trailingParts], { + group([await printChild(childPath, options, print), ...trailingParts], { id: groupIds[childIndex], }), ]), diff --git a/src/language-html/print/element.js b/src/language-html/print/element.js index 0894227ea..c67c64b8e 100644 --- a/src/language-html/print/element.js +++ b/src/language-html/print/element.js @@ -27,15 +27,15 @@ import { } from "./tag.js"; import { printChildren } from "./children.js"; -function printElement(path, options, print) { +async function printElement(path, options, print) { const node = path.getValue(); if (shouldPreserveContent(node, options)) { return [ printOpeningTagPrefix(node, options), - group(printOpeningTag(path, options, print)), + group(await printOpeningTag(path, options, print)), ...replaceTextEndOfLine(getNodeContent(node, options)), - ...printClosingTag(node, options), + ...(await printClosingTag(node, options)), printClosingTagSuffix(node, options), ]; } @@ -69,9 +69,9 @@ function printElement(path, options, print) { const attrGroupId = Symbol("element-attr-group-id"); - const printTag = (doc) => + const printTag = async (doc) => group([ - group(printOpeningTag(path, options, print), { id: attrGroupId }), + group(await printOpeningTag(path, options, print), { id: attrGroupId }), doc, printClosingTag(node, options), ]); @@ -163,7 +163,7 @@ function printElement(path, options, print) { forceBreakContent(node) ? breakParent : "", printChildrenDoc([ printLineBeforeChildren(), - printChildren(path, options, print), + await printChildren(path, options, print), ]), printLineAfterChildren(), ]); diff --git a/src/language-html/print/tag.js b/src/language-html/print/tag.js index c1f112670..d0b52204a 100644 --- a/src/language-html/print/tag.js +++ b/src/language-html/print/tag.js @@ -213,7 +213,7 @@ function needsToBorrowParentOpeningTagEndMarker(node) { return !node.prev && node.isLeadingSpaceSensitive && !node.hasLeadingSpaces; } -function printAttributes(path, options, print) { +async function printAttributes(path, options, print) { const node = path.getValue(); if (!isNonEmptyArray(node.attrs)) { @@ -238,7 +238,7 @@ function printAttributes(path, options, print) { ? (attribute) => ignoreAttributeData.includes(attribute.rawName) : () => false; - const printedAttributes = path.map((attributePath) => { + const printedAttributes = await path.map((attributePath) => { const attribute = attributePath.getValue(); return hasPrettierIgnoreAttribute(attribute) ? replaceTextEndOfLine( @@ -310,12 +310,12 @@ function printOpeningTagEnd(node) { : printOpeningTagEndMarker(node); } -function printOpeningTag(path, options, print) { +async function printOpeningTag(path, options, print) { const node = path.getValue(); return [ printOpeningTagStart(node, options), - printAttributes(path, options, print), + await printAttributes(path, options, print), node.isSelfClosing ? "" : printOpeningTagEnd(node), ]; } diff --git a/src/language-html/printer-html.js b/src/language-html/printer-html.js index 0d46cfd3a..55ae5162e 100644 --- a/src/language-html/printer-html.js +++ b/src/language-html/printer-html.js @@ -28,7 +28,7 @@ import { import { printElement } from "./print/element.js"; import { printChildren } from "./print/children.js"; -function genericPrint(path, options, print) { +async function genericPrint(path, options, print) { const node = path.getValue(); switch (node.type) { @@ -39,7 +39,7 @@ function genericPrint(path, options, print) { options.__onHtmlRoot(node); } // use original concat to not break stripTrailingHardline - return [group(printChildren(path, options, print)), hardline]; + return [group(await printChildren(path, options, print)), hardline]; case "element": case "ieConditionalComment": { return printElement(path, options, print); @@ -50,7 +50,7 @@ function genericPrint(path, options, print) { case "interpolation": return [ printOpeningTagStart(node, options), - ...path.map(print, "children"), + ...(await path.map(print, "children")), printClosingTagEnd(node, options), ]; case "text": { diff --git a/src/language-html/syntax-vue.js b/src/language-html/syntax-vue.js index 82395f889..901b57511 100644 --- a/src/language-html/syntax-vue.js +++ b/src/language-html/syntax-vue.js @@ -6,11 +6,11 @@ import { group } from "../document/builders.js"; * v-for="(..., ...) in ..." * v-for="(..., ...) of ..." */ -function printVueFor(value, textToDoc) { +async function printVueFor(value, attributeTextToDoc) { const { left, operator, right } = parseVueFor(value); return [ group( - textToDoc(`function _(${left}) {}`, { + await attributeTextToDoc(`function _(${left}) {}`, { parser: "babel", __isVueForBindingLeft: true, }) @@ -18,7 +18,7 @@ function printVueFor(value, textToDoc) { " ", operator, " ", - textToDoc( + await attributeTextToDoc( right, { parser: "__js_expression" }, { stripTrailingHardline: true } @@ -72,8 +72,8 @@ function parseVueFor(value) { }; } -function printVueBindings(value, textToDoc) { - return textToDoc(`function _(${value}) {}`, { +function printVueBindings(value, attributeTextToDoc) { + return attributeTextToDoc(`function _(${value}) {}`, { parser: "babel", __isVueBindings: true, }); diff --git a/src/language-js/embed/css.js b/src/language-js/embed/css.js index 8f1c1a1e5..3aeeacab8 100644 --- a/src/language-js/embed/css.js +++ b/src/language-js/embed/css.js @@ -3,7 +3,7 @@ import { indent, hardline, softline } from "../../document/builders.js"; import { mapDoc, replaceEndOfLine, cleanDoc } from "../../document/utils.js"; import { printTemplateExpressions } from "../print/template-literal.js"; -function format(path, print, textToDoc) { +async function format(path, print, textToDoc) { const node = path.getValue(); // Get full template literal with expressions replaced by placeholders @@ -20,12 +20,12 @@ function format(path, print, textToDoc) { currVal, "" ); - const doc = textToDoc( + const doc = await textToDoc( text, { parser: "scss" }, { stripTrailingHardline: true } ); - const expressionDocs = printTemplateExpressions(path, print); + const expressionDocs = await printTemplateExpressions(path, print); return transformCssDoc(doc, node, expressionDocs); } diff --git a/src/language-js/embed/graphql.js b/src/language-js/embed/graphql.js index d8a484341..476bd877f 100644 --- a/src/language-js/embed/graphql.js +++ b/src/language-js/embed/graphql.js @@ -4,7 +4,7 @@ import { printTemplateExpressions, } from "../print/template-literal.js"; -function format(path, print, textToDoc) { +async function format(path, print, textToDoc) { const node = path.getValue(); const numQuasis = node.quasis.length; @@ -12,7 +12,7 @@ function format(path, print, textToDoc) { return "``"; } - const expressionDocs = printTemplateExpressions(path, print); + const expressionDocs = await printTemplateExpressions(path, print); const parts = []; for (let i = 0; i < numQuasis; i++) { @@ -46,7 +46,7 @@ function format(path, print, textToDoc) { if (commentsAndWhitespaceOnly) { doc = printGraphqlComments(lines); } else { - doc = textToDoc( + doc = await textToDoc( text, { parser: "graphql" }, { stripTrailingHardline: true } diff --git a/src/language-js/embed/html.js b/src/language-js/embed/html.js index e2b9e4028..2fe0df5b9 100644 --- a/src/language-js/embed/html.js +++ b/src/language-js/embed/html.js @@ -7,7 +7,7 @@ import { // The counter is needed to distinguish nested embeds. let htmlTemplateLiteralCounter = 0; -function format(path, print, textToDoc, options, { parser }) { +async function format(path, print, textToDoc, options, { parser }) { const node = path.getValue(); const counter = htmlTemplateLiteralCounter; htmlTemplateLiteralCounter = (htmlTemplateLiteralCounter + 1) >>> 0; @@ -23,14 +23,14 @@ function format(path, print, textToDoc, options, { parser }) { ) .join(""); - const expressionDocs = printTemplateExpressions(path, print); + const expressionDocs = await printTemplateExpressions(path, print); if (expressionDocs.length === 0 && text.trim().length === 0) { return "``"; } const placeholderRegex = new RegExp(composePlaceholder("(\\d+)"), "g"); let topLevelCount = 0; - const doc = textToDoc( + const doc = await textToDoc( text, { parser, diff --git a/src/language-js/embed/markdown.js b/src/language-js/embed/markdown.js index 636ffda39..2039165b1 100644 --- a/src/language-js/embed/markdown.js +++ b/src/language-js/embed/markdown.js @@ -6,7 +6,7 @@ import { } from "../../document/builders.js"; import { escapeTemplateCharacters } from "../print/template-literal.js"; -function format(path, print, textToDoc) { +async function format(path, print, textToDoc) { const node = path.getValue(); let text = node.quasis[0].value.raw.replace( /((?:\\\\)*)\\`/g, @@ -18,7 +18,7 @@ function format(path, print, textToDoc) { text = text.replace(new RegExp(`^${indentation}`, "gm"), ""); } const doc = escapeTemplateCharacters( - textToDoc( + await textToDoc( text, { parser: "markdown", __inJsTemplate: true }, { stripTrailingHardline: true } diff --git a/src/language-js/print/angular.js b/src/language-js/print/angular.js index 8cb4fe5c6..abd1927e1 100644 --- a/src/language-js/print/angular.js +++ b/src/language-js/print/angular.js @@ -4,7 +4,7 @@ import { printBinaryishExpression } from "./binaryish.js"; /** @typedef {import("../../common/ast-path.js").default} AstPath */ -function printAngular(path, options, print) { +async function printAngular(path, options, print) { const node = path.getValue(); // Angular nodes always starts with `NG` @@ -15,7 +15,7 @@ function printAngular(path, options, print) { switch (node.type) { case "NGRoot": return [ - print("node"), + await print("node"), !hasComment(node.node) ? "" : " //" + getComments(node.node)[0].value.trimEnd(), @@ -26,9 +26,9 @@ function printAngular(path, options, print) { return group( join( [";", line], - path.map( - (childPath) => - hasNgSideEffect(childPath) ? print() : ["(", print(), ")"], + await path.map( + async (childPath) => + hasNgSideEffect(childPath) ? print() : ["(", await print(), ")"], "expressions" ) ) @@ -39,13 +39,13 @@ function printAngular(path, options, print) { return [node.prefix, ": ", node.value.trim()]; case "NGMicrosyntax": return path.map( - (childPath, index) => [ + async (childPath, index) => [ index === 0 ? "" : isNgForOf(childPath.getValue(), index, node) ? " " : [";", line], - print(), + await print(), ], "body" ); @@ -55,8 +55,8 @@ function printAngular(path, options, print) { : JSON.stringify(node.name); case "NGMicrosyntaxExpression": return [ - print("expression"), - node.alias === null ? "" : [" as ", print("alias")], + await print("expression"), + node.alias === null ? "" : [" as ", await print("alias")], ]; case "NGMicrosyntaxKeyedExpression": { const index = path.getName(); @@ -72,19 +72,19 @@ function printAngular(path, options, print) { parentNode.body[index - 1].key.name === "then")) && parentNode.body[0].type === "NGMicrosyntaxExpression"); return [ - print("key"), + await print("key"), shouldNotPrintColon ? " " : ": ", - print("expression"), + await print("expression"), ]; } case "NGMicrosyntaxLet": return [ "let ", - print("key"), - node.value === null ? "" : [" = ", print("value")], + await print("key"), + node.value === null ? "" : [" = ", await print("value")], ]; case "NGMicrosyntaxAs": - return [print("key"), " as ", print("alias")]; + return [await print("key"), " as ", await print("alias")]; default: /* istanbul ignore next */ throw new Error( diff --git a/src/language-js/print/array.js b/src/language-js/print/array.js index 45a7c72bb..6247075e7 100644 --- a/src/language-js/print/array.js +++ b/src/language-js/print/array.js @@ -23,7 +23,7 @@ import { printOptionalToken, printTypeAnnotation } from "./misc.js"; /** @typedef {import("../../document/builders.js").Doc} Doc */ -function printArray(path, options, print) { +async function printArray(path, options, print) { const node = path.getValue(); /** @type{Doc[]} */ const parts = []; @@ -103,9 +103,14 @@ function printArray(path, options, print) { indent([ softline, shouldUseConciseFormatting - ? printArrayItemsConcisely(path, options, print, trailingComma) + ? await printArrayItemsConcisely( + path, + options, + print, + trailingComma + ) : [ - printArrayItems(path, options, "elements", print), + await printArrayItems(path, options, "elements", print), trailingComma, ], printDanglingComments(path, options, /* sameIndent */ true), @@ -120,7 +125,7 @@ function printArray(path, options, print) { parts.push( printOptionalToken(path), - printTypeAnnotation(path, options, print) + await printTypeAnnotation(path, options, print) ); return parts; @@ -146,12 +151,12 @@ function isConciselyPrintedArray(node, options) { ); } -function printArrayItems(path, options, printPath, print) { +async function printArrayItems(path, options, printPath, print) { const printedElements = []; let separatorParts = []; - path.each((childPath) => { - printedElements.push(separatorParts, group(print())); + await path.each(async (childPath) => { + printedElements.push(separatorParts, group(await print())); separatorParts = [",", line]; if ( @@ -165,13 +170,13 @@ function printArrayItems(path, options, printPath, print) { return printedElements; } -function printArrayItemsConcisely(path, options, print, trailingComma) { +async function printArrayItemsConcisely(path, options, print, trailingComma) { const parts = []; - path.each((childPath, i, elements) => { + await path.each(async (childPath, i, elements) => { const isLast = i === elements.length - 1; - parts.push([print(), isLast ? trailingComma : ","]); + parts.push([await print(), isLast ? trailingComma : ","]); if (!isLast) { parts.push( diff --git a/src/language-js/print/assignment.js b/src/language-js/print/assignment.js index 0fd328078..9efef3c87 100644 --- a/src/language-js/print/assignment.js +++ b/src/language-js/print/assignment.js @@ -24,7 +24,7 @@ import { import { shouldInlineLogicalExpression } from "./binaryish.js"; import { printCallExpression } from "./call-expression.js"; -function printAssignment( +async function printAssignment( path, options, print, @@ -32,9 +32,15 @@ function printAssignment( operator, rightPropertyName ) { - const layout = chooseLayout(path, options, print, leftDoc, rightPropertyName); + const layout = await chooseLayout( + path, + options, + print, + leftDoc, + rightPropertyName + ); - const rightDoc = print(rightPropertyName, { assignmentLayout: layout }); + const rightDoc = await print(rightPropertyName, { assignmentLayout: layout }); switch (layout) { // First break after operator, then the sides are broken independently on their own lines @@ -76,23 +82,23 @@ function printAssignment( } } -function printAssignmentExpression(path, options, print) { +async function printAssignmentExpression(path, options, print) { const node = path.getValue(); return printAssignment( path, options, print, - print("left"), + await print("left"), [" ", node.operator], "right" ); } -function printVariableDeclarator(path, options, print) { - return printAssignment(path, options, print, print("id"), " =", "init"); +async function printVariableDeclarator(path, options, print) { + return printAssignment(path, options, print, await print("id"), " =", "init"); } -function chooseLayout(path, options, print, leftDoc, rightPropertyName) { +async function chooseLayout(path, options, print, leftDoc, rightPropertyName) { const node = path.getValue(); const rightNode = node[rightPropertyName]; @@ -153,7 +159,7 @@ function chooseLayout(path, options, print, leftDoc, rightPropertyName) { const hasShortKey = isObjectPropertyWithShortKey(node, leftDoc, options); if ( - path.call( + await path.call( () => shouldBreakAfterOperator(path, options, print, hasShortKey), rightPropertyName ) @@ -175,7 +181,7 @@ function chooseLayout(path, options, print, leftDoc, rightPropertyName) { return "fluid"; } -function shouldBreakAfterOperator(path, options, print, hasShortKey) { +async function shouldBreakAfterOperator(path, options, print, hasShortKey) { const rightNode = path.getValue(); if (isBinaryish(rightNode) && !shouldInlineLogicalExpression(rightNode)) { @@ -213,10 +219,10 @@ function shouldBreakAfterOperator(path, options, print, hasShortKey) { } if ( isStringLiteral(node) || - path.call( + (await path.call( () => isPoorlyBreakableMemberOrCallChain(path, options, print), ...propertiesForPath - ) + )) ) { return true; } @@ -328,7 +334,7 @@ function isTypeReference(node) { * A chain with no calls at all or whose calls are all without arguments or with lone short arguments, * excluding chains printed by `printMemberChain` */ -function isPoorlyBreakableMemberOrCallChain( +async function isPoorlyBreakableMemberOrCallChain( path, options, print, @@ -344,7 +350,7 @@ function isPoorlyBreakableMemberOrCallChain( if (isCallExpression(node)) { /** @type {any} TODO */ - const doc = printCallExpression(path, options, print); + const doc = await printCallExpression(path, options, print); if (doc.label === "member-chain") { return false; } @@ -357,7 +363,7 @@ function isPoorlyBreakableMemberOrCallChain( return false; } - if (isCallExpressionWithComplexTypeArguments(node, print)) { + if (await isCallExpressionWithComplexTypeArguments(node, print)) { return false; } @@ -431,7 +437,7 @@ function isObjectPropertyWithShortKey(node, keyDoc, options) { ); } -function isCallExpressionWithComplexTypeArguments(node, print) { +async function isCallExpressionWithComplexTypeArguments(node, print) { const typeArgs = getTypeArgumentsFromCallExpression(node); if (isNonEmptyArray(typeArgs)) { if (typeArgs.length > 1) { @@ -453,7 +459,7 @@ function isCallExpressionWithComplexTypeArguments(node, print) { const typeArgsKeyName = node.typeParameters ? "typeParameters" : "typeArguments"; - if (willBreak(print(typeArgsKeyName))) { + if (willBreak(await print(typeArgsKeyName))) { return true; } } diff --git a/src/language-js/print/binaryish.js b/src/language-js/print/binaryish.js index 1c2c39e9c..c4df3e117 100644 --- a/src/language-js/print/binaryish.js +++ b/src/language-js/print/binaryish.js @@ -27,7 +27,7 @@ import { /** @typedef {import("../../document/builders.js").Doc} Doc */ let uid = 0; -function printBinaryishExpression(path, options, print) { +async function printBinaryishExpression(path, options, print) { const node = path.getValue(); const parent = path.getParentNode(); const parentParent = path.getParentNode(1); @@ -40,7 +40,7 @@ function printBinaryishExpression(path, options, print) { const isHackPipeline = isEnabledHackPipeline(options) && node.operator === "|>"; - const parts = printBinaryishExpressions( + const parts = await printBinaryishExpressions( path, print, options, @@ -180,7 +180,7 @@ function printBinaryishExpression(path, options, print) { // precedence level and the AST is structured based on precedence // level, things are naturally broken up correctly, i.e. `&&` is // broken before `+`. -function printBinaryishExpressions( +async function printBinaryishExpressions( path, print, options, @@ -191,7 +191,7 @@ function printBinaryishExpressions( // Simply print the node normally. if (!isBinaryish(node)) { - return [group(print())]; + return [group(await print())]; } /** @type{Doc[]} */ @@ -210,7 +210,7 @@ function printBinaryishExpressions( // which is unique in that it is right-associative.) if (shouldFlatten(node.operator, node.left.operator)) { // Flatten them out by recursively calling this function. - parts = path.call( + parts = await path.call( (left) => printBinaryishExpressions( left, @@ -222,7 +222,7 @@ function printBinaryishExpressions( "left" ); } else { - parts.push(group(print("left"))); + parts.push(group(await print("left"))); } const shouldInline = shouldInlineLogicalExpression(node); @@ -241,7 +241,9 @@ function printBinaryishExpressions( ": ", join( [softline, ":", ifBreak(" ")], - path.map(print, "arguments").map((arg) => align(2, group(arg))) + (await path.map(print, "arguments")).map((arg) => + align(2, group(arg)) + ) ), ]) ) @@ -250,10 +252,10 @@ function printBinaryishExpressions( /** @type {Doc} */ let right; if (shouldInline) { - right = [operator, " ", print("right"), rightSuffix]; + right = [operator, " ", await print("right"), rightSuffix]; } else { const isHackPipeline = isEnabledHackPipeline(options) && operator === "|>"; - const rightContent = isHackPipeline + const rightContent = await (isHackPipeline ? path.call( (left) => printBinaryishExpressions( @@ -265,7 +267,7 @@ function printBinaryishExpressions( ), "right" ) - : print("right"); + : print("right")); right = [ lineBeforeOperator ? line : "", operator, diff --git a/src/language-js/print/block.js b/src/language-js/print/block.js index fdd022520..d675b9d1c 100644 --- a/src/language-js/print/block.js +++ b/src/language-js/print/block.js @@ -12,7 +12,7 @@ import { printBody } from "./statement.js"; /** @typedef {import("../../document/builders.js").Doc} Doc */ -function printBlock(path, options, print) { +async function printBlock(path, options, print) { const node = path.getValue(); const parts = []; @@ -26,7 +26,7 @@ function printBlock(path, options, print) { } parts.push("{"); - const printed = printBlockBody(path, options, print); + const printed = await printBlockBody(path, options, print); if (printed) { parts.push(indent([hardline, printed]), hardline); } else { @@ -60,7 +60,7 @@ function printBlock(path, options, print) { return parts; } -function printBlockBody(path, options, print) { +async function printBlockBody(path, options, print) { const node = path.getValue(); const nodeHasDirectives = isNonEmptyArray(node.directives); @@ -74,8 +74,8 @@ function printBlockBody(path, options, print) { const parts = []; // Babel 6 if (nodeHasDirectives) { - path.each((childPath, index, directives) => { - parts.push(print()); + await path.each(async (childPath, index, directives) => { + parts.push(await print()); if (index < directives.length - 1 || nodeHasBody || nodeHasComment) { parts.push(hardline); if (isNextLineEmpty(childPath.getValue(), options)) { @@ -86,7 +86,7 @@ function printBlockBody(path, options, print) { } if (nodeHasBody) { - parts.push(printBody(path, options, print)); + parts.push(await printBody(path, options, print)); } if (nodeHasComment) { diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index 1b977abbd..a94176400 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -31,7 +31,7 @@ import { willBreak } from "../../document/utils.js"; import { ArgExpansionBailout } from "../../common/errors.js"; import { isConciselyPrintedArray } from "./array.js"; -function printCallArguments(path, options, print) { +async function printCallArguments(path, options, print) { const node = path.getValue(); const isDynamicImport = node.type === "ImportExpression"; @@ -46,16 +46,22 @@ function printCallArguments(path, options, print) { // useEffect(() => { ... }, [foo, bar, baz]) if (isReactHookCallWithDepsArray(args)) { - return ["(", print(["arguments", 0]), ", ", print(["arguments", 1]), ")"]; + return [ + "(", + await print(["arguments", 0]), + ", ", + await print(["arguments", 1]), + ")", + ]; } let anyArgEmptyLine = false; let hasEmptyLineFollowingFirstArg = false; const lastArgIndex = args.length - 1; const printedArguments = []; - iterateCallArgumentsPath(path, (argPath, index) => { + await iterateCallArgumentsPath(path, async (argPath, index) => { const arg = argPath.getNode(); - const parts = [print()]; + const parts = [await print()]; if (index === lastArgIndex) { // do nothing @@ -110,12 +116,12 @@ function printCallArguments(path, options, print) { let printedExpanded = []; try { - path.try(() => { - iterateCallArgumentsPath(path, (argPath, i) => { + await path.try(async () => { + await iterateCallArgumentsPath(path, async (argPath, i) => { if (shouldGroupFirst && i === 0) { printedExpanded = [ [ - print([], { expandFirstArg: true }), + await print([], { expandFirstArg: true }), printedArguments.length > 1 ? "," : "", hasEmptyLineFollowingFirstArg ? hardline : line, hasEmptyLineFollowingFirstArg ? hardline : "", @@ -126,7 +132,7 @@ function printCallArguments(path, options, print) { if (shouldGroupLast && i === lastArgIndex) { printedExpanded = [ ...printedArguments.slice(0, -1), - print([], { expandLastArg: true }), + await print([], { expandLastArg: true }), ]; } }); diff --git a/src/language-js/print/call-expression.js b/src/language-js/print/call-expression.js index 4b210a085..c09ee5f4f 100644 --- a/src/language-js/print/call-expression.js +++ b/src/language-js/print/call-expression.js @@ -14,7 +14,7 @@ import printMemberChain from "./member-chain.js"; import printCallArguments from "./call-arguments.js"; import { printOptionalToken, printFunctionTypeParameters } from "./misc.js"; -function printCallExpression(path, options, print) { +async function printCallExpression(path, options, print) { const node = path.getValue(); const parentNode = path.getParentNode(); const isNew = node.type === "NewExpression"; @@ -37,14 +37,14 @@ function printCallExpression(path, options, print) { (!isNew && isTestCall(node, parentNode))) ) { const printed = []; - iterateCallArgumentsPath(path, () => { - printed.push(print()); + await iterateCallArgumentsPath(path, async () => { + printed.push(await print()); }); return [ isNew ? "new " : "", - print("callee"), + await print("callee"), optional, - printFunctionTypeParameters(path, options, print), + await printFunctionTypeParameters(path, options, print), "(", join(", ", printed), ")", @@ -79,13 +79,13 @@ function printCallExpression(path, options, print) { const contents = [ isNew ? "new " : "", - isDynamicImport ? "import" : print("callee"), + isDynamicImport ? "import" : await print("callee"), optional, isIdentifierWithFlowAnnotation ? `/*:: ${node.callee.trailingComments[0].value.slice(2).trim()} */` : "", - printFunctionTypeParameters(path, options, print), - printCallArguments(path, options, print), + await printFunctionTypeParameters(path, options, print), + await printCallArguments(path, options, print), ]; // We group here when the callee is itself a call expression. diff --git a/src/language-js/print/class.js b/src/language-js/print/class.js index 4c181954c..a259a0c2c 100644 --- a/src/language-js/print/class.js +++ b/src/language-js/print/class.js @@ -21,7 +21,7 @@ import { printPropertyKey } from "./property.js"; import { printAssignment } from "./assignment.js"; import { printClassMemberDecorators } from "./decorators.js"; -function printClass(path, options, print) { +async function printClass(path, options, print) { const node = path.getValue(); const parts = []; @@ -50,17 +50,17 @@ function printClass(path, options, print) { const extendsParts = []; if (node.id) { - partsGroup.push(" ", print("id")); + partsGroup.push(" ", await print("id")); } - partsGroup.push(print("typeParameters")); + partsGroup.push(await print("typeParameters")); if (node.superClass) { const printed = [ - printSuperClass(path, options, print), - print("superTypeParameters"), + await printSuperClass(path, options, print), + await print("superTypeParameters"), ]; - const printedWithComments = path.call( + const printedWithComments = await path.call( (superClass) => ["extends ", printComments(superClass, printed, options)], "superClass" ); @@ -70,12 +70,12 @@ function printClass(path, options, print) { extendsParts.push(" ", printedWithComments); } } else { - extendsParts.push(printList(path, options, print, "extends")); + extendsParts.push(await printList(path, options, print, "extends")); } extendsParts.push( - printList(path, options, print, "mixins"), - printList(path, options, print, "implements") + await printList(path, options, print, "mixins"), + await printList(path, options, print, "implements") ); if (groupMode) { @@ -90,7 +90,7 @@ function printClass(path, options, print) { parts.push(...partsGroup, ...extendsParts); } - parts.push(" ", print("body")); + parts.push(" ", await print("body")); return parts; } @@ -120,7 +120,7 @@ function shouldIndentOnlyHeritageClauses(node) { ); } -function printList(path, options, print, listName) { +async function printList(path, options, print, listName) { const node = path.getValue(); if (!isNonEmptyArray(node[listName])) { return ""; @@ -141,12 +141,12 @@ function printList(path, options, print, listName) { printedLeadingComments, printedLeadingComments && hardline, listName, - group(indent([line, join([",", line], path.map(print, listName))])), + group(indent([line, join([",", line], await path.map(print, listName))])), ]; } -function printSuperClass(path, options, print) { - const printed = print("superClass"); +async function printSuperClass(path, options, print) { + const printed = await print("superClass"); const parent = path.getParentNode(); if (parent.type === "AssignmentExpression") { return group( @@ -156,12 +156,12 @@ function printSuperClass(path, options, print) { return printed; } -function printClassMethod(path, options, print) { +async function printClassMethod(path, options, print) { const node = path.getValue(); const parts = []; if (isNonEmptyArray(node.decorators)) { - parts.push(printClassMemberDecorators(path, options, print)); + parts.push(await printClassMemberDecorators(path, options, print)); } if (node.accessibility) { parts.push(node.accessibility + " "); @@ -185,18 +185,18 @@ function printClassMethod(path, options, print) { parts.push("override "); } - parts.push(printMethod(path, options, print)); + parts.push(await printMethod(path, options, print)); return parts; } -function printClassProperty(path, options, print) { +async function printClassProperty(path, options, print) { const node = path.getValue(); const parts = []; const semi = options.semi ? ";" : ""; if (isNonEmptyArray(node.decorators)) { - parts.push(printClassMemberDecorators(path, options, print)); + parts.push(await printClassMemberDecorators(path, options, print)); } if (node.accessibility) { parts.push(node.accessibility + " "); @@ -217,19 +217,22 @@ function printClassProperty(path, options, print) { parts.push("readonly "); } if (node.variance) { - parts.push(print("variance")); + parts.push(await print("variance")); } if (node.type === "ClassAccessorProperty") { parts.push("accessor "); } parts.push( - printPropertyKey(path, options, print), - printOptionalToken(path), - printDefiniteToken(path), - printTypeAnnotation(path, options, print) + await printPropertyKey(path, options, print), + await printOptionalToken(path), + await printDefiniteToken(path), + await printTypeAnnotation(path, options, print) ); - return [printAssignment(path, options, print, parts, " =", "value"), semi]; + return [ + await printAssignment(path, options, print, parts, " =", "value"), + semi, + ]; } export { diff --git a/src/language-js/print/decorators.js b/src/language-js/print/decorators.js index 23f72f562..9bcf25a70 100644 --- a/src/language-js/print/decorators.js +++ b/src/language-js/print/decorators.js @@ -9,24 +9,24 @@ import { import { locStart, locEnd } from "../loc.js"; import { getParentExportDeclaration } from "../utils/index.js"; -function printClassMemberDecorators(path, options, print) { +async function printClassMemberDecorators(path, options, print) { const node = path.getValue(); return group([ - join(line, path.map(print, "decorators")), + join(line, await path.map(print, "decorators")), hasNewlineBetweenOrAfterDecorators(node, options) ? hardline : line, ]); } -function printDecoratorsBeforeExport(path, options, print) { +async function printDecoratorsBeforeExport(path, options, print) { // Export declarations are responsible for printing any decorators // that logically apply to node.declaration. return [ - join(hardline, path.map(print, "declaration", "decorators")), + join(hardline, await path.map(print, "declaration", "decorators")), hardline, ]; } -function printDecorators(path, options, print) { +async function printDecorators(path, options, print) { const node = path.getValue(); const { decorators } = node; @@ -51,7 +51,7 @@ function printDecorators(path, options, print) { : shouldBreak ? breakParent : "", - join(line, path.map(print, "decorators")), + join(line, await path.map(print, "decorators")), line, ]; } diff --git a/src/language-js/print/flow.js b/src/language-js/print/flow.js index 09b699e83..517b7ec79 100644 --- a/src/language-js/print/flow.js +++ b/src/language-js/print/flow.js @@ -34,53 +34,62 @@ import { printRestSpread, } from "./misc.js"; -function printFlow(path, options, print) { +async function printFlow(path, options, print) { const node = path.getValue(); const semi = options.semi ? ";" : ""; /** @type{Doc[]} */ const parts = []; switch (node.type) { case "DeclareClass": - return printFlowDeclaration(path, printClass(path, options, print)); + return printFlowDeclaration(path, await printClass(path, options, print)); case "DeclareFunction": return printFlowDeclaration(path, [ "function ", - print("id"), + await print("id"), node.predicate ? " " : "", - print("predicate"), + await print("predicate"), semi, ]); case "DeclareModule": return printFlowDeclaration(path, [ "module ", - print("id"), + await print("id"), " ", - print("body"), + await print("body"), ]); case "DeclareModuleExports": return printFlowDeclaration(path, [ "module.exports", ": ", - print("typeAnnotation"), + await print("typeAnnotation"), semi, ]); case "DeclareVariable": - return printFlowDeclaration(path, ["var ", print("id"), semi]); + return printFlowDeclaration(path, ["var ", await print("id"), semi]); case "DeclareOpaqueType": - return printFlowDeclaration(path, printOpaqueType(path, options, print)); + return printFlowDeclaration( + path, + await printOpaqueType(path, options, print) + ); case "DeclareInterface": - return printFlowDeclaration(path, printInterface(path, options, print)); + return printFlowDeclaration( + path, + await printInterface(path, options, print) + ); case "DeclareTypeAlias": - return printFlowDeclaration(path, printTypeAlias(path, options, print)); + return printFlowDeclaration( + path, + await printTypeAlias(path, options, print) + ); case "DeclareExportDeclaration": return printFlowDeclaration( path, - printExportDeclaration(path, options, print) + await printExportDeclaration(path, options, print) ); case "DeclareExportAllDeclaration": return printFlowDeclaration( path, - printExportAllDeclaration(path, options, print) + await printExportAllDeclaration(path, options, print) ); case "OpaqueType": return printOpaqueType(path, options, print); @@ -96,8 +105,8 @@ function printFlow(path, options, print) { return printTupleType(path, options, print); case "GenericTypeAnnotation": return [ - print("id"), - printTypeParameters(path, options, print, "typeParameters"), + await print("id"), + await printTypeParameters(path, options, print, "typeParameters"), ]; case "IndexedAccessType": case "OptionalIndexedAccessType": @@ -109,7 +118,7 @@ function printFlow(path, options, print) { case "TypeParameter": return printTypeParameter(path, options, print); case "TypeofTypeAnnotation": - return ["typeof ", print("argument")]; + return ["typeof ", await print("argument")]; case "ExistsTypeAnnotation": return "*"; case "EmptyTypeAnnotation": @@ -117,11 +126,11 @@ function printFlow(path, options, print) { case "MixedTypeAnnotation": return "mixed"; case "ArrayTypeAnnotation": - return [print("elementType"), "[]"]; + return [await print("elementType"), "[]"]; case "BooleanLiteralTypeAnnotation": return String(node.value); case "EnumDeclaration": - return ["enum ", print("id"), " ", print("body")]; + return ["enum ", await print("id"), " ", await print("body")]; case "EnumBooleanBody": case "EnumNumberBody": case "EnumStringBody": @@ -153,7 +162,7 @@ function printFlow(path, options, print) { node.members.length > 0 ? [ hardline, - printArrayItems(path, options, "members", print), + await printArrayItems(path, options, "members", print), node.hasUnknownMembers || shouldPrintComma(options) ? "," : "", ] : []; @@ -177,23 +186,23 @@ function printFlow(path, options, print) { case "EnumNumberMember": case "EnumStringMember": return [ - print("id"), + await print("id"), " = ", - typeof node.init === "object" ? print("init") : String(node.init), + typeof node.init === "object" ? await print("init") : String(node.init), ]; case "EnumDefaultedMember": return print("id"); case "FunctionTypeParam": { const name = node.name - ? print("name") + ? await print("name") : path.getParentNode().this === node ? "this" : ""; return [ name, - printOptionalToken(path), + await printOptionalToken(path), name ? ": " : "", - print("typeAnnotation"), + await print("typeAnnotation"), ]; } @@ -202,9 +211,9 @@ function printFlow(path, options, print) { return printInterface(path, options, print); case "ClassImplements": case "InterfaceExtends": - return [print("id"), print("typeParameters")]; + return [await print("id"), await print("typeParameters")]; case "NullableTypeAnnotation": - return ["?", print("typeAnnotation")]; + return ["?", await print("typeAnnotation")]; case "Variance": { const { kind } = node; assert.ok(kind === "plus" || kind === "minus"); @@ -215,19 +224,19 @@ function printFlow(path, options, print) { parts.push("static "); } - parts.push(print("value")); + parts.push(await print("value")); return parts; case "ObjectTypeIndexer": { return [ node.static ? "static " : "", - node.variance ? print("variance") : "", + node.variance ? await print("variance") : "", "[", - print("id"), + await print("id"), node.id ? ": " : "", - print("key"), + await print("key"), "]: ", - print("value"), + await print("value"), ]; } case "ObjectTypeProperty": { @@ -242,11 +251,11 @@ function printFlow(path, options, print) { return [ modifier, isGetterOrSetter(node) ? node.kind + " " : "", - node.variance ? print("variance") : "", - printPropertyKey(path, options, print), + node.variance ? await print("variance") : "", + await printPropertyKey(path, options, print), printOptionalToken(path), isFunctionNotation(node) ? "" : ": ", - print("value"), + await print("value"), ]; } case "ObjectTypeAnnotation": @@ -255,18 +264,18 @@ function printFlow(path, options, print) { return [ node.static ? "static " : "", "[[", - print("id"), + await print("id"), "]]", printOptionalToken(path), node.method ? "" : ": ", - print("value"), + await print("value"), ]; // Same as `RestElement` case "ObjectTypeSpreadProperty": return printRestSpread(path, options, print); case "QualifiedTypeofIdentifier": case "QualifiedTypeIdentifier": - return [print("qualification"), ".", print("id")]; + return [await print("qualification"), ".", await print("id")]; case "StringLiteralTypeAnnotation": return printString(rawText(node), options); case "NumberLiteralTypeAnnotation": @@ -280,15 +289,15 @@ function printFlow(path, options, print) { case "TypeCastExpression": { return [ "(", - print("expression"), - printTypeAnnotation(path, options, print), + await print("expression"), + await printTypeAnnotation(path, options, print), ")", ]; } case "TypeParameterDeclaration": case "TypeParameterInstantiation": { - const printed = printTypeParameters(path, options, print, "params"); + const printed = await printTypeParameters(path, options, print, "params"); if (options.parser === "flow") { const start = locStart(node); @@ -318,7 +327,7 @@ function printFlow(path, options, print) { // be either left alone or desugared into AST types that are fully // supported by the pretty-printer. case "DeclaredPredicate": - return ["%checks(", print("value"), ")"]; + return ["%checks(", await print("value"), ")"]; case "AnyTypeAnnotation": return "any"; case "BooleanTypeAnnotation": diff --git a/src/language-js/print/function-parameters.js b/src/language-js/print/function-parameters.js index d7ac5872c..b4dc2cdda 100644 --- a/src/language-js/print/function-parameters.js +++ b/src/language-js/print/function-parameters.js @@ -26,7 +26,7 @@ import { locEnd } from "../loc.js"; import { ArgExpansionBailout } from "../../common/errors.js"; import { printFunctionTypeParameters } from "./misc.js"; -function printFunctionParameters( +async function printFunctionParameters( path, print, options, @@ -36,7 +36,7 @@ function printFunctionParameters( const functionNode = path.getValue(); const parameters = getFunctionParameters(functionNode); const typeParams = printTypeParams - ? printFunctionTypeParameters(path, options, print) + ? await printFunctionTypeParameters(path, options, print) : ""; if (parameters.length === 0) { @@ -62,12 +62,12 @@ function printFunctionParameters( const isParametersInTestCall = isTestCall(parent); const shouldHugParameters = shouldHugFunctionParameters(functionNode); const printed = []; - iterateFunctionParametersPath(path, (parameterPath, index) => { + await iterateFunctionParametersPath(path, async (parameterPath, index) => { const isLastParameter = index === parameters.length - 1; if (isLastParameter && functionNode.rest) { printed.push("..."); } - printed.push(print()); + printed.push(await print()); if (isLastParameter) { return; } diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js index b1cc517e1..3faae6efc 100644 --- a/src/language-js/print/function.js +++ b/src/language-js/print/function.js @@ -46,7 +46,7 @@ import { import { printPropertyKey } from "./property.js"; import { printFunctionTypeParameters } from "./misc.js"; -function printFunction(path, print, options, args) { +async function printFunction(path, print, options, args) { const node = path.getValue(); let expandArg = false; @@ -81,29 +81,29 @@ function printFunction(path, print, options, args) { } if (node.id) { - parts.push(print("id")); + parts.push(await print("id")); } - const parametersDoc = printFunctionParameters( + const parametersDoc = await printFunctionParameters( path, print, options, expandArg ); - const returnTypeDoc = printReturnType(path, print, options); + const returnTypeDoc = await printReturnType(path, print, options); const shouldGroupParameters = shouldGroupFunctionParameters( node, returnTypeDoc ); parts.push( - printFunctionTypeParameters(path, options, print), + await printFunctionTypeParameters(path, options, print), group([ shouldGroupParameters ? group(parametersDoc) : parametersDoc, returnTypeDoc, ]), node.body ? " " : "", - print("body") + await print("body") ); if (options.semi && (node.declare || !node.body)) { @@ -113,7 +113,7 @@ function printFunction(path, print, options, args) { return parts; } -function printMethod(path, options, print) { +async function printMethod(path, options, print) { const node = path.getNode(); const { kind } = node; const value = node.value || node; @@ -135,33 +135,36 @@ function printMethod(path, options, print) { } parts.push( - printPropertyKey(path, options, print), + await printPropertyKey(path, options, print), node.optional || node.key.optional ? "?" : "" ); if (node === value) { - parts.push(printMethodInternal(path, options, print)); + parts.push(await printMethodInternal(path, options, print)); } else if (value.type === "FunctionExpression") { parts.push( - path.call((path) => printMethodInternal(path, options, print), "value") + await path.call( + (path) => printMethodInternal(path, options, print), + "value" + ) ); } else { - parts.push(print("value")); + parts.push(await print("value")); } return parts; } -function printMethodInternal(path, options, print) { +async function printMethodInternal(path, options, print) { const node = path.getNode(); - const parametersDoc = printFunctionParameters(path, print, options); - const returnTypeDoc = printReturnType(path, print, options); + const parametersDoc = await printFunctionParameters(path, print, options); + const returnTypeDoc = await printReturnType(path, print, options); const shouldGroupParameters = shouldGroupFunctionParameters( node, returnTypeDoc ); const parts = [ - printFunctionTypeParameters(path, options, print), + await printFunctionTypeParameters(path, options, print), group([ shouldGroupParameters ? group(parametersDoc) : parametersDoc, returnTypeDoc, @@ -169,7 +172,7 @@ function printMethodInternal(path, options, print) { ]; if (node.body) { - parts.push(" ", print("body")); + parts.push(" ", await print("body")); } else { parts.push(options.semi ? ";" : ""); } @@ -177,7 +180,7 @@ function printMethodInternal(path, options, print) { return parts; } -function printArrowFunctionSignature(path, options, print, args) { +async function printArrowFunctionSignature(path, options, print, args) { const node = path.getValue(); const parts = []; @@ -186,10 +189,10 @@ function printArrowFunctionSignature(path, options, print, args) { } if (shouldPrintParamsWithoutParens(path, options)) { - parts.push(print(["params", 0])); + parts.push(await print(["params", 0])); } else { const expandArg = args && (args.expandLastArg || args.expandFirstArg); - let returnTypeDoc = printReturnType(path, print, options); + let returnTypeDoc = await printReturnType(path, print, options); if (expandArg) { if (willBreak(returnTypeDoc)) { throw new ArgExpansionBailout(); @@ -198,7 +201,7 @@ function printArrowFunctionSignature(path, options, print, args) { } parts.push( group([ - printFunctionParameters( + await printFunctionParameters( path, print, options, @@ -277,15 +280,15 @@ function printArrowChain( ]); } -function printArrowFunction(path, options, print, args) { +async function printArrowFunction(path, options, print, args) { let node = path.getValue(); /** @type {Doc[]} */ const signatures = []; const body = []; let chainShouldBreak = false; - (function rec() { - const doc = printArrowFunctionSignature(path, options, print, args); + await (async function rec() { + const doc = await printArrowFunctionSignature(path, options, print, args); if (signatures.length === 0) { signatures.push(doc); } else { @@ -305,10 +308,10 @@ function printArrowFunction(path, options, print, args) { node.body.type !== "ArrowFunctionExpression" || (args && args.expandLastArg) ) { - body.unshift(print("body", args)); + body.unshift(await print("body", args)); } else { node = node.body; - path.call(rec, "body"); + await path.call(rec, "body"); } })(); @@ -415,10 +418,10 @@ function shouldPrintParamsWithoutParens(path, options) { return false; } -/** @returns {Doc} */ -function printReturnType(path, print, options) { +/** @returns {Promise} */ +async function printReturnType(path, print, options) { const node = path.getValue(); - const returnType = print("returnType"); + const returnType = await print("returnType"); if ( node.returnType && @@ -437,21 +440,26 @@ function printReturnType(path, print, options) { if (node.predicate) { // The return type will already add the colon, but otherwise we // need to do it ourselves - parts.push(node.returnType ? " " : ": ", print("predicate")); + parts.push(node.returnType ? " " : ": ", await print("predicate")); } return parts; } // `ReturnStatement` and `ThrowStatement` -function printReturnOrThrowArgument(path, options, print) { +async function printReturnOrThrowArgument(path, options, print) { const node = path.getValue(); const semi = options.semi ? ";" : ""; const parts = []; if (node.argument) { if (returnArgumentHasLeadingComment(options, node.argument)) { - parts.push([" (", indent([hardline, print("argument")]), hardline, ")"]); + parts.push([ + " (", + indent([hardline, await print("argument")]), + hardline, + ")", + ]); } else if ( isBinaryish(node.argument) || node.argument.type === "SequenceExpression" @@ -459,13 +467,13 @@ function printReturnOrThrowArgument(path, options, print) { parts.push( group([ ifBreak(" (", " "), - indent([softline, print("argument")]), + indent([softline, await print("argument")]), softline, ifBreak(")"), ]) ); } else { - parts.push(" ", print("argument")); + parts.push(" ", await print("argument")); } } @@ -491,12 +499,12 @@ function printReturnOrThrowArgument(path, options, print) { return parts; } -function printReturnStatement(path, options, print) { - return ["return", printReturnOrThrowArgument(path, options, print)]; +async function printReturnStatement(path, options, print) { + return ["return", await printReturnOrThrowArgument(path, options, print)]; } -function printThrowStatement(path, options, print) { - return ["throw", printReturnOrThrowArgument(path, options, print)]; +async function printThrowStatement(path, options, print) { + return ["throw", await printReturnOrThrowArgument(path, options, print)]; } // This recurses the return argument, looking for the first token diff --git a/src/language-js/print/html-binding.js b/src/language-js/print/html-binding.js index 8180b754e..93a82ad46 100644 --- a/src/language-js/print/html-binding.js +++ b/src/language-js/print/html-binding.js @@ -19,10 +19,10 @@ function printHtmlBinding(path, options, print) { if (options.__isVueForBindingLeft) { return path.call( - (functionDeclarationPath) => { + async (functionDeclarationPath) => { const printed = join( [",", line], - functionDeclarationPath.map(print, "params") + await functionDeclarationPath.map(print, "params") ); const { params } = functionDeclarationPath.getValue(); @@ -40,8 +40,8 @@ function printHtmlBinding(path, options, print) { if (options.__isVueBindings) { return path.call( - (functionDeclarationPath) => - join([",", line], functionDeclarationPath.map(print, "params")), + async (functionDeclarationPath) => + join([",", line], await functionDeclarationPath.map(print, "params")), "program", "body", 0 diff --git a/src/language-js/print/interface.js b/src/language-js/print/interface.js index 3354109dd..071aff992 100644 --- a/src/language-js/print/interface.js +++ b/src/language-js/print/interface.js @@ -4,7 +4,7 @@ import { hasComment, identity, CommentCheckFlags } from "../utils/index.js"; import { getTypeParametersGroupId } from "./type-parameters.js"; import { printTypeScriptModifiers } from "./misc.js"; -function printInterface(path, options, print) { +async function printInterface(path, options, print) { const node = path.getValue(); const parts = []; if (node.declare) { @@ -14,7 +14,7 @@ function printInterface(path, options, print) { if (node.type === "TSInterfaceDeclaration") { parts.push( node.abstract ? "abstract " : "", - printTypeScriptModifiers(path, options, print) + await printTypeScriptModifiers(path, options, print) ); } @@ -24,7 +24,7 @@ function printInterface(path, options, print) { const extendsParts = []; if (node.type !== "InterfaceTypeAnnotation") { - partsGroup.push(" ", print("id"), print("typeParameters")); + partsGroup.push(" ", await print("id"), await print("typeParameters")); } const shouldIndentOnlyHeritageClauses = @@ -43,7 +43,7 @@ function printInterface(path, options, print) { : line, "extends ", (node.extends.length === 1 ? identity : indent)( - join([",", line], path.map(print, "extends")) + join([",", line], await path.map(print, "extends")) ) ); } @@ -61,7 +61,7 @@ function printInterface(path, options, print) { parts.push(...partsGroup, ...extendsParts); } - parts.push(" ", print("body")); + parts.push(" ", await print("body")); return group(parts); } diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index d7a0ff585..8a4339e97 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -52,21 +52,21 @@ const isEmptyStringOrAnyLine = (doc) => // // To support that case properly, all leading and trailing spaces // are stripped from the list of children, and replaced with a single hardline. -function printJsxElementInternal(path, options, print) { +async function printJsxElementInternal(path, options, print) { const node = path.getValue(); if (node.type === "JSXElement" && isEmptyJsxElement(node)) { - return [print("openingElement"), print("closingElement")]; + return [await print("openingElement"), await print("closingElement")]; } const openingLines = node.type === "JSXElement" - ? print("openingElement") - : print("openingFragment"); + ? await print("openingElement") + : await print("openingFragment"); const closingLines = node.type === "JSXElement" - ? print("closingElement") - : print("closingFragment"); + ? await print("closingElement") + : await print("closingFragment"); if ( node.children.length === 1 && @@ -74,7 +74,7 @@ function printJsxElementInternal(path, options, print) { (node.children[0].expression.type === "TemplateLiteral" || node.children[0].expression.type === "TaggedTemplateExpression") ) { - return [openingLines, ...path.map(print, "children"), closingLines]; + return [openingLines, ...(await path.map(print, "children")), closingLines]; } // Convert `{" "}` to text nodes containing a space. @@ -117,7 +117,7 @@ function printJsxElementInternal(path, options, print) { node.openingElement.name && node.openingElement.name.name === "fbt"; - const children = printJsxChildren( + const children = await printJsxChildren( path, options, print, @@ -261,7 +261,7 @@ function printJsxElementInternal(path, options, print) { // This requires that we give it an array of alternating // content and whitespace elements. // To ensure this we add dummy `""` content elements as needed. -function printJsxChildren( +async function printJsxChildren( path, options, print, @@ -269,7 +269,7 @@ function printJsxChildren( isFacebookTranslationTag ) { const parts = []; - path.each((childPath, i, children) => { + await path.each(async (childPath, i, children) => { const child = childPath.getValue(); if (isLiteral(child)) { const text = rawText(child); @@ -353,7 +353,7 @@ function printJsxChildren( parts.push("", jsxWhitespace); } } else { - const printedChild = print(); + const printedChild = await print(); parts.push(printedChild); const next = children[i + 1]; @@ -463,10 +463,10 @@ function maybeWrapJsxElementInParens(path, elem, options) { ); } -function printJsxAttribute(path, options, print) { +async function printJsxAttribute(path, options, print) { const node = path.getValue(); const parts = []; - parts.push(print("name")); + parts.push(await print("name")); if (node.value) { let res; @@ -485,7 +485,7 @@ function printJsxAttribute(path, options, print) { final = final.replace(regex, escaped); res = [quote, final, quote]; } else { - res = print("value"); + res = await print("value"); } parts.push("=", res); } @@ -493,7 +493,7 @@ function printJsxAttribute(path, options, print) { return parts; } -function printJsxExpressionContainer(path, options, print) { +async function printJsxExpressionContainer(path, options, print) { const node = path.getValue(); const shouldInline = (node, parent) => @@ -514,19 +514,19 @@ function printJsxExpressionContainer(path, options, print) { (node.type === "ConditionalExpression" || isBinaryish(node))))); if (shouldInline(node.expression, path.getParentNode(0))) { - return group(["{", print("expression"), lineSuffixBoundary, "}"]); + return group(["{", await print("expression"), lineSuffixBoundary, "}"]); } return group([ "{", - indent([softline, print("expression")]), + indent([softline, await print("expression")]), softline, lineSuffixBoundary, "}", ]); } -function printJsxOpeningElement(path, options, print) { +async function printJsxOpeningElement(path, options, print) { const node = path.getValue(); const nameHasComments = @@ -535,7 +535,7 @@ function printJsxOpeningElement(path, options, print) { // Don't break self-closing elements with no attributes and no comments if (node.selfClosing && node.attributes.length === 0 && !nameHasComments) { - return ["<", print("name"), print("typeParameters"), " />"]; + return ["<", await print("name"), await print("typeParameters"), " />"]; } // don't break up opening elements with a single long text attribute @@ -559,10 +559,10 @@ function printJsxOpeningElement(path, options, print) { ) { return group([ "<", - print("name"), - print("typeParameters"), + await print("name"), + await print("typeParameters"), " ", - ...path.map(print, "attributes"), + ...(await path.map(print, "attributes")), node.selfClosing ? " />" : ">", ]); } @@ -586,10 +586,12 @@ function printJsxOpeningElement(path, options, print) { return group( [ "<", - print("name"), - print("typeParameters"), - indent(path.map(() => [attributeLine, print()], "attributes")), - ...printEndOfOpeningTag(node, options, nameHasComments), + await print("name"), + await print("typeParameters"), + indent( + await path.map(async () => [attributeLine, await print()], "attributes") + ), + ...(await printEndOfOpeningTag(node, options, nameHasComments)), ], { shouldBreak } ); @@ -633,13 +635,13 @@ function shouldPrintBracketSameLine(node, options, nameHasComments) { ); } -function printJsxClosingElement(path, options, print) { +async function printJsxClosingElement(path, options, print) { const node = path.getValue(); const parts = []; parts.push(" { - const printed = ["...", print()]; + await path.call( + async (p) => { + const printed = ["...", await print()]; const node = p.getValue(); if (!hasComment(node) || !willPrintOwnComments(p)) { return printed; @@ -719,7 +721,7 @@ function printJsxSpreadAttribute(path, options, print) { ]; } -function printJsx(path, options, print) { +async function printJsx(path, options, print) { const node = path.getValue(); // JSX nodes always starts with `JSX` @@ -733,9 +735,9 @@ function printJsx(path, options, print) { case "JSXIdentifier": return String(node.name); case "JSXNamespacedName": - return join(":", [print("namespace"), print("name")]); + return join(":", [await print("namespace"), await print("name")]); case "JSXMemberExpression": - return join(".", [print("object"), print("property")]); + return join(".", [await print("object"), await print("property")]); case "JSXSpreadAttribute": return printJsxSpreadAttribute(path, options, print); case "JSXSpreadChild": { diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index 5a8235cdf..ac30ed569 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -48,7 +48,7 @@ import { // The way it is structured in the AST is via a nested sequence of // MemberExpression and CallExpression. We need to traverse the AST // and make groups out of it to print it in the desired way. -function printMemberChain(path, options, print) { +async function printMemberChain(path, options, print) { const parent = path.getParentNode(); const isExpressionStatement = !parent || parent.type === "ExpressionStatement"; @@ -85,7 +85,7 @@ function printMemberChain(path, options, print) { return isNextLineEmpty(node, options); } - function rec(path) { + async function rec(path) { const node = path.getValue(); if ( isCallExpression(node) && @@ -97,16 +97,16 @@ function printMemberChain(path, options, print) { printComments( path, [ - printOptionalToken(path), - printFunctionTypeParameters(path, options, print), - printCallArguments(path, options, print), + await printOptionalToken(path), + await printFunctionTypeParameters(path, options, print), + await printCallArguments(path, options, print), ], options ), shouldInsertEmptyLineAfter(node) ? hardline : "", ], }); - path.call((callee) => rec(callee), "callee"); + await path.call((callee) => rec(callee), "callee"); } else if (isMemberish(node)) { printedNodes.unshift({ node, @@ -114,22 +114,22 @@ function printMemberChain(path, options, print) { printed: printComments( path, isMemberExpression(node) - ? printMemberLookup(path, options, print) - : printBindExpressionCallee(path, options, print), + ? await printMemberLookup(path, options, print) + : await printBindExpressionCallee(path, options, print), options ), }); - path.call((object) => rec(object), "object"); + await path.call((object) => rec(object), "object"); } else if (node.type === "TSNonNullExpression") { printedNodes.unshift({ node, printed: printComments(path, "!", options), }); - path.call((expression) => rec(expression), "expression"); + await path.call((expression) => rec(expression), "expression"); } else { printedNodes.unshift({ node, - printed: print(), + printed: await print(), }); } } @@ -140,14 +140,14 @@ function printMemberChain(path, options, print) { printedNodes.unshift({ node, printed: [ - printOptionalToken(path), - printFunctionTypeParameters(path, options, print), - printCallArguments(path, options, print), + await printOptionalToken(path), + await printFunctionTypeParameters(path, options, print), + await printCallArguments(path, options, print), ], }); if (node.callee) { - path.call((callee) => rec(callee), "callee"); + await path.call((callee) => rec(callee), "callee"); } // Once we have a linear list of printed nodes, we want to create groups out diff --git a/src/language-js/print/member.js b/src/language-js/print/member.js index c19a39030..71055513e 100644 --- a/src/language-js/print/member.js +++ b/src/language-js/print/member.js @@ -6,7 +6,7 @@ import { } from "../utils/index.js"; import { printOptionalToken } from "./misc.js"; -function printMemberExpression(path, options, print) { +async function printMemberExpression(path, options, print) { const node = path.getValue(); const parent = path.getParentNode(); @@ -21,8 +21,8 @@ function printMemberExpression(path, options, print) { firstNonMemberParent.type === "TSNonNullExpression") ); - const objectDoc = print("object"); - const lookupDoc = printMemberLookup(path, options, print); + const objectDoc = await print("object"); + const lookupDoc = await printMemberLookup(path, options, print); const shouldInline = (firstNonMemberParent && @@ -48,8 +48,8 @@ function printMemberExpression(path, options, print) { ]); } -function printMemberLookup(path, options, print) { - const property = print("property"); +async function printMemberLookup(path, options, print) { + const property = await print("property"); const node = path.getValue(); const optional = printOptionalToken(path); diff --git a/src/language-js/print/misc.js b/src/language-js/print/misc.js index 5a065a0ea..3ddd8fc5d 100644 --- a/src/language-js/print/misc.js +++ b/src/language-js/print/misc.js @@ -43,7 +43,7 @@ function printFunctionTypeParameters(path, options, print) { return ""; } -function printTypeAnnotation(path, options, print) { +async function printTypeAnnotation(path, options, print) { const node = path.getValue(); if (!node.typeAnnotation) { return ""; @@ -55,22 +55,25 @@ function printTypeAnnotation(path, options, print) { parentNode.type === "DeclareFunction" && parentNode.id === node; if (isFlowAnnotationComment(options.originalText, node.typeAnnotation)) { - return [" /*: ", print("typeAnnotation"), " */"]; + return [" /*: ", await print("typeAnnotation"), " */"]; } - return [isFunctionDeclarationIdentifier ? "" : ": ", print("typeAnnotation")]; + return [ + isFunctionDeclarationIdentifier ? "" : ": ", + await print("typeAnnotation"), + ]; } -function printBindExpressionCallee(path, options, print) { - return ["::", print("callee")]; +async function printBindExpressionCallee(path, options, print) { + return ["::", await print("callee")]; } -function printTypeScriptModifiers(path, options, print) { +async function printTypeScriptModifiers(path, options, print) { const node = path.getValue(); if (!isNonEmptyArray(node.modifiers)) { return ""; } - return [join(" ", path.map(print, "modifiers")), " "]; + return [join(" ", await path.map(print, "modifiers")), " "]; } function adjustClause(node, clause, forceSpace) { @@ -85,8 +88,12 @@ function adjustClause(node, clause, forceSpace) { return indent([line, clause]); } -function printRestSpread(path, options, print) { - return ["...", print("argument"), printTypeAnnotation(path, options, print)]; +async function printRestSpread(path, options, print) { + return [ + "...", + await print("argument"), + await printTypeAnnotation(path, options, print), + ]; } export { diff --git a/src/language-js/print/module.js b/src/language-js/print/module.js index c427aa025..9ee4779a0 100644 --- a/src/language-js/print/module.js +++ b/src/language-js/print/module.js @@ -28,7 +28,7 @@ import { * @typedef {import("../../document/builders.js").Doc} Doc */ -function printImportDeclaration(path, options, print) { +async function printImportDeclaration(path, options, print) { const node = path.getValue(); const semi = options.semi ? ";" : ""; /** @type{Doc[]} */ @@ -43,16 +43,16 @@ function printImportDeclaration(path, options, print) { } parts.push( - printModuleSpecifiers(path, options, print), - printModuleSource(path, options, print), - printImportAssertions(path, options, print), + await printModuleSpecifiers(path, options, print), + await printModuleSource(path, options, print), + await printImportAssertions(path, options, print), semi ); return parts; } -function printExportDeclaration(path, options, print) { +async function printExportDeclaration(path, options, print) { const node = path.getValue(); /** @type{Doc[]} */ const parts = []; @@ -60,7 +60,7 @@ function printExportDeclaration(path, options, print) { // Only print decorators here if they were written before the export, // otherwise they are printed by the node.declaration if (hasDecoratorsBeforeExport(node)) { - parts.push(printDecoratorsBeforeExport(path, options, print)); + parts.push(await printDecoratorsBeforeExport(path, options, print)); } const { type, exportKind, declaration } = node; @@ -84,13 +84,13 @@ function printExportDeclaration(path, options, print) { } if (declaration) { - parts.push(" ", print("declaration")); + parts.push(" ", await print("declaration")); } else { parts.push( exportKind === "type" ? " type" : "", - printModuleSpecifiers(path, options, print), - printModuleSource(path, options, print), - printImportAssertions(path, options, print) + await printModuleSpecifiers(path, options, print), + await printModuleSource(path, options, print), + await printImportAssertions(path, options, print) ); } @@ -101,7 +101,7 @@ function printExportDeclaration(path, options, print) { return parts; } -function printExportAllDeclaration(path, options, print) { +async function printExportAllDeclaration(path, options, print) { const node = path.getValue(); const semi = options.semi ? ";" : ""; /** @type{Doc[]} */ @@ -118,12 +118,12 @@ function printExportAllDeclaration(path, options, print) { parts.push(" *"); if (exported) { - parts.push(" as ", print("exported")); + parts.push(" as ", await print("exported")); } parts.push( - printModuleSource(path, options, print), - printImportAssertions(path, options, print), + await printModuleSource(path, options, print), + await printImportAssertions(path, options, print), semi ); @@ -157,7 +157,7 @@ function shouldExportDeclarationPrintSemi(node, options) { return false; } -function printModuleSource(path, options, print) { +async function printModuleSource(path, options, print) { const node = path.getValue(); if (!node.source) { @@ -169,12 +169,12 @@ function printModuleSource(path, options, print) { if (!shouldNotPrintSpecifiers(node, options)) { parts.push(" from"); } - parts.push(" ", print("source")); + parts.push(" ", await print("source")); return parts; } -function printModuleSpecifiers(path, options, print) { +async function printModuleSpecifiers(path, options, print) { const node = path.getValue(); if (shouldNotPrintSpecifiers(node, options)) { @@ -188,7 +188,7 @@ function printModuleSpecifiers(path, options, print) { const standaloneSpecifiers = []; const groupedSpecifiers = []; - path.each(() => { + await path.each(async () => { const specifierType = path.getValue().type; if ( specifierType === "ExportNamespaceSpecifier" || @@ -196,12 +196,12 @@ function printModuleSpecifiers(path, options, print) { specifierType === "ImportNamespaceSpecifier" || specifierType === "ImportDefaultSpecifier" ) { - standaloneSpecifiers.push(print()); + standaloneSpecifiers.push(await print()); } else if ( specifierType === "ExportSpecifier" || specifierType === "ImportSpecifier" ) { - groupedSpecifiers.push(print()); + groupedSpecifiers.push(await print()); } else { /* istanbul ignore next */ throw new Error( @@ -268,13 +268,13 @@ function shouldNotPrintSpecifiers(node, options) { ); } -function printImportAssertions(path, options, print) { +async function printImportAssertions(path, options, print) { const node = path.getNode(); if (isNonEmptyArray(node.assertions)) { return [ " assert {", options.bracketSpacing ? " " : "", - join(", ", path.map(print, "assertions")), + join(", ", await path.map(print, "assertions")), options.bracketSpacing ? " " : "", "}", ]; @@ -282,7 +282,7 @@ function printImportAssertions(path, options, print) { return ""; } -function printModuleSpecifier(path, options, print) { +async function printModuleSpecifier(path, options, print) { const node = path.getNode(); const { type } = node; @@ -310,11 +310,11 @@ function printModuleSpecifier(path, options, print) { ) { left = "*"; } else if (leftSideNode) { - left = print(leftSideProperty); + left = await print(leftSideProperty); } if (rightSideNode && !isShorthandSpecifier(node)) { - right = print(rightSideProperty); + right = await print(rightSideProperty); } parts.push(left, left && right ? " as " : "", right); diff --git a/src/language-js/print/object.js b/src/language-js/print/object.js index 05548d996..ef214fdbe 100644 --- a/src/language-js/print/object.js +++ b/src/language-js/print/object.js @@ -29,7 +29,7 @@ import { printHardlineAfterHeritage } from "./class.js"; /** @typedef {import("../../document/builders.js").Doc} Doc */ -function printObject(path, options, print) { +async function printObject(path, options, print) { const semi = options.semi ? ";" : ""; const node = path.getValue(); @@ -101,11 +101,11 @@ function printObject(path, options, print) { // printing them. const propsAndLoc = []; for (const field of fields) { - path.each((childPath) => { + await path.each(async (childPath) => { const node = childPath.getValue(); propsAndLoc.push({ node, - printed: print(), + printed: await print(), loc: locStart(node), }); }, field); @@ -173,7 +173,11 @@ function printObject(path, options, print) { let content; if (props.length === 0) { if (!hasComment(node, CommentCheckFlags.Dangling)) { - return [leftBrace, rightBrace, printTypeAnnotation(path, options, print)]; + return [ + leftBrace, + rightBrace, + await printTypeAnnotation(path, options, print), + ]; } content = group([ @@ -182,7 +186,7 @@ function printObject(path, options, print) { softline, rightBrace, printOptionalToken(path), - printTypeAnnotation(path, options, print), + await printTypeAnnotation(path, options, print), ]); } else { content = [ @@ -200,7 +204,7 @@ function printObject(path, options, print) { options.bracketSpacing ? line : softline, rightBrace, printOptionalToken(path), - printTypeAnnotation(path, options, print), + await printTypeAnnotation(path, options, print), ]; } diff --git a/src/language-js/print/property.js b/src/language-js/print/property.js index b825fee5d..555631d5d 100644 --- a/src/language-js/print/property.js +++ b/src/language-js/print/property.js @@ -11,11 +11,11 @@ import { printAssignment } from "./assignment.js"; const needsQuoteProps = new WeakMap(); -function printPropertyKey(path, options, print) { +async function printPropertyKey(path, options, print) { const node = path.getNode(); if (node.computed) { - return ["[", print("key"), "]"]; + return ["[", await print("key"), "]"]; } const parent = path.getParentNode(); @@ -23,7 +23,7 @@ function printPropertyKey(path, options, print) { // flow has `Identifier` key, other parsers use `PrivateIdentifier` (ESTree) or `PrivateName` if (node.type === "ClassPrivateProperty" && key.type === "Identifier") { - return ["#", print("key")]; + return ["#", await print("key")]; } if (options.quoteProps === "consistent" && !needsQuoteProps.has(parent)) { @@ -87,7 +87,7 @@ function printPropertyKey(path, options, print) { return print("key"); } -function printProperty(path, options, print) { +async function printProperty(path, options, print) { const node = path.getValue(); if (node.shorthand) { return print("value"); @@ -97,7 +97,7 @@ function printProperty(path, options, print) { path, options, print, - printPropertyKey(path, options, print), + await printPropertyKey(path, options, print), ":", "value" ); diff --git a/src/language-js/print/statement.js b/src/language-js/print/statement.js index 456c09f0d..2c6a56e97 100644 --- a/src/language-js/print/statement.js +++ b/src/language-js/print/statement.js @@ -16,13 +16,13 @@ import { shouldPrintParamsWithoutParens } from "./function.js"; * @typedef {import("../../common/ast-path.js")} AstPath */ -function printStatementSequence(path, options, print, property) { +async function printStatementSequence(path, options, print, property) { const node = path.getValue(); const parts = []; const isClassBody = node.type === "ClassBody"; const lastStatement = getLastStatement(node[property]); - path.each((path, index, statements) => { + await path.each(async (path, index, statements) => { const node = path.getValue(); // Skip printing EmptyStatement nodes to avoid leaving stray @@ -31,7 +31,7 @@ function printStatementSequence(path, options, print, property) { return; } - const printed = print(); + const printed = await print(); // in no-semi mode, prepend statement with semicolon if it might break ASI // don't prepend the only JSX element in a program with semicolon @@ -42,7 +42,7 @@ function printStatementSequence(path, options, print, property) { statementNeedsASIProtection(path, options) ) { if (hasComment(node, CommentCheckFlags.Leading)) { - parts.push(print([], { needsSemi: true })); + parts.push(await print([], { needsSemi: true })); } else { parts.push(";", printed); } diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js index f5aacd5cc..85d667a77 100644 --- a/src/language-js/print/template-literal.js +++ b/src/language-js/print/template-literal.js @@ -20,7 +20,7 @@ import { isMemberExpression, } from "../utils/index.js"; -function printTemplateLiteral(path, print, options) { +async function printTemplateLiteral(path, print, options) { const node = path.getValue(); const isTemplateLiteral = node.type === "TemplateLiteral"; @@ -28,7 +28,7 @@ function printTemplateLiteral(path, print, options) { isTemplateLiteral && isJestEachTemplateLiteral(node, path.getParentNode()) ) { - const printed = printJestEachTemplateLiteral(path, options, print); + const printed = await printJestEachTemplateLiteral(path, options, print); if (printed) { return printed; } @@ -39,7 +39,7 @@ function printTemplateLiteral(path, print, options) { } const parts = []; - let expressions = path.map(print, expressionsKey); + let expressions = await path.map(print, expressionsKey); const isSimple = isSimpleTemplateLiteral(node); if (isSimple) { @@ -54,10 +54,10 @@ function printTemplateLiteral(path, print, options) { parts.push(lineSuffixBoundary, "`"); - path.each((childPath) => { + await path.each(async (childPath) => { const i = childPath.getName(); - parts.push(print()); + parts.push(await print()); if (i < expressions.length) { // For a template literal of the following form: @@ -107,7 +107,7 @@ function printTemplateLiteral(path, print, options) { return parts; } -function printJestEachTemplateLiteral(path, options, print) { +async function printJestEachTemplateLiteral(path, options, print) { /** * a | b | expected * ${1} | ${1} | ${2} @@ -121,7 +121,7 @@ function printJestEachTemplateLiteral(path, options, print) { headerNames.some((headerName) => headerName.length > 0) ) { options.__inJestEach = true; - const expressions = path.map(print, "expressions"); + const expressions = await path.map(print, "expressions"); options.__inJestEach = false; const parts = []; const stringifiedExpressions = expressions.map( @@ -196,9 +196,9 @@ function printJestEachTemplateLiteral(path, options, print) { } } -function printTemplateExpression(path, print) { +async function printTemplateExpression(path, print) { const node = path.getValue(); - let printed = print(); + let printed = await print(); if (hasComment(node)) { printed = group([indent([softline, printed]), softline]); } diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index 1658e1076..a7cf7254e 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -101,7 +101,7 @@ function conditionalExpressionChainContainsJsx(node) { return false; } -function printTernaryTest(path, options, print) { +async function printTernaryTest(path, options, print) { const node = path.getValue(); const isConditionalExpression = node.type === "ConditionalExpression"; const alternateNodePropertyName = isConditionalExpression @@ -111,8 +111,14 @@ function printTernaryTest(path, options, print) { const parent = path.getParentNode(); const printed = isConditionalExpression - ? print("test") - : [print("checkType"), " ", "extends", " ", print("extendsType")]; + ? await print("test") + : [ + await print("checkType"), + " ", + "extends", + " ", + await print("extendsType"), + ]; /** * a * ? b @@ -185,9 +191,9 @@ function shouldExtraIndentForConditionalExpression(path) { * @param {AstPath} path - The path to the ConditionalExpression/TSConditionalType node. * @param {Options} options - Prettier options * @param {Function} print - Print function to call recursively - * @returns {Doc} + * @returns {Promise} */ -function printTernary(path, options, print) { +async function printTernary(path, options, print) { const node = path.getValue(); const isConditionalExpression = node.type === "ConditionalExpression"; const consequentNodePropertyName = isConditionalExpression @@ -264,12 +270,12 @@ function printTernary(path, options, print) { parts.push( " ? ", isNil(consequentNode) - ? print(consequentNodePropertyName) - : wrap(print(consequentNodePropertyName)), + ? await print(consequentNodePropertyName) + : wrap(await print(consequentNodePropertyName)), " : ", alternateNode.type === node.type || isNil(alternateNode) - ? print(alternateNodePropertyName) - : wrap(print(alternateNodePropertyName)) + ? await print(alternateNodePropertyName) + : wrap(await print(alternateNodePropertyName)) ); } else { // normal mode @@ -277,13 +283,13 @@ function printTernary(path, options, print) { line, "? ", consequentNode.type === node.type ? ifBreak("", "(") : "", - align(2, print(consequentNodePropertyName)), + align(2, await print(consequentNodePropertyName)), consequentNode.type === node.type ? ifBreak("", ")") : "", line, ": ", alternateNode.type === node.type - ? print(alternateNodePropertyName) - : align(2, print(alternateNodePropertyName)), + ? await print(alternateNodePropertyName) + : align(2, await print(alternateNodePropertyName)), ]; parts.push( parent.type !== node.type || @@ -336,7 +342,7 @@ function printTernary(path, options, print) { const shouldExtraIndent = shouldExtraIndentForConditionalExpression(path); const result = maybeGroup([ - printTernaryTest(path, options, print), + await printTernaryTest(path, options, print), forceNoIndent ? parts : indent(parts), isConditionalExpression && breakClosingParen && !shouldExtraIndent ? softline diff --git a/src/language-js/print/type-annotation.js b/src/language-js/print/type-annotation.js index 0bf486c42..6e92bce63 100644 --- a/src/language-js/print/type-annotation.js +++ b/src/language-js/print/type-annotation.js @@ -56,18 +56,18 @@ function shouldHugType(node) { return false; } -function printOpaqueType(path, options, print) { +async function printOpaqueType(path, options, print) { const semi = options.semi ? ";" : ""; const node = path.getValue(); const parts = []; - parts.push("opaque type ", print("id"), print("typeParameters")); + parts.push("opaque type ", await print("id"), await print("typeParameters")); if (node.supertype) { - parts.push(": ", print("supertype")); + parts.push(": ", await print("supertype")); } if (node.impltype) { - parts.push(" = ", print("impltype")); + parts.push(" = ", await print("impltype")); } parts.push(semi); @@ -75,26 +75,26 @@ function printOpaqueType(path, options, print) { return parts; } -function printTypeAlias(path, options, print) { +async function printTypeAlias(path, options, print) { const semi = options.semi ? ";" : ""; const node = path.getValue(); const parts = []; if (node.declare) { parts.push("declare "); } - parts.push("type ", print("id"), print("typeParameters")); + parts.push("type ", await print("id"), await print("typeParameters")); const rightPropertyName = node.type === "TSTypeAliasDeclaration" ? "typeAnnotation" : "right"; return [ - printAssignment(path, options, print, parts, " =", rightPropertyName), + await printAssignment(path, options, print, parts, " =", rightPropertyName), semi, ]; } // `TSIntersectionType` and `IntersectionTypeAnnotation` -function printIntersectionType(path, options, print) { +async function printIntersectionType(path, options, print) { const node = path.getValue(); - const types = path.map(print, "types"); + const types = await path.map(print, "types"); const result = []; let wasIndented = false; for (let i = 0; i < types.length; ++i) { @@ -121,7 +121,7 @@ function printIntersectionType(path, options, print) { } // `TSUnionType` and `UnionTypeAnnotation` -function printUnionType(path, options, print) { +async function printUnionType(path, options, print) { const node = path.getValue(); // single-line variation // A | B | C @@ -164,8 +164,8 @@ function printUnionType(path, options, print) { // | child1 // // comment // | child2 - const printed = path.map((typePath) => { - let printedType = print(); + const printed = await path.map(async (typePath) => { + let printedType = await print(); if (!shouldHug) { printedType = align(2, printedType); } @@ -203,7 +203,7 @@ function printUnionType(path, options, print) { } // `TSFunctionType` and `FunctionTypeAnnotation` -function printFunctionType(path, options, print) { +async function printFunctionType(path, options, print) { const node = path.getValue(); const parts = []; // FunctionTypeAnnotation is ambiguous: @@ -246,7 +246,7 @@ function printFunctionType(path, options, print) { parts.push("("); } - const parametersDoc = printFunctionParameters( + const parametersDoc = await printFunctionParameters( path, print, options, @@ -260,9 +260,9 @@ function printFunctionType(path, options, print) { node.returnType || node.predicate || node.typeAnnotation ? [ isArrowFunctionTypeAnnotation ? " => " : ": ", - print("returnType"), - print("predicate"), - print("typeAnnotation"), + await print("returnType"), + await print("predicate"), + await print("typeAnnotation"), ] : ""; @@ -285,7 +285,7 @@ function printFunctionType(path, options, print) { } // `TSTupleType` and `TupleTypeAnnotation` -function printTupleType(path, options, print) { +async function printTupleType(path, options, print) { const node = path.getValue(); const typesField = node.type === "TSTupleType" ? "elementTypes" : "types"; const types = node[typesField]; @@ -295,7 +295,7 @@ function printTupleType(path, options, print) { "[", indent([ bracketsDelimiterLine, - printArrayItems(path, options, typesField, print), + await printArrayItems(path, options, typesField, print), ]), ifBreak(isNonEmptyTuple && shouldPrintComma(options, "all") ? "," : ""), printDanglingComments(path, options, /* sameIndent */ true), @@ -305,19 +305,24 @@ function printTupleType(path, options, print) { } // `TSIndexedAccessType`, `IndexedAccessType`, and `OptionalIndexedAccessType` -function printIndexedAccessType(path, options, print) { +async function printIndexedAccessType(path, options, print) { const node = path.getValue(); const leftDelimiter = node.type === "OptionalIndexedAccessType" && node.optional ? "?.[" : "["; - return [print("objectType"), leftDelimiter, print("indexType"), "]"]; + return [ + await print("objectType"), + leftDelimiter, + await print("indexType"), + "]", + ]; } // `TSJSDocNullableType`, `TSJSDocNonNullableType` -function printJSDocType(path, print, token) { +async function printJSDocType(path, print, token) { const node = path.getValue(); return [ node.postfix ? "" : token, - print("typeAnnotation"), + await print("typeAnnotation"), node.postfix ? token : "", ]; } diff --git a/src/language-js/print/type-parameters.js b/src/language-js/print/type-parameters.js index bf68e5441..dbc04a334 100644 --- a/src/language-js/print/type-parameters.js +++ b/src/language-js/print/type-parameters.js @@ -23,7 +23,7 @@ import { isArrowFunctionVariableDeclarator } from "./assignment.js"; const getTypeParametersGroupId = createGroupIdMapper("typeParameters"); -function printTypeParameters(path, options, print, paramsKey) { +async function printTypeParameters(path, options, print, paramsKey) { const node = path.getValue(); if (!node[paramsKey]) { @@ -58,7 +58,7 @@ function printTypeParameters(path, options, print, paramsKey) { if (shouldInline) { return [ "<", - join(", ", path.map(print, paramsKey)), + join(", ", await path.map(print, paramsKey)), printDanglingCommentsForInline(path, options), ">", ]; @@ -82,7 +82,7 @@ function printTypeParameters(path, options, print, paramsKey) { return group( [ "<", - indent([softline, join([",", line], path.map(print, paramsKey))]), + indent([softline, join([",", line], await path.map(print, paramsKey))]), trailingComma, softline, ">", @@ -108,27 +108,24 @@ function printDanglingCommentsForInline(path, options) { return [printed, hardline]; } -function printTypeParameter(path, options, print) { +async function printTypeParameter(path, options, print) { const node = path.getValue(); const parts = []; const parent = path.getParentNode(); if (parent.type === "TSMappedType") { - parts.push("[", print("name")); + parts.push("[", await print("name")); if (node.constraint) { - parts.push(" in ", print("constraint")); + parts.push(" in ", await print("constraint")); } if (parent.nameType) { - parts.push( - " as ", - path.callParent(() => print("nameType")) - ); + parts.push(" as ", await path.callParent(() => print("nameType"))); } parts.push("]"); return parts; } if (node.variance) { - parts.push(print("variance")); + parts.push(await print("variance")); } if (node.in) { @@ -139,18 +136,18 @@ function printTypeParameter(path, options, print) { parts.push("out "); } - parts.push(print("name")); + parts.push(await print("name")); if (node.bound) { - parts.push(": ", print("bound")); + parts.push(": ", await print("bound")); } if (node.constraint) { - parts.push(" extends ", print("constraint")); + parts.push(" extends ", await print("constraint")); } if (node.default) { - parts.push(" = ", print("default")); + parts.push(" = ", await print("default")); } return parts; diff --git a/src/language-js/print/typescript.js b/src/language-js/print/typescript.js index b0d690574..ed71b6e6c 100644 --- a/src/language-js/print/typescript.js +++ b/src/language-js/print/typescript.js @@ -45,7 +45,7 @@ import { printJSDocType, } from "./type-annotation.js"; -function printTypescript(path, options, print) { +async function printTypescript(path, options, print) { const node = path.getValue(); // TypeScript nodes always starts with `TS` @@ -71,31 +71,31 @@ function printTypescript(path, options, print) { const castGroup = group([ "<", - indent([softline, print("typeAnnotation")]), + indent([softline, await print("typeAnnotation")]), softline, ">", ]); const exprContents = [ ifBreak("("), - indent([softline, print("expression")]), + indent([softline, await print("expression")]), softline, ifBreak(")"), ]; if (shouldBreakAfterCast) { return conditionalGroup([ - [castGroup, print("expression")], + [castGroup, await print("expression")], [castGroup, group(exprContents, { shouldBreak: true })], - [castGroup, print("expression")], + [castGroup, await print("expression")], ]); } - return group([castGroup, print("expression")]); + return group([castGroup, await print("expression")]); } case "TSDeclareFunction": return printFunction(path, print, options); case "TSExportAssignment": - return ["export = ", print("expression"), semi]; + return ["export = ", await print("expression"), semi]; case "TSModuleBlock": return printBlock(path, options, print); case "TSInterfaceBody": @@ -104,7 +104,7 @@ function printTypescript(path, options, print) { case "TSTypeAliasDeclaration": return printTypeAlias(path, options, print); case "TSQualifiedName": - return join(".", [print("left"), print("right")]); + return join(".", [await print("left"), await print("right")]); case "TSAbstractMethodDefinition": case "TSDeclareMethod": return printClassMethod(path, options, print); @@ -112,10 +112,10 @@ function printTypescript(path, options, print) { return printClassProperty(path, options, print); case "TSInterfaceHeritage": case "TSExpressionWithTypeArguments": // Babel AST - parts.push(print("expression")); + parts.push(await print("expression")); if (node.typeParameters) { - parts.push(print("typeParameters")); + parts.push(await print("typeParameters")); } return parts; @@ -123,26 +123,30 @@ function printTypescript(path, options, print) { return printTemplateLiteral(path, print, options); case "TSNamedTupleMember": return [ - print("label"), + await print("label"), node.optional ? "?" : "", ": ", - print("elementType"), + await print("elementType"), ]; case "TSRestType": - return ["...", print("typeAnnotation")]; + return ["...", await print("typeAnnotation")]; case "TSOptionalType": - return [print("typeAnnotation"), "?"]; + return [await print("typeAnnotation"), "?"]; case "TSInterfaceDeclaration": return printInterface(path, options, print); case "TSClassImplements": - return [print("expression"), print("typeParameters")]; + return [await print("expression"), await print("typeParameters")]; case "TSTypeParameterDeclaration": case "TSTypeParameterInstantiation": return printTypeParameters(path, options, print, "params"); case "TSTypeParameter": return printTypeParameter(path, options, print); case "TSAsExpression": { - parts.push(print("expression"), " as ", print("typeAnnotation")); + parts.push( + await print("expression"), + " as ", + await print("typeAnnotation") + ); const parent = path.getParentNode(); if ( (isCallExpression(parent) && parent.callee === node) || @@ -153,24 +157,24 @@ function printTypescript(path, options, print) { return parts; } case "TSArrayType": - return [print("elementType"), "[]"]; + return [await print("elementType"), "[]"]; case "TSPropertySignature": { if (node.readonly) { parts.push("readonly "); } parts.push( - printPropertyKey(path, options, print), - printOptionalToken(path) + await printPropertyKey(path, options, print), + await printOptionalToken(path) ); if (node.typeAnnotation) { - parts.push(": ", print("typeAnnotation")); + parts.push(": ", await print("typeAnnotation")); } // This isn't valid semantically, but it's in the AST so we can print it. if (node.initializer) { - parts.push(" = ", print("initializer")); + parts.push(" = ", await print("initializer")); } return parts; @@ -192,11 +196,15 @@ function printTypescript(path, options, print) { parts.push("readonly "); } - parts.push(print("parameter")); + parts.push(await print("parameter")); return parts; case "TSTypeQuery": - return ["typeof ", print("exprName"), print("typeParameters")]; + return [ + "typeof ", + await print("exprName"), + await print("typeParameters"), + ]; case "TSIndexSignature": { const parent = path.getParentNode(); @@ -212,7 +220,7 @@ function printTypescript(path, options, print) { const parametersGroup = group([ indent([ softline, - join([", ", softline], path.map(print, "parameters")), + join([", ", softline], await path.map(print, "parameters")), ]), trailingComma, softline, @@ -227,26 +235,26 @@ function printTypescript(path, options, print) { "[", node.parameters ? parametersGroup : "", node.typeAnnotation ? "]: " : "]", - node.typeAnnotation ? print("typeAnnotation") : "", + node.typeAnnotation ? await print("typeAnnotation") : "", parent.type === "ClassBody" ? semi : "", ]; } case "TSTypePredicate": return [ node.asserts ? "asserts " : "", - print("parameterName"), - node.typeAnnotation ? [" is ", print("typeAnnotation")] : "", + await print("parameterName"), + node.typeAnnotation ? [" is ", await print("typeAnnotation")] : "", ]; case "TSNonNullExpression": - return [print("expression"), "!"]; + return [await print("expression"), "!"]; case "TSImportType": return [ !node.isTypeOf ? "" : "typeof ", "import(", - print(node.parameter ? "parameter" : "argument"), + await print(node.parameter ? "parameter" : "argument"), ")", - !node.qualifier ? "" : [".", print("qualifier")], - printTypeParameters(path, options, print, "typeParameters"), + !node.qualifier ? "" : [".", await print("qualifier")], + await printTypeParameters(path, options, print, "typeParameters"), ]; case "TSLiteralType": return print("literal"); @@ -264,7 +272,7 @@ function printTypescript(path, options, print) { parts.push( group( - printFunctionParameters( + await printFunctionParameters( path, print, options, @@ -278,14 +286,14 @@ function printTypescript(path, options, print) { const isType = node.type === "TSConstructorType"; parts.push( isType ? " => " : ": ", - print("returnType"), - print("typeAnnotation") + await print("returnType"), + await print("typeAnnotation") ); } return parts; } case "TSTypeOperator": - return [node.operator, " ", print("typeAnnotation")]; + return [node.operator, " ", await print("typeAnnotation")]; case "TSMappedType": { const shouldBreak = hasNewlineInRange( options.originalText, @@ -303,13 +311,13 @@ function printTypescript(path, options, print) { " ", ] : "", - printTypeScriptModifiers(path, options, print), - print("typeParameter"), + await printTypeScriptModifiers(path, options, print), + await print("typeParameter"), node.optional ? getTypeScriptMappedTypeModifier(node.optional, "?") : "", node.typeAnnotation ? ": " : "", - print("typeAnnotation"), + await print("typeAnnotation"), ifBreak(semi), ]), printDanglingComments(path, options, /* sameIndent */ true), @@ -332,12 +340,12 @@ function printTypescript(path, options, print) { node.abstract ? "abstract " : "", node.declare ? "declare " : "", node.computed ? "[" : "", - print("key"), + await print("key"), node.computed ? "]" : "", printOptionalToken(path) ); - const parametersDoc = printFunctionParameters( + const parametersDoc = await printFunctionParameters( path, print, options, @@ -349,7 +357,9 @@ function printTypescript(path, options, print) { ? "returnType" : "typeAnnotation"; const returnTypeNode = node[returnTypePropertyName]; - const returnTypeDoc = returnTypeNode ? print(returnTypePropertyName) : ""; + const returnTypeDoc = returnTypeNode + ? await print(returnTypePropertyName) + : ""; const shouldGroupParameters = shouldGroupFunctionParameters( node, returnTypeDoc @@ -364,7 +374,7 @@ function printTypescript(path, options, print) { return group(parts); } case "TSNamespaceExportDeclaration": - parts.push("export as namespace ", print("id")); + parts.push("export as namespace ", await print("id")); if (options.semi) { parts.push(";"); @@ -377,13 +387,13 @@ function printTypescript(path, options, print) { } if (node.modifiers) { - parts.push(printTypeScriptModifiers(path, options, print)); + parts.push(await printTypeScriptModifiers(path, options, print)); } if (node.const) { parts.push("const "); } - parts.push("enum ", print("id"), " "); + parts.push("enum ", await print("id"), " "); if (node.members.length === 0) { parts.push( @@ -395,7 +405,7 @@ function printTypescript(path, options, print) { "{", indent([ hardline, - printArrayItems(path, options, "members", print), + await printArrayItems(path, options, "members", print), shouldPrintComma(options, "es5") ? "," : "", ]), printDanglingComments(path, options, /* sameIndent */ true), @@ -408,13 +418,13 @@ function printTypescript(path, options, print) { return parts; case "TSEnumMember": if (node.computed) { - parts.push("[", print("id"), "]"); + parts.push("[", await print("id"), "]"); } else { - parts.push(print("id")); + parts.push(await print("id")); } if (node.initializer) { - parts.push(" = ", print("initializer")); + parts.push(" = ", await print("initializer")); } return parts; case "TSImportEqualsDeclaration": @@ -428,7 +438,7 @@ function printTypescript(path, options, print) { parts.push(node.importKind, " "); } - parts.push(print("id"), " = ", print("moduleReference")); + parts.push(await print("id"), " = ", await print("moduleReference")); if (options.semi) { parts.push(";"); @@ -436,7 +446,7 @@ function printTypescript(path, options, print) { return group(parts); case "TSExternalModuleReference": - return ["require(", print("expression"), ")"]; + return ["require(", await print("expression"), ")"]; case "TSModuleDeclaration": { const parent = path.getParentNode(); const isExternalModule = isLiteral(node.id); @@ -450,7 +460,7 @@ function printTypescript(path, options, print) { if (node.declare) { parts.push("declare "); } - parts.push(printTypeScriptModifiers(path, options, print)); + parts.push(await printTypeScriptModifiers(path, options, print)); const textBetweenNodeAndItsId = options.originalText.slice( locStart(node), @@ -474,12 +484,12 @@ function printTypescript(path, options, print) { } } - parts.push(print("id")); + parts.push(await print("id")); if (bodyIsDeclaration) { - parts.push(print("body")); + parts.push(await print("body")); } else if (node.body) { - parts.push(" ", group(print("body"))); + parts.push(" ", group(await print("body"))); } else { parts.push(semi); } @@ -491,7 +501,7 @@ function printTypescript(path, options, print) { return printTernary(path, options, print); case "TSInferType": - return ["infer", " ", print("typeParameter")]; + return ["infer", " ", await print("typeParameter")]; case "TSIntersectionType": return printIntersectionType(path, options, print); case "TSUnionType": @@ -502,8 +512,8 @@ function printTypescript(path, options, print) { return printTupleType(path, options, print); case "TSTypeReference": return [ - print("typeName"), - printTypeParameters(path, options, print, "typeParameters"), + await print("typeName"), + await printTypeParameters(path, options, print, "typeParameters"), ]; case "TSTypeAnnotation": return print("typeAnnotation"); @@ -520,7 +530,7 @@ function printTypescript(path, options, print) { case "TSJSDocNonNullableType": return printJSDocType(path, print, /* token */ "!"); case "TSInstantiationExpression": - return [print("expression"), print("typeParameters")]; + return [await print("expression"), await print("typeParameters")]; default: /* istanbul ignore next */ throw new Error( diff --git a/src/language-js/printer-estree-json.js b/src/language-js/printer-estree-json.js index 423758509..58b4011f6 100644 --- a/src/language-js/printer-estree-json.js +++ b/src/language-js/printer-estree-json.js @@ -1,17 +1,18 @@ import { hardline, indent, join } from "../document/builders.js"; import preprocess from "./print-preprocess.js"; -function genericPrint(path, options, print) { +async function genericPrint(path, options, print) { const node = path.getValue(); + switch (node.type) { case "JsonRoot": - return [print("node"), hardline]; + return [await print("node"), hardline]; case "ArrayExpression": { if (node.elements.length === 0) { return "[]"; } - const printed = path.map( + const printed = await path.map( () => (path.getValue() === null ? "null" : print()), "elements" ); @@ -30,15 +31,18 @@ function genericPrint(path, options, print) { "{", indent([ hardline, - join([",", hardline], path.map(print, "properties")), + join([",", hardline], await path.map(print, "properties")), ]), hardline, "}", ]; case "ObjectProperty": - return [print("key"), ": ", print("value")]; + return [await print("key"), ": ", await print("value")]; case "UnaryExpression": - return [node.operator === "+" ? "" : node.operator, print("argument")]; + return [ + node.operator === "+" ? "" : node.operator, + await print("argument"), + ]; case "NullLiteral": return "null"; case "BooleanLiteral": diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index b984d8e9c..17525657d 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -87,8 +87,8 @@ import { printComment } from "./print/comment.js"; import { printLiteral } from "./print/literal.js"; import { printDecorators } from "./print/decorators.js"; -function genericPrint(path, options, print, args) { - const printed = printPathNoParens(path, options, print, args); +async function genericPrint(path, options, print, args) { + const printed = await printPathNoParens(path, options, print, args); if (!printed) { return ""; } @@ -113,7 +113,7 @@ function genericPrint(path, options, print, args) { let parts = [printed]; - const printedDecorators = printDecorators(path, options, print); + const printedDecorators = await printDecorators(path, options, print); const isClassExpressionWithDecorators = node.type === "ClassExpression" && printedDecorators; // Nodes (except `ClassExpression`) with decorators can't have parentheses and don't need leading semicolons @@ -165,7 +165,7 @@ function genericPrint(path, options, print, args) { return parts; } -function printPathNoParens(path, options, print, args) { +async function printPathNoParens(path, options, print, args) { const node = path.getValue(); const semi = options.semi ? ";" : ""; @@ -185,7 +185,7 @@ function printPathNoParens(path, options, print, args) { printFlow, printTypescript, ]) { - const printed = printer(path, options, print); + const printed = await printer(path, options, print); if (typeof printed !== "undefined") { return printed; } @@ -198,15 +198,15 @@ function printPathNoParens(path, options, print, args) { case "JsExpressionRoot": return print("node"); case "JsonRoot": - return [print("node"), hardline]; + return [await print("node"), hardline]; case "File": // Print @babel/parser's InterpreterDirective here so that // leading comments on the `Program` node get printed after the hashbang. if (node.program && node.program.interpreter) { - parts.push(print(["program", "interpreter"])); + parts.push(await print(["program", "interpreter"])); } - parts.push(print("program")); + parts.push(await print("program")); return parts; @@ -218,7 +218,7 @@ function printPathNoParens(path, options, print, args) { case "ExpressionStatement": { // Detect Flow and TypeScript directives if (node.directive) { - return [printDirective(node.expression, options), semi]; + return [await printDirective(node.expression, options), semi]; } if ( @@ -232,7 +232,7 @@ function printPathNoParens(path, options, print, args) { parent.body[0] === node ) { return [ - print("expression"), + await print("expression"), isVueEventBindingExpression(node.expression) ? ";" : "", ]; } @@ -247,7 +247,7 @@ function printPathNoParens(path, options, print, args) { // Do not append semicolon after the only JSX element in a program return [ - print("expression"), + await print("expression"), isTheOnlyJsxElementInMarkdown(options, path) ? "" : semi, danglingComment ? [" ", danglingComment] : "", ]; @@ -259,11 +259,11 @@ function printPathNoParens(path, options, print, args) { (node.expression.type === "ObjectExpression" || node.expression.type === "ArrayExpression"); if (shouldHug) { - return ["(", print("expression"), ")"]; + return ["(", await print("expression"), ")"]; } return group([ "(", - indent([softline, print("expression")]), + indent([softline, await print("expression")]), softline, ")", ]); @@ -276,21 +276,24 @@ function printPathNoParens(path, options, print, args) { case "LogicalExpression": return printBinaryishExpression(path, options, print); case "AssignmentPattern": - return [print("left"), " = ", print("right")]; + return [await print("left"), " = ", await print("right")]; case "OptionalMemberExpression": case "MemberExpression": { return printMemberExpression(path, options, print); } case "MetaProperty": - return [print("meta"), ".", print("property")]; + return [await print("meta"), ".", await print("property")]; case "BindExpression": if (node.object) { - parts.push(print("object")); + parts.push(await print("object")); } parts.push( group( - indent([softline, printBindExpressionCallee(path, options, print)]) + indent([ + softline, + await printBindExpressionCallee(path, options, print), + ]) ) ); @@ -298,9 +301,9 @@ function printPathNoParens(path, options, print, args) { case "Identifier": { return [ node.name, - printOptionalToken(path), - printDefiniteToken(path), - printTypeAnnotation(path, options, print), + await printOptionalToken(path), + await printDefiniteToken(path), + await printTypeAnnotation(path, options, print), ]; } case "V8IntrinsicIdentifier": @@ -323,14 +326,14 @@ function printPathNoParens(path, options, print, args) { parts.push("*"); } if (node.argument) { - parts.push(" ", print("argument")); + parts.push(" ", await print("argument")); } return parts; case "AwaitExpression": { parts.push("await"); if (node.argument) { - parts.push(" ", print("argument")); + parts.push(" ", await print("argument")); const parent = path.getParentNode(); if ( (isCallExpression(parent) && parent.callee === node) || @@ -366,7 +369,7 @@ function printPathNoParens(path, options, print, args) { case "ExportDefaultSpecifier": return printModuleSpecifier(path, options, print); case "ImportAttribute": - return [print("key"), ": ", print("value")]; + return [await print("key"), ": ", await print("value")]; case "Import": return "import"; case "BlockStatement": @@ -397,7 +400,7 @@ function printPathNoParens(path, options, print, args) { case "ObjectMethod": return printMethod(path, options, print); case "Decorator": - return ["@", print("expression")]; + return ["@", await print("expression")]; case "ArrayExpression": case "ArrayPattern": case "TupleExpression": @@ -412,23 +415,23 @@ function printPathNoParens(path, options, print, args) { // the few places a SequenceExpression appears unparenthesized, we want // to indent expressions after the first. const parts = []; - path.each((expressionPath, index) => { + await path.each(async (expressionPath, index) => { if (index === 0) { - parts.push(print()); + parts.push(await print()); } else { - parts.push(",", indent([line, print()])); + parts.push(",", indent([line, await print()])); } }, "expressions"); return group(parts); } - return group(join([",", line], path.map(print, "expressions"))); + return group(join([",", line], await path.map(print, "expressions"))); } case "ThisExpression": return "this"; case "Super": return "super"; case "Directive": - return [print("value"), semi]; // Babel 6 + return [await print("value"), semi]; // Babel 6 case "DirectiveLiteral": return printDirective(node, options); case "UnaryExpression": @@ -440,15 +443,20 @@ function printPathNoParens(path, options, print, args) { if (hasComment(node.argument)) { parts.push( - group(["(", indent([softline, print("argument")]), softline, ")"]) + group([ + "(", + indent([softline, await print("argument")]), + softline, + ")", + ]) ); } else { - parts.push(print("argument")); + parts.push(await print("argument")); } return parts; case "UpdateExpression": - parts.push(print("argument"), node.operator); + parts.push(await print("argument"), node.operator); if (node.prefix) { parts.reverse(); @@ -458,7 +466,7 @@ function printPathNoParens(path, options, print, args) { case "ConditionalExpression": return printTernary(path, options, print); case "VariableDeclaration": { - const printed = path.map(print, "declarations"); + const printed = await path.map(print, "declarations"); // We generally want to terminate all variable declarations with a // semicolon, except when they in the () part of for loops. @@ -503,15 +511,15 @@ function printPathNoParens(path, options, print, args) { case "WithStatement": return group([ "with (", - print("object"), + await print("object"), ")", - adjustClause(node.body, print("body")), + adjustClause(node.body, await print("body")), ]); case "IfStatement": { - const con = adjustClause(node.consequent, print("consequent")); + const con = adjustClause(node.consequent, await print("consequent")); const opening = group([ "if (", - group([indent([softline, print("test")]), softline]), + group([indent([softline, await print("test")]), softline]), ")", con, ]); @@ -540,7 +548,7 @@ function printPathNoParens(path, options, print, args) { group( adjustClause( node.alternate, - print("alternate"), + await print("alternate"), node.alternate.type === "IfStatement" ) ) @@ -550,7 +558,7 @@ function printPathNoParens(path, options, print, args) { return parts; } case "ForStatement": { - const body = adjustClause(node.body, print("body")); + const body = adjustClause(node.body, await print("body")); // We want to keep dangling comments above the loop to stay consistent. // Any comment positioned between the for statement and the parentheses @@ -573,13 +581,13 @@ function printPathNoParens(path, options, print, args) { group([ indent([ softline, - print("init"), + await print("init"), ";", line, - print("test"), + await print("test"), ";", line, - print("update"), + await print("update"), ]), softline, ]), @@ -591,18 +599,18 @@ function printPathNoParens(path, options, print, args) { case "WhileStatement": return group([ "while (", - group([indent([softline, print("test")]), softline]), + group([indent([softline, await print("test")]), softline]), ")", - adjustClause(node.body, print("body")), + adjustClause(node.body, await print("body")), ]); case "ForInStatement": return group([ "for (", - print("left"), + await print("left"), " in ", - print("right"), + await print("right"), ")", - adjustClause(node.body, print("body")), + adjustClause(node.body, await print("body")), ]); case "ForOfStatement": @@ -610,15 +618,15 @@ function printPathNoParens(path, options, print, args) { "for", node.await ? " await" : "", " (", - print("left"), + await print("left"), " of ", - print("right"), + await print("right"), ")", - adjustClause(node.body, print("body")), + adjustClause(node.body, await print("body")), ]); case "DoWhileStatement": { - const clause = adjustClause(node.body, print("body")); + const clause = adjustClause(node.body, await print("body")); const doBody = group(["do", clause]); parts = [doBody]; @@ -629,7 +637,7 @@ function printPathNoParens(path, options, print, args) { } parts.push( "while (", - group([indent([softline, print("test")]), softline]), + group([indent([softline, await print("test")]), softline]), ")", semi ); @@ -637,12 +645,12 @@ function printPathNoParens(path, options, print, args) { return parts; } case "DoExpression": - return [node.async ? "async " : "", "do ", print("body")]; + return [node.async ? "async " : "", "do ", await print("body")]; case "BreakStatement": parts.push("break"); if (node.label) { - parts.push(" ", print("label")); + parts.push(" ", await print("label")); } parts.push(semi); @@ -652,7 +660,7 @@ function printPathNoParens(path, options, print, args) { parts.push("continue"); if (node.label) { - parts.push(" ", print("label")); + parts.push(" ", await print("label")); } parts.push(semi); @@ -660,16 +668,16 @@ function printPathNoParens(path, options, print, args) { return parts; case "LabeledStatement": if (node.body.type === "EmptyStatement") { - return [print("label"), ":;"]; + return [await print("label"), ":;"]; } - return [print("label"), ": ", print("body")]; + return [await print("label"), ": ", await print("body")]; case "TryStatement": return [ "try ", - print("block"), - node.handler ? [" ", print("handler")] : "", - node.finalizer ? [" finally ", print("finalizer")] : "", + await print("block"), + node.handler ? [" ", await print("handler")] : "", + node.finalizer ? [" finally ", await print("finalizer")] : "", ]; case "CatchClause": if (node.param) { @@ -684,24 +692,24 @@ function printPathNoParens(path, options, print, args) { backwards: true, })) ); - const param = print("param"); + const param = await print("param"); return [ "catch ", parameterHasComments ? ["(", indent([softline, param]), softline, ") "] : ["(", param, ") "], - print("body"), + await print("body"), ]; } - return ["catch ", print("body")]; + return ["catch ", await print("body")]; // Note: ignoring n.lexical because it has no printing consequences. case "SwitchStatement": return [ group([ "switch (", - indent([softline, print("discriminant")]), + indent([softline, await print("discriminant")]), softline, ")", ]), @@ -711,10 +719,10 @@ function printPathNoParens(path, options, print, args) { hardline, join( hardline, - path.map((casePath, index, cases) => { + await path.map(async (casePath, index, cases) => { const caseNode = casePath.getValue(); return [ - print(), + await print(), index !== cases.length - 1 && isNextLineEmpty(caseNode, options) ? hardline @@ -729,7 +737,7 @@ function printPathNoParens(path, options, print, args) { ]; case "SwitchCase": { if (node.test) { - parts.push("case ", print("test"), ":"); + parts.push("case ", await print("test"), ":"); } else { parts.push("default:"); } @@ -743,7 +751,7 @@ function printPathNoParens(path, options, print, args) { ); if (consequent.length > 0) { - const cons = printSwitchCaseConsequent(path, options, print); + const cons = await printSwitchCaseConsequent(path, options, print); parts.push( consequent.length === 1 && consequent[0].type === "BlockStatement" @@ -775,11 +783,15 @@ function printPathNoParens(path, options, print, args) { case "TemplateLiteral": return printTemplateLiteral(path, print, options); case "TaggedTemplateExpression": - return [print("tag"), print("typeParameters"), print("quasi")]; + return [ + await print("tag"), + await print("typeParameters"), + await print("quasi"), + ]; case "PrivateIdentifier": - return ["#", print("name")]; + return ["#", await print("name")]; case "PrivateName": - return ["#", print("id")]; + return ["#", await print("id")]; case "InterpreterDirective": parts.push("#!", node.value, hardline); @@ -799,7 +811,7 @@ function printPathNoParens(path, options, print, args) { case "ModuleExpression": { parts.push("module {"); - const printed = print("body"); + const printed = await print("body"); if (printed) { parts.push(indent([hardline, printed]), hardline); } diff --git a/src/language-js/utils/index.js b/src/language-js/utils/index.js index 9247b5aff..203b67e83 100644 --- a/src/language-js/utils/index.js +++ b/src/language-js/utils/index.js @@ -1120,20 +1120,20 @@ function getFunctionParameters(node) { return parameters; } -function iterateFunctionParametersPath(path, iteratee) { +async function iterateFunctionParametersPath(path, iteratee) { const node = path.getValue(); let index = 0; const callback = (childPath) => iteratee(childPath, index++); if (node.this) { - path.call(callback, "this"); + await path.call(callback, "this"); } if (Array.isArray(node.parameters)) { - path.each(callback, "parameters"); + await path.each(callback, "parameters"); } else if (Array.isArray(node.params)) { - path.each(callback, "params"); + await path.each(callback, "params"); } if (node.rest) { - path.call(callback, "rest"); + await path.call(callback, "rest"); } } @@ -1156,16 +1156,16 @@ function getCallArguments(node) { return args; } -function iterateCallArgumentsPath(path, iteratee) { +async function iterateCallArgumentsPath(path, iteratee) { const node = path.getValue(); if (node.type === "ImportExpression") { - path.call((sourcePath) => iteratee(sourcePath, 0), "source"); + await path.call((sourcePath) => iteratee(sourcePath, 0), "source"); if (node.attributes) { - path.call((sourcePath) => iteratee(sourcePath, 1), "attributes"); + await path.call((sourcePath) => iteratee(sourcePath, 1), "attributes"); } } else { - path.each(iteratee, "arguments"); + await path.each(iteratee, "arguments"); } } diff --git a/src/language-markdown/embed.js b/src/language-markdown/embed.js index 1e19f5121..30d5c7bb5 100644 --- a/src/language-markdown/embed.js +++ b/src/language-markdown/embed.js @@ -7,7 +7,7 @@ import { replaceEndOfLine } from "../document/utils.js"; import printFrontMatter from "../utils/front-matter/print.js"; import { getFencedCodeBlockValue } from "./utils.js"; -function embed(path, print, textToDoc, options) { +async function embed(path, print, textToDoc, options) { const node = path.getValue(); if (node.type === "code" && node.lang !== null) { @@ -21,7 +21,7 @@ function embed(path, print, textToDoc, options) { if (node.lang === "tsx") { newOptions.filepath = "dummy.tsx"; } - const doc = textToDoc( + const doc = await textToDoc( getFencedCodeBlockValue(node, options.originalText), newOptions, { stripTrailingHardline: true } @@ -45,7 +45,7 @@ function embed(path, print, textToDoc, options) { // MDX case "importExport": return [ - textToDoc( + await textToDoc( node.value, { parser: "babel" }, { stripTrailingHardline: true } diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index adfd7df42..004ab6583 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -49,7 +49,7 @@ const SIBLING_NODE_TYPES = new Set([ "footnoteDefinition", ]); -function genericPrint(path, options, print) { +async function genericPrint(path, options, print) { const node = path.getValue(); if (shouldRemainTheSameContent(path)) { @@ -79,7 +79,7 @@ function genericPrint(path, options, print) { return ""; } return [ - normalizeDoc(printRoot(path, options, print)), + normalizeDoc(await printRoot(path, options, print)), !TRAILING_HARDLINE_NODES.has(getLastDescendantNode(node).type) ? hardline : "", @@ -167,12 +167,12 @@ function genericPrint(path, options, print) { style = hasPrevOrNextWord || getAncestorNode(path, "emphasis") ? "*" : "_"; } - return [style, printChildren(path, options, print), style]; + return [style, await printChildren(path, options, print), style]; } case "strong": - return ["**", printChildren(path, options, print), "**"]; + return ["**", await printChildren(path, options, print), "**"]; case "delete": - return ["~~", printChildren(path, options, print), "~~"]; + return ["~~", await printChildren(path, options, print), "~~"]; case "inlineCode": { const backtickCount = getMinNotPresentContinuousCount(node.value, "`"); const style = "`".repeat(backtickCount || 1); @@ -207,7 +207,7 @@ function genericPrint(path, options, print) { case "[": return [ "[", - printChildren(path, options, print), + await printChildren(path, options, print), "](", printUrl(node.url, ")"), printTitle(node.title, options), @@ -229,11 +229,11 @@ function genericPrint(path, options, print) { ")", ]; case "blockquote": - return ["> ", align("> ", printChildren(path, options, print))]; + return ["> ", align("> ", await printChildren(path, options, print))]; case "heading": return [ "#".repeat(node.depth) + " ", - printChildren(path, options, print), + await printChildren(path, options, print), ]; case "code": { if (node.isIndented) { @@ -290,7 +290,7 @@ function genericPrint(path, options, print) { ); return printChildren(path, options, print, { - processor: (childPath, index) => { + processor: async (childPath, index) => { const prefix = getPrefix(); const childNode = childPath.getValue(); @@ -300,14 +300,17 @@ function genericPrint(path, options, print) { childNode.children[0].position.start.column !== childNode.children[1].position.start.column ) { - return [prefix, printListItem(childPath, options, print, prefix)]; + return [ + prefix, + await printListItem(childPath, options, print, prefix), + ]; } return [ prefix, align( " ".repeat(prefix.length), - printListItem(childPath, options, print, prefix) + await printListItem(childPath, options, print, prefix) ), ]; @@ -345,7 +348,7 @@ function genericPrint(path, options, print) { case "linkReference": return [ "[", - printChildren(path, options, print), + await printChildren(path, options, print), "]", node.referenceType === "full" ? ["[", node.identifier, "]"] @@ -384,7 +387,7 @@ function genericPrint(path, options, print) { // https://github.com/remarkjs/remark-footnotes#optionsinlinenotes /* istanbul ignore next */ case "footnote": - return ["[^", printChildren(path, options, print), "]"]; + return ["[^", await printChildren(path, options, print), "]"]; case "footnoteReference": return ["[^", node.identifier, "]"]; case "footnoteDefinition": { @@ -401,13 +404,13 @@ function genericPrint(path, options, print) { node.identifier, "]: ", shouldInlineFootnote - ? printChildren(path, options, print) + ? await printChildren(path, options, print) : group([ align( " ".repeat(4), - printChildren(path, options, print, { - processor: (childPath, index) => - index === 0 ? group([softline, print()]) : print(), + await printChildren(path, options, print, { + processor: async (childPath, index) => + index === 0 ? group([softline, await print()]) : print(), }) ), nextNode && nextNode.type === "footnoteDefinition" @@ -458,21 +461,21 @@ function genericPrint(path, options, print) { } } -function printListItem(path, options, print, listPrefix) { +async function printListItem(path, options, print, listPrefix) { const node = path.getValue(); const prefix = node.checked === null ? "" : node.checked ? "[x] " : "[ ] "; return [ prefix, - printChildren(path, options, print, { - processor: (childPath, index) => { + await printChildren(path, options, print, { + processor: async (childPath, index) => { if (index === 0 && childPath.getValue().type !== "list") { - return align(" ".repeat(prefix.length), print()); + return align(" ".repeat(prefix.length), await print()); } const alignment = " ".repeat( clamp(options.tabWidth - listPrefix.length, 0, 3) // 4+ will cause indented code block ); - return [alignment, align(alignment, print())]; + return [alignment, align(alignment, await print())]; }, }), ]; @@ -554,15 +557,15 @@ function printLine(path, value, options) { : ""; } -function printTable(path, options, print) { +async function printTable(path, options, print) { const node = path.getValue(); const columnMaxWidths = []; // { [rowIndex: number]: { [columnIndex: number]: {text: string, width: number} } } - const contents = path.map( + const contents = await path.map( (rowPath) => - rowPath.map((cellPath, columnIndex) => { - const text = printDocToString(print(), options).formatted; + rowPath.map(async (cellPath, columnIndex) => { + const text = printDocToString(await print(), options).formatted; const width = getStringWidth(text); columnMaxWidths[columnIndex] = Math.max( columnMaxWidths[columnIndex] || 3, // minimum width = 3 (---, :--, :-:, --:) @@ -693,7 +696,7 @@ function printRoot(path, options, print) { }); } -function printChildren(path, options, print, events = {}) { +async function printChildren(path, options, print, events = {}) { const { postprocessor } = events; const processor = events.processor || (() => print()); @@ -702,10 +705,10 @@ function printChildren(path, options, print, events = {}) { let lastChildNode; - path.each((childPath, index) => { + await path.each(async (childPath, index) => { const childNode = childPath.getValue(); - const result = processor(childPath, index); + const result = await processor(childPath, index); if (result !== false) { const data = { parts, diff --git a/src/language-yaml/print/block.js b/src/language-yaml/print/block.js index 16acd834c..037cf908c 100644 --- a/src/language-yaml/print/block.js +++ b/src/language-yaml/print/block.js @@ -20,7 +20,7 @@ import { } from "../utils.js"; import { alignWithSpaces } from "./misc.js"; -function printBlock(path, print, options) { +async function printBlock(path, print, options) { const node = path.getValue(); const parentIndent = getAncestorCount(path, (ancestorNode) => isNode(ancestorNode, ["sequence", "mapping"]) @@ -37,7 +37,7 @@ function printBlock(path, print, options) { } if (hasIndicatorComment(node)) { - parts.push(" ", print("indicatorComment")); + parts.push(" ", await print("indicatorComment")); } const lineContents = getBlockValueLineContents(node, { diff --git a/src/language-yaml/print/flow-mapping-sequence.js b/src/language-yaml/print/flow-mapping-sequence.js index 183587a2c..bc79702c9 100644 --- a/src/language-yaml/print/flow-mapping-sequence.js +++ b/src/language-yaml/print/flow-mapping-sequence.js @@ -8,7 +8,7 @@ import { import { isEmptyNode, getLast, hasEndComments } from "../utils.js"; import { printNextEmptyLine, alignWithSpaces } from "./misc.js"; -function printFlowMapping(path, print, options) { +async function printFlowMapping(path, print, options) { const node = path.getValue(); const isMapping = node.type === "flowMapping"; const openMarker = isMapping ? "{" : "["; @@ -30,10 +30,10 @@ function printFlowMapping(path, print, options) { openMarker, alignWithSpaces(options.tabWidth, [ bracketSpacing, - printChildren(path, print, options), + await printChildren(path, print, options), options.trailingComma === "none" ? "" : ifBreak(","), hasEndComments(node) - ? [hardline, join(hardline, path.map(print, "endComments"))] + ? [hardline, join(hardline, await path.map(print, "endComments"))] : "", ]), isLastItemEmptyMappingItem ? "" : bracketSpacing, @@ -41,11 +41,11 @@ function printFlowMapping(path, print, options) { ]; } -function printChildren(path, print, options) { +async function printChildren(path, print, options) { const node = path.getValue(); - const parts = path.map( - (childPath, index) => [ - print(), + const parts = await path.map( + async (childPath, index) => [ + await print(), index === node.children.length - 1 ? "" : [ diff --git a/src/language-yaml/print/mapping-item.js b/src/language-yaml/print/mapping-item.js index f7d75958d..0a9a24fee 100644 --- a/src/language-yaml/print/mapping-item.js +++ b/src/language-yaml/print/mapping-item.js @@ -19,7 +19,7 @@ import { } from "../utils.js"; import { alignWithSpaces } from "./misc.js"; -function printMappingItem(node, parentNode, path, print, options) { +async function printMappingItem(node, parentNode, path, print, options) { const { key, value } = node; const isEmptyMappingKey = isEmptyNode(key); @@ -29,7 +29,7 @@ function printMappingItem(node, parentNode, path, print, options) { return ": "; } - const printedKey = print("key"); + const printedKey = await print("key"); const spaceBeforeColon = needsSpaceInFrontOfMappingValue(node) ? " " : ""; if (isEmptyMappingValue) { @@ -49,7 +49,7 @@ function printMappingItem(node, parentNode, path, print, options) { return ["? ", alignWithSpaces(2, printedKey)]; } - const printedValue = print("value"); + const printedValue = await print("value"); if (isEmptyMappingKey) { return [": ", alignWithSpaces(2, printedValue)]; } @@ -62,9 +62,10 @@ function printMappingItem(node, parentNode, path, print, options) { hardline, join( "", - path - .map(print, "value", "leadingComments") - .map((comment) => [comment, hardline]) + (await path.map(print, "value", "leadingComments")).map((comment) => [ + comment, + hardline, + ]) ), ": ", alignWithSpaces(2, printedValue), diff --git a/src/language-yaml/printer-yaml.js b/src/language-yaml/printer-yaml.js index 71e325415..f63c487dd 100644 --- a/src/language-yaml/printer-yaml.js +++ b/src/language-yaml/printer-yaml.js @@ -40,24 +40,27 @@ import { import printMappingItem from "./print/mapping-item.js"; import printBlock from "./print/block.js"; -function genericPrint(path, options, print) { +async function genericPrint(path, options, print) { const node = path.getValue(); /** @type {Doc[]} */ const parts = []; if (node.type !== "mappingValue" && hasLeadingComments(node)) { - parts.push([join(hardline, path.map(print, "leadingComments")), hardline]); + parts.push([ + join(hardline, await path.map(print, "leadingComments")), + hardline, + ]); } const { tag, anchor } = node; if (tag) { - parts.push(print("tag")); + parts.push(await print("tag")); } if (tag && anchor) { parts.push(" "); } if (anchor) { - parts.push(print("anchor")); + parts.push(await print("anchor")); } /** @type {Doc} */ @@ -88,7 +91,7 @@ function genericPrint(path, options, print) { if (hasMiddleComments(node)) { parts.push([ node.middleComments.length === 1 ? "" : hardline, - join(hardline, path.map(print, "middleComments")), + join(hardline, await path.map(print, "middleComments")), hardline, ]); } @@ -104,7 +107,7 @@ function genericPrint(path, options, print) { ) ); } else { - parts.push(group(printNode(node, parentNode, path, options, print))); + parts.push(group(await printNode(node, parentNode, path, options, print))); } if (hasTrailingComment(node) && !isNode(node, ["document", "documentHead"])) { @@ -116,7 +119,7 @@ function genericPrint(path, options, print) { isInlineNode(node) ? "" : breakParent, - print("trailingComment"), + await print("trailingComment"), ]) ); } @@ -127,8 +130,8 @@ function genericPrint(path, options, print) { hardline, join( hardline, - path.map( - (path) => [ + await path.map( + async (path) => [ isPreviousLineEmpty( options.originalText, path.getValue(), @@ -136,7 +139,7 @@ function genericPrint(path, options, print) { ) ? hardline : "", - print(), + await print(), ], "endComments" ) @@ -148,22 +151,22 @@ function genericPrint(path, options, print) { return parts; } -function printNode(node, parentNode, path, options, print) { +async function printNode(node, parentNode, path, options, print) { switch (node.type) { case "root": { const { children } = node; const parts = []; - path.each((childPath, index) => { + await path.each(async (childPath, index) => { const document = children[index]; const nextDocument = children[index + 1]; if (index !== 0) { parts.push(hardline); } - parts.push(print()); + parts.push(await print()); if (shouldPrintDocumentEndMarker(document, nextDocument)) { parts.push(hardline, "..."); if (hasTrailingComment(document)) { - parts.push(" ", print("trailingComment")); + parts.push(" ", await print("trailingComment")); } } else if (nextDocument && !hasTrailingComment(nextDocument.head)) { parts.push(hardline, "---"); @@ -191,26 +194,26 @@ function printNode(node, parentNode, path, options, print) { ) === "head" ) { if (node.head.children.length > 0 || node.head.endComments.length > 0) { - parts.push(print("head")); + parts.push(await print("head")); } if (hasTrailingComment(node.head)) { - parts.push(["---", " ", print(["head", "trailingComment"])]); + parts.push(["---", " ", await print(["head", "trailingComment"])]); } else { parts.push("---"); } } if (shouldPrintDocumentBody(node)) { - parts.push(print("body")); + parts.push(await print("body")); } return join(hardline, parts); } case "documentHead": return join(hardline, [ - ...path.map(print, "children"), - ...path.map(print, "endComments"), + ...(await path.map(print, "children")), + ...(await path.map(print, "endComments")), ]); case "documentBody": { const { children, endComments } = node; @@ -230,9 +233,9 @@ function printNode(node, parentNode, path, options, print) { } return [ - join(hardline, path.map(print, "children")), + join(hardline, await path.map(print, "children")), separator, - join(hardline, path.map(print, "endComments")), + join(hardline, await path.map(print, "endComments")), ]; } case "directive": @@ -277,7 +280,7 @@ function printNode(node, parentNode, path, options, print) { node.type === "quoteDouble" ? doubleQuote : singleQuote; return [ originalQuote, - printFlowScalarContent(node.type, raw, options), + await printFlowScalarContent(node.type, raw, options), originalQuote, ]; } @@ -285,7 +288,7 @@ function printNode(node, parentNode, path, options, print) { if (raw.includes(doubleQuote)) { return [ singleQuote, - printFlowScalarContent( + await printFlowScalarContent( node.type, node.type === "quoteDouble" ? raw @@ -302,7 +305,7 @@ function printNode(node, parentNode, path, options, print) { if (raw.includes(singleQuote)) { return [ doubleQuote, - printFlowScalarContent( + await printFlowScalarContent( node.type, node.type === "quoteSingle" ? // single quote needs to be escaped by 2 single quotes in quoteSingle @@ -315,7 +318,11 @@ function printNode(node, parentNode, path, options, print) { } const quote = options.singleQuote ? singleQuote : doubleQuote; - return [quote, printFlowScalarContent(node.type, raw, options), quote]; + return [ + quote, + await printFlowScalarContent(node.type, raw, options), + quote, + ]; } case "blockFolded": case "blockLiteral": { @@ -323,9 +330,12 @@ function printNode(node, parentNode, path, options, print) { } case "mapping": case "sequence": - return join(hardline, path.map(print, "children")); + return join(hardline, await path.map(print, "children")); case "sequenceItem": - return ["- ", alignWithSpaces(2, node.content ? print("content") : "")]; + return [ + "- ", + alignWithSpaces(2, node.content ? await print("content") : ""), + ]; case "mappingKey": case "mappingValue": return !node.content ? "" : print("content"); diff --git a/src/main/ast-to-doc.js b/src/main/ast-to-doc.js index 589435d10..feb6e3a6f 100644 --- a/src/main/ast-to-doc.js +++ b/src/main/ast-to-doc.js @@ -25,7 +25,7 @@ import { printSubtree } from "./multiparser.js"; * state of the recursion. It is called "path", because it represents * the path to the current node through the Abstract Syntax Tree. */ -function printAstToDoc(ast, options, alignmentSize = 0) { +async function printAstToDoc(ast, options, alignmentSize = 0) { const { printer } = options; if (printer.preprocess) { @@ -35,7 +35,7 @@ function printAstToDoc(ast, options, alignmentSize = 0) { const cache = new Map(); const path = new AstPath(ast); - let doc = mainPrint(); + let doc = await mainPrint(); if (alignmentSize > 0) { // Add a hardline to make the indents take effect @@ -69,13 +69,13 @@ function printAstToDoc(ast, options, alignmentSize = 0) { return cache.get(value); } - const doc = callPluginPrintFunction(path, options, mainPrint, args); + const promise = callPluginPrintFunction(path, options, mainPrint, args); if (shouldCache) { - cache.set(value, doc); + cache.set(value, promise); } - return doc; + return promise; } } @@ -101,13 +101,12 @@ function printPrettierIgnoredNode(node, options) { return { doc: originalText.slice(start, end), printedComments }; } -function callPluginPrintFunction(path, options, printPath, args) { +async function callPluginPrintFunction(path, options, printPath, args) { const node = path.getValue(); const { printer } = options; let doc; let printedComments; - // Escape hatch if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path)) { ({ doc, printedComments } = printPrettierIgnoredNode(node, options)); @@ -115,7 +114,7 @@ function callPluginPrintFunction(path, options, printPath, args) { if (node) { try { // Potentially switch to a different parser - doc = printSubtree(path, printPath, options, printAstToDoc); + doc = await printSubtree(path, printPath, options, printAstToDoc); } catch (error) { /* istanbul ignore if */ if (process.env.PRETTIER_DEBUG) { @@ -126,7 +125,7 @@ function callPluginPrintFunction(path, options, printPath, args) { } if (!doc) { - doc = printer.print(path, options, printPath, args); + doc = await printer.print(path, options, printPath, args); } } diff --git a/src/main/core.js b/src/main/core.js index a3da2d9c1..e71a23d52 100644 --- a/src/main/core.js +++ b/src/main/core.js @@ -47,7 +47,7 @@ async function coreFormat(originalText, opts, addAlignmentSize = 0) { } const astComments = attachComments(text, ast, opts); - const doc = printAstToDoc(ast, opts, addAlignmentSize); + const doc = await printAstToDoc(ast, opts, addAlignmentSize); const result = printDocToString(doc, opts); @@ -334,9 +334,9 @@ const prettier = { return parsed; }, - formatAST(ast, options) { + async formatAST(ast, options) { options = normalizeOptions(options); - const doc = printAstToDoc(ast, options); + const doc = await printAstToDoc(ast, options); return printDocToString(doc, options); }, diff --git a/src/main/multiparser.js b/src/main/multiparser.js index 58d0e4348..1c053db63 100644 --- a/src/main/multiparser.js +++ b/src/main/multiparser.js @@ -1,7 +1,7 @@ import { stripTrailingHardline } from "../document/utils.js"; import { normalize } from "./options.js"; import { ensureAllCommentsPrinted, attach } from "./comments.js"; -import { parseSync } from "./parser.js"; +import { parse } from "./parser.js"; function printSubtree(path, print, options, printAstToDoc) { if (options.printer.embed && options.embeddedLanguageFormatting === "auto") { @@ -21,7 +21,7 @@ function printSubtree(path, print, options, printAstToDoc) { } } -function textToDoc( +async function textToDoc( text, partialNextOptions, parentOptions, @@ -39,13 +39,9 @@ function textToDoc( { passThrough: true } ); - const result = parseSync(text, nextOptions); + const result = await parse(text, nextOptions); const { ast } = result; - if (typeof ast?.then === "function") { - throw new TypeError("async parse is not supported in embed"); - } - text = result.text; const astComments = ast.comments; @@ -56,7 +52,7 @@ function textToDoc( // @ts-expect-error -- Casting to `unique symbol` isn't allowed in JSDoc comment nextOptions[Symbol.for("tokens")] = ast.tokens || []; - const doc = printAstToDoc(ast, nextOptions); + const doc = await printAstToDoc(ast, nextOptions); ensureAllCommentsPrinted(astComments); if (shouldStripTrailingHardline) { diff --git a/src/main/parser.js b/src/main/parser.js index fdff76264..4869cbef8 100644 --- a/src/main/parser.js +++ b/src/main/parser.js @@ -111,9 +111,4 @@ async function parse(originalText, opts) { } } -function parseSync(originalText, opts) { - const { text, result } = callPluginParseFunction(originalText, opts); - return { text, ast: result }; -} - -export { parse, parseSync, resolveParser }; +export { parse, resolveParser }; diff --git a/src/utils/front-matter/print.js b/src/utils/front-matter/print.js index fad3f94be..c4c3a58de 100644 --- a/src/utils/front-matter/print.js +++ b/src/utils/front-matter/print.js @@ -1,10 +1,14 @@ import { hardline, markAsRoot } from "../../document/builders.js"; -function print(node, textToDoc) { +async function print(node, textToDoc) { if (node.lang === "yaml") { const value = node.value.trim(); const doc = value - ? textToDoc(value, { parser: "yaml" }, { stripTrailingHardline: true }) + ? await textToDoc( + value, + { parser: "yaml" }, + { stripTrailingHardline: true } + ) : ""; return markAsRoot([ node.startDelimiter, diff --git a/tests/format/misc/plugins/embed-async-parser/__snapshots__/jsfmt.spec.js.snap b/tests/format/misc/plugins/embed-async-parser/__snapshots__/jsfmt.spec.js.snap deleted file mode 100644 index 151c0ea16..000000000 --- a/tests/format/misc/plugins/embed-async-parser/__snapshots__/jsfmt.spec.js.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`async-parser.txt format 1`] = ` -====================================options===================================== -parsers: ["async-parser"] -printWidth: 80 - | printWidth -=====================================input====================================== -A text will format as "Formatted by async-parser plugin". - -=====================================output===================================== -Formatted by async-parser plugin -================================================================================ -`; - -exports[`with-aync-parser-code-block.md format 1`] = ` -====================================options===================================== -parsers: ["markdown"] -printWidth: 80 - | printWidth -=====================================input====================================== -\`\`\`async-parser -Since we don't allow async parser in embed format, so this will not be changed. -\`\`\` - -\`\`\`uppercase-rocks -This text should be uppercased. -\`\`\` - -=====================================output===================================== -\`\`\`async-parser -Since we don't allow async parser in embed format, so this will not be changed. -\`\`\` - -\`\`\`uppercase-rocks -THIS TEXT SHOULD BE UPPERCASED. -\`\`\` - -================================================================================ -`; diff --git a/tests/format/misc/plugins/embed-async-parser/jsfmt.spec.js b/tests/format/misc/plugins/embed-async-parser/jsfmt.spec.js deleted file mode 100644 index 86c1e6b30..000000000 --- a/tests/format/misc/plugins/embed-async-parser/jsfmt.spec.js +++ /dev/null @@ -1,10 +0,0 @@ -import createEsmUtils from "esm-utils"; - -const { require } = createEsmUtils(import.meta); - -const plugins = [ - require("../../../../config/prettier-plugins/prettier-plugin-async-parser/index.cjs"), - require("../../../../config/prettier-plugins/prettier-plugin-uppercase-rocks/index.cjs"), -]; - -run_spec(import.meta, ["markdown"], { plugins }); diff --git a/tests/format/misc/plugins/embed-async-parser/with-aync-parser-code-block.md b/tests/format/misc/plugins/embed-async-parser/with-aync-parser-code-block.md deleted file mode 100644 index 66dd689df..000000000 --- a/tests/format/misc/plugins/embed-async-parser/with-aync-parser-code-block.md +++ /dev/null @@ -1,7 +0,0 @@ -```async-parser -Since we don't allow async parser in embed format, so this will not be changed. -``` - -```uppercase-rocks -This text should be uppercased. -```