diff --git a/changelog_unreleased/api/17679.md b/changelog_unreleased/api/17679.md new file mode 100644 index 000000000..1565b6967 --- /dev/null +++ b/changelog_unreleased/api/17679.md @@ -0,0 +1,5 @@ +#### Allow `plugin.parser.preprocess()` to return a `Promise` (#17679 by @fisker) + +Align with [`plugin.printer.preprocess()`](https://prettier.io/docs/plugins#optional-preprocess), which allows to return a `Promise`. + +We still suggest move your async work into `plugin.parser.parse()`, which already allow to return a `Promise`, we may remove support for `plugin.parser.preprocess()` in future. diff --git a/docs/plugins.md b/docs/plugins.md index 639bb6ea1..d57095ad6 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -149,7 +149,7 @@ function hasIgnorePragma(text: string): boolean; _(Optional)_ The preprocess function can process the input text before passing into `parse` function. ```ts -function preprocess(text: string, options: object): string; +function preprocess(text: string, options: object): string | Promise; ``` ### `printers` diff --git a/src/index.d.ts b/src/index.d.ts index 3cb809ad1..7d69e54ab 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -480,7 +480,7 @@ export interface Parser { locStart: (node: T) => number; locEnd: (node: T) => number; preprocess?: - | ((text: string, options: ParserOptions) => string) + | ((text: string, options: ParserOptions) => string | Promise) | undefined; } diff --git a/src/main/parse.js b/src/main/parse.js index faef62ebf..18fc564a7 100644 --- a/src/main/parse.js +++ b/src/main/parse.js @@ -4,7 +4,7 @@ import { resolveParser } from "./parser-and-printer.js"; async function parse(originalText, options) { const parser = await resolveParser(options); const text = parser.preprocess - ? parser.preprocess(originalText, options) + ? await parser.preprocess(originalText, options) : originalText; options.originalText = text; diff --git a/tests/integration/__tests__/plugin-preprocess.js b/tests/integration/__tests__/plugin-preprocess.js index 9affc78c6..702785283 100644 --- a/tests/integration/__tests__/plugin-preprocess.js +++ b/tests/integration/__tests__/plugin-preprocess.js @@ -7,4 +7,16 @@ describe("parser preprocess function is used to reshape input text", () => { status: 0, write: [], }); + runCli( + "plugins/preprocess", + ["*.foo", "--plugin=./plugin-with-async-preprocess.cjs"], + { + ignoreLineEndings: true, + }, + ).test({ + stdout: "preprocessed:async:contents", + stderr: "", + status: 0, + write: [], + }); }); diff --git a/tests/integration/plugins/preprocess/plugin-with-async-preprocess.cjs b/tests/integration/plugins/preprocess/plugin-with-async-preprocess.cjs new file mode 100644 index 000000000..6d9d144f6 --- /dev/null +++ b/tests/integration/plugins/preprocess/plugin-with-async-preprocess.cjs @@ -0,0 +1,24 @@ +"use strict"; + +module.exports = { + languages: [ + { + name: "foo", + parsers: ["foo-parser"], + extensions: [".foo"], + since: "1.0.0", + }, + ], + parsers: { + "foo-parser": { + preprocess: (text) => Promise.resolve(`preprocessed:async:${text}`), + parse: (text) => ({ text }), + astFormat: "foo-ast", + }, + }, + printers: { + "foo-ast": { + print: ({ node }) => node.text, + }, + }, +}; diff --git a/tests/integration/plugins/preprocess/plugin.cjs b/tests/integration/plugins/preprocess/plugin.cjs index 0e11e2138..43be9f76f 100644 --- a/tests/integration/plugins/preprocess/plugin.cjs +++ b/tests/integration/plugins/preprocess/plugin.cjs @@ -18,7 +18,7 @@ module.exports = { }, printers: { "foo-ast": { - print: (path) => path.getValue().text, + print: ({ node }) => node.text, }, }, };