eslint-plugin-jsdoc 48.8.3 → 48.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import jsdocUtils from './jsdocUtils.js';
1
+ import * as jsdocUtils from './jsdocUtils.js';
2
2
  import {
3
3
  commentHandler,
4
4
  getJSDocComment,
@@ -628,11 +628,11 @@ const getBasicUtils = (context, {
628
628
  utils.getPreferredTagNameObject = ({
629
629
  tagName,
630
630
  }) => {
631
- const ret = jsdocUtils.getPreferredTagName(
632
- context,
633
- /** @type {import('./jsdocUtils.js').ParserMode} */ (mode),
631
+ const ret = jsdocUtils.getPreferredTagNameSimple(
634
632
  tagName,
633
+ /** @type {import('./jsdocUtils.js').ParserMode} */ (mode),
635
634
  tagNamePreference,
635
+ context,
636
636
  );
637
637
  const isObject = ret && typeof ret === 'object';
638
638
  if (ret === false || (isObject && !ret.replacement)) {
@@ -783,44 +783,7 @@ const getUtils = (
783
783
 
784
784
  /** @type {GetTagDescription} */
785
785
  utils.getTagDescription = (tg, returnArray) => {
786
- /**
787
- * @type {string[]}
788
- */
789
- const descriptions = [];
790
- tg.source.some(({
791
- tokens: {
792
- end,
793
- lineEnd,
794
- postDelimiter,
795
- tag,
796
- postTag,
797
- name,
798
- type,
799
- description,
800
- },
801
- }) => {
802
- const desc = (
803
- tag && postTag ||
804
- !tag && !name && !type && postDelimiter || ''
805
-
806
- // Remove space
807
- ).slice(1) +
808
- (description || '') + (lineEnd || '');
809
-
810
- if (end) {
811
- if (desc) {
812
- descriptions.push(desc);
813
- }
814
-
815
- return true;
816
- }
817
-
818
- descriptions.push(desc);
819
-
820
- return false;
821
- });
822
-
823
- return returnArray ? descriptions : descriptions.join('\n');
786
+ return jsdocUtils.getTagDescription(tg, returnArray);
824
787
  };
825
788
 
826
789
  /** @type {SetTagDescription} */
@@ -1375,29 +1338,13 @@ const getUtils = (
1375
1338
  };
1376
1339
 
1377
1340
  /** @type {GetPreferredTagName} */
1378
- utils.getPreferredTagName = ({
1379
- tagName,
1380
- skipReportingBlockedTag = false,
1381
- allowObjectReturn = false,
1382
- defaultMessage = `Unexpected tag \`@${tagName}\``,
1383
- }) => {
1384
- const ret = jsdocUtils.getPreferredTagName(context, mode, tagName, tagNamePreference);
1385
- const isObject = ret && typeof ret === 'object';
1386
- if (utils.hasTag(tagName) && (ret === false || isObject && !ret.replacement)) {
1387
- if (skipReportingBlockedTag) {
1388
- return {
1389
- blocked: true,
1390
- tagName,
1391
- };
1341
+ utils.getPreferredTagName = (args) => {
1342
+ return jsdocUtils.getPreferredTagName(
1343
+ jsdoc, {
1344
+ ...args,
1345
+ context, mode, report, tagNamePreference,
1392
1346
  }
1393
-
1394
- const message = isObject && ret.message || defaultMessage;
1395
- report(message, null, utils.getTags(tagName)[0]);
1396
-
1397
- return false;
1398
- }
1399
-
1400
- return isObject && !allowObjectReturn ? ret.replacement : ret;
1347
+ );
1401
1348
  };
1402
1349
 
1403
1350
  /** @type {IsValidTag} */
@@ -1619,21 +1566,19 @@ const getUtils = (
1619
1566
 
1620
1567
  /** @type {GetTags} */
1621
1568
  utils.getTags = (tagName) => {
1622
- return utils.filterTags((item) => {
1623
- return item.tag === tagName;
1624
- });
1569
+ return jsdocUtils.getTags(jsdoc, tagName);
1625
1570
  };
1626
1571
 
1627
1572
  /** @type {GetPresentTags} */
1628
1573
  utils.getPresentTags = (tagList) => {
1629
- return utils.filterTags((tag) => {
1574
+ return jsdocUtils.filterTags(jsdoc, (tag) => {
1630
1575
  return tagList.includes(tag.tag);
1631
1576
  });
1632
1577
  };
1633
1578
 
1634
1579
  /** @type {FilterTags} */
1635
1580
  utils.filterTags = (filter) => {
1636
- return jsdoc.tags.filter((tag) => {
1581
+ return jsdocUtils.filterTags(jsdoc, (tag) => {
1637
1582
  return filter(tag);
1638
1583
  });
1639
1584
  };
@@ -1699,34 +1644,13 @@ const getUtils = (
1699
1644
  };
1700
1645
 
1701
1646
  /** @type {ForEachPreferredTag} */
1702
- utils.forEachPreferredTag = (tagName, arrayHandler, skipReportingBlockedTag = false) => {
1703
- const targetTagName = /** @type {string|false} */ (
1704
- utils.getPreferredTagName({
1647
+ utils.forEachPreferredTag = (tagName, arrayHandler, skipReportingBlockedTag) => {
1648
+ return jsdocUtils.forEachPreferredTag(
1649
+ jsdoc, tagName, arrayHandler, {
1705
1650
  skipReportingBlockedTag,
1706
- tagName,
1707
- })
1651
+ context, mode, report, tagNamePreference
1652
+ }
1708
1653
  );
1709
- if (!targetTagName ||
1710
- skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object'
1711
- ) {
1712
- return;
1713
- }
1714
-
1715
- const matchingJsdocTags = jsdoc.tags.filter(({
1716
- tag,
1717
- }) => {
1718
- return tag === targetTagName;
1719
- });
1720
-
1721
- for (const matchingJsdocTag of matchingJsdocTags) {
1722
- arrayHandler(
1723
- /**
1724
- * @type {import('@es-joy/jsdoccomment').JsdocTagWithInline}
1725
- */ (
1726
- matchingJsdocTag
1727
- ), targetTagName,
1728
- );
1729
- }
1730
1654
  };
1731
1655
 
1732
1656
  /** @type {FindContext} */
@@ -2030,8 +1954,8 @@ const iterate = (
2030
1954
  !ruleConfig.checkPrivate && settings.ignorePrivate &&
2031
1955
  (
2032
1956
  utils.hasTag('private') ||
2033
- jsdoc.tags
2034
- .filter(({
1957
+ jsdocUtils
1958
+ .filterTags(jsdoc, ({
2035
1959
  tag,
2036
1960
  }) => {
2037
1961
  return tag === 'access';
package/src/jsdocUtils.js CHANGED
@@ -521,7 +521,7 @@ const modeWarnSettings = WarnSettings();
521
521
 
522
522
  /**
523
523
  * @param {ParserMode|undefined} mode
524
- * @param {import('eslint').Rule.RuleContext} context
524
+ * @param {Reporter} context
525
525
  * @returns {import('./tagNames.js').AliasedTags}
526
526
  */
527
527
  const getTagNamesForMode = (mode, context) => {
@@ -556,20 +556,76 @@ const getTagNamesForMode = (mode, context) => {
556
556
  };
557
557
 
558
558
  /**
559
- * @param {import('eslint').Rule.RuleContext} context
560
- * @param {ParserMode|undefined} mode
559
+ * @param {import('comment-parser').Spec} tg
560
+ * @param {boolean} [returnArray]
561
+ * @returns {string[]|string}
562
+ */
563
+ const getTagDescription = (tg, returnArray) => {
564
+ /**
565
+ * @type {string[]}
566
+ */
567
+ const descriptions = [];
568
+ tg.source.some(({
569
+ tokens: {
570
+ end,
571
+ lineEnd,
572
+ postDelimiter,
573
+ tag,
574
+ postTag,
575
+ name,
576
+ type,
577
+ description,
578
+ },
579
+ }) => {
580
+ const desc = (
581
+ tag && postTag ||
582
+ !tag && !name && !type && postDelimiter || ''
583
+
584
+ // Remove space
585
+ ).slice(1) +
586
+ (description || '') + (lineEnd || '');
587
+
588
+ if (end) {
589
+ if (desc) {
590
+ descriptions.push(desc);
591
+ }
592
+
593
+ return true;
594
+ }
595
+
596
+ descriptions.push(desc);
597
+
598
+ return false;
599
+ });
600
+
601
+ return returnArray ? descriptions : descriptions.join('\n');
602
+ };
603
+
604
+ /**
605
+ * @typedef {{
606
+ * report: (descriptor: import('eslint').Rule.ReportDescriptor) => void
607
+ * }} Reporter
608
+ */
609
+
610
+ /**
561
611
  * @param {string} name
612
+ * @param {ParserMode|undefined} mode
562
613
  * @param {TagNamePreference} tagPreference
614
+ * @param {Reporter} context
563
615
  * @returns {string|false|{
564
616
  * message: string;
565
617
  * replacement?: string|undefined;
566
618
  * }}
567
619
  */
568
- const getPreferredTagName = (
569
- context,
570
- mode,
620
+ const getPreferredTagNameSimple = (
571
621
  name,
622
+ mode,
572
623
  tagPreference = {},
624
+ context = {
625
+ report () {
626
+ // No-op
627
+ }
628
+ },
573
629
  ) => {
574
630
  const prefValues = Object.values(tagPreference);
575
631
  if (prefValues.includes(name) || prefValues.some((prefVal) => {
@@ -649,6 +705,129 @@ const hasTag = (jsdoc, targetTagName) => {
649
705
  });
650
706
  };
651
707
 
708
+ /**
709
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
710
+ * @param {(tag: import('@es-joy/jsdoccomment').JsdocTagWithInline) => boolean} filter
711
+ * @returns {import('@es-joy/jsdoccomment').JsdocTagWithInline[]}
712
+ */
713
+ const filterTags = (jsdoc, filter) => {
714
+ return jsdoc.tags.filter((tag) => {
715
+ return filter(tag);
716
+ });
717
+ };
718
+
719
+ /**
720
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
721
+ * @param {string} tagName
722
+ * @returns {import('comment-parser').Spec[]}
723
+ */
724
+ const getTags = (jsdoc, tagName) => {
725
+ return filterTags(jsdoc, (item) => {
726
+ return item.tag === tagName;
727
+ });
728
+ };
729
+
730
+ /**
731
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
732
+ * @param {{
733
+ * tagName: string,
734
+ * context?: import('eslint').Rule.RuleContext,
735
+ * mode?: ParserMode,
736
+ * report?: import('./iterateJsdoc.js').Report
737
+ * tagNamePreference?: TagNamePreference
738
+ * skipReportingBlockedTag?: boolean,
739
+ * allowObjectReturn?: boolean,
740
+ * defaultMessage?: string,
741
+ * }} cfg
742
+ * @returns {string|undefined|false|{
743
+ * message: string;
744
+ * replacement?: string|undefined;
745
+ * }|{
746
+ * blocked: true,
747
+ * tagName: string
748
+ * }}
749
+ */
750
+ const getPreferredTagName = (jsdoc, {
751
+ tagName,
752
+ context, mode,
753
+ tagNamePreference,
754
+ report = () => {},
755
+ skipReportingBlockedTag = false,
756
+ allowObjectReturn = false,
757
+ defaultMessage = `Unexpected tag \`@${tagName}\``,
758
+ }) => {
759
+ const ret = getPreferredTagNameSimple(tagName, mode, tagNamePreference, context);
760
+ const isObject = ret && typeof ret === 'object';
761
+ if (hasTag(jsdoc, tagName) && (ret === false || isObject && !ret.replacement)) {
762
+ if (skipReportingBlockedTag) {
763
+ return {
764
+ blocked: true,
765
+ tagName,
766
+ };
767
+ }
768
+
769
+ const message = isObject && ret.message || defaultMessage;
770
+ report(message, null, getTags(jsdoc, tagName)[0]);
771
+
772
+ return false;
773
+ }
774
+
775
+ return isObject && !allowObjectReturn ? ret.replacement : ret;
776
+ };
777
+
778
+ /**
779
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
780
+ * @param {string} tagName
781
+ * @param {(
782
+ * matchingJsdocTag: import('@es-joy/jsdoccomment').JsdocTagWithInline,
783
+ * targetTagName: string
784
+ * ) => void} arrayHandler
785
+ * @param {object} cfg
786
+ * @param {import('eslint').Rule.RuleContext} [cfg.context]
787
+ * @param {ParserMode} [cfg.mode]
788
+ * @param {import('./iterateJsdoc.js').Report} [cfg.report]
789
+ * @param {TagNamePreference} [cfg.tagNamePreference]
790
+ * @param {boolean} [cfg.skipReportingBlockedTag]
791
+ * @returns {void}
792
+ */
793
+ const forEachPreferredTag = (
794
+ jsdoc, tagName, arrayHandler,
795
+ {
796
+ context, mode, report,
797
+ tagNamePreference,
798
+ skipReportingBlockedTag = false,
799
+ } = {}
800
+ ) => {
801
+ const targetTagName = /** @type {string|false} */ (
802
+ getPreferredTagName(jsdoc, {
803
+ skipReportingBlockedTag,
804
+ tagName,
805
+ context, mode, report, tagNamePreference
806
+ })
807
+ );
808
+ if (!targetTagName ||
809
+ skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object'
810
+ ) {
811
+ return;
812
+ }
813
+
814
+ const matchingJsdocTags = jsdoc.tags.filter(({
815
+ tag,
816
+ }) => {
817
+ return tag === targetTagName;
818
+ });
819
+
820
+ for (const matchingJsdocTag of matchingJsdocTags) {
821
+ arrayHandler(
822
+ /**
823
+ * @type {import('@es-joy/jsdoccomment').JsdocTagWithInline}
824
+ */ (
825
+ matchingJsdocTag
826
+ ), targetTagName,
827
+ );
828
+ }
829
+ };
830
+
652
831
  /**
653
832
  * Get all tags, inline tags and inline tags in tags
654
833
  * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
@@ -1652,19 +1831,24 @@ const getRegexFromString = (regexString, requiredFlags) => {
1652
1831
  return new RegExp(regex, flags);
1653
1832
  };
1654
1833
 
1655
- export default {
1834
+ export {
1656
1835
  comparePaths,
1657
1836
  dropPathSegmentQuotes,
1658
1837
  enforcedContexts,
1659
1838
  exemptSpeciaMethods,
1839
+ filterTags,
1660
1840
  flattenRoots,
1841
+ forEachPreferredTag,
1661
1842
  getAllTags,
1662
1843
  getContextObject,
1663
1844
  getFunctionParameterNames,
1664
1845
  getIndent,
1665
1846
  getJsdocTagsDeep,
1666
1847
  getPreferredTagName,
1848
+ getPreferredTagNameSimple,
1667
1849
  getRegexFromString,
1850
+ getTagDescription,
1851
+ getTags,
1668
1852
  getTagsByType,
1669
1853
  getTagStructureForMode,
1670
1854
  hasATag,
@@ -2,7 +2,11 @@ import iterateJsdoc from '../iterateJsdoc.js';
2
2
  import {
3
3
  getSettings,
4
4
  } from '../iterateJsdoc.js';
5
- import jsdocUtils from '../jsdocUtils.js';
5
+ import {
6
+ getIndent,
7
+ getContextObject,
8
+ enforcedContexts,
9
+ } from '../jsdocUtils.js';
6
10
  import {
7
11
  getNonJsdocComment,
8
12
  getDecorator,
@@ -114,7 +118,7 @@ export default {
114
118
  );
115
119
  }
116
120
 
117
- const indent = jsdocUtils.getIndent({
121
+ const indent = getIndent({
118
122
  text: sourceCode.getText(
119
123
  /** @type {import('eslint').Rule.Node} */ (baseNode),
120
124
  /** @type {import('eslint').AST.SourceLocation} */
@@ -255,17 +259,17 @@ export default {
255
259
 
256
260
  // Todo: add contexts to check after (and handle if want both before and after)
257
261
  return {
258
- ...jsdocUtils.getContextObject(
259
- jsdocUtils.enforcedContexts(context, true, settings),
262
+ ...getContextObject(
263
+ enforcedContexts(context, true, settings),
260
264
  checkNonJsdoc,
261
265
  ),
262
- ...jsdocUtils.getContextObject(
266
+ ...getContextObject(
263
267
  contextsAfter,
264
268
  (_info, _handler, node) => {
265
269
  checkNonJsdocAfter(node, contextsAfter);
266
270
  },
267
271
  ),
268
- ...jsdocUtils.getContextObject(
272
+ ...getContextObject(
269
273
  contextsBeforeAndAfter,
270
274
  (_info, _handler, node) => {
271
275
  checkNonJsdoc({}, null, node);
@@ -2,7 +2,15 @@ import exportParser from '../exportParser.js';
2
2
  import {
3
3
  getSettings,
4
4
  } from '../iterateJsdoc.js';
5
- import jsdocUtils from '../jsdocUtils.js';
5
+ import {
6
+ exemptSpeciaMethods,
7
+ isConstructor,
8
+ getFunctionParameterNames,
9
+ hasReturnValue,
10
+ getIndent,
11
+ getContextObject,
12
+ enforcedContexts,
13
+ } from '../jsdocUtils.js';
6
14
  import {
7
15
  getDecorator,
8
16
  getJSDocComment,
@@ -381,7 +389,7 @@ export default {
381
389
 
382
390
  // For those who have options configured against ANY constructors (or
383
391
  // setters or getters) being reported
384
- if (jsdocUtils.exemptSpeciaMethods(
392
+ if (exemptSpeciaMethods(
385
393
  {
386
394
  description: '',
387
395
  inlineTags: [],
@@ -405,10 +413,10 @@ export default {
405
413
 
406
414
  // Avoid reporting param-less, return-less constructor methods (when
407
415
  // `exemptEmptyConstructors` option is set)
408
- exemptEmptyConstructors && jsdocUtils.isConstructor(node)
416
+ exemptEmptyConstructors && isConstructor(node)
409
417
  ) {
410
- const functionParameterNames = jsdocUtils.getFunctionParameterNames(node);
411
- if (!functionParameterNames.length && !jsdocUtils.hasReturnValue(node)) {
418
+ const functionParameterNames = getFunctionParameterNames(node);
419
+ if (!functionParameterNames.length && !hasReturnValue(node)) {
412
420
  return;
413
421
  }
414
422
  }
@@ -427,7 +435,7 @@ export default {
427
435
  baseNode = decorator;
428
436
  }
429
437
 
430
- const indent = jsdocUtils.getIndent({
438
+ const indent = getIndent({
431
439
  text: sourceCode.getText(
432
440
  /** @type {import('eslint').Rule.Node} */ (baseNode),
433
441
  /** @type {import('eslint').AST.SourceLocation} */
@@ -516,8 +524,8 @@ export default {
516
524
  };
517
525
 
518
526
  return {
519
- ...jsdocUtils.getContextObject(
520
- jsdocUtils.enforcedContexts(context, [], settings),
527
+ ...getContextObject(
528
+ enforcedContexts(context, [], settings),
521
529
  checkJsDoc,
522
530
  ),
523
531
  ArrowFunctionExpression (node) {