no-inner-declarations.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /**
  2. * @fileoverview Rule to enforce declarations in program or function body root.
  3. * @author Brandon Mills
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const astUtils = require("./utils/ast-utils");
  10. //------------------------------------------------------------------------------
  11. // Rule Definition
  12. //------------------------------------------------------------------------------
  13. const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]);
  14. const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
  15. module.exports = {
  16. meta: {
  17. type: "problem",
  18. docs: {
  19. description: "disallow variable or `function` declarations in nested blocks",
  20. category: "Possible Errors",
  21. recommended: true,
  22. url: "https://eslint.org/docs/rules/no-inner-declarations"
  23. },
  24. schema: [
  25. {
  26. enum: ["functions", "both"]
  27. }
  28. ],
  29. messages: {
  30. moveDeclToRoot: "Move {{type}} declaration to {{body}} root."
  31. }
  32. },
  33. create(context) {
  34. /**
  35. * Ensure that a given node is at a program or function body's root.
  36. * @param {ASTNode} node Declaration node to check.
  37. * @returns {void}
  38. */
  39. function check(node) {
  40. const parent = node.parent;
  41. if (
  42. parent.type === "BlockStatement" && validBlockStatementParent.has(parent.parent.type)
  43. ) {
  44. return;
  45. }
  46. if (validParent.has(parent.type)) {
  47. return;
  48. }
  49. const upperFunction = astUtils.getUpperFunction(parent);
  50. context.report({
  51. node,
  52. messageId: "moveDeclToRoot",
  53. data: {
  54. type: (node.type === "FunctionDeclaration" ? "function" : "variable"),
  55. body: (upperFunction === null ? "program" : "function body")
  56. }
  57. });
  58. }
  59. return {
  60. FunctionDeclaration: check,
  61. VariableDeclaration(node) {
  62. if (context.options[0] === "both" && node.kind === "var") {
  63. check(node);
  64. }
  65. }
  66. };
  67. }
  68. };