UNPKG

3.8 kBJavaScriptView Raw
1/**
2 * @fileoverview Restrict usage of specified globals.
3 * @author Benoît Zugmeyer
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Helpers
9//------------------------------------------------------------------------------
10
11const DEFAULT_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'.",
12 CUSTOM_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'. {{customMessage}}";
13
14//------------------------------------------------------------------------------
15// Rule Definition
16//------------------------------------------------------------------------------
17
18module.exports = {
19 meta: {
20 docs: {
21 description: "disallow specified global variables",
22 category: "Variables",
23 recommended: false,
24 url: "https://eslint.org/docs/rules/no-restricted-globals"
25 },
26
27 schema: {
28 type: "array",
29 items: {
30 oneOf: [
31 {
32 type: "string"
33 },
34 {
35 type: "object",
36 properties: {
37 name: { type: "string" },
38 message: { type: "string" }
39 },
40 required: ["name"],
41 additionalProperties: false
42 }
43 ]
44 },
45 uniqueItems: true,
46 minItems: 0
47 }
48 },
49
50 create(context) {
51
52 // If no globals are restricted, we don't need to do anything
53 if (context.options.length === 0) {
54 return {};
55 }
56
57 const restrictedGlobalMessages = context.options.reduce((memo, option) => {
58 if (typeof option === "string") {
59 memo[option] = null;
60 } else {
61 memo[option.name] = option.message;
62 }
63
64 return memo;
65 }, {});
66
67 /**
68 * Report a variable to be used as a restricted global.
69 * @param {Reference} reference the variable reference
70 * @returns {void}
71 * @private
72 */
73 function reportReference(reference) {
74 const name = reference.identifier.name,
75 customMessage = restrictedGlobalMessages[name],
76 message = customMessage
77 ? CUSTOM_MESSAGE_TEMPLATE
78 : DEFAULT_MESSAGE_TEMPLATE;
79
80 context.report({
81 node: reference.identifier,
82 message,
83 data: {
84 name,
85 customMessage
86 }
87 });
88 }
89
90 /**
91 * Check if the given name is a restricted global name.
92 * @param {string} name name of a variable
93 * @returns {boolean} whether the variable is a restricted global or not
94 * @private
95 */
96 function isRestricted(name) {
97 return restrictedGlobalMessages.hasOwnProperty(name);
98 }
99
100 return {
101 Program() {
102 const scope = context.getScope();
103
104 // Report variables declared elsewhere (ex: variables defined as "global" by eslint)
105 scope.variables.forEach(variable => {
106 if (!variable.defs.length && isRestricted(variable.name)) {
107 variable.references.forEach(reportReference);
108 }
109 });
110
111 // Report variables not declared at all
112 scope.through.forEach(reference => {
113 if (isRestricted(reference.identifier.name)) {
114 reportReference(reference);
115 }
116 });
117
118 }
119 };
120 }
121};