Skip to content

Commit 44bbe5d

Browse files
authored
feat!: upgrade to prettier v3 (#516)
1 parent 478b4e0 commit 44bbe5d

6 files changed

Lines changed: 210 additions & 136 deletions

File tree

.changeset/orange-eyes-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-prettier": major
3+
---
4+
5+
feat!: upgrade to prettier v3

.changeset/pre.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mode": "pre",
3+
"tag": "alpha",
4+
"initialVersions": {
5+
"eslint-plugin-prettier": "4.2.2"
6+
},
7+
"changesets": []
8+
}

eslint-plugin-prettier.js

Lines changed: 30 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* @typedef {import('eslint').AST.Range} Range
1010
* @typedef {import('eslint').AST.SourceLocation} SourceLocation
1111
* @typedef {import('eslint').ESLint.Plugin} Plugin
12+
* @typedef {import('prettier').FileInfoOptions} FileInfoOptions
13+
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean }} Options
1214
*/
1315

1416
'use strict';
@@ -34,9 +36,9 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;
3436

3537
// Lazily-loaded Prettier.
3638
/**
37-
* @type {typeof import('prettier')}
39+
* @type {(source: string, options: Options, fileInfoOptions: FileInfoOptions) => string}
3840
*/
39-
let prettier;
41+
let prettierFormat;
4042

