line-comment-position.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * @fileoverview Rule to enforce the position of line comments
  3. * @author Alberto Rodríguez
  4. * @deprecated in ESLint v9.3.0
  5. */
  6. "use strict";
  7. const astUtils = require("./utils/ast-utils");
  8. //------------------------------------------------------------------------------
  9. // Rule Definition
  10. //------------------------------------------------------------------------------
  11. /** @type {import('../types').Rule.RuleModule} */
  12. module.exports = {
  13. meta: {
  14. deprecated: {
  15. message: "Formatting rules are being moved out of ESLint core.",
  16. url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
  17. deprecatedSince: "9.3.0",
  18. availableUntil: "11.0.0",
  19. replacedBy: [
  20. {
  21. message:
  22. "ESLint Stylistic now maintains deprecated stylistic core rules.",
  23. url: "https://eslint.style/guide/migration",
  24. plugin: {
  25. name: "@stylistic/eslint-plugin",
  26. url: "https://eslint.style",
  27. },
  28. rule: {
  29. name: "line-comment-position",
  30. url: "https://eslint.style/rules/line-comment-position",
  31. },
  32. },
  33. ],
  34. },
  35. type: "layout",
  36. docs: {
  37. description: "Enforce position of line comments",
  38. recommended: false,
  39. url: "https://eslint.org/docs/latest/rules/line-comment-position",
  40. },
  41. schema: [
  42. {
  43. oneOf: [
  44. {
  45. enum: ["above", "beside"],
  46. },
  47. {
  48. type: "object",
  49. properties: {
  50. position: {
  51. enum: ["above", "beside"],
  52. },
  53. ignorePattern: {
  54. type: "string",
  55. },
  56. applyDefaultPatterns: {
  57. type: "boolean",
  58. },
  59. applyDefaultIgnorePatterns: {
  60. type: "boolean",
  61. },
  62. },
  63. additionalProperties: false,
  64. },
  65. ],
  66. },
  67. ],
  68. messages: {
  69. above: "Expected comment to be above code.",
  70. beside: "Expected comment to be beside code.",
  71. },
  72. },
  73. create(context) {
  74. const options = context.options[0];
  75. let above,
  76. ignorePattern,
  77. applyDefaultIgnorePatterns = true;
  78. if (!options || typeof options === "string") {
  79. above = !options || options === "above";
  80. } else {
  81. above = !options.position || options.position === "above";
  82. ignorePattern = options.ignorePattern;
  83. if (Object.hasOwn(options, "applyDefaultIgnorePatterns")) {
  84. applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns;
  85. } else {
  86. applyDefaultIgnorePatterns =
  87. options.applyDefaultPatterns !== false;
  88. }
  89. }
  90. const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN;
  91. const fallThroughRegExp = /^\s*falls?\s?through/u;
  92. const customIgnoreRegExp = new RegExp(ignorePattern, "u");
  93. const sourceCode = context.sourceCode;
  94. //--------------------------------------------------------------------------
  95. // Public
  96. //--------------------------------------------------------------------------
  97. return {
  98. Program() {
  99. const comments = sourceCode.getAllComments();
  100. comments
  101. .filter(token => token.type === "Line")
  102. .forEach(node => {
  103. if (
  104. applyDefaultIgnorePatterns &&
  105. (defaultIgnoreRegExp.test(node.value) ||
  106. fallThroughRegExp.test(node.value))
  107. ) {
  108. return;
  109. }
  110. if (
  111. ignorePattern &&
  112. customIgnoreRegExp.test(node.value)
  113. ) {
  114. return;
  115. }
  116. const previous = sourceCode.getTokenBefore(node, {
  117. includeComments: true,
  118. });
  119. const isOnSameLine =
  120. previous &&
  121. previous.loc.end.line === node.loc.start.line;
  122. if (above) {
  123. if (isOnSameLine) {
  124. context.report({
  125. node,
  126. messageId: "above",
  127. });
  128. }
  129. } else {
  130. if (!isOnSameLine) {
  131. context.report({
  132. node,
  133. messageId: "beside",
  134. });
  135. }
  136. }
  137. });
  138. },
  139. };
  140. },
  141. };