1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const ACCEPTABLE_PARENTS = [
|
9 | "AssignmentExpression",
|
10 | "VariableDeclarator",
|
11 | "MemberExpression",
|
12 | "ExpressionStatement",
|
13 | "CallExpression",
|
14 | "ConditionalExpression",
|
15 | "Program",
|
16 | "VariableDeclaration",
|
17 | "ChainExpression"
|
18 | ];
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | function findReference(scope, node) {
|
27 | const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] &&
|
28 | reference.identifier.range[1] === node.range[1]);
|
29 |
|
30 |
|
31 | if (references.length === 1) {
|
32 | return references[0];
|
33 | }
|
34 | return null;
|
35 |
|
36 | }
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | function isShadowed(scope, node) {
|
45 | const reference = findReference(scope, node);
|
46 |
|
47 | return reference && reference.resolved && reference.resolved.defs.length > 0;
|
48 | }
|
49 |
|
50 | module.exports = {
|
51 | meta: {
|
52 | deprecated: true,
|
53 |
|
54 | replacedBy: [],
|
55 |
|
56 | type: "suggestion",
|
57 |
|
58 | docs: {
|
59 | description: "require `require()` calls to be placed at top-level module scope",
|
60 | category: "Node.js and CommonJS",
|
61 | recommended: false,
|
62 | url: "https://eslint.org/docs/rules/global-require"
|
63 | },
|
64 |
|
65 | schema: [],
|
66 | messages: {
|
67 | unexpected: "Unexpected require()."
|
68 | }
|
69 | },
|
70 |
|
71 | create(context) {
|
72 | return {
|
73 | CallExpression(node) {
|
74 | const currentScope = context.getScope();
|
75 |
|
76 | if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
|
77 | const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1);
|
78 |
|
79 | if (!isGoodRequire) {
|
80 | context.report({ node, messageId: "unexpected" });
|
81 | }
|
82 | }
|
83 | }
|
84 | };
|
85 | }
|
86 | };
|