@@ -62,19 +62,21 @@ function reportDifference(context, difference) {
6262}
6363
6464/**
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
6668 * @param {string } filepath
6769 * @returns {string }
6870 */
69- function normalizeFilepath ( filepath ) {
71+ function getOnDiskFilepath ( filepath ) {
7072 try {
7173 if ( fs . statSync ( filepath ) . isFile ( ) ) {
7274 return filepath ;
7375 }
7476 } catch ( err ) {
7577 // https://github.com/eslint/eslint/issues/11989
7678 if ( err . code === 'ENOTDIR' ) {
77- return normalizeFilepath ( path . dirname ( filepath ) ) ;
79+ return getOnDiskFilepath ( path . dirname ( filepath ) ) ;
7880 }
7981 }
8082
@@ -138,7 +140,14 @@ module.exports = {
138140 ( context . options [ 1 ] && context . options [ 1 ] . fileInfoOptions ) || { } ;
139141 const sourceCode = context . getSourceCode ( ) ;
140142 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 ) ;
142151 const source = sourceCode . text ;
143152
144153 return {
@@ -151,13 +160,13 @@ module.exports = {
151160 const eslintPrettierOptions = context . options [ 0 ] || { } ;
152161
153162 const prettierRcOptions = usePrettierrc
154- ? prettier . resolveConfig . sync ( normalizedFilepath , {
163+ ? prettier . resolveConfig . sync ( onDiskFilepath , {
155164 editorconfig : true
156165 } )
157166 : null ;
158167
159168 const prettierFileInfo = prettier . getFileInfo . sync (
160- normalizedFilepath ,
169+ onDiskFilepath ,
161170 Object . assign (
162171 { } ,
163172 { resolveConfig : true , ignorePath : '.prettierignore' } ,
@@ -172,18 +181,22 @@ module.exports = {
172181
173182 const initialOptions = { } ;
174183
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
177185 // fragments within a non-JS language. In the cases where prettier
178186 // supports the same language as a processor, we want to process
179187 // the provided source code as javascript (as ESLint provides the
180188 // rules with fragments of JS) instead of guessing the parser
181189 // based off the filename. Otherwise, for instance, on a .md file we
182190 // end up trying to run prettier over a fragment of JS using the
183191 // 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.
187200 // This is added to the options first, so that
188201 // prettierRcOptions and eslintPrettierOptions can still override
189202 // the parser.
@@ -193,13 +206,9 @@ module.exports = {
193206 // * Prettier supports parsing the file type
194207 // * There is an ESLint processor that extracts JavaScript snippets
195208 // 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
200209 const parserBlocklist = [ null , 'graphql' , 'markdown' , 'html' ] ;
201210 if (
202- filepath === normalizedFilepath &&
211+ filepath === onDiskFilepath &&
203212 parserBlocklist . indexOf ( prettierFileInfo . inferredParser ) !== - 1
204213 ) {
205214 // Prettier v1.16.0 renamed the `babylon` parser to `babel`
0 commit comments