Skip to content

Commit

Permalink
feat: support processor virtual filename (#401)
Browse files Browse the repository at this point in the history
* feat: support processor virtual filename

close #393

* refactor: normalize filepath first in case recursive virtual filename
  • Loading branch information
JounQin authored Apr 14, 2021
1 parent d1a5b2b commit ee0ccc6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
43 changes: 38 additions & 5 deletions eslint-plugin-prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
// Requirements
// ------------------------------------------------------------------------------

const fs = require('fs');
const path = require('path');

const {
showInvisibles,
generateDifferences
Expand All @@ -25,6 +28,9 @@ const { INSERT, DELETE, REPLACE } = generateDifferences;
// ------------------------------------------------------------------------------

// Lazily-loaded Prettier.
/**
* @type {import('prettier')}
*/
let prettier;

// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -55,6 +61,26 @@ function reportDifference(context, difference) {
});
}

/**
* get normalized filepath in case of virtual filename
* @param {string} filepath
* @returns {string}
*/
function normalizeFilepath(filepath) {
try {
if (fs.statSync(filepath).isFile()) {
return filepath;
}
} catch (err) {
// https://github.com/eslint/eslint/issues/11989
if (err.code === 'ENOTDIR') {
return normalizeFilepath(path.dirname(filepath));
}
}

return filepath;
}

// ------------------------------------------------------------------------------
// Module Definition
// ------------------------------------------------------------------------------
Expand Down Expand Up @@ -112,6 +138,7 @@ module.exports = {
(context.options[1] && context.options[1].fileInfoOptions) || {};
const sourceCode = context.getSourceCode();
const filepath = context.getFilename();
const normalizedFilepath = normalizeFilepath(filepath);
const source = sourceCode.text;

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

const prettierRcOptions = usePrettierrc
? prettier.resolveConfig.sync(filepath, {
? prettier.resolveConfig.sync(normalizedFilepath, {
editorconfig: true
})
: null;

const prettierFileInfo = prettier.getFileInfo.sync(
filepath,
normalizedFilepath,
Object.assign(
{},
{ resolveConfig: true, ignorePath: '.prettierignore' },
Expand All @@ -145,7 +172,8 @@ module.exports = {

const initialOptions = {};

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

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

// Prettier's message contains a codeframe style preview of the
// invalid code and the line/column at which the error occured.
// invalid code and the line/column at which the error occurred.
// ESLint shows those pieces of information elsewhere already so
// remove them from the message
if (err.codeFrame) {
Expand Down
4 changes: 4 additions & 0 deletions test/prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ ruleTester.run('prettier', rule, {
{
code: 'a();;;;;;\n',
filename: 'node_modules/dummy.js'
},
{
code: `('');\n`,
filename: path.join(__filename, '0_fake_virtual_name.js')
}
],
invalid: [
Expand Down

0 comments on commit ee0ccc6

Please sign in to comment.