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 | ];
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | function findReference(scope, node) {
|
26 | const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] &&
|
27 | reference.identifier.range[1] === node.range[1]);
|
28 |
|
29 |
|
30 | if (references.length === 1) {
|
31 | return references[0];
|
32 | }
|
33 | return null;
|
34 |
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | function isShadowed(scope, node) {
|
44 | const reference = findReference(scope, node);
|
45 |
|
46 | return reference && reference.resolved && reference.resolved.defs.length > 0;
|
47 | }
|
48 |
|
49 | module.exports = {
|
50 | meta: {
|
51 | docs: {
|
52 | description: "require `require()` calls to be placed at top-level module scope",
|
53 | category: "Node.js and CommonJS",
|
54 | recommended: false,
|
55 | url: "https://eslint.org/docs/rules/global-require"
|
56 | },
|
57 |
|
58 | schema: []
|
59 | },
|
60 |
|
61 | create(context) {
|
62 | return {
|
63 | CallExpression(node) {
|
64 | const currentScope = context.getScope();
|
65 |
|
66 | if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
|
67 | const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1);
|
68 |
|
69 | if (!isGoodRequire) {
|
70 | context.report({ node, message: "Unexpected require()." });
|
71 | }
|
72 | }
|
73 | }
|
74 | };
|
75 | }
|
76 | };
|