From c4ff5c8e0a5cad1ee1f326f7055c7304c44a8eb7 Mon Sep 17 00:00:00 2001 From: "wangjun.hops" Date: Sun, 17 Apr 2022 00:49:38 +0800 Subject: [PATCH 1/2] fix: get the real filename to avoid rule invalidation --- lib/rules/multi-word-component-names.js | 2 +- lib/rules/no-multi-spaces.js | 6 +++--- lib/rules/require-direct-export.js | 2 +- lib/utils/indent-common.js | 4 +++- lib/utils/index.js | 18 +++++++++++++----- typings/eslint/index.d.ts | 9 +++++++++ 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/lib/rules/multi-word-component-names.js b/lib/rules/multi-word-component-names.js index 6f73de294..adad8a27d 100644 --- a/lib/rules/multi-word-component-names.js +++ b/lib/rules/multi-word-component-names.js @@ -111,7 +111,7 @@ module.exports = { 'Program:exit'(node) { if (hasName) return if (!hasVue && node.body.length > 0) return - const fileName = context.getFilename() + const fileName = context.getPhysicalFilename() const componentName = path.basename(fileName, path.extname(fileName)) if ( utils.isVueFile(fileName) && diff --git a/lib/rules/no-multi-spaces.js b/lib/rules/no-multi-spaces.js index aa8b70a22..a0a2f1706 100644 --- a/lib/rules/no-multi-spaces.js +++ b/lib/rules/no-multi-spaces.js @@ -4,7 +4,7 @@ */ 'use strict' -const path = require('path') +const utils = require('../utils') // ------------------------------------------------------------------------------ // Rule Definition @@ -52,8 +52,8 @@ module.exports = { return { Program(node) { if (context.parserServices.getTemplateBodyTokenStore == null) { - const filename = context.getFilename() - if (path.extname(filename) === '.vue') { + const filename = context.getPhysicalFilename() + if (utils.isVueFile(filename)) { context.report({ loc: { line: 1, column: 0 }, message: diff --git a/lib/rules/require-direct-export.js b/lib/rules/require-direct-export.js index 18897eb07..d533f770a 100644 --- a/lib/rules/require-direct-export.js +++ b/lib/rules/require-direct-export.js @@ -31,7 +31,7 @@ module.exports = { }, /** @param {RuleContext} context */ create(context) { - const filePath = context.getFilename() + const filePath = context.getPhysicalFilename() if (!utils.isVueFile(filePath)) return {} const disallowFunctional = (context.options[0] || {}) diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index 020b6373b..23bd1f628 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -33,6 +33,7 @@ const { last } = require('./indent-utils') const { defineVisitor: tsDefineVisitor } = require('./indent-ts') +const utils = require('../utils') /** * @typedef {import('../../typings/eslint-plugin-vue/util-types/node').HasLocation} HasLocation @@ -205,7 +206,8 @@ module.exports.defineVisitor = function create( tokenStore, defaultOptions ) { - if (!context.getFilename().endsWith('.vue')) return {} + const filename = context.getPhysicalFilename() + if (!utils.isVueFile(filename)) return {} const options = parseOptions( context.options[0], diff --git a/lib/utils/index.js b/lib/utils/index.js index 69cd84a31..edf7bb02f 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -1987,8 +1987,8 @@ function defineTemplateBodyVisitor( options ) { if (context.parserServices.defineTemplateBodyVisitor == null) { - const filename = context.getFilename() - if (path.extname(filename) === '.vue') { + const filename = context.getPhysicalFilename() + if (isVueFile(filename)) { context.report({ loc: { line: 1, column: 0 }, message: @@ -2015,8 +2015,8 @@ function defineTemplateBodyVisitor( */ function defineDocumentVisitor(context, documentVisitor, options) { if (context.parserServices.defineDocumentVisitor == null) { - const filename = context.getFilename() - if (path.extname(filename) === '.vue') { + const filename = context.getPhysicalFilename() + if (isVueFile(filename)) { context.report({ loc: { line: 1, column: 0 }, message: @@ -2373,6 +2373,14 @@ function getVExpressionContainer(node) { * @param {string} path */ function isVueFile(path) { + /** + * When `path` is `context.getFilename()`, it returns the filename associated with the source or `` if not specified. + * When `path` is `context.getPhysicalFilename()`, it returns the full path of the file on disk or `` if not specified. + * If filename is not specified, we assume it's a vue file. + */ + if (['', ''].includes(path)) { + return true + } return path.endsWith('.vue') || path.endsWith('.jsx') } @@ -2583,7 +2591,7 @@ function isSFCObject(context, node) { if (node.type !== 'ObjectExpression') { return false } - const filePath = context.getFilename() + const filePath = context.getPhysicalFilename() const ext = path.extname(filePath) if (ext !== '.vue' && ext) { return false diff --git a/typings/eslint/index.d.ts b/typings/eslint/index.d.ts index 7bfda0245..ea8b55604 100644 --- a/typings/eslint/index.d.ts +++ b/typings/eslint/index.d.ts @@ -329,6 +329,15 @@ export namespace Rule { // eslint@6 does not have this method. getCwd?: () => string + + /** + * When linting a file, it returns the full path of the file on disk without any code block information. + * When linting text, it returns the value passed to `—stdin-filename` or `` if not specified. + * If not set, it will fallback to `getFilename()` + * This was added in eslint@7.28.0 + * @since 7.28.0 + */ + getPhysicalFilename: () => string } type ReportDescriptor = From a22947d70ff51d4d8791f02ad1c573578873295b Mon Sep 17 00:00:00 2001 From: "wangjun.hops" Date: Sun, 17 Apr 2022 02:56:24 +0800 Subject: [PATCH 2/2] fix: compatible with ESLint v6 --- lib/rules/multi-word-component-names.js | 2 +- lib/rules/no-multi-spaces.js | 2 +- lib/rules/require-direct-export.js | 2 +- lib/utils/indent-common.js | 2 +- lib/utils/index.js | 27 +++++++++++++++++++++---- typings/eslint/index.d.ts | 2 +- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/rules/multi-word-component-names.js b/lib/rules/multi-word-component-names.js index adad8a27d..8413bb5f0 100644 --- a/lib/rules/multi-word-component-names.js +++ b/lib/rules/multi-word-component-names.js @@ -111,7 +111,7 @@ module.exports = { 'Program:exit'(node) { if (hasName) return if (!hasVue && node.body.length > 0) return - const fileName = context.getPhysicalFilename() + const fileName = utils.getPhysicalFilename(context) const componentName = path.basename(fileName, path.extname(fileName)) if ( utils.isVueFile(fileName) && diff --git a/lib/rules/no-multi-spaces.js b/lib/rules/no-multi-spaces.js index a0a2f1706..209a9f967 100644 --- a/lib/rules/no-multi-spaces.js +++ b/lib/rules/no-multi-spaces.js @@ -52,7 +52,7 @@ module.exports = { return { Program(node) { if (context.parserServices.getTemplateBodyTokenStore == null) { - const filename = context.getPhysicalFilename() + const filename = utils.getPhysicalFilename(context) if (utils.isVueFile(filename)) { context.report({ loc: { line: 1, column: 0 }, diff --git a/lib/rules/require-direct-export.js b/lib/rules/require-direct-export.js index d533f770a..aef7530d1 100644 --- a/lib/rules/require-direct-export.js +++ b/lib/rules/require-direct-export.js @@ -31,7 +31,7 @@ module.exports = { }, /** @param {RuleContext} context */ create(context) { - const filePath = context.getPhysicalFilename() + const filePath = utils.getPhysicalFilename(context) if (!utils.isVueFile(filePath)) return {} const disallowFunctional = (context.options[0] || {}) diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js index 23bd1f628..ab8690e8c 100644 --- a/lib/utils/indent-common.js +++ b/lib/utils/indent-common.js @@ -206,7 +206,7 @@ module.exports.defineVisitor = function create( tokenStore, defaultOptions ) { - const filename = context.getPhysicalFilename() + const filename = utils.getPhysicalFilename(context) if (!utils.isVueFile(filename)) return {} const options = parseOptions( diff --git a/lib/utils/index.js b/lib/utils/index.js index edf7bb02f..68c63f034 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -311,6 +311,18 @@ function wrapContextToOverrideReportMethodToSkipDynamicArgument(context) { }) } +/** + * Return the full path of the file on disk, if not set, it will fallback to `context.getFilename()`. + * @param {RuleContext} context The ESLint rule context. + * @returns {string} + */ +function getPhysicalFilename(context) { + if (context.getPhysicalFilename) { + return context.getPhysicalFilename() + } + return context.getFilename() +} + // ------------------------------------------------------------------------------ // Exports // ------------------------------------------------------------------------------ @@ -1891,7 +1903,14 @@ module.exports = { } return true - } + }, + + /** + * Return the full path of the file on disk, if not set, it will fallback to `context.getFilename()`. + * @param {RuleContext} context The ESLint rule context. + * @returns {string} + */ + getPhysicalFilename } // ------------------------------------------------------------------------------ @@ -1987,7 +2006,7 @@ function defineTemplateBodyVisitor( options ) { if (context.parserServices.defineTemplateBodyVisitor == null) { - const filename = context.getPhysicalFilename() + const filename = getPhysicalFilename(context) if (isVueFile(filename)) { context.report({ loc: { line: 1, column: 0 }, @@ -2015,7 +2034,7 @@ function defineTemplateBodyVisitor( */ function defineDocumentVisitor(context, documentVisitor, options) { if (context.parserServices.defineDocumentVisitor == null) { - const filename = context.getPhysicalFilename() + const filename = getPhysicalFilename(context) if (isVueFile(filename)) { context.report({ loc: { line: 1, column: 0 }, @@ -2591,7 +2610,7 @@ function isSFCObject(context, node) { if (node.type !== 'ObjectExpression') { return false } - const filePath = context.getPhysicalFilename() + const filePath = getPhysicalFilename(context) const ext = path.extname(filePath) if (ext !== '.vue' && ext) { return false diff --git a/typings/eslint/index.d.ts b/typings/eslint/index.d.ts index ea8b55604..efb35dd52 100644 --- a/typings/eslint/index.d.ts +++ b/typings/eslint/index.d.ts @@ -337,7 +337,7 @@ export namespace Rule { * This was added in eslint@7.28.0 * @since 7.28.0 */ - getPhysicalFilename: () => string + getPhysicalFilename?: () => string } type ReportDescriptor =