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.

newline-before-return.js 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @fileoverview Rule to require newlines before `return` statement
  3. * @author Kai Cataldo
  4. * @deprecated
  5. */
  6. "use strict";
  7. //------------------------------------------------------------------------------
  8. // Rule Definition
  9. //------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. type: "layout",
  13. docs: {
  14. description: "require an empty line before `return` statements",
  15. category: "Stylistic Issues",
  16. recommended: false,
  17. url: "https://eslint.org/docs/rules/newline-before-return"
  18. },
  19. fixable: "whitespace",
  20. schema: [],
  21. deprecated: true,
  22. replacedBy: ["padding-line-between-statements"]
  23. },
  24. create(context) {
  25. const sourceCode = context.getSourceCode();
  26. //--------------------------------------------------------------------------
  27. // Helpers
  28. //--------------------------------------------------------------------------
  29. /**
  30. * Tests whether node is preceded by supplied tokens
  31. * @param {ASTNode} node - node to check
  32. * @param {array} testTokens - array of tokens to test against
  33. * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens
  34. * @private
  35. */
  36. function isPrecededByTokens(node, testTokens) {
  37. const tokenBefore = sourceCode.getTokenBefore(node);
  38. return testTokens.some(token => tokenBefore.value === token);
  39. }
  40. /**
  41. * Checks whether node is the first node after statement or in block
  42. * @param {ASTNode} node - node to check
  43. * @returns {boolean} Whether or not the node is the first node after statement or in block
  44. * @private
  45. */
  46. function isFirstNode(node) {
  47. const parentType = node.parent.type;
  48. if (node.parent.body) {
  49. return Array.isArray(node.parent.body)
  50. ? node.parent.body[0] === node
  51. : node.parent.body === node;
  52. }
  53. if (parentType === "IfStatement") {
  54. return isPrecededByTokens(node, ["else", ")"]);
  55. }
  56. if (parentType === "DoWhileStatement") {
  57. return isPrecededByTokens(node, ["do"]);
  58. }
  59. if (parentType === "SwitchCase") {
  60. return isPrecededByTokens(node, [":"]);
  61. }
  62. return isPrecededByTokens(node, [")"]);
  63. }
  64. /**
  65. * Returns the number of lines of comments that precede the node
  66. * @param {ASTNode} node - node to check for overlapping comments
  67. * @param {number} lineNumTokenBefore - line number of previous token, to check for overlapping comments
  68. * @returns {number} Number of lines of comments that precede the node
  69. * @private
  70. */
  71. function calcCommentLines(node, lineNumTokenBefore) {
  72. const comments = sourceCode.getCommentsBefore(node);
  73. let numLinesComments = 0;
  74. if (!comments.length) {
  75. return numLinesComments;
  76. }
  77. comments.forEach(comment => {
  78. numLinesComments++;
  79. if (comment.type === "Block") {
  80. numLinesComments += comment.loc.end.line - comment.loc.start.line;
  81. }
  82. // avoid counting lines with inline comments twice
  83. if (comment.loc.start.line === lineNumTokenBefore) {
  84. numLinesComments--;
  85. }
  86. if (comment.loc.end.line === node.loc.start.line) {
  87. numLinesComments--;
  88. }
  89. });
  90. return numLinesComments;
  91. }
  92. /**
  93. * Returns the line number of the token before the node that is passed in as an argument
  94. * @param {ASTNode} node - The node to use as the start of the calculation
  95. * @returns {number} Line number of the token before `node`
  96. * @private
  97. */
  98. function getLineNumberOfTokenBefore(node) {
  99. const tokenBefore = sourceCode.getTokenBefore(node);
  100. let lineNumTokenBefore;
  101. /**
  102. * Global return (at the beginning of a script) is a special case.
  103. * If there is no token before `return`, then we expect no line
  104. * break before the return. Comments are allowed to occupy lines
  105. * before the global return, just no blank lines.
  106. * Setting lineNumTokenBefore to zero in that case results in the
  107. * desired behavior.
  108. */
  109. if (tokenBefore) {
  110. lineNumTokenBefore = tokenBefore.loc.end.line;
  111. } else {
  112. lineNumTokenBefore = 0; // global return at beginning of script
  113. }
  114. return lineNumTokenBefore;
  115. }
  116. /**
  117. * Checks whether node is preceded by a newline
  118. * @param {ASTNode} node - node to check
  119. * @returns {boolean} Whether or not the node is preceded by a newline
  120. * @private
  121. */
  122. function hasNewlineBefore(node) {
  123. const lineNumNode = node.loc.start.line;
  124. const lineNumTokenBefore = getLineNumberOfTokenBefore(node);
  125. const commentLines = calcCommentLines(node, lineNumTokenBefore);
  126. return (lineNumNode - lineNumTokenBefore - commentLines) > 1;
  127. }
  128. /**
  129. * Checks whether it is safe to apply a fix to a given return statement.
  130. *
  131. * The fix is not considered safe if the given return statement has leading comments,
  132. * as we cannot safely determine if the newline should be added before or after the comments.
  133. * For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211
  134. *
  135. * @param {ASTNode} node - The return statement node to check.
  136. * @returns {boolean} `true` if it can fix the node.
  137. * @private
  138. */
  139. function canFix(node) {
  140. const leadingComments = sourceCode.getCommentsBefore(node);
  141. const lastLeadingComment = leadingComments[leadingComments.length - 1];
  142. const tokenBefore = sourceCode.getTokenBefore(node);
  143. if (leadingComments.length === 0) {
  144. return true;
  145. }
  146. /*
  147. * if the last leading comment ends in the same line as the previous token and
  148. * does not share a line with the `return` node, we can consider it safe to fix.
  149. * Example:
  150. * function a() {
  151. * var b; //comment
  152. * return;
  153. * }
  154. */
  155. if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line &&
  156. lastLeadingComment.loc.end.line !== node.loc.start.line) {
  157. return true;
  158. }
  159. return false;
  160. }
  161. //--------------------------------------------------------------------------
  162. // Public
  163. //--------------------------------------------------------------------------
  164. return {
  165. ReturnStatement(node) {
  166. if (!isFirstNode(node) && !hasNewlineBefore(node)) {
  167. context.report({
  168. node,
  169. message: "Expected newline before return statement.",
  170. fix(fixer) {
  171. if (canFix(node)) {
  172. const tokenBefore = sourceCode.getTokenBefore(node);
  173. const newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n";
  174. return fixer.insertTextBefore(node, newlines);
  175. }
  176. return null;
  177. }
  178. });
  179. }
  180. }
  181. };
  182. }
  183. };