• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview Ensure modules are not required twice at top level of a module
3 * @author devsnek
4 */
5'use strict';
6
7const { isRequireCall, isString } = require('./rules-utils.js');
8
9//------------------------------------------------------------------------------
10// Rule Definition
11//------------------------------------------------------------------------------
12
13
14function isTopLevel(node) {
15  do {
16    if (node.type === 'FunctionDeclaration' ||
17        node.type === 'FunctionExpression' ||
18        node.type === 'ArrowFunctionExpression' ||
19        node.type === 'ClassBody' ||
20        node.type === 'MethodDefinition') {
21      return false;
22    }
23  } while (node = node.parent);
24  return true;
25}
26
27module.exports = (context) => {
28  if (context.parserOptions.sourceType === 'module') {
29    return {};
30  }
31
32  function getRequiredModuleNameFromCall(node) {
33    // Node has arguments and first argument is string
34    if (node.arguments.length && isString(node.arguments[0])) {
35      return node.arguments[0].value.trim();
36    }
37
38    return undefined;
39  }
40
41  const required = new Set();
42
43  const rules = {
44    CallExpression: (node) => {
45      if (isRequireCall(node) && isTopLevel(node)) {
46        const moduleName = getRequiredModuleNameFromCall(node);
47        if (moduleName === undefined) {
48          return;
49        }
50        if (required.has(moduleName)) {
51          context.report(
52            node,
53            '\'{{moduleName}}\' require is duplicated.',
54            { moduleName }
55          );
56        } else {
57          required.add(moduleName);
58        }
59      }
60    },
61  };
62
63  return rules;
64};
65