Skip to content

Commit ee0ccc6

Browse files
authored
feat: support processor virtual filename (#401)
* feat: support processor virtual filename close #393 * refactor: normalize filepath first in case recursive virtual filename
1 parent d1a5b2b commit ee0ccc6

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

eslint-plugin-prettier.js

+38-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
// Requirements
1010
// ------------------------------------------------------------------------------
1111

12+
const fs = require('fs');
13+
const path = require('path');
14+
1215
const {
1316
showInvisibles,
1417
generateDifferences
@@ -25,6 +28,9 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;
2528
// ------------------------------------------------------------------------------
2629

2730
// Lazily-loaded Prettier.
31+
/**
32+
* @type {import('prettier')}
33+
*/
2834
let prettier;
2935

3036
// ------------------------------------------------------------------------------
@@ -55,6 +61,26 @@ function reportDifference(context, difference) {
5561
});
5662
}
5763

64+
/**
65+
* get normalized filepath in case of virtual filename
66+
* @param {string} filepath
67+
* @returns {string}
68+
*/
69+
function normalizeFilepath(filepath) {
70+
try {
71+
if (fs.statSync(filepath).isFile()) {
72+
return filepath;
73+
}
74+
} catch (err) {
75+
// https://github.com/eslint/eslint/issues/11989
76+
if (err.code === 'ENOTDIR') {
77+
return normalizeFilepath(path.dirname(filepath));
78+
}
79+
}
80+
81+
return filepath;
82+
}
83+
5884
// ------------------------------------------------------------------------------
5985
// Module Definition
6086
// ------------------------------------------------------------------------------
@@ -112,6 +138,7 @@ module.exports = {
112138
(context.options[1] && context.options[1].fileInfoOptions) || {};
113139
const sourceCode = context.getSourceCode();
114140
const filepath = context.getFilename();
141+
const normalizedFilepath = normalizeFilepath(filepath);
115142
const source = sourceCode.text;
116143

117144
return {
@@ -124,13 +151,13 @@ module.exports = {
124151
const eslintPrettierOptions = context.options[0] || {};
125152

126153
const prettierRcOptions = usePrettierrc
127-
? prettier.resolveConfig.sync(filepath, {
154+
? prettier.resolveConfig.sync(normalizedFilepath, {
128155
editorconfig: true
129156
})
130157
: null;
131158

132159
const prettierFileInfo = prettier.getFileInfo.sync(
133-
filepath,
160+
normalizedFilepath,
134161
Object.assign(
135162
{},
136163
{ resolveConfig: true, ignorePath: '.prettierignore' },
@@ -145,7 +172,8 @@ module.exports = {
145172

146173
const initialOptions = {};
147174

148-
// ESLint suppports processors that let you extract and lint JS
175+
// for ESLint < 6.0
176+
// it supports processors that let you extract and lint JS
149177
// fragments within a non-JS language. In the cases where prettier
150178
// supports the same language as a processor, we want to process
151179
// the provided source code as javascript (as ESLint provides the
@@ -165,8 +193,13 @@ module.exports = {
165193
// * Prettier supports parsing the file type
166194
// * There is an ESLint processor that extracts JavaScript snippets
167195
// from the file type.
196+
//
197+
// for ESLint >= 6.0
198+
// it supports virtual filename, if filepath is not same as normalizedFilepath,
199+
// it means filepath is virtual name, and we can guess the file type by prettier automatically
168200
const parserBlocklist = [null, 'graphql', 'markdown', 'html'];
169201
if (
202+
filepath === normalizedFilepath &&
170203
parserBlocklist.indexOf(prettierFileInfo.inferredParser) !== -1
171204
) {
172205
// Prettier v1.16.0 renamed the `babylon` parser to `babel`
@@ -187,7 +220,7 @@ module.exports = {
187220
);
188221

189222
// prettier.format() may throw a SyntaxError if it cannot parse the
190-
// source code it is given. Ususally for JS files this isn't a
223+
// source code it is given. Usually for JS files this isn't a
191224
// problem as ESLint will report invalid syntax before trying to
192225
// pass it to the prettier plugin. However this might be a problem
193226
// for non-JS languages that are handled by a plugin. Notably Vue
@@ -205,7 +238,7 @@ module.exports = {
205238
let message = 'Parsing error: ' + err.message;
206239

207240
// Prettier's message contains a codeframe style preview of the
208-
// invalid code and the line/column at which the error occured.
241+
// invalid code and the line/column at which the error occurred.
209242
// ESLint shows those pieces of information elsewhere already so
210243
// remove them from the message
211244
if (err.codeFrame) {

test/prettier.js

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ ruleTester.run('prettier', rule, {
6666
{
6767
code: 'a();;;;;;\n',
6868
filename: 'node_modules/dummy.js'
69+
},
70+
{
71+
code: `('');\n`,
72+
filename: path.join(__filename, '0_fake_virtual_name.js')
6973
}
7074
],
7175
invalid: [

0 commit comments

Comments
 (0)