no-undefined.js 1.8 KB

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