(lines: Array<string>)
| 1096 | } |
| 1097 | |
| 1098 | function parseDescriptionContent(lines: Array<string>): ParsedContentResult { |
| 1099 | const diagnostics: Array<JSDocDiagnostic> = [] |
| 1100 | const sections: Record<StandardHeading, string | null> = { |
| 1101 | "**When to use**": null, |
| 1102 | "**Details**": null, |
| 1103 | "**Gotchas**": null |
| 1104 | } |
| 1105 | const examples: Array<ParsedExample> = [] |
| 1106 | const exampleTitles = new Set<string>() |
| 1107 | let index = 0 |
| 1108 | let currentSectionOrder = -1 |
| 1109 | let examplesStarted = false |
| 1110 | |
| 1111 | while (index < lines.length && lines[index].trim() !== "" && !isHeadingLine(lines[index])) { |
| 1112 | if (isForbiddenMarkdownHeading(lines[index], false)) { |
| 1113 | diagnostics.push(diagnostic("invalid-heading", "Markdown headings are not allowed in JSDoc descriptions")) |
| 1114 | } |
| 1115 | index++ |
| 1116 | } |
| 1117 | |
| 1118 | const shortLines = lines.slice(0, index) |
| 1119 | if (shortLines.length === 0 || joinBody(shortLines).trim() === "") { |
| 1120 | diagnostics.push(diagnostic("missing-description", "JSDoc must include a short description")) |
| 1121 | } |
| 1122 | if (index < lines.length && lines[index].trim() === "") { |
| 1123 | const next = lines[index + 1] |
| 1124 | if (next !== undefined && !isHeadingLine(next)) { |
| 1125 | diagnostics.push(diagnostic("multiple-description-paragraphs", "JSDoc short description must be one paragraph")) |
| 1126 | } |
| 1127 | } |
| 1128 | |
| 1129 | while (index < lines.length) { |
| 1130 | if (lines[index].trim() !== "") { |
| 1131 | diagnostics.push(diagnostic("invalid-spacing", "JSDoc sections must be separated by exactly one blank line")) |
| 1132 | break |
| 1133 | } |
| 1134 | if (lines[index + 1]?.trim() === "") { |
| 1135 | diagnostics.push(diagnostic("invalid-spacing", "JSDoc sections must be separated by exactly one blank line")) |
| 1136 | while (lines[index + 1]?.trim() === "") index++ |
| 1137 | } |
| 1138 | index++ |
| 1139 | if (index >= lines.length) { |
| 1140 | break |
| 1141 | } |
| 1142 | |
| 1143 | const line = lines[index].trim() |
| 1144 | if (line.startsWith("**Example**")) { |
| 1145 | examplesStarted = true |
| 1146 | const parsed = parseExample(lines, index) |
| 1147 | diagnostics.push(...parsed.diagnostics) |
| 1148 | if (parsed.example !== undefined) { |
| 1149 | const key = parsed.example.title.trim().toLowerCase() |
| 1150 | if (exampleTitles.has(key)) { |
| 1151 | diagnostics.push(diagnostic("duplicate-example", `Duplicate example title: ${parsed.example.title.trim()}`)) |
| 1152 | } |
| 1153 | exampleTitles.add(key) |
| 1154 | examples.push(parsed.example) |
| 1155 | } |
no test coverage detected