Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
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.

consistent-return.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /**
  2. * @fileoverview Rule to flag consistent return values
  3. * @author Nicholas C. Zakas
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const astUtils = require("./utils/ast-utils");
  10. const { upperCaseFirst } = require("../shared/string-utils");
  11. //------------------------------------------------------------------------------
  12. // Helpers
  13. //------------------------------------------------------------------------------
  14. /**
  15. * Checks whether or not a given code path segment is unreachable.
  16. * @param {CodePathSegment} segment A CodePathSegment to check.
  17. * @returns {boolean} `true` if the segment is unreachable.
  18. */
  19. function isUnreachable(segment) {
  20. return !segment.reachable;
  21. }
  22. /**
  23. * Checks whether a given node is a `constructor` method in an ES6 class
  24. * @param {ASTNode} node A node to check
  25. * @returns {boolean} `true` if the node is a `constructor` method
  26. */
  27. function isClassConstructor(node) {
  28. return node.type === "FunctionExpression" &&
  29. node.parent &&
  30. node.parent.type === "MethodDefinition" &&
  31. node.parent.kind === "constructor";
  32. }
  33. //------------------------------------------------------------------------------
  34. // Rule Definition
  35. //------------------------------------------------------------------------------
  36. module.exports = {
  37. meta: {
  38. type: "suggestion",
  39. docs: {
  40. description: "require `return` statements to either always or never specify values",
  41. category: "Best Practices",
  42. recommended: false,
  43. url: "https://eslint.org/docs/rules/consistent-return"
  44. },
  45. schema: [{
  46. type: "object",
  47. properties: {
  48. treatUndefinedAsUnspecified: {
  49. type: "boolean",
  50. default: false
  51. }
  52. },
  53. additionalProperties: false
  54. }],
  55. messages: {
  56. missingReturn: "Expected to return a value at the end of {{name}}.",
  57. missingReturnValue: "{{name}} expected a return value.",
  58. unexpectedReturnValue: "{{name}} expected no return value."
  59. }
  60. },
  61. create(context) {
  62. const options = context.options[0] || {};
  63. const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true;
  64. let funcInfo = null;
  65. /**
  66. * Checks whether of not the implicit returning is consistent if the last
  67. * code path segment is reachable.
  68. * @param {ASTNode} node A program/function node to check.
  69. * @returns {void}
  70. */
  71. function checkLastSegment(node) {
  72. let loc, name;
  73. /*
  74. * Skip if it expected no return value or unreachable.
  75. * When unreachable, all paths are returned or thrown.
  76. */
  77. if (!funcInfo.hasReturnValue ||
  78. funcInfo.codePath.currentSegments.every(isUnreachable) ||
  79. astUtils.isES5Constructor(node) ||
  80. isClassConstructor(node)
  81. ) {
  82. return;
  83. }
  84. // Adjust a location and a message.
  85. if (node.type === "Program") {
  86. // The head of program.
  87. loc = { line: 1, column: 0 };
  88. name = "program";
  89. } else if (node.type === "ArrowFunctionExpression") {
  90. // `=>` token
  91. loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc;
  92. } else if (
  93. node.parent.type === "MethodDefinition" ||
  94. (node.parent.type === "Property" && node.parent.method)
  95. ) {
  96. // Method name.
  97. loc = node.parent.key.loc;
  98. } else {
  99. // Function name or `function` keyword.
  100. loc = (node.id || context.getSourceCode().getFirstToken(node)).loc;
  101. }
  102. if (!name) {
  103. name = astUtils.getFunctionNameWithKind(node);
  104. }
  105. // Reports.
  106. context.report({
  107. node,
  108. loc,
  109. messageId: "missingReturn",
  110. data: { name }
  111. });
  112. }
  113. return {
  114. // Initializes/Disposes state of each code path.
  115. onCodePathStart(codePath, node) {
  116. funcInfo = {
  117. upper: funcInfo,
  118. codePath,
  119. hasReturn: false,
  120. hasReturnValue: false,
  121. messageId: "",
  122. node
  123. };
  124. },
  125. onCodePathEnd() {
  126. funcInfo = funcInfo.upper;
  127. },
  128. // Reports a given return statement if it's inconsistent.
  129. ReturnStatement(node) {
  130. const argument = node.argument;
  131. let hasReturnValue = Boolean(argument);
  132. if (treatUndefinedAsUnspecified && hasReturnValue) {
  133. hasReturnValue = !astUtils.isSpecificId(argument, "undefined") && argument.operator !== "void";
  134. }
  135. if (!funcInfo.hasReturn) {
  136. funcInfo.hasReturn = true;
  137. funcInfo.hasReturnValue = hasReturnValue;
  138. funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue";
  139. funcInfo.data = {
  140. name: funcInfo.node.type === "Program"
  141. ? "Program"
  142. : upperCaseFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
  143. };
  144. } else if (funcInfo.hasReturnValue !== hasReturnValue) {
  145. context.report({
  146. node,
  147. messageId: funcInfo.messageId,
  148. data: funcInfo.data
  149. });
  150. }
  151. },
  152. // Reports a given program/function if the implicit returning is not consistent.
  153. "Program:exit": checkLastSegment,
  154. "FunctionDeclaration:exit": checkLastSegment,
  155. "FunctionExpression:exit": checkLastSegment,
  156. "ArrowFunctionExpression:exit": checkLastSegment
  157. };
  158. }
  159. };