]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to flag references to the undefined variable. | |
3 | * @author Michael Ficarra | |
4 | */ | |
5 | "use strict"; | |
6 | ||
7 | //------------------------------------------------------------------------------ | |
8 | // Rule Definition | |
9 | //------------------------------------------------------------------------------ | |
10 | ||
34eeec05 | 11 | /** @type {import('../shared/types').Rule} */ |
eb39fafa DC |
12 | module.exports = { |
13 | meta: { | |
14 | type: "suggestion", | |
15 | ||
16 | docs: { | |
8f9d1d4d | 17 | description: "Disallow the use of `undefined` as an identifier", |
eb39fafa | 18 | recommended: false, |
f2a92ac6 | 19 | url: "https://eslint.org/docs/latest/rules/no-undefined" |
eb39fafa DC |
20 | }, |
21 | ||
22 | schema: [], | |
23 | ||
24 | messages: { | |
25 | unexpectedUndefined: "Unexpected use of undefined." | |
26 | } | |
27 | }, | |
28 | ||
29 | create(context) { | |
30 | ||
f2a92ac6 DC |
31 | const sourceCode = context.sourceCode; |
32 | ||
eb39fafa DC |
33 | /** |
34 | * Report an invalid "undefined" identifier node. | |
35 | * @param {ASTNode} node The node to report. | |
36 | * @returns {void} | |
37 | */ | |
38 | function report(node) { | |
39 | context.report({ | |
40 | node, | |
41 | messageId: "unexpectedUndefined" | |
42 | }); | |
43 | } | |
44 | ||
45 | /** | |
46 | * Checks the given scope for references to `undefined` and reports | |
47 | * all references found. | |
48 | * @param {eslint-scope.Scope} scope The scope to check. | |
49 | * @returns {void} | |
50 | */ | |
51 | function checkScope(scope) { | |
52 | const undefinedVar = scope.set.get("undefined"); | |
53 | ||
54 | if (!undefinedVar) { | |
55 | return; | |
56 | } | |
57 | ||
58 | const references = undefinedVar.references; | |
59 | ||
60 | const defs = undefinedVar.defs; | |
61 | ||
62 | // Report non-initializing references (those are covered in defs below) | |
63 | references | |
64 | .filter(ref => !ref.init) | |
65 | .forEach(ref => report(ref.identifier)); | |
66 | ||
67 | defs.forEach(def => report(def.name)); | |
68 | } | |
69 | ||
70 | return { | |
f2a92ac6 DC |
71 | "Program:exit"(node) { |
72 | const globalScope = sourceCode.getScope(node); | |
eb39fafa DC |
73 | |
74 | const stack = [globalScope]; | |
75 | ||
76 | while (stack.length) { | |
77 | const scope = stack.pop(); | |
78 | ||
79 | stack.push(...scope.childScopes); | |
80 | checkScope(scope); | |
81 | } | |
82 | } | |
83 | }; | |
84 | ||
85 | } | |
86 | }; |