1 | /**
|
---|
2 | * @fileoverview Rule for disallowing require() outside of the top-level module context
|
---|
3 | * @author Jamund Ferguson
|
---|
4 | * @deprecated in ESLint v7.0.0
|
---|
5 | */
|
---|
6 |
|
---|
7 | "use strict";
|
---|
8 |
|
---|
9 | const ACCEPTABLE_PARENTS = new Set([
|
---|
10 | "AssignmentExpression",
|
---|
11 | "VariableDeclarator",
|
---|
12 | "MemberExpression",
|
---|
13 | "ExpressionStatement",
|
---|
14 | "CallExpression",
|
---|
15 | "ConditionalExpression",
|
---|
16 | "Program",
|
---|
17 | "VariableDeclaration",
|
---|
18 | "ChainExpression"
|
---|
19 | ]);
|
---|
20 |
|
---|
21 | /**
|
---|
22 | * Finds the eslint-scope reference in the given scope.
|
---|
23 | * @param {Object} scope The scope to search.
|
---|
24 | * @param {ASTNode} node The identifier node.
|
---|
25 | * @returns {Reference|null} Returns the found reference or null if none were found.
|
---|
26 | */
|
---|
27 | function findReference(scope, node) {
|
---|
28 | const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] &&
|
---|
29 | reference.identifier.range[1] === node.range[1]);
|
---|
30 |
|
---|
31 | if (references.length === 1) {
|
---|
32 | return references[0];
|
---|
33 | }
|
---|
34 |
|
---|
35 | /* c8 ignore next */
|
---|
36 | return null;
|
---|
37 |
|
---|
38 | }
|
---|
39 |
|
---|
40 | /**
|
---|
41 | * Checks if the given identifier node is shadowed in the given scope.
|
---|
42 | * @param {Object} scope The current scope.
|
---|
43 | * @param {ASTNode} node The identifier node to check.
|
---|
44 | * @returns {boolean} Whether or not the name is shadowed.
|
---|
45 | */
|
---|
46 | function isShadowed(scope, node) {
|
---|
47 | const reference = findReference(scope, node);
|
---|
48 |
|
---|
49 | return reference && reference.resolved && reference.resolved.defs.length > 0;
|
---|
50 | }
|
---|
51 |
|
---|
52 | /** @type {import('../shared/types').Rule} */
|
---|
53 | module.exports = {
|
---|
54 | meta: {
|
---|
55 | deprecated: true,
|
---|
56 |
|
---|
57 | replacedBy: [],
|
---|
58 |
|
---|
59 | type: "suggestion",
|
---|
60 |
|
---|
61 | docs: {
|
---|
62 | description: "Require `require()` calls to be placed at top-level module scope",
|
---|
63 | recommended: false,
|
---|
64 | url: "https://eslint.org/docs/latest/rules/global-require"
|
---|
65 | },
|
---|
66 |
|
---|
67 | schema: [],
|
---|
68 | messages: {
|
---|
69 | unexpected: "Unexpected require()."
|
---|
70 | }
|
---|
71 | },
|
---|
72 |
|
---|
73 | create(context) {
|
---|
74 | const sourceCode = context.sourceCode;
|
---|
75 |
|
---|
76 | return {
|
---|
77 | CallExpression(node) {
|
---|
78 | const currentScope = sourceCode.getScope(node);
|
---|
79 |
|
---|
80 | if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
|
---|
81 | const isGoodRequire = sourceCode.getAncestors(node).every(parent => ACCEPTABLE_PARENTS.has(parent.type));
|
---|
82 |
|
---|
83 | if (!isGoodRequire) {
|
---|
84 | context.report({ node, messageId: "unexpected" });
|
---|
85 | }
|
---|
86 | }
|
---|
87 | }
|
---|
88 | };
|
---|
89 | }
|
---|
90 | };
|
---|