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