Allow plugin override builtin parsers when inferring parser (#17549)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
d49444352a
commit
7fb9875413
16 files changed
+197
-42
No files matched your search
@@ -0,0 +1,32 @@
|
||||
#### Allow plugin to override builtin parsers when inferring parser (#17549 by @fisker)
|
||||
|
||||
Previously when inferring parser for file, builtin plugins are checked first, so plugins are not able to override parsers for files like `.js`.
|
||||
|
||||
```js
|
||||
// prettier-plugin-foo
|
||||
export const languages = [
|
||||
{
|
||||
parsers: ["foo"],
|
||||
extensions: [".js"],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
```js
|
||||
// prettier.config.js
|
||||
import * as prettierPluginFoo from "prettier-plugin-foo";
|
||||
|
||||
export default {
|
||||
plugins: [prettierPluginFoo],
|
||||
};
|
||||
```
|
||||
|
||||
```console
|
||||
prettier --file-info file.js
|
||||
|
||||
# Prettier stable
|
||||
{ "ignored": false, "inferredParser": "babel" }
|
||||
|
||||
# Prettier main
|
||||
{ "ignored": false, "inferredParser": "foo" }
|
||||
```
|
||||
@@ -12,16 +12,19 @@ yarn add --dev prettier @prettier/plugin-hermes
|
||||
|
||||
Create or modify your [prettier configuration file](https://prettier.io/docs/en/configuration) to use the plugin:
|
||||
|
||||
```json
|
||||
{
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.{js.flow,js,mjs,cjs}"],
|
||||
"options": {
|
||||
"plugins": ["@prettier/plugin-hermes"],
|
||||
"parser": "hermes"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```yaml
|
||||
plugins:
|
||||
- "@prettier/plugin-hermes"
|
||||
```
|
||||
|
||||
Or config explicitly
|
||||
|
||||
```yaml
|
||||
overrides:
|
||||
- files:
|
||||
- "**/*.{js.flow,js,mjs,cjs}"
|
||||
options:
|
||||
plugins:
|
||||
- "@prettier/plugin-hermes"
|
||||
parser: hermes
|
||||
```
|
||||
@@ -1 +1,2 @@
|
||||
export * as parsers from "../../src/language-js/parse/hermes.js";
|
||||
export { default as languages } from "./languages.evaluate.js";
|
||||
@@ -0,0 +1,15 @@
|
||||
import builtinJsLanguages from "../../src/language-js/languages.evaluate.js";
|
||||
|
||||
const replacements = new Map([["flow", "hermes"]]);
|
||||
|
||||
const languages = builtinJsLanguages
|
||||
.map((language) => {
|
||||
const parsers = language.parsers
|
||||
.map((parser) => replacements.get(parser))
|
||||
.filter(Boolean);
|
||||
|
||||
return parsers.length > 0 ? { ...language, parsers } : undefined;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
export default languages;
|
||||
@@ -12,23 +12,25 @@ yarn add --dev prettier @prettier/plugin-oxc
|
||||
|
||||
Create or modify your [prettier configuration file](https://prettier.io/docs/en/configuration) to use the plugin:
|
||||
|
||||
```json
|
||||
{
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.{js,mjs,cjs,jsx}"],
|
||||
"options": {
|
||||
"plugins": ["@prettier/plugin-oxc"],
|
||||
"parser": "oxc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["**/*.{ts,mts,cts,tsx}"],
|
||||
"options": {
|
||||
"plugins": ["@prettier/plugin-oxc"],
|
||||
"parser": "oxc-ts"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```yaml
|
||||
plugins:
|
||||
- "@prettier/plugin-oxc"
|
||||
```
|
||||
|
||||
Or config explicitly
|
||||
|
||||
```yaml
|
||||
overrides:
|
||||
- files:
|
||||
- "**/*.{js,mjs,cjs,jsx}"
|
||||
options:
|
||||
plugins:
|
||||
- "@prettier/plugin-oxc"
|
||||
parser: oxc
|
||||
- files:
|
||||
- "**/*.{ts,mts,cts,tsx}"
|
||||
options:
|
||||
plugins:
|
||||
- "@prettier/plugin-oxc"
|
||||
parser: oxc-ts
|
||||
```
|
||||
@@ -1 +1,2 @@
|
||||
export * as parsers from "../../src/language-js/parse/oxc.js";
|
||||
export { default as languages } from "./languages.evaluate.js";
|
||||
@@ -0,0 +1,18 @@
|
||||
import builtinJsLanguages from "../../src/language-js/languages.evaluate.js";
|
||||
|
||||
const replacements = new Map([
|
||||
["babel", "oxc"],
|
||||
["typescript", "oxc-ts"],
|
||||
]);
|
||||
|
||||
const languages = builtinJsLanguages
|
||||
.map((language) => {
|
||||
const parsers = language.parsers
|
||||
.map((parser) => replacements.get(parser))
|
||||
.filter(Boolean);
|
||||
|
||||
return parsers.length > 0 ? { ...language, parsers } : undefined;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
export default languages;
|
||||
@@ -0,0 +1,13 @@
|
||||
const arrayToReversed = (isOptionalObject, array) => {
|
||||
if (isOptionalObject && (array === undefined || array === null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (array.toReversed || !Array.isArray(array)) {
|
||||
return array.toReversed();
|
||||
}
|
||||
|
||||
return [...array].reverse();
|
||||
};
|
||||
|
||||
export default arrayToReversed;
|
||||
@@ -1,5 +1,6 @@
|
||||
import transformArrayFindLast from "./transform-array-find-last.js";
|
||||
import transformArrayFindLastIndex from "./transform-array-find-last-index.js";
|
||||
import transformArrayToReversed from "./transform-array-to-reversed.js";
|
||||
import transformObjectHasOwnCall from "./transform-object-has-own.js";
|
||||
import transformRelativeIndexing from "./transform-relative-indexing.js";
|
||||
import transformStringReplaceAll from "./transform-string-replace-all.js";
|
||||
@@ -18,4 +19,6 @@ export default [
|
||||
transformRelativeIndexing,
|
||||
// Node.js 15.0.0
|
||||
transformStringReplaceAll,
|
||||
// Node.js 20
|
||||
transformArrayToReversed,
|
||||
];
|
||||
@@ -0,0 +1,13 @@
|
||||
import createMethodCallTransform from "./create-method-call-transform.js";
|
||||
|
||||
const transformArrayToReversed = createMethodCallTransform({
|
||||
methodName: "toReversed",
|
||||
argumentsLength: 0,
|
||||
functionName: "__arrayToReversed",
|
||||
functionImplementationUrl: new URL(
|
||||
"../../shims/array-to-reversed.js",
|
||||
import.meta.url,
|
||||
),
|
||||
});
|
||||
|
||||
export default transformArrayToReversed;
|
||||
@@ -118,7 +118,7 @@ function getLanguageByIsSupported(languages, file) {
|
||||
* @returns {string | undefined} matched parser name if found
|
||||
*/
|
||||
function inferParser(options, fileInfo) {
|
||||
const languages = options.plugins.flatMap(
|
||||
const languages = options.plugins.toReversed().flatMap(
|
||||
(plugin) =>
|
||||
// @ts-expect-error -- Safe
|
||||
plugin.languages ?? [],
|
||||
|
||||
@@ -166,6 +166,28 @@ describe("--write and --list-different with unknown path and no parser", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Allow plugin to override builtin plugins", () => {
|
||||
runCli(
|
||||
"cli/infer-parser/override-builtin-plugin-languages",
|
||||
["--stdin-filepath=foo.js"],
|
||||
{
|
||||
input: "foo( )",
|
||||
},
|
||||
).test({ write: [], status: 0, stderr: "", stdout: "foo();" });
|
||||
runCli(
|
||||
"cli/infer-parser/override-builtin-plugin-languages",
|
||||
["--stdin-filepath=foo.js", "--plugin=./dummy-js-plugin.js"],
|
||||
{
|
||||
input: "foo( )",
|
||||
},
|
||||
).test({
|
||||
write: [],
|
||||
status: 0,
|
||||
stderr: "",
|
||||
stdout: "foo( )\nformatted by 'dummy-js-parser' parser",
|
||||
});
|
||||
});
|
||||
|
||||
describe("API with no path and no parser", () => {
|
||||
test("prettier.format", async () => {
|
||||
await expect(prettier.format(" foo ( )")).rejects.toThrow(
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
import createPlugin from "../../../../config/utils/create-plugin.cjs";
|
||||
|
||||
const PARSER_NAME = 'dummy-js-parser'
|
||||
const PRINT_MARK = `formatted by '${PARSER_NAME}' parser`
|
||||
|
||||
const languages = [
|
||||
{
|
||||
parsers: [PARSER_NAME],
|
||||
extensions: ['.js']
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
...createPlugin({
|
||||
name: PARSER_NAME,
|
||||
print: (content) => `${content.replace(PRINT_MARK,"").trim()}\n${PRINT_MARK}`,
|
||||
finalNewLine: false,
|
||||
}),
|
||||
languages,
|
||||
};
|
||||
@@ -45,7 +45,7 @@ test(".at", () => {
|
||||
__at (/* isOptionalObject */false,foo,-1)?.bar"
|
||||
`);
|
||||
|
||||
// Don't support optional call
|
||||
// Optional call not supported
|
||||
expect(transform("foo.at?.(-1)")).toMatchInlineSnapshot(`"foo.at?.(-1)"`);
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ test("Array#findLast", () => {
|
||||
__arrayFindLast(/* isOptionalObject */true,foo,callback)"
|
||||
`);
|
||||
|
||||
// Don't support
|
||||
// Not supported
|
||||
expect(
|
||||
transform("foo.findLast(callback, thisArgument)"),
|
||||
).toMatchInlineSnapshot(`"foo.findLast(callback, thisArgument)"`);
|
||||
@@ -87,8 +87,25 @@ test("Array#findLastIndex", () => {
|
||||
__arrayFindLastIndex(/* isOptionalObject */true,foo,callback)"
|
||||
`);
|
||||
|
||||
// Don't support
|
||||
// Not supported
|
||||
expect(
|
||||
transform("foo.findLastIndex(callback, thisArgument)"),
|
||||
).toMatchInlineSnapshot(`"foo.findLastIndex(callback, thisArgument)"`);
|
||||
});
|
||||
|
||||
test("Array#toReversed", () => {
|
||||
expect(transform("foo.toReversed()")).toMatchInlineSnapshot(`
|
||||
"import __arrayToReversed from "<SHIMS>/array-to-reversed.js";
|
||||
|
||||
__arrayToReversed(/* isOptionalObject */false,foo)"
|
||||
`);
|
||||
expect(transform("foo?.toReversed()")).toMatchInlineSnapshot(`
|
||||
"import __arrayToReversed from "<SHIMS>/array-to-reversed.js";
|
||||
|
||||
__arrayToReversed(/* isOptionalObject */true,foo)"
|
||||
`);
|
||||
|
||||
expect(transform("foo.toReversed(extraArgument)")).toMatchInlineSnapshot(
|
||||
`"foo.toReversed(extraArgument)"`,
|
||||
);
|
||||
});
|
||||
@@ -62,13 +62,6 @@ const plugins = [
|
||||
createPlugin(plugin),
|
||||
),
|
||||
docExplorerPlugin,
|
||||
prettierPackageManifest.builtinPlugins.some((plugin) =>
|
||||
plugin.parsers?.includes("hermes"),
|
||||
)
|
||||
? {
|
||||
languages: [{ name: "hermes", parsers: ["hermes"] }],
|
||||
}
|
||||
: {},
|
||||
];
|
||||
|
||||
self.onmessage = async function (event) {
|
||||
|
||||
Reference in new issue
Block a user