Skip to content

Commit dd58fd6

Browse files
michaelfaithsparten11740
authored andcommitted
[utils] [new] add context compatibility helpers
This change adds helper functions to `eslint-module-utils` in order to add eslint v9 support to `eslint-plugin-import` in a backwards compatible way. Contributes to import-js#2996
1 parent 55add49 commit dd58fd6

File tree

5 files changed

+117
-1
lines changed

5 files changed

+117
-1
lines changed

utils/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
55

66
## Unreleased
77

8+
### New
9+
- add context compatibility helpers ([#3049], thanks [@michaelfaith])
10+
811
## v2.9.0 - 2024-09-02
912

1013
### New
@@ -155,6 +158,7 @@ Yanked due to critical issue with cache key resulting from #839.
155158
### Fixed
156159
- `unambiguous.test()` regex is now properly in multiline mode
157160

161+
[#3049]: https://github.com/import-js/eslint-plugin-import/pull/3049
158162
[#3039]: https://github.com/import-js/eslint-plugin-import/pull/3039
159163
[#3018]: https://github.com/import-js/eslint-plugin-import/pull/3018
160164
[#2963]: https://github.com/import-js/eslint-plugin-import/pull/2963

utils/contextCompat.d.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Scope, SourceCode, Rule } from 'eslint';
2+
import * as ESTree from 'estree';
3+
4+
type LegacyContext = {
5+
getFilename: () => string,
6+
getPhysicalFilename: () => string,
7+
getSourceCode: () => SourceCode,
8+
getScope: never,
9+
getAncestors: never,
10+
getDeclaredVariables: never,
11+
};
12+
13+
type NewContext = {
14+
filename: string,
15+
sourceCode: SourceCode,
16+
getPhysicalFilename?: () => string,
17+
getScope: () => Scope.Scope,
18+
getAncestors: () => ESTree.Node[],
19+
getDeclaredVariables: (node: ESTree.Node) => Scope.Variable[],
20+
};
21+
22+
export type Context = LegacyContext | NewContext | Rule.RuleContext;
23+
24+
declare function getAncestors(context: Context, node: ESTree.Node): ESTree.Node[];
25+
declare function getDeclaredVariables(context: Context, node: ESTree.Node): Scope.Variable[];
26+
declare function getFilename(context: Context): string;
27+
declare function getPhysicalFilename(context: Context): string;
28+
declare function getScope(context: Context, node: ESTree.Node): Scope.Scope;
29+
declare function getSourceCode(context: Context): SourceCode;
30+
31+
export {
32+
getAncestors,
33+
getDeclaredVariables,
34+
getFilename,
35+
getPhysicalFilename,
36+
getScope,
37+
getSourceCode,
38+
};

utils/contextCompat.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
exports.__esModule = true;
4+
5+
/** @type {import('./contextCompat').getAncestors} */
6+
function getAncestors(context, node) {
7+
const sourceCode = getSourceCode(context);
8+
9+
if (sourceCode && sourceCode.getAncestors) {
10+
return sourceCode.getAncestors(node);
11+
}
12+
13+
return context.getAncestors();
14+
}
15+
16+
/** @type {import('./contextCompat').getDeclaredVariables} */
17+
function getDeclaredVariables(context, node) {
18+
const sourceCode = getSourceCode(context);
19+
20+
if (sourceCode && sourceCode.getDeclaredVariables) {
21+
return sourceCode.getDeclaredVariables(node);
22+
}
23+
24+
return context.getDeclaredVariables(node);
25+
}
26+
27+
/** @type {import('./contextCompat').getFilename} */
28+
function getFilename(context) {
29+
if ('filename' in context) {
30+
return context.filename;
31+
}
32+
33+
return context.getFilename();
34+
}
35+
36+
/** @type {import('./contextCompat').getPhysicalFilename} */
37+
function getPhysicalFilename(context) {
38+
if (context.getPhysicalFilename) {
39+
return context.getPhysicalFilename();
40+
}
41+
42+
return getFilename(context);
43+
}
44+
45+
/** @type {import('./contextCompat').getScope} */
46+
function getScope(context, node) {
47+
const sourceCode = getSourceCode(context);
48+
49+
if (sourceCode && sourceCode.getScope) {
50+
return sourceCode.getScope(node);
51+
}
52+
53+
return context.getScope();
54+
}
55+
56+
/** @type {import('./contextCompat').getSourceCode} */
57+
function getSourceCode(context) {
58+
if ('sourceCode' in context) {
59+
return context.sourceCode;
60+
}
61+
62+
return context.getSourceCode();
63+
}
64+
65+
module.exports = {
66+
getAncestors,
67+
getDeclaredVariables,
68+
getFilename,
69+
getPhysicalFilename,
70+
getScope,
71+
getSourceCode,
72+
};

utils/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
},
88
"main": false,
99
"exports": {
10+
"./contextCompat": "./contextCompat.js",
1011
"./ModuleCache": "./ModuleCache.js",
1112
"./ModuleCache.js": "./ModuleCache.js",
1213
"./declaredScope": "./declaredScope.js",

utils/resolve.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ exports.__esModule = true;
55
const fs = require('fs');
66
const Module = require('module');
77
const path = require('path');
8+
const { getPhysicalFilename } = require('./contextCompat');
89

910
const hashObject = require('./hash').hashObject;
1011
const ModuleCache = require('./ModuleCache').default;
@@ -229,7 +230,7 @@ const erroredContexts = new Set();
229230
*/
230231
function resolve(p, context) {
231232
try {
232-
return relative(p, context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(), context.settings);
233+
return relative(p, getPhysicalFilename(context), context.settings);
233234
} catch (err) {
234235
if (!erroredContexts.has(context)) {
235236
// The `err.stack` string starts with `err.name` followed by colon and `err.message`.

0 commit comments

Comments
 (0)