]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to flag references to undeclared variables. | |
3 | * @author Mark Macdonald | |
4 | */ | |
5 | "use strict"; | |
6 | ||
7 | //------------------------------------------------------------------------------ | |
8 | // Helpers | |
9 | //------------------------------------------------------------------------------ | |
10 | ||
11 | /** | |
12 | * Checks if the given node is the argument of a typeof operator. | |
13 | * @param {ASTNode} node The AST node being checked. | |
14 | * @returns {boolean} Whether or not the node is the argument of a typeof operator. | |
15 | */ | |
16 | function hasTypeOfOperator(node) { | |
17 | const parent = node.parent; | |
18 | ||
19 | return parent.type === "UnaryExpression" && parent.operator === "typeof"; | |
20 | } | |
21 | ||
22 | //------------------------------------------------------------------------------ | |
23 | // Rule Definition | |
24 | //------------------------------------------------------------------------------ | |
25 | ||
34eeec05 | 26 | /** @type {import('../shared/types').Rule} */ |
eb39fafa DC |
27 | module.exports = { |
28 | meta: { | |
29 | type: "problem", | |
30 | ||
31 | docs: { | |
32 | description: "disallow the use of undeclared variables unless mentioned in `/*global */` comments", | |
eb39fafa DC |
33 | recommended: true, |
34 | url: "https://eslint.org/docs/rules/no-undef" | |
35 | }, | |
36 | ||
37 | schema: [ | |
38 | { | |
39 | type: "object", | |
40 | properties: { | |
41 | typeof: { | |
42 | type: "boolean", | |
43 | default: false | |
44 | } | |
45 | }, | |
46 | additionalProperties: false | |
47 | } | |
48 | ], | |
49 | messages: { | |
50 | undef: "'{{name}}' is not defined." | |
51 | } | |
52 | }, | |
53 | ||
54 | create(context) { | |
55 | const options = context.options[0]; | |
56 | const considerTypeOf = options && options.typeof === true || false; | |
57 | ||
58 | return { | |
59 | "Program:exit"(/* node */) { | |
60 | const globalScope = context.getScope(); | |
61 | ||
62 | globalScope.through.forEach(ref => { | |
63 | const identifier = ref.identifier; | |
64 | ||
65 | if (!considerTypeOf && hasTypeOfOperator(identifier)) { | |
66 | return; | |
67 | } | |
68 | ||
69 | context.report({ | |
70 | node: identifier, | |
71 | messageId: "undef", | |
72 | data: identifier | |
73 | }); | |
74 | }); | |
75 | } | |
76 | }; | |
77 | } | |
78 | }; |