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.

iterateJsdoc.js 31KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = iterateJsdoc;
  6. Object.defineProperty(exports, "parseComment", {
  7. enumerable: true,
  8. get: function () {
  9. return _jsdoccomment.parseComment;
  10. }
  11. });
  12. exports.getSettings = void 0;
  13. var _jsdoccomment = require("@es-joy/jsdoccomment");
  14. var _commentParser = require("comment-parser");
  15. var _lodash = _interopRequireDefault(require("lodash"));
  16. var _jsdocUtils = _interopRequireDefault(require("./jsdocUtils"));
  17. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  18. const {
  19. rewireSpecs,
  20. seedTokens
  21. } = _commentParser.util;
  22. /*
  23. const {
  24. align as commentAlign,
  25. flow: commentFlow,
  26. indent: commentIndent,
  27. } = transforms;
  28. */
  29. const globalState = new Map();
  30. const getBasicUtils = (context, {
  31. tagNamePreference,
  32. mode
  33. }) => {
  34. const utils = {};
  35. utils.reportSettings = message => {
  36. context.report({
  37. loc: {
  38. start: {
  39. column: 1,
  40. line: 1
  41. }
  42. },
  43. message
  44. });
  45. };
  46. utils.parseClosureTemplateTag = tag => {
  47. return _jsdocUtils.default.parseClosureTemplateTag(tag);
  48. };
  49. utils.pathDoesNotBeginWith = _jsdocUtils.default.pathDoesNotBeginWith;
  50. utils.getPreferredTagNameObject = ({
  51. tagName
  52. }) => {
  53. const ret = _jsdocUtils.default.getPreferredTagName(context, mode, tagName, tagNamePreference);
  54. const isObject = ret && typeof ret === 'object';
  55. if (ret === false || isObject && !ret.replacement) {
  56. return {
  57. blocked: true,
  58. tagName
  59. };
  60. }
  61. return ret;
  62. };
  63. return utils;
  64. };
  65. const getUtils = (node, jsdoc, jsdocNode, settings, report, context, iteratingAll, ruleConfig, indent) => {
  66. const ancestors = context.getAncestors();
  67. const sourceCode = context.getSourceCode();
  68. const utils = getBasicUtils(context, settings);
  69. const {
  70. tagNamePreference,
  71. overrideReplacesDocs,
  72. ignoreReplacesDocs,
  73. implementsReplacesDocs,
  74. augmentsExtendsReplacesDocs,
  75. maxLines,
  76. minLines,
  77. mode
  78. } = settings;
  79. utils.isIteratingFunction = () => {
  80. return !iteratingAll || ['MethodDefinition', 'ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].includes(node && node.type);
  81. };
  82. utils.isVirtualFunction = () => {
  83. return iteratingAll && utils.hasATag(['callback', 'function', 'func', 'method']);
  84. };
  85. utils.stringify = (tagBlock, specRewire) => {
  86. return (0, _commentParser.stringify)(specRewire ? rewireSpecs(tagBlock) : tagBlock);
  87. };
  88. utils.reportJSDoc = (msg, tag, handler, specRewire, data) => {
  89. report(msg, handler ? fixer => {
  90. handler();
  91. const replacement = utils.stringify(jsdoc, specRewire);
  92. return fixer.replaceText(jsdocNode, replacement);
  93. } : null, tag, data);
  94. };
  95. utils.getRegexFromString = (str, requiredFlags) => {
  96. return _jsdocUtils.default.getRegexFromString(str, requiredFlags);
  97. };
  98. utils.getTagDescription = tg => {
  99. const descriptions = [];
  100. tg.source.some(({
  101. tokens: {
  102. end,
  103. lineEnd,
  104. postDelimiter,
  105. tag,
  106. postTag,
  107. name,
  108. type,
  109. description
  110. }
  111. }) => {
  112. const desc = (tag && postTag || !tag && !name && !type && postDelimiter || '' // Remove space
  113. ).slice(1) + (description || '') + (lineEnd || '');
  114. if (end) {
  115. if (desc) {
  116. descriptions.push(desc);
  117. }
  118. return true;
  119. }
  120. descriptions.push(desc);
  121. return false;
  122. });
  123. return descriptions.join('\n');
  124. };
  125. utils.getDescription = () => {
  126. const descriptions = [];
  127. let lastDescriptionLine = 0;
  128. jsdoc.source.some(({
  129. tokens: {
  130. description,
  131. tag,
  132. end
  133. }
  134. }, idx) => {
  135. if (idx && (tag || end)) {
  136. lastDescriptionLine = idx - 1;
  137. return true;
  138. }
  139. if (idx || description) {
  140. descriptions.push(description);
  141. }
  142. return false;
  143. });
  144. return {
  145. description: descriptions.join('\n'),
  146. lastDescriptionLine
  147. };
  148. };
  149. utils.changeTag = (tag, ...tokens) => {
  150. tag.source.forEach((src, idx) => {
  151. src.tokens = { ...src.tokens,
  152. ...tokens[idx]
  153. };
  154. });
  155. };
  156. utils.setTag = (tag, tokens) => {
  157. tag.source = [{
  158. // Or tag.source[0].number?
  159. number: tag.line,
  160. tokens: seedTokens({
  161. delimiter: '*',
  162. postDelimiter: ' ',
  163. start: indent + ' ',
  164. tag: '@' + tag.tag,
  165. ...tokens
  166. })
  167. }];
  168. };
  169. utils.removeTag = idx => {
  170. return utils.removeTagItem(idx);
  171. };
  172. utils.removeTagItem = (tagIndex, tagSourceOffset = 0) => {
  173. const {
  174. source: tagSource
  175. } = jsdoc.tags[tagIndex];
  176. let lastIndex;
  177. const firstNumber = jsdoc.source[0].number;
  178. tagSource.some(({
  179. number
  180. }, tagIdx) => {
  181. const sourceIndex = jsdoc.source.findIndex(({
  182. number: srcNumber,
  183. tokens: {
  184. end
  185. }
  186. }) => {
  187. return number === srcNumber && !end;
  188. }); // istanbul ignore else
  189. if (sourceIndex > -1) {
  190. let spliceCount = 1;
  191. tagSource.slice(tagIdx + 1).some(({
  192. tokens: {
  193. tag,
  194. end
  195. }
  196. }) => {
  197. if (!tag && !end) {
  198. spliceCount++;
  199. return false;
  200. }
  201. return true;
  202. });
  203. jsdoc.source.splice(sourceIndex + tagSourceOffset, spliceCount - tagSourceOffset);
  204. tagSource.splice(tagIdx + tagSourceOffset, spliceCount - tagSourceOffset);
  205. lastIndex = sourceIndex;
  206. return true;
  207. } // istanbul ignore next
  208. return false;
  209. });
  210. jsdoc.source.slice(lastIndex).forEach((src, idx) => {
  211. src.number = firstNumber + lastIndex + idx;
  212. });
  213. };
  214. utils.addTag = targetTagName => {
  215. var _jsdoc$tags$source$0$, _jsdoc$tags, _jsdoc$tags$source$;
  216. const number = ((_jsdoc$tags$source$0$ = (_jsdoc$tags = jsdoc.tags[jsdoc.tags.length - 1]) === null || _jsdoc$tags === void 0 ? void 0 : (_jsdoc$tags$source$ = _jsdoc$tags.source[0]) === null || _jsdoc$tags$source$ === void 0 ? void 0 : _jsdoc$tags$source$.number) !== null && _jsdoc$tags$source$0$ !== void 0 ? _jsdoc$tags$source$0$ : 0) + 1;
  217. jsdoc.source.splice(number, 0, {
  218. number,
  219. source: '',
  220. tokens: seedTokens({
  221. delimiter: '*',
  222. postDelimiter: ' ',
  223. start: indent + ' ',
  224. tag: `@${targetTagName}`
  225. })
  226. });
  227. jsdoc.source.slice(number + 1).forEach(src => {
  228. src.number++;
  229. });
  230. };
  231. utils.seedTokens = seedTokens;
  232. utils.emptyTokens = tokens => {
  233. ['start', 'postDelimiter', 'tag', 'type', 'postType', 'postTag', 'name', 'postName', 'description', 'end', 'lineEnd'].forEach(prop => {
  234. tokens[prop] = '';
  235. });
  236. };
  237. utils.addLine = (sourceIndex, tokens) => {
  238. var _jsdoc$source;
  239. const number = (((_jsdoc$source = jsdoc.source[sourceIndex - 1]) === null || _jsdoc$source === void 0 ? void 0 : _jsdoc$source.number) || 0) + 1;
  240. jsdoc.source.splice(sourceIndex, 0, {
  241. number,
  242. source: '',
  243. tokens: seedTokens(tokens)
  244. }); // If necessary, we can rewire the tags (misnamed method)
  245. // rewireSource(jsdoc);
  246. };
  247. utils.addLines = (tagIndex, tagSourceOffset, numLines) => {
  248. const {
  249. source: tagSource
  250. } = jsdoc.tags[tagIndex];
  251. let lastIndex;
  252. const firstNumber = jsdoc.source[0].number;
  253. tagSource.some(({
  254. number
  255. }) => {
  256. const makeLine = () => {
  257. return {
  258. number,
  259. source: '',
  260. tokens: seedTokens({
  261. delimiter: '*',
  262. start: indent + ' '
  263. })
  264. };
  265. };
  266. const makeLines = () => {
  267. return Array.from({
  268. length: numLines
  269. }, makeLine);
  270. };
  271. const sourceIndex = jsdoc.source.findIndex(({
  272. number: srcNumber,
  273. tokens: {
  274. end
  275. }
  276. }) => {
  277. return number === srcNumber && !end;
  278. }); // istanbul ignore else
  279. if (sourceIndex > -1) {
  280. const lines = makeLines();
  281. jsdoc.source.splice(sourceIndex + tagSourceOffset, 0, ...lines); // tagSource.splice(tagIdx + 1, 0, ...makeLines());
  282. lastIndex = sourceIndex;
  283. return true;
  284. } // istanbul ignore next
  285. return false;
  286. });
  287. jsdoc.source.slice(lastIndex).forEach((src, idx) => {
  288. src.number = firstNumber + lastIndex + idx;
  289. });
  290. };
  291. utils.makeMultiline = () => {
  292. const {
  293. source: [{
  294. tokens
  295. }]
  296. } = jsdoc;
  297. const {
  298. postDelimiter,
  299. description,
  300. lineEnd,
  301. tag,
  302. name,
  303. type
  304. } = tokens;
  305. let {
  306. tokens: {
  307. postName,
  308. postTag,
  309. postType
  310. }
  311. } = jsdoc.source[0]; // Strip trailing leftovers from single line ending
  312. if (!description) {
  313. if (postName) {
  314. postName = '';
  315. } else if (postType) {
  316. postType = ''; // eslint-disable-next-line max-len, no-inline-comments
  317. } else
  318. /* istanbul ignore else -- `comment-parser` prevents empty blocks currently per https://github.com/syavorsky/comment-parser/issues/128 */
  319. if (postTag) {
  320. postTag = '';
  321. }
  322. }
  323. utils.emptyTokens(tokens);
  324. utils.addLine(1, {
  325. delimiter: '*',
  326. // If a description were present, it may have whitespace attached
  327. // due to being at the end of the single line
  328. description: description.trimEnd(),
  329. name,
  330. postDelimiter,
  331. postName,
  332. postTag,
  333. postType,
  334. start: indent + ' ',
  335. tag,
  336. type
  337. });
  338. utils.addLine(2, {
  339. end: '*/',
  340. lineEnd,
  341. start: indent + ' '
  342. });
  343. };
  344. utils.flattenRoots = params => {
  345. return _jsdocUtils.default.flattenRoots(params);
  346. };
  347. utils.getFunctionParameterNames = useDefaultObjectProperties => {
  348. return _jsdocUtils.default.getFunctionParameterNames(node, useDefaultObjectProperties);
  349. };
  350. utils.hasParams = () => {
  351. return _jsdocUtils.default.hasParams(node);
  352. };
  353. utils.isGenerator = () => {
  354. return node && (node.generator || node.type === 'MethodDefinition' && node.value.generator || ['ExportNamedDeclaration', 'ExportDefaultDeclaration'].includes(node.type) && node.declaration.generator);
  355. };
  356. utils.isConstructor = () => {
  357. return _jsdocUtils.default.isConstructor(node);
  358. };
  359. utils.getJsdocTagsDeep = tagName => {
  360. const name = utils.getPreferredTagName({
  361. tagName
  362. });
  363. if (!name) {
  364. return false;
  365. }
  366. return _jsdocUtils.default.getJsdocTagsDeep(jsdoc, name);
  367. };
  368. utils.getPreferredTagName = ({
  369. tagName,
  370. skipReportingBlockedTag = false,
  371. allowObjectReturn = false,
  372. defaultMessage = `Unexpected tag \`@${tagName}\``
  373. }) => {
  374. const ret = _jsdocUtils.default.getPreferredTagName(context, mode, tagName, tagNamePreference);
  375. const isObject = ret && typeof ret === 'object';
  376. if (utils.hasTag(tagName) && (ret === false || isObject && !ret.replacement)) {
  377. if (skipReportingBlockedTag) {
  378. return {
  379. blocked: true,
  380. tagName
  381. };
  382. }
  383. const message = isObject && ret.message || defaultMessage;
  384. report(message, null, utils.getTags(tagName)[0]);
  385. return false;
  386. }
  387. return isObject && !allowObjectReturn ? ret.replacement : ret;
  388. };
  389. utils.isValidTag = (name, definedTags) => {
  390. return _jsdocUtils.default.isValidTag(context, mode, name, definedTags);
  391. };
  392. utils.hasATag = names => {
  393. return _jsdocUtils.default.hasATag(jsdoc, names);
  394. };
  395. utils.hasTag = name => {
  396. return _jsdocUtils.default.hasTag(jsdoc, name);
  397. };
  398. utils.comparePaths = name => {
  399. return _jsdocUtils.default.comparePaths(name);
  400. };
  401. utils.dropPathSegmentQuotes = name => {
  402. return _jsdocUtils.default.dropPathSegmentQuotes(name);
  403. };
  404. utils.avoidDocs = () => {
  405. var _context$options$0$ex, _context$options$;
  406. if (ignoreReplacesDocs !== false && (utils.hasTag('ignore') || utils.classHasTag('ignore')) || overrideReplacesDocs !== false && (utils.hasTag('override') || utils.classHasTag('override')) || implementsReplacesDocs !== false && (utils.hasTag('implements') || utils.classHasTag('implements')) || augmentsExtendsReplacesDocs && (utils.hasATag(['augments', 'extends']) || utils.classHasTag('augments') || utils.classHasTag('extends'))) {
  407. return true;
  408. }
  409. if (_jsdocUtils.default.exemptSpeciaMethods(jsdoc, node, context, ruleConfig.meta.schema)) {
  410. return true;
  411. }
  412. const exemptedBy = (_context$options$0$ex = (_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.exemptedBy) !== null && _context$options$0$ex !== void 0 ? _context$options$0$ex : ['inheritDoc', ...(mode === 'closure' ? [] : ['inheritdoc'])];
  413. if (exemptedBy.length && utils.getPresentTags(exemptedBy).length) {
  414. return true;
  415. }
  416. return false;
  417. };
  418. ['tagMightHaveNamePosition', 'tagMightHaveTypePosition'].forEach(method => {
  419. utils[method] = (tagName, otherModeMaps) => {
  420. const result = _jsdocUtils.default[method](tagName);
  421. if (result) {
  422. return true;
  423. }
  424. if (!otherModeMaps) {
  425. return false;
  426. }
  427. const otherResult = otherModeMaps.some(otherModeMap => {
  428. return _jsdocUtils.default[method](tagName, otherModeMap);
  429. });
  430. return otherResult ? {
  431. otherMode: true
  432. } : false;
  433. };
  434. });
  435. ['tagMustHaveNamePosition', 'tagMustHaveTypePosition', 'tagMissingRequiredTypeOrNamepath'].forEach(method => {
  436. utils[method] = (tagName, otherModeMaps) => {
  437. const result = _jsdocUtils.default[method](tagName);
  438. if (!result) {
  439. return false;
  440. } // if (!otherModeMaps) { return true; }
  441. const otherResult = otherModeMaps.every(otherModeMap => {
  442. return _jsdocUtils.default[method](tagName, otherModeMap);
  443. });
  444. return otherResult ? true : {
  445. otherMode: false
  446. };
  447. };
  448. });
  449. ['isNamepathDefiningTag', 'tagMightHaveNamepath'].forEach(method => {
  450. utils[method] = tagName => {
  451. return _jsdocUtils.default[method](tagName);
  452. };
  453. });
  454. utils.getTagStructureForMode = mde => {
  455. return _jsdocUtils.default.getTagStructureForMode(mde, settings.structuredTags);
  456. };
  457. utils.hasDefinedTypeTag = tag => {
  458. return _jsdocUtils.default.hasDefinedTypeTag(tag);
  459. };
  460. utils.hasValueOrExecutorHasNonEmptyResolveValue = anyPromiseAsReturn => {
  461. return _jsdocUtils.default.hasValueOrExecutorHasNonEmptyResolveValue(node, anyPromiseAsReturn);
  462. };
  463. utils.hasYieldValue = () => {
  464. if (['ExportNamedDeclaration', 'ExportDefaultDeclaration'].includes(node.type)) {
  465. return _jsdocUtils.default.hasYieldValue(node.declaration);
  466. }
  467. return _jsdocUtils.default.hasYieldValue(node);
  468. };
  469. utils.hasYieldReturnValue = () => {
  470. return _jsdocUtils.default.hasYieldValue(node, true);
  471. };
  472. utils.hasThrowValue = () => {
  473. return _jsdocUtils.default.hasThrowValue(node);
  474. };
  475. utils.isAsync = () => {
  476. return node.async;
  477. };
  478. utils.getTags = tagName => {
  479. return utils.filterTags(item => {
  480. return item.tag === tagName;
  481. });
  482. };
  483. utils.getPresentTags = tagList => {
  484. return utils.filterTags(tag => {
  485. return tagList.includes(tag.tag);
  486. });
  487. };
  488. utils.filterTags = filter => {
  489. return _jsdocUtils.default.filterTags(jsdoc.tags, filter);
  490. };
  491. utils.getTagsByType = tags => {
  492. return _jsdocUtils.default.getTagsByType(context, mode, tags, tagNamePreference);
  493. };
  494. utils.hasOptionTag = tagName => {
  495. var _context$options$2;
  496. const {
  497. tags
  498. } = (_context$options$2 = context.options[0]) !== null && _context$options$2 !== void 0 ? _context$options$2 : {};
  499. return Boolean(tags && tags.includes(tagName));
  500. };
  501. utils.getClassNode = () => {
  502. return [...ancestors, node].reverse().find(parent => {
  503. return parent && ['ClassDeclaration', 'ClassExpression'].includes(parent.type);
  504. }) || null;
  505. };
  506. utils.getClassJsdoc = () => {
  507. const classNode = utils.getClassNode();
  508. if (!classNode) {
  509. return null;
  510. }
  511. const classJsdocNode = (0, _jsdoccomment.getJSDocComment)(sourceCode, classNode, {
  512. maxLines,
  513. minLines
  514. });
  515. if (classJsdocNode) {
  516. const indnt = ' '.repeat(classJsdocNode.loc.start.column);
  517. return (0, _jsdoccomment.parseComment)(classJsdocNode, indnt);
  518. }
  519. return null;
  520. };
  521. utils.classHasTag = tagName => {
  522. const classJsdoc = utils.getClassJsdoc();
  523. return Boolean(classJsdoc) && _jsdocUtils.default.hasTag(classJsdoc, tagName);
  524. };
  525. utils.forEachPreferredTag = (tagName, arrayHandler, skipReportingBlockedTag = false) => {
  526. const targetTagName = utils.getPreferredTagName({
  527. skipReportingBlockedTag,
  528. tagName
  529. });
  530. if (!targetTagName || skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object') {
  531. return;
  532. }
  533. const matchingJsdocTags = _lodash.default.filter(jsdoc.tags, {
  534. tag: targetTagName
  535. });
  536. matchingJsdocTags.forEach(matchingJsdocTag => {
  537. arrayHandler(matchingJsdocTag, targetTagName);
  538. });
  539. };
  540. return utils;
  541. };
  542. const getSettings = context => {
  543. var _context$settings$jsd, _context$settings$jsd2, _context$settings$jsd3, _context$settings$jsd4, _context$settings$jsd5, _context$settings$jsd6, _context$settings$jsd7, _context$settings$jsd8, _context$settings$jsd9, _context$settings$jsd10, _context$settings$jsd11, _context$settings$jsd12, _context$settings$jsd13, _context$settings$jsd14, _context$settings$jsd15, _context$settings$jsd16, _context$settings$jsd17, _context$settings$jsd18;
  544. /* eslint-disable sort-keys-fix/sort-keys-fix */
  545. const settings = {
  546. // All rules
  547. ignorePrivate: Boolean((_context$settings$jsd = context.settings.jsdoc) === null || _context$settings$jsd === void 0 ? void 0 : _context$settings$jsd.ignorePrivate),
  548. ignoreInternal: Boolean((_context$settings$jsd2 = context.settings.jsdoc) === null || _context$settings$jsd2 === void 0 ? void 0 : _context$settings$jsd2.ignoreInternal),
  549. maxLines: Number((_context$settings$jsd3 = (_context$settings$jsd4 = context.settings.jsdoc) === null || _context$settings$jsd4 === void 0 ? void 0 : _context$settings$jsd4.maxLines) !== null && _context$settings$jsd3 !== void 0 ? _context$settings$jsd3 : 1),
  550. minLines: Number((_context$settings$jsd5 = (_context$settings$jsd6 = context.settings.jsdoc) === null || _context$settings$jsd6 === void 0 ? void 0 : _context$settings$jsd6.minLines) !== null && _context$settings$jsd5 !== void 0 ? _context$settings$jsd5 : 0),
  551. // `check-tag-names` and many returns/param rules
  552. tagNamePreference: (_context$settings$jsd7 = (_context$settings$jsd8 = context.settings.jsdoc) === null || _context$settings$jsd8 === void 0 ? void 0 : _context$settings$jsd8.tagNamePreference) !== null && _context$settings$jsd7 !== void 0 ? _context$settings$jsd7 : {},
  553. // `check-types` and `no-undefined-types`
  554. preferredTypes: (_context$settings$jsd9 = (_context$settings$jsd10 = context.settings.jsdoc) === null || _context$settings$jsd10 === void 0 ? void 0 : _context$settings$jsd10.preferredTypes) !== null && _context$settings$jsd9 !== void 0 ? _context$settings$jsd9 : {},
  555. // `check-types`, `no-undefined-types`, `valid-types`
  556. structuredTags: (_context$settings$jsd11 = (_context$settings$jsd12 = context.settings.jsdoc) === null || _context$settings$jsd12 === void 0 ? void 0 : _context$settings$jsd12.structuredTags) !== null && _context$settings$jsd11 !== void 0 ? _context$settings$jsd11 : {},
  557. // `require-param`, `require-description`, `require-example`,
  558. // `require-returns`, `require-throw`, `require-yields`
  559. overrideReplacesDocs: (_context$settings$jsd13 = context.settings.jsdoc) === null || _context$settings$jsd13 === void 0 ? void 0 : _context$settings$jsd13.overrideReplacesDocs,
  560. ignoreReplacesDocs: (_context$settings$jsd14 = context.settings.jsdoc) === null || _context$settings$jsd14 === void 0 ? void 0 : _context$settings$jsd14.ignoreReplacesDocs,
  561. implementsReplacesDocs: (_context$settings$jsd15 = context.settings.jsdoc) === null || _context$settings$jsd15 === void 0 ? void 0 : _context$settings$jsd15.implementsReplacesDocs,
  562. augmentsExtendsReplacesDocs: (_context$settings$jsd16 = context.settings.jsdoc) === null || _context$settings$jsd16 === void 0 ? void 0 : _context$settings$jsd16.augmentsExtendsReplacesDocs,
  563. // Many rules, e.g., `check-tag-names`
  564. mode: (_context$settings$jsd17 = (_context$settings$jsd18 = context.settings.jsdoc) === null || _context$settings$jsd18 === void 0 ? void 0 : _context$settings$jsd18.mode) !== null && _context$settings$jsd17 !== void 0 ? _context$settings$jsd17 : context.parserPath.includes('@typescript-eslint') ? 'typescript' : 'jsdoc'
  565. };
  566. /* eslint-enable sort-keys-fix/sort-keys-fix */
  567. _jsdocUtils.default.setTagStructure(settings.mode);
  568. try {
  569. _jsdocUtils.default.overrideTagStructure(settings.structuredTags);
  570. } catch (error) {
  571. context.report({
  572. loc: {
  573. start: {
  574. column: 1,
  575. line: 1
  576. }
  577. },
  578. message: error.message
  579. });
  580. return false;
  581. }
  582. return settings;
  583. };
  584. /**
  585. * Create the report function
  586. *
  587. * @param {object} context
  588. * @param {object} commentNode
  589. */
  590. exports.getSettings = getSettings;
  591. const makeReport = (context, commentNode) => {
  592. const report = (message, fix = null, jsdocLoc = null, data = null) => {
  593. let loc;
  594. if (jsdocLoc) {
  595. if (!('line' in jsdocLoc)) {
  596. jsdocLoc.line = jsdocLoc.source[0].number;
  597. }
  598. const lineNumber = commentNode.loc.start.line + jsdocLoc.line;
  599. loc = {
  600. end: {
  601. line: lineNumber
  602. },
  603. start: {
  604. line: lineNumber
  605. }
  606. };
  607. if (jsdocLoc.column) {
  608. const colNumber = commentNode.loc.start.column + jsdocLoc.column;
  609. loc.end.column = colNumber;
  610. loc.start.column = colNumber;
  611. }
  612. }
  613. context.report({
  614. data,
  615. fix,
  616. loc,
  617. message,
  618. node: commentNode
  619. });
  620. };
  621. return report;
  622. };
  623. /**
  624. * @typedef {ReturnType<typeof getUtils>} Utils
  625. * @typedef {ReturnType<typeof getSettings>} Settings
  626. * @typedef {(
  627. * arg: {
  628. * context: object,
  629. * sourceCode: object,
  630. * indent: string,
  631. * jsdoc: object,
  632. * jsdocNode: object,
  633. * node: object | null,
  634. * report: ReturnType<typeof makeReport>,
  635. * settings: Settings,
  636. * utils: Utils,
  637. * }
  638. * ) => any } JsdocVisitor
  639. */
  640. const iterate = (info, indent, jsdoc, ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, iteratingAll) => {
  641. const report = makeReport(context, jsdocNode);
  642. const utils = getUtils(node, jsdoc, jsdocNode, settings, report, context, iteratingAll, ruleConfig, indent);
  643. if (!ruleConfig.checkInternal && settings.ignoreInternal && utils.hasTag('internal')) {
  644. return;
  645. }
  646. if (!ruleConfig.checkPrivate && settings.ignorePrivate && (utils.hasTag('private') || _lodash.default.filter(jsdoc.tags, {
  647. tag: 'access'
  648. }).some(({
  649. description
  650. }) => {
  651. return description === 'private';
  652. }))) {
  653. return;
  654. }
  655. iterator({
  656. context,
  657. globalState,
  658. indent,
  659. info,
  660. iteratingAll,
  661. jsdoc,
  662. jsdocNode,
  663. node,
  664. report,
  665. settings,
  666. sourceCode,
  667. state,
  668. utils
  669. });
  670. };
  671. const getIndentAndJSDoc = function (lines, jsdocNode) {
  672. const sourceLine = lines[jsdocNode.loc.start.line - 1];
  673. const indnt = sourceLine.charAt(0).repeat(jsdocNode.loc.start.column);
  674. const jsdc = (0, _jsdoccomment.parseComment)(jsdocNode, indnt);
  675. return [indnt, jsdc];
  676. };
  677. /**
  678. * Create an eslint rule that iterates over all JSDocs, regardless of whether
  679. * they are attached to a function-like node.
  680. *
  681. * @param {JsdocVisitor} iterator
  682. * @param {{meta: any}} ruleConfig
  683. * @param contexts
  684. * @param {boolean} additiveContexts
  685. */
  686. const iterateAllJsdocs = (iterator, ruleConfig, contexts, additiveContexts) => {
  687. const trackedJsdocs = [];
  688. let handler;
  689. let settings;
  690. const callIterator = (context, node, jsdocNodes, state, lastCall) => {
  691. const sourceCode = context.getSourceCode();
  692. const {
  693. lines
  694. } = sourceCode;
  695. const utils = getBasicUtils(context, settings);
  696. jsdocNodes.forEach(jsdocNode => {
  697. if (!/^\/\*\*\s/.test(sourceCode.getText(jsdocNode))) {
  698. return;
  699. }
  700. const [indent, jsdoc] = getIndentAndJSDoc(lines, jsdocNode);
  701. if (additiveContexts) {
  702. contexts.forEach(({
  703. comment
  704. }, idx) => {
  705. if (comment && handler(comment, jsdoc) === false) {
  706. return;
  707. }
  708. iterate({
  709. comment,
  710. lastIndex: idx,
  711. selector: node === null || node === void 0 ? void 0 : node.type
  712. }, indent, jsdoc, ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, true);
  713. });
  714. return;
  715. }
  716. let lastComment;
  717. let lastIndex;
  718. if (contexts && contexts.every(({
  719. comment
  720. }, idx) => {
  721. lastComment = comment;
  722. lastIndex = idx;
  723. return comment && handler(comment, jsdoc) === false;
  724. })) {
  725. return;
  726. }
  727. iterate(lastComment ? {
  728. comment: lastComment,
  729. lastIndex,
  730. selector: node === null || node === void 0 ? void 0 : node.type
  731. } : {
  732. lastIndex,
  733. selector: node === null || node === void 0 ? void 0 : node.type
  734. }, indent, jsdoc, ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, true);
  735. });
  736. if (lastCall && ruleConfig.exit) {
  737. ruleConfig.exit({
  738. context,
  739. state,
  740. utils
  741. });
  742. }
  743. };
  744. return {
  745. create(context) {
  746. const sourceCode = context.getSourceCode();
  747. settings = getSettings(context);
  748. if (!settings) {
  749. return {};
  750. }
  751. if (contexts) {
  752. handler = (0, _jsdoccomment.commentHandler)(settings);
  753. }
  754. const state = {};
  755. return {
  756. '*:not(Program)'(node) {
  757. const reducedNode = (0, _jsdoccomment.getReducedASTNode)(node, sourceCode);
  758. if (node !== reducedNode) {
  759. return;
  760. }
  761. const commentNode = (0, _jsdoccomment.getJSDocComment)(sourceCode, node, settings);
  762. if (trackedJsdocs.includes(commentNode)) {
  763. return;
  764. }
  765. if (!commentNode) {
  766. if (ruleConfig.nonComment) {
  767. ruleConfig.nonComment({
  768. node,
  769. state
  770. });
  771. }
  772. return;
  773. }
  774. trackedJsdocs.push(commentNode);
  775. callIterator(context, node, [commentNode], state);
  776. },
  777. 'Program:exit'() {
  778. const allComments = sourceCode.getAllComments();
  779. const untrackedJSdoc = allComments.filter(node => {
  780. return !trackedJsdocs.includes(node);
  781. });
  782. callIterator(context, null, untrackedJSdoc, state, true);
  783. }
  784. };
  785. },
  786. meta: ruleConfig.meta
  787. };
  788. };
  789. /**
  790. * Create an eslint rule that iterates over all JSDocs, regardless of whether
  791. * they are attached to a function-like node.
  792. *
  793. * @param {JsdocVisitor} iterator
  794. * @param {{meta: any}} ruleConfig
  795. */
  796. const checkFile = (iterator, ruleConfig) => {
  797. return {
  798. create(context) {
  799. const sourceCode = context.getSourceCode();
  800. const settings = getSettings(context);
  801. if (!settings) {
  802. return {};
  803. }
  804. return {
  805. 'Program:exit'() {
  806. const allComments = sourceCode.getAllComments();
  807. const {
  808. lines
  809. } = sourceCode;
  810. const utils = getBasicUtils(context, settings);
  811. iterator({
  812. allComments,
  813. context,
  814. lines,
  815. makeReport,
  816. settings,
  817. sourceCode,
  818. utils
  819. });
  820. }
  821. };
  822. },
  823. meta: ruleConfig.meta
  824. };
  825. };
  826. /**
  827. * @param {JsdocVisitor} iterator
  828. * @param {{
  829. * meta: any,
  830. * contextDefaults?: true | string[],
  831. * contextSelected?: true,
  832. * iterateAllJsdocs?: true,
  833. * }} ruleConfig
  834. */
  835. function iterateJsdoc(iterator, ruleConfig) {
  836. var _ruleConfig$meta;
  837. const metaType = ruleConfig === null || ruleConfig === void 0 ? void 0 : (_ruleConfig$meta = ruleConfig.meta) === null || _ruleConfig$meta === void 0 ? void 0 : _ruleConfig$meta.type;
  838. if (!metaType || !['problem', 'suggestion', 'layout'].includes(metaType)) {
  839. throw new TypeError('Rule must include `meta.type` option (with value "problem", "suggestion", or "layout")');
  840. }
  841. if (typeof iterator !== 'function') {
  842. throw new TypeError('The iterator argument must be a function.');
  843. }
  844. if (ruleConfig.checkFile) {
  845. return checkFile(iterator, ruleConfig);
  846. }
  847. if (ruleConfig.iterateAllJsdocs) {
  848. return iterateAllJsdocs(iterator, ruleConfig);
  849. }
  850. return {
  851. /**
  852. * The entrypoint for the JSDoc rule.
  853. *
  854. * @param {*} context
  855. * a reference to the context which hold all important information
  856. * like settings and the sourcecode to check.
  857. * @returns {object}
  858. * a list with parser callback function.
  859. */
  860. create(context) {
  861. const settings = getSettings(context);
  862. if (!settings) {
  863. return {};
  864. }
  865. let contexts;
  866. if (ruleConfig.contextDefaults || ruleConfig.contextSelected || ruleConfig.matchContext) {
  867. var _context$options$3, _contexts, _contexts2;
  868. contexts = ruleConfig.matchContext && (_context$options$3 = context.options[0]) !== null && _context$options$3 !== void 0 && _context$options$3.match ? context.options[0].match : _jsdocUtils.default.enforcedContexts(context, ruleConfig.contextDefaults);
  869. if (contexts) {
  870. contexts = contexts.map(obj => {
  871. if (typeof obj === 'object' && !obj.context) {
  872. return { ...obj,
  873. context: 'any'
  874. };
  875. }
  876. return obj;
  877. });
  878. }
  879. const hasPlainAny = (_contexts = contexts) === null || _contexts === void 0 ? void 0 : _contexts.includes('any');
  880. const hasObjectAny = !hasPlainAny && ((_contexts2 = contexts) === null || _contexts2 === void 0 ? void 0 : _contexts2.find(ctxt => {
  881. return (ctxt === null || ctxt === void 0 ? void 0 : ctxt.context) === 'any';
  882. }));
  883. if (hasPlainAny || hasObjectAny) {
  884. return iterateAllJsdocs(iterator, ruleConfig, hasObjectAny ? contexts : null, ruleConfig.matchContext).create(context);
  885. }
  886. }
  887. const sourceCode = context.getSourceCode();
  888. const {
  889. lines
  890. } = sourceCode;
  891. const state = {};
  892. const checkJsdoc = (info, handler, node) => {
  893. const jsdocNode = (0, _jsdoccomment.getJSDocComment)(sourceCode, node, settings);
  894. if (!jsdocNode) {
  895. return;
  896. }
  897. const [indent, jsdoc] = getIndentAndJSDoc(lines, jsdocNode);
  898. if ( // Note, `handler` should already be bound in its first argument
  899. // with these only to be called after the value of
  900. // `comment`
  901. handler && handler(jsdoc) === false) {
  902. return;
  903. }
  904. iterate(info, indent, jsdoc, ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state);
  905. };
  906. let contextObject = {};
  907. if (contexts && (ruleConfig.contextDefaults || ruleConfig.contextSelected || ruleConfig.matchContext)) {
  908. contextObject = _jsdocUtils.default.getContextObject(contexts, checkJsdoc, (0, _jsdoccomment.commentHandler)(settings));
  909. } else {
  910. ['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].forEach(prop => {
  911. contextObject[prop] = checkJsdoc.bind(null, {
  912. selector: prop
  913. }, null);
  914. });
  915. }
  916. if (ruleConfig.exit) {
  917. contextObject['Program:exit'] = () => {
  918. ruleConfig.exit({
  919. context,
  920. state
  921. });
  922. };
  923. }
  924. return contextObject;
  925. },
  926. meta: ruleConfig.meta
  927. };
  928. }
  929. //# sourceMappingURL=iterateJsdoc.js.map