checkPropertyNames.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _iterateJsdoc = _interopRequireDefault(require("../iterateJsdoc.js"));
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. /**
  9. * @param {string} targetTagName
  10. * @param {boolean} enableFixer
  11. * @param {import('comment-parser').Block} jsdoc
  12. * @param {import('../iterateJsdoc.js').Utils} utils
  13. * @returns {boolean}
  14. */
  15. const validatePropertyNames = (targetTagName, enableFixer, jsdoc, utils) => {
  16. const propertyTags = Object.entries(jsdoc.tags).filter(([, tag]) => {
  17. return tag.tag === targetTagName;
  18. });
  19. return propertyTags.some(([, tag], index) => {
  20. /** @type {import('../iterateJsdoc.js').Integer} */
  21. let tagsIndex;
  22. const dupeTagInfo = propertyTags.find(([tgsIndex, tg], idx) => {
  23. tagsIndex = Number(tgsIndex);
  24. return tg.name === tag.name && idx !== index;
  25. });
  26. if (dupeTagInfo) {
  27. utils.reportJSDoc(`Duplicate @${targetTagName} "${tag.name}"`, dupeTagInfo[1], enableFixer ? () => {
  28. utils.removeTag(tagsIndex);
  29. } : null);
  30. return true;
  31. }
  32. return false;
  33. });
  34. };
  35. /**
  36. * @param {string} targetTagName
  37. * @param {{
  38. * idx: number;
  39. * name: string;
  40. * type: string;
  41. * }[]} jsdocPropertyNames
  42. * @param {import('comment-parser').Block} jsdoc
  43. * @param {Function} report
  44. */
  45. const validatePropertyNamesDeep = (targetTagName, jsdocPropertyNames, jsdoc, report) => {
  46. /** @type {string} */
  47. let lastRealProperty;
  48. return jsdocPropertyNames.some(({
  49. name: jsdocPropertyName,
  50. idx
  51. }) => {
  52. const isPropertyPath = jsdocPropertyName.includes('.');
  53. if (isPropertyPath) {
  54. if (!lastRealProperty) {
  55. report(`@${targetTagName} path declaration ("${jsdocPropertyName}") appears before any real property.`, null, jsdoc.tags[idx]);
  56. return true;
  57. }
  58. let pathRootNodeName = jsdocPropertyName.slice(0, jsdocPropertyName.indexOf('.'));
  59. if (pathRootNodeName.endsWith('[]')) {
  60. pathRootNodeName = pathRootNodeName.slice(0, -2);
  61. }
  62. if (pathRootNodeName !== lastRealProperty) {
  63. report(`@${targetTagName} path declaration ("${jsdocPropertyName}") root node name ("${pathRootNodeName}") ` + `does not match previous real property name ("${lastRealProperty}").`, null, jsdoc.tags[idx]);
  64. return true;
  65. }
  66. } else {
  67. lastRealProperty = jsdocPropertyName;
  68. }
  69. return false;
  70. });
  71. };
  72. var _default = exports.default = (0, _iterateJsdoc.default)(({
  73. context,
  74. jsdoc,
  75. report,
  76. utils
  77. }) => {
  78. const {
  79. enableFixer = false
  80. } = context.options[0] || {};
  81. const jsdocPropertyNamesDeep = utils.getJsdocTagsDeep('property');
  82. if (!jsdocPropertyNamesDeep || !jsdocPropertyNamesDeep.length) {
  83. return;
  84. }
  85. const targetTagName = /** @type {string} */utils.getPreferredTagName({
  86. tagName: 'property'
  87. });
  88. const isError = validatePropertyNames(targetTagName, enableFixer, jsdoc, utils);
  89. if (isError) {
  90. return;
  91. }
  92. validatePropertyNamesDeep(targetTagName, jsdocPropertyNamesDeep, jsdoc, report);
  93. }, {
  94. iterateAllJsdocs: true,
  95. meta: {
  96. docs: {
  97. description: 'Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.',
  98. url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-property-names.md#repos-sticky-header'
  99. },
  100. fixable: 'code',
  101. schema: [{
  102. additionalProperties: false,
  103. properties: {
  104. enableFixer: {
  105. type: 'boolean'
  106. }
  107. },
  108. type: 'object'
  109. }],
  110. type: 'suggestion'
  111. }
  112. });
  113. module.exports = exports.default;
  114. //# sourceMappingURL=checkPropertyNames.js.map