@@ -62,19 +62,21 @@ function reportDifference(context, difference) {
62
62
}
63
63
64
64
/**
65
- * get normalized filepath in case of virtual filename
65
+ * Given a filepath, get the nearest path that is a regular file.
66
+ * The filepath provided by eslint may be a virtual filepath rather than a file
67
+ * on disk. This attempts to transform a virtual path into an on-disk path
66
68
* @param {string } filepath
67
69
* @returns {string }
68
70
*/
69
- function normalizeFilepath ( filepath ) {
71
+ function getOnDiskFilepath ( filepath ) {
70
72
try {
71
73
if ( fs . statSync ( filepath ) . isFile ( ) ) {
72
74
return filepath ;
73
75
}
74
76
} catch ( err ) {
75
77
// https://github.com/eslint/eslint/issues/11989
76
78
if ( err . code === 'ENOTDIR' ) {
77
- return normalizeFilepath ( path . dirname ( filepath ) ) ;
79
+ return getOnDiskFilepath ( path . dirname ( filepath ) ) ;
78
80
}
79
81
}
80
82
@@ -138,7 +140,14 @@ module.exports = {
138
140
( context . options [ 1 ] && context . options [ 1 ] . fileInfoOptions ) || { } ;
139
141
const sourceCode = context . getSourceCode ( ) ;
140
142
const filepath = context . getFilename ( ) ;
141
- const normalizedFilepath = normalizeFilepath ( filepath ) ;
143
+ // Processors that extract content from a file, such as the markdown
144
+ // plugin extracting fenced code blocks may choose to specify virtual
145
+ // file paths. If this is the case then we need to resolve prettier
146
+ // config and file info using the on-disk path instead of the virtual
147
+ // path.
148
+ // See https://github.com/eslint/eslint/issues/11989 for ideas around
149
+ // being able to get this value directly from eslint in the future.
150
+ const onDiskFilepath = getOnDiskFilepath ( filepath ) ;
142
151
const source = sourceCode . text ;
143
152
144
153
return {
@@ -151,13 +160,13 @@ module.exports = {
151
160
const eslintPrettierOptions = context . options [ 0 ] || { } ;
152
161
153
162
const prettierRcOptions = usePrettierrc
154
- ? prettier . resolveConfig . sync ( normalizedFilepath , {
163
+ ? prettier . resolveConfig . sync ( onDiskFilepath , {
155
164
editorconfig : true
156
165
} )
157
166
: null ;
158
167
159
168
const prettierFileInfo = prettier . getFileInfo . sync (
160
- normalizedFilepath ,
169
+ onDiskFilepath ,
161
170
Object . assign (
162
171
{ } ,
163
172
{ resolveConfig : true , ignorePath : '.prettierignore' } ,
@@ -172,18 +181,22 @@ module.exports = {
172
181
173
182
const initialOptions = { } ;
174
183
175
- // for ESLint < 6.0
176
- // it supports processors that let you extract and lint JS
184
+ // ESLint supports processors that let you extract and lint JS
177
185
// fragments within a non-JS language. In the cases where prettier
178
186
// supports the same language as a processor, we want to process
179
187
// the provided source code as javascript (as ESLint provides the
180
188
// rules with fragments of JS) instead of guessing the parser
181
189
// based off the filename. Otherwise, for instance, on a .md file we
182
190
// end up trying to run prettier over a fragment of JS using the
183
191
// markdown parser, which throws an error.
184
- // If we can't infer the parser from from the filename, either
185
- // because no filename was provided or because there is no parser
186
- // found for the filename, use javascript.
192
+ // Processors may set virtual filenames for these extracted blocks.
193
+ // If they do so then we want to trust the file extension they
194
+ // provide, and no override is needed.
195
+ // If the processor does not set any virtual filename (signified by
196
+ // `filepath` and `onDiskFilepath` being equal) AND we can't
197
+ // infer the parser from the filename, either because no filename
198
+ // was provided or because there is no parser found for the
199
+ // filename, use javascript.
187
200
// This is added to the options first, so that
188
201
// prettierRcOptions and eslintPrettierOptions can still override
189
202
// the parser.
@@ -193,13 +206,9 @@ module.exports = {
193
206
// * Prettier supports parsing the file type
194
207
// * There is an ESLint processor that extracts JavaScript snippets
195
208
// 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
200
209
const parserBlocklist = [ null , 'graphql' , 'markdown' , 'html' ] ;
201
210
if (
202
- filepath === normalizedFilepath &&
211
+ filepath === onDiskFilepath &&
203
212
parserBlocklist . indexOf ( prettierFileInfo . inferredParser ) !== - 1
204
213
) {
205
214
// Prettier v1.16.0 renamed the `babylon` parser to `babel`
0 commit comments