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-unreachable.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @fileoverview Checks for unreachable code due to return, throws, break, and continue.
  3. * @author Joel Feenstra
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Helpers
  8. //------------------------------------------------------------------------------
  9. /**
  10. * Checks whether or not a given variable declarator has the initializer.
  11. * @param {ASTNode} node - A VariableDeclarator node to check.
  12. * @returns {boolean} `true` if the node has the initializer.
  13. */
  14. function isInitialized(node) {
  15. return Boolean(node.init);
  16. }
  17. /**
  18. * Checks whether or not a given code path segment is unreachable.
  19. * @param {CodePathSegment} segment - A CodePathSegment to check.
  20. * @returns {boolean} `true` if the segment is unreachable.
  21. */
  22. function isUnreachable(segment) {
  23. return !segment.reachable;
  24. }
  25. /**
  26. * The class to distinguish consecutive unreachable statements.
  27. */
  28. class ConsecutiveRange {
  29. constructor(sourceCode) {
  30. this.sourceCode = sourceCode;
  31. this.startNode = null;
  32. this.endNode = null;
  33. }
  34. /**
  35. * The location object of this range.
  36. * @type {Object}
  37. */
  38. get location() {
  39. return {
  40. start: this.startNode.loc.start,
  41. end: this.endNode.loc.end
  42. };
  43. }
  44. /**
  45. * `true` if this range is empty.
  46. * @type {boolean}
  47. */
  48. get isEmpty() {
  49. return !(this.startNode && this.endNode);
  50. }
  51. /**
  52. * Checks whether the given node is inside of this range.
  53. * @param {ASTNode|Token} node - The node to check.
  54. * @returns {boolean} `true` if the node is inside of this range.
  55. */
  56. contains(node) {
  57. return (
  58. node.range[0] >= this.startNode.range[0] &&
  59. node.range[1] <= this.endNode.range[1]
  60. );
  61. }
  62. /**
  63. * Checks whether the given node is consecutive to this range.
  64. * @param {ASTNode} node - The node to check.
  65. * @returns {boolean} `true` if the node is consecutive to this range.
  66. */
  67. isConsecutive(node) {
  68. return this.contains(this.sourceCode.getTokenBefore(node));
  69. }
  70. /**
  71. * Merges the given node to this range.
  72. * @param {ASTNode} node - The node to merge.
  73. * @returns {void}
  74. */
  75. merge(node) {
  76. this.endNode = node;
  77. }
  78. /**
  79. * Resets this range by the given node or null.
  80. * @param {ASTNode|null} node - The node to reset, or null.
  81. * @returns {void}
  82. */
  83. reset(node) {
  84. this.startNode = this.endNode = node;
  85. }
  86. }
  87. //------------------------------------------------------------------------------
  88. // Rule Definition
  89. //------------------------------------------------------------------------------
  90. module.exports = {
  91. meta: {
  92. type: "problem",
  93. docs: {
  94. description: "disallow unreachable code after `return`, `throw`, `continue`, and `break` statements",
  95. category: "Possible Errors",
  96. recommended: true,
  97. url: "https://eslint.org/docs/rules/no-unreachable"
  98. },
  99. schema: []
  100. },
  101. create(context) {
  102. let currentCodePath = null;
  103. const range = new ConsecutiveRange(context.getSourceCode());
  104. /**
  105. * Reports a given node if it's unreachable.
  106. * @param {ASTNode} node - A statement node to report.
  107. * @returns {void}
  108. */
  109. function reportIfUnreachable(node) {
  110. let nextNode = null;
  111. if (node && currentCodePath.currentSegments.every(isUnreachable)) {
  112. // Store this statement to distinguish consecutive statements.
  113. if (range.isEmpty) {
  114. range.reset(node);
  115. return;
  116. }
  117. // Skip if this statement is inside of the current range.
  118. if (range.contains(node)) {
  119. return;
  120. }
  121. // Merge if this statement is consecutive to the current range.
  122. if (range.isConsecutive(node)) {
  123. range.merge(node);
  124. return;
  125. }
  126. nextNode = node;
  127. }
  128. /*
  129. * Report the current range since this statement is reachable or is
  130. * not consecutive to the current range.
  131. */
  132. if (!range.isEmpty) {
  133. context.report({
  134. message: "Unreachable code.",
  135. loc: range.location,
  136. node: range.startNode
  137. });
  138. }
  139. // Update the current range.
  140. range.reset(nextNode);
  141. }
  142. return {
  143. // Manages the current code path.
  144. onCodePathStart(codePath) {
  145. currentCodePath = codePath;
  146. },
  147. onCodePathEnd() {
  148. currentCodePath = currentCodePath.upper;
  149. },
  150. // Registers for all statement nodes (excludes FunctionDeclaration).
  151. BlockStatement: reportIfUnreachable,
  152. BreakStatement: reportIfUnreachable,
  153. ClassDeclaration: reportIfUnreachable,
  154. ContinueStatement: reportIfUnreachable,
  155. DebuggerStatement: reportIfUnreachable,
  156. DoWhileStatement: reportIfUnreachable,
  157. ExpressionStatement: reportIfUnreachable,
  158. ForInStatement: reportIfUnreachable,
  159. ForOfStatement: reportIfUnreachable,
  160. ForStatement: reportIfUnreachable,
  161. IfStatement: reportIfUnreachable,
  162. ImportDeclaration: reportIfUnreachable,
  163. LabeledStatement: reportIfUnreachable,
  164. ReturnStatement: reportIfUnreachable,
  165. SwitchStatement: reportIfUnreachable,
  166. ThrowStatement: reportIfUnreachable,
  167. TryStatement: reportIfUnreachable,
  168. VariableDeclaration(node) {
  169. if (node.kind !== "var" || node.declarations.some(isInitialized)) {
  170. reportIfUnreachable(node);
  171. }
  172. },
  173. WhileStatement: reportIfUnreachable,
  174. WithStatement: reportIfUnreachable,
  175. ExportNamedDeclaration: reportIfUnreachable,
  176. ExportDefaultDeclaration: reportIfUnreachable,
  177. ExportAllDeclaration: reportIfUnreachable,
  178. "Program:exit"() {
  179. reportIfUnreachable();
  180. }
  181. };
  182. }
  183. };