Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

no-lone-blocks.js 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /**
  2. * @fileoverview Rule to flag blocks with no reason to exist
  3. * @author Brandon Mills
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Rule Definition
  8. //------------------------------------------------------------------------------
  9. module.exports = {
  10. meta: {
  11. type: "suggestion",
  12. docs: {
  13. description: "disallow unnecessary nested blocks",
  14. category: "Best Practices",
  15. recommended: false,
  16. url: "https://eslint.org/docs/rules/no-lone-blocks"
  17. },
  18. schema: []
  19. },
  20. create(context) {
  21. // A stack of lone blocks to be checked for block-level bindings
  22. const loneBlocks = [];
  23. let ruleDef;
  24. /**
  25. * Reports a node as invalid.
  26. * @param {ASTNode} node - The node to be reported.
  27. * @returns {void}
  28. */
  29. function report(node) {
  30. const message = node.parent.type === "BlockStatement" ? "Nested block is redundant." : "Block is redundant.";
  31. context.report({ node, message });
  32. }
  33. /**
  34. * Checks for any ocurrence of a BlockStatement in a place where lists of statements can appear
  35. * @param {ASTNode} node The node to check
  36. * @returns {boolean} True if the node is a lone block.
  37. */
  38. function isLoneBlock(node) {
  39. return node.parent.type === "BlockStatement" ||
  40. node.parent.type === "Program" ||
  41. // Don't report blocks in switch cases if the block is the only statement of the case.
  42. node.parent.type === "SwitchCase" && !(node.parent.consequent[0] === node && node.parent.consequent.length === 1);
  43. }
  44. /**
  45. * Checks the enclosing block of the current node for block-level bindings,
  46. * and "marks it" as valid if any.
  47. * @returns {void}
  48. */
  49. function markLoneBlock() {
  50. if (loneBlocks.length === 0) {
  51. return;
  52. }
  53. const block = context.getAncestors().pop();
  54. if (loneBlocks[loneBlocks.length - 1] === block) {
  55. loneBlocks.pop();
  56. }
  57. }
  58. // Default rule definition: report all lone blocks
  59. ruleDef = {
  60. BlockStatement(node) {
  61. if (isLoneBlock(node)) {
  62. report(node);
  63. }
  64. }
  65. };
  66. // ES6: report blocks without block-level bindings
  67. if (context.parserOptions.ecmaVersion >= 6) {
  68. ruleDef = {
  69. BlockStatement(node) {
  70. if (isLoneBlock(node)) {
  71. loneBlocks.push(node);
  72. }
  73. },
  74. "BlockStatement:exit"(node) {
  75. if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) {
  76. loneBlocks.pop();
  77. report(node);
  78. }
  79. }
  80. };
  81. ruleDef.VariableDeclaration = function(node) {
  82. if (node.kind === "let" || node.kind === "const") {
  83. markLoneBlock();
  84. }
  85. };
  86. ruleDef.FunctionDeclaration = function() {
  87. if (context.getScope().isStrict) {
  88. markLoneBlock();
  89. }
  90. };
  91. ruleDef.ClassDeclaration = markLoneBlock;
  92. }
  93. return ruleDef;
  94. }
  95. };