-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathno-mutable-exports.js
62 lines (54 loc) · 1.84 KB
/
no-mutable-exports.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { getScope } from 'eslint-module-utils/contextCompat';
import docsUrl from '../docsUrl';
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
category: 'Helpful warnings',
description: 'Forbid the use of mutable exports with `var` or `let`.',
url: docsUrl('no-mutable-exports'),
},
schema: [],
},
create(context) {
function checkDeclaration(node) {
const { kind } = node;
if (kind === 'var' || kind === 'let') {
context.report(node, `Exporting mutable '${kind}' binding, use 'const' instead.`);
}
}
/** @type {(scope: import('eslint').Scope.Scope, name: string) => void} */
function checkDeclarationsInScope({ variables }, name) {
variables
.filter((variable) => variable.name === name)
.forEach((variable) => {
variable.defs
.filter((def) => def.type === 'Variable' && def.parent)
.forEach((def) => {
checkDeclaration(def.parent);
});
});
}
return {
/** @param {import('estree').ExportDefaultDeclaration} node */
ExportDefaultDeclaration(node) {
const scope = getScope(context, node);
if ('name' in node.declaration && node.declaration.name) {
checkDeclarationsInScope(scope, node.declaration.name);
}
},
/** @param {import('estree').ExportNamedDeclaration} node */
ExportNamedDeclaration(node) {
const scope = getScope(context, node);
if ('declaration' in node && node.declaration) {
checkDeclaration(node.declaration);
} else if (!('source' in node) || !node.source) {
node.specifiers.forEach((specifier) => {
checkDeclarationsInScope(scope, specifier.local.name);
});
}
},
};
},
};