4143
// ------------------------------------------------------------------------------
4244
// Rule Definition
@@ -123,7 +125,10 @@ const eslintPluginPrettier = {
123125
create(context) {
124126
const usePrettierrc =
125127
!context.options[1] || context.options[1].usePrettierrc !== false;
126-
const eslintFileInfoOptions =
128+
/**
129+
* @type {FileInfoOptions}
130+
*/
131+
const fileInfoOptions =
127132
(context.options[1] && context.options[1].fileInfoOptions) || {};
128133
const sourceCode = context.getSourceCode();
129134
const filepath = context.getFilename();
@@ -136,136 +141,19 @@ const eslintPluginPrettier = {
136141
const source = sourceCode.text;
137142

138143
return {
139-
// eslint-disable-next-line sonarjs/cognitive-complexity
140144
Program() {
141-
if (!prettier) {
145+
if (!prettierFormat) {
142146
// Prettier is expensive to load, so only load it if needed.
143-
prettier = require('prettier');
147+
prettierFormat = require('synckit').createSyncFn(
148+
require.resolve('./worker'),
149+
);
144150
}
145151

152+
/**
153+
* @type {{}}
154+
*/
146155
const eslintPrettierOptions = context.options[0] || {};
147156

148-
const prettierRcOptions = usePrettierrc
149-
? prettier.resolveConfig.sync(onDiskFilepath, {
150-
editorconfig: true,
151-
})
152-
: null;
153-
154-
const { ignored, inferredParser } = prettier.getFileInfo.sync(
155-
onDiskFilepath,
156-
{
157-
resolveConfig: false,
158-
withNodeModules: false,
159-
ignorePath: '.prettierignore',
160-
plugins: prettierRcOptions ? prettierRcOptions.plugins : null,
161-
...eslintFileInfoOptions,
162-
},
163-
);
164-
165-
// Skip if file is ignored using a .prettierignore file
166-
if (ignored) {
167-
return;
168-
}
169-
170-
const initialOptions = {};
171-
172-
// ESLint supports processors that let you extract and lint JS
173-
// fragments within a non-JS language. In the cases where prettier
174-
// supports the same language as a processor, we want to process
175-
// the provided source code as javascript (as ESLint provides the
176-
// rules with fragments of JS) instead of guessing the parser
177-
// based off the filename. Otherwise, for instance, on a .md file we
178-
// end up trying to run prettier over a fragment of JS using the
179-
// markdown parser, which throws an error.
180-
// Processors may set virtual filenames for these extracted blocks.
181-
// If they do so then we want to trust the file extension they
182-
// provide, and no override is needed.
183-
// If the processor does not set any virtual filename (signified by
184-
// `filepath` and `onDiskFilepath` being equal) AND we can't
185-
// infer the parser from the filename, either because no filename
186-
// was provided or because there is no parser found for the
187-
// filename, use javascript.
188-
// This is added to the options first, so that
189-
// prettierRcOptions and eslintPrettierOptions can still override
190-
// the parser.
191-
//
192-
// `parserBlocklist` should contain the list of prettier parser
193-
// names for file types where:
194-
// * Prettier supports parsing the file type
195-
// * There is an ESLint processor that extracts JavaScript snippets
196-
// from the file type.
197-
if (filepath === onDiskFilepath) {
198-
// The following list means the plugin process source into js content
199-
// but with same filename, so we need to change the parser to `babel`
200-
// by default.
201-
// Related ESLint plugins are:
202-
// 1. `eslint-plugin-graphql` (replacement: `@graphql-eslint/eslint-plugin`)
203-
// 2. `eslint-plugin-html`
204-
// 3. `eslint-plugin-markdown@1` (replacement: `eslint-plugin-markdown@2+`)
205-
// 4. `eslint-plugin-svelte3` (replacement: `eslint-plugin-svelte@2+`)
206-
const parserBlocklist = [null, 'markdown', 'html'];
207-
208-
let inferParserToBabel = parserBlocklist.includes(inferredParser);
209-
210-
switch (inferredParser) {
211-
// it could be processed by `@graphql-eslint/eslint-plugin` or `eslint-plugin-graphql`
212-
case 'graphql': {
213-
if (
214-
// for `eslint-plugin-graphql`, see https://github.com/apollographql/eslint-plugin-graphql/blob/master/src/index.js#L416
215-
source.startsWith('ESLintPluginGraphQLFile`')
216-
) {
217-
inferParserToBabel = true;
218-
}
219-
break;
220-
}
221-
// it could be processed by `@ota-meshi/eslint-plugin-svelte`, `eslint-plugin-svelte` or `eslint-plugin-svelte3`
222-
case 'svelte': {
223-
// The `source` would be modified by `eslint-plugin-svelte3`
224-
if (!context.parserPath.includes('svelte-eslint-parser')) {
225-
// We do not support `eslint-plugin-svelte3`,
226-
// the users should run `prettier` on `.svelte` files manually
227-
return;
228-
}
229-
}
230-
}
231-
232-
if (inferParserToBabel) {
233-
initialOptions.parser = 'babel';
234-
}
235-
} else {
236-
// Similar to https://github.com/prettier/stylelint-prettier/pull/22
237-
// In all of the following cases ESLint extracts a part of a file to
238-
// be formatted and there exists a prettier parser for the whole file.
239-
// If you're interested in prettier you'll want a fully formatted file so
240-
// you're about to run prettier over the whole file anyway.
241-
// Therefore running prettier over just the style section is wasteful, so
242-
// skip it.
243-
const parserBlocklist = [
244-
'babel',
245-
'babylon',
246-
'flow',
247-
'typescript',
248-
'vue',
249-
'markdown',
250-
'html',
251-
'mdx',
252-
'angular',
253-
'svelte',
254-
];
255-
if (
256-
parserBlocklist.includes(/** @type {string} */ (inferredParser))
257-
) {
258-
return;
259-
}
260-
}
261-
262-
const prettierOptions = {
263-
...initialOptions,
264-
...prettierRcOptions,
265-
...eslintPrettierOptions,
266-
filepath,
267-
};
268-
269157
// prettier.format() may throw a SyntaxError if it cannot parse the
270158
// source code it is given. Usually for JS files this isn't a
271159
// problem as ESLint will report invalid syntax before trying to
@@ -279,7 +167,17 @@ const eslintPluginPrettier = {
279167
*/
280168
let prettierSource;
281169
try {
282-
prettierSource = prettier.format(source, prettierOptions);
170+
prettierSource = prettierFormat(
171+
source,
172+
{
173+
...eslintPrettierOptions,
174+
filepath,
175+
onDiskFilepath,
176+
parserPath: context.parserPath,
177+
usePrettierrc,
178+
},
179+
fileInfoOptions,
180+
);
283181
} catch (err) {
284182
if (!(err instanceof SyntaxError)) {
285183
throw err;
@@ -308,6 +206,10 @@ const eslintPluginPrettier = {
308206
return;
309207
}
310208

209+
if (prettierSource == null) {
210+
return;
211+
}
212+
311213
if (source !== prettierSource) {
312214
const differences = generateDifferences(source, prettierSource);
313215

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"prettier"
2828
],
2929
"scripts": {
30-
"build": "tsc -b",
3130
"format": "yarn prettier '**/*.{js,json,md,yml}' --write && yarn lint --fix",
3231
"lint": "eslint . --cache -f friendly --max-warnings 10",
3332
"prepare": "simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0",
@@ -38,7 +37,7 @@
3837
"peerDependencies": {
3938
"@types/eslint": ">=8.0.0",
4039
"eslint": ">=8.0.0",
41-
"prettier": ">=2.0.0"
40+
"prettier": ">=3.0.0"
4241
},
4342
"peerDependenciesMeta": {
4443
"@types/eslint": {
@@ -49,7 +48,6 @@
4948
}
5049
},
5150
"dependencies": {
52-
"eslint-plugin-prettier": "link:.",
5351
"prettier-linter-helpers": "^1.0.0"
5452
},
5553
"devDependencies": {
@@ -76,6 +74,6 @@
7674
},
7775
"resolutions": {
7876
"eslint-plugin-prettier": "link:.",
79-
"prettier": "^2.0.0"
77+
"prettier": "^3.0.0-alpha.0"
8078
}
8179
}

0 commit comments

Comments
 (0)