• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
16function hasTypeOfOperator(node) {
17    const parent = node.parent;
18
19    return parent.type === "UnaryExpression" && parent.operator === "typeof";
20}
21
22//------------------------------------------------------------------------------
23// Rule Definition
24//------------------------------------------------------------------------------
25
26module.exports = {
27    meta: {
28        type: "problem",
29
30        docs: {
31            description: "disallow the use of undeclared variables unless mentioned in `/*global */` comments",
32            category: "Variables",
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};
79