Skip to content

Commit

Permalink
refactor: eslint v8 compat (#397)
Browse files Browse the repository at this point in the history
  • Loading branch information
aladdin-add authored Dec 24, 2024
1 parent 6aee9f2 commit 86a5242
Show file tree
Hide file tree
Showing 18 changed files with 90 additions and 65 deletions.
3 changes: 2 additions & 1 deletion lib/rules/callback-return.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* See LICENSE file in root directory for full license.
*/
"use strict"
const { getSourceCode } = require("../util/eslint-compat")

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
Expand All @@ -27,7 +28,7 @@ module.exports = {

create(context) {
const callbacks = context.options[0] || ["callback", "cb", "next"]
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const sourceCode = getSourceCode(context)

/**
* Find the closest parent matching a list of types.
Expand Down
7 changes: 4 additions & 3 deletions lib/rules/exports-style.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"use strict"

const { hasParentNode } = require("../util/has-parent-node.js")
const { getSourceCode, getScope } = require("../util/eslint-compat")

/*istanbul ignore next */
/**
Expand Down Expand Up @@ -302,7 +303,7 @@ module.exports = {
const batchAssignAllowed = Boolean(
context.options[1] != null && context.options[1].allowBatchAssign
)
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const sourceCode = getSourceCode(context)

/**
* Gets the location info of reports.
Expand Down Expand Up @@ -426,8 +427,8 @@ module.exports = {
}

return {
"Program:exit"(node) {
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
"Program:exit"() {
const scope = getScope(context)

switch (mode) {
case "module.exports":
Expand Down
18 changes: 6 additions & 12 deletions lib/rules/global-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
"use strict"

const { getScope, getAncestors } = require("../util/eslint-compat")

const ACCEPTABLE_PARENTS = [
"AssignmentExpression",
"VariableDeclarator",
Expand Down Expand Up @@ -59,26 +61,18 @@ module.exports = {
},

create(context) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9

return {
CallExpression(node) {
const currentScope =
sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const currentScope = getScope(context, node)

if (
node.callee.type === "Identifier" &&
node.callee.name === "require" &&
!isShadowed(currentScope, node.callee)
) {
const isGoodRequire = (
sourceCode.getAncestors?.(node) ??
context.getAncestors()
) // TODO: remove context.getAncestors() when dropping support for ESLint < v9
.every(
parent =>
ACCEPTABLE_PARENTS.indexOf(parent.type) > -1
)
const isGoodRequire = getAncestors(context, node).every(
parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1
)

if (!isGoodRequire) {
context.report({ node, messageId: "unexpected" })
Expand Down
5 changes: 3 additions & 2 deletions lib/rules/handle-callback-err.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
"use strict"

const { getScope } = require("../util/eslint-compat")

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
Expand All @@ -25,7 +27,6 @@ module.exports = {
},

create(context) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const errorArgument = context.options[0] || "err"

/**
Expand Down Expand Up @@ -71,7 +72,7 @@ module.exports = {
* @returns {void}
*/
function checkForError(node) {
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const scope = getScope(context, node)
const parameters = getParameters(scope)
const firstParameter = parameters[0]

Expand Down
3 changes: 2 additions & 1 deletion lib/rules/hashbang.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const getConvertPath = require("../util/get-convert-path")
const { getPackageJson } = require("../util/get-package-json")
const getNpmignore = require("../util/get-npmignore")
const { isBinFile } = require("../util/is-bin-file")
const { getSourceCode } = require("../util/eslint-compat")

const ENV_SHEBANG = "#!/usr/bin/env"
const NODE_SHEBANG = `${ENV_SHEBANG} {{executableName}}\n`
Expand Down Expand Up @@ -119,7 +120,7 @@ module.exports = {
},
},
create(context) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const sourceCode = getSourceCode(context)
const filePath = context.filename ?? context.getFilename()
if (filePath === "<input>") {
return {}
Expand Down
6 changes: 3 additions & 3 deletions lib/rules/no-deprecated-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const getConfiguredNodeVersion = require("../util/get-configured-node-version")
const getSemverRange = require("../util/get-semver-range")
const extendTrackmapWithNodePrefix = require("../util/extend-trackmap-with-node-prefix")
const unprefixNodeColon = require("../util/unprefix-node-colon")
const { getScope } = require("../util/eslint-compat")

/** @typedef {import('../unsupported-features/types.js').DeprecatedInfo} DeprecatedInfo */
/**
Expand Down Expand Up @@ -820,10 +821,9 @@ module.exports = {
})
}

const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
return {
"Program:exit"(node) {
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
"Program:exit"() {
const scope = getScope(context)

const tracker = new ReferenceTracker(scope, {
mode: "legacy",
Expand Down
5 changes: 2 additions & 3 deletions lib/rules/no-exports-assign.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"use strict"

const { findVariable } = require("@eslint-community/eslint-utils")
const { getScope } = require("../util/eslint-compat")

/**
* @param {import('estree').Node} node
Expand Down Expand Up @@ -61,11 +62,9 @@ module.exports = {
type: "problem",
},
create(context) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9

return {
AssignmentExpression(node) {
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const scope = getScope(context)

if (
!isExports(node.left, scope) ||
Expand Down
3 changes: 2 additions & 1 deletion lib/rules/no-path-concat.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {
getStringIfConstant,
} = require("@eslint-community/eslint-utils")
const { hasParentNode } = require("../util/has-parent-node.js")
const { getSourceCode } = require("../util/eslint-compat")

/**
* Get the first char of the specified template element.
Expand Down Expand Up @@ -195,7 +196,7 @@ module.exports = {
create(context) {
return {
"Program:exit"(programNode) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const sourceCode = getSourceCode(context)
const globalScope =
sourceCode.getScope?.(programNode) ?? context.getScope()
const tracker = new ReferenceTracker(globalScope)
Expand Down
4 changes: 2 additions & 2 deletions lib/rules/no-unsupported-features/es-syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const rangeSubset = require("semver/ranges/subset")
const getConfiguredNodeVersion = require("../../util/get-configured-node-version")
const getSemverRange = require("../../util/get-semver-range")
const mergeVisitorsInPlace = require("../../util/merge-visitors-in-place")
const { getScope } = require("../../util/eslint-compat")
/** @type {Record<string, ESSyntax>} */
const features = require("./es-syntax.json")

Expand Down Expand Up @@ -113,8 +114,7 @@ function normalizeScope(initialScope, node) {
* @returns {boolean}
*/
function isStrict(context, node) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const scope = getScope(context)
return normalizeScope(scope, node).isStrict
}

Expand Down
6 changes: 3 additions & 3 deletions lib/rules/prefer-promises/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
CONSTRUCT,
ReferenceTracker,
} = require("@eslint-community/eslint-utils")
const { getScope } = require("../../util/eslint-compat")

/** @type {import('@eslint-community/eslint-utils').TraceMap<boolean>} */
const dns = {
Expand Down Expand Up @@ -57,9 +58,8 @@ module.exports = {

create(context) {
return {
"Program:exit"(node) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
"Program:exit"() {
const scope = getScope(context)
const tracker = new ReferenceTracker(scope, { mode: "legacy" })
const references = [
...tracker.iterateCjsReferences(traceMap),
Expand Down
6 changes: 3 additions & 3 deletions lib/rules/prefer-promises/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"use strict"

const { CALL, ReferenceTracker } = require("@eslint-community/eslint-utils")
const { getScope } = require("../../util/eslint-compat")

/** @type {import('@eslint-community/eslint-utils').TraceMap<boolean>} */
const traceMap = {
Expand Down Expand Up @@ -55,9 +56,8 @@ module.exports = {

create(context) {
return {
"Program:exit"(node) {
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const scope = sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
"Program:exit"() {
const scope = getScope(context)
const tracker = new ReferenceTracker(scope, { mode: "legacy" })
const references = [
...tracker.iterateCjsReferences(traceMap),
Expand Down
10 changes: 3 additions & 7 deletions lib/util/check-prefer-global.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"use strict"

const { ReferenceTracker } = require("@eslint-community/eslint-utils")

const { getScope } = require("../util/eslint-compat")
/**
* @typedef TraceMap
* @property {import('@eslint-community/eslint-utils').TraceMap<boolean>} globals
Expand Down Expand Up @@ -36,9 +36,7 @@ class Verifier {
*/
verifyToPreferGlobals() {
const { context, traceMap } = this
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const scope =
sourceCode.getScope?.(sourceCode.ast) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const scope = getScope(context)
const tracker = new ReferenceTracker(scope, {
mode: "legacy",
})
Expand All @@ -57,9 +55,7 @@ class Verifier {
*/
verifyToPreferModules() {
const { context, traceMap } = this
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const scope =
sourceCode.getScope?.(sourceCode.ast) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const scope = getScope(context)
const tracker = new ReferenceTracker(scope)

for (const { node } of tracker.iterateGlobalReferences(
Expand Down
4 changes: 2 additions & 2 deletions lib/util/check-unsupported-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const getConfiguredNodeVersion = require("./get-configured-node-version")
const getSemverRange = require("./get-semver-range")
const unprefixNodeColon = require("./unprefix-node-colon")
const semverRangeSubset = require("semver/ranges/subset")
const { getScope } = require("../util/eslint-compat")

/**
* Parses the options.
Expand Down Expand Up @@ -86,8 +87,7 @@ module.exports.checkUnsupportedBuiltins = function checkUnsupportedBuiltins(
traceMap
) {
const options = parseOptions(context)
const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
const scope = sourceCode.getScope?.(sourceCode.ast) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
const scope = getScope(context)
const tracker = new ReferenceTracker(scope, { mode: "legacy" })
const references = [
...tracker.iterateCjsReferences(traceMap.modules ?? {}),
Expand Down
43 changes: 43 additions & 0 deletions lib/util/eslint-compat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @fileoverview Utilities for eslint compatibility.
* @see https://eslint.org/docs/latest/use/migrate-to-9.0.0#removed-context-methods
* @author aladdin-add<[email protected]>
*/
"use strict"

/** @import { Rule } from 'eslint' */
/** @typedef {import('estree').Node} Node */

exports.getSourceCode = function (/** @type Rule.RuleContext */ context) {
return context.sourceCode || context.getSourceCode()
}

exports.getScope = function (
/** @type {Rule.RuleContext} */ context,
/** @type {Node} */ node
) {
const sourceCode = exports.getSourceCode(context)
return sourceCode.getScope?.(node || sourceCode.ast) || context.getScope()
}

exports.getAncestors = function (
/** @type {Rule.RuleContext} */ context,
/** @type {Node} */ node
) {
const sourceCode = exports.getSourceCode(context)
return sourceCode.getAncestors?.(node) || context.getAncestors()
}

exports.getCwd = function (/** @type {Rule.RuleContext} */ context) {
return context.cwd || context.getCwd()
}

exports.getPhysicalFilename = function (
/** @type {Rule.RuleContext} */ context
) {
return context.physicalFilename || context.getPhysicalFilename?.()
}

exports.getFilename = function (/** @type {Rule.RuleContext} */ context) {
return context.filename || context.getFilename?.()
}
8 changes: 2 additions & 6 deletions lib/util/get-tsconfig.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict"

const { getTsconfig, parseTsconfig } = require("get-tsconfig")
const { getPhysicalFilename, getFilename } = require("./eslint-compat")
const fsCache = new Map()

/**
Expand Down Expand Up @@ -30,12 +31,7 @@ function getTSConfigForFile(filename) {
* @returns {import("get-tsconfig").TsConfigResult | null}
*/
function getTSConfigForContext(context) {
// TODO: remove context.get(PhysicalFilename|Filename) when dropping eslint < v10
const filename =
context.physicalFilename ??
context.getPhysicalFilename?.() ??
context.filename ??
context.getFilename?.()
const filename = getPhysicalFilename(context) ?? getFilename(context)

return getTSConfigForFile(filename)
}
Expand Down
6 changes: 2 additions & 4 deletions lib/util/is-typescript.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict"

const path = require("path")
const { getPhysicalFilename, getFilename } = require("./eslint-compat")

const typescriptExtensions = [".ts", ".tsx", ".cts", ".mts"]

Expand All @@ -12,10 +13,7 @@ const typescriptExtensions = [".ts", ".tsx", ".cts", ".mts"]
*/
module.exports = function isTypescript(context) {
const sourceFileExt = path.extname(
context.physicalFilename ??
context.getPhysicalFilename?.() ??
context.filename ??
context.getFilename?.()
getPhysicalFilename(context) ?? getFilename(context)
)
return typescriptExtensions.includes(sourceFileExt)
}
6 changes: 2 additions & 4 deletions lib/util/visit-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const getResolverConfig = require("./get-resolver-config")
const getTryExtensions = require("./get-try-extensions")
const ImportTarget = require("./import-target")
const stripImportPathParams = require("./strip-import-path-params")

const { getFilename } = require("./eslint-compat")
/** @typedef {import('@typescript-eslint/typescript-estree').TSESTree.ImportDeclaration} ImportDeclaration */

/**
Expand All @@ -38,9 +38,7 @@ module.exports = function visitImport(
) {
/** @type {import('./import-target.js')[]} */
const targets = []
const basedir = path.dirname(
path.resolve(context.filename ?? context.getFilename())
)
const basedir = path.dirname(path.resolve(getFilename(context)))
const paths = getResolvePaths(context, optionIndex)
const resolverConfig = getResolverConfig(context, optionIndex)
const extensions = getTryExtensions(context, optionIndex)
Expand Down
Loading

0 comments on commit 86a5242

Please sign in to comment.