UNPKG

eslint-plugin-jsdoc

Version:
1 lines 9.45 kB
{"version":3,"file":"checkIndentation.cjs","names":["iterateJsdoc"],"sources":["../../src/rules/checkIndentation.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\n\n/**\n * @param {string} str\n * @param {string[]} excludeTags\n * @returns {string}\n */\nconst maskExcludedContent = (str, excludeTags) => {\n const regContent = new RegExp(`([ \\\\t]+\\\\*)[ \\\\t]@(?:${excludeTags.join('|')})(?=[ \\\\n])([\\\\w\\\\|\\\\W]*?\\\\n)(?=[ \\\\t]*\\\\*(?:[ \\\\t]*@\\\\w+\\\\s|\\\\/))`, 'gv');\n\n return str.replace(regContent, (_match, margin, code) => {\n return (margin + '\\n').repeat(code.match(/\\n/gv).length);\n });\n};\n\n/**\n * @param {string} str\n * @returns {string}\n */\nconst maskCodeBlocks = (str) => {\n const regContent = /([ \\t]+\\*)[ \\t]```[^\\n]*?([\\w\\|\\W]*?\\n)(?=[ \\t]*\\*(?:[ \\t]*(?:```|@\\w+\\s)|\\/))/gv;\n\n return str.replaceAll(regContent, (_match, margin, code) => {\n return (margin + '\\n').repeat(code.match(/\\n/gv).length);\n });\n};\n\n/**\n * @param {string[]} lines\n * @param {number} lineIndex\n * @returns {number}\n */\nconst getLineNumber = (lines, lineIndex) => {\n const precedingText = lines.slice(0, lineIndex).join('\\n');\n const lineBreaks = precedingText.match(/\\n/gv) || [];\n return lineBreaks.length + 1;\n};\n\nexport default iterateJsdoc(({\n context,\n jsdocNode,\n report,\n sourceCode,\n}) => {\n const options = context.options[0] || {};\n const /** @type {{excludeTags: string[], allowIndentedSections: boolean}} */ {\n allowIndentedSections = false,\n excludeTags = [\n 'example',\n ],\n } = options;\n\n const textWithoutCodeBlocks = maskCodeBlocks(sourceCode.getText(jsdocNode));\n const text = excludeTags.length ? maskExcludedContent(textWithoutCodeBlocks, excludeTags) : textWithoutCodeBlocks;\n\n if (allowIndentedSections) {\n // When allowIndentedSections is enabled, only check for indentation on tag lines\n // and the very first line of the main description\n const lines = text.split('\\n');\n let hasSeenContent = false;\n let currentSectionIndent = null;\n\n for (const [\n lineIndex,\n line,\n ] of lines.entries()) {\n // Check for indentation (two or more spaces after *)\n const indentMatch = line.match(/^(?:\\/?\\**|[\\t ]*)\\*([\\t ]{2,})/v);\n\n if (indentMatch) {\n // Check what comes after the indentation\n const afterIndent = line.slice(indentMatch[0].length);\n const indentAmount = indentMatch[1].length;\n\n // If this is a tag line with indentation, always report\n if (/^@\\w+/v.test(afterIndent)) {\n report('There must be no indentation.', null, {\n line: getLineNumber(lines, lineIndex),\n });\n return;\n }\n\n // If we haven't seen any content yet (main description first line) and there's content, report\n if (!hasSeenContent && afterIndent.trim().length > 0) {\n report('There must be no indentation.', null, {\n line: getLineNumber(lines, lineIndex),\n });\n return;\n }\n\n // For continuation lines, check consistency\n if (hasSeenContent && afterIndent.trim().length > 0) {\n if (currentSectionIndent === null) {\n // First indented line in this section, set the indent level\n currentSectionIndent = indentAmount;\n } else if (indentAmount < currentSectionIndent) {\n // Indentation is less than the established level (inconsistent)\n report('There must be no indentation.', null, {\n line: getLineNumber(lines, lineIndex),\n });\n return;\n }\n }\n } else if (/^\\s*\\*\\s+\\S/v.test(line)) {\n // No indentation on this line, reset section indent tracking\n // (unless it's just whitespace or a closing comment)\n currentSectionIndent = null;\n }\n\n // Track if we've seen any content (non-whitespace after the *)\n if (/^\\s*\\*\\s+\\S/v.test(line)) {\n hasSeenContent = true;\n }\n\n // Reset section indent when we encounter a tag\n if (/@\\w+/v.test(line)) {\n currentSectionIndent = null;\n }\n }\n } else {\n const reg = /^(?:\\/?\\**|[ \\t]*)\\*[ \\t]{2}/gmv;\n if (reg.test(text)) {\n const lineBreaks = text.slice(0, reg.lastIndex).match(/\\n/gv) || [];\n report('There must be no indentation.', null, {\n line: lineBreaks.length,\n });\n }\n }\n}, {\n iterateAllJsdocs: true,\n meta: {\n docs: {\n description: 'Reports invalid padding inside JSDoc blocks.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-indentation.md#repos-sticky-header',\n },\n schema: [\n {\n additionalProperties: false,\n properties: {\n allowIndentedSections: {\n description: 'Allows indentation of nested sections on subsequent lines (like bullet lists)',\n type: 'boolean',\n },\n excludeTags: {\n description: `Array of tags (e.g., \\`['example', 'description']\\`) whose content will be\n\"hidden\" from the \\`check-indentation\\` rule. Defaults to \\`['example']\\`.\n\nBy default, the whole JSDoc block will be checked for invalid padding.\nThat would include \\`@example\\` blocks too, which can get in the way\nof adding full, readable examples of code without ending up with multiple\nlinting issues.\n\nWhen disabled (by passing \\`excludeTags: []\\` option), the following code *will*\nreport a padding issue:\n\n\\`\\`\\`js\n/**\n * @example\n * anArray.filter((a) => {\n * return a.b;\n * });\n */\n\\`\\`\\``,\n items: {\n pattern: '^\\\\S+$',\n type: 'string',\n },\n type: 'array',\n },\n },\n type: 'object',\n },\n ],\n type: 'layout',\n },\n});\n"],"mappings":"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","ignoreList":[]}