in src/docs.ts [85:167]
function parseDocParts(comments: string | undefined, tags: ts.JSDocTagInfo[]): DocsParsingResult {
const diagnostics = new Array<string>();
const docs: spec.Docs = {};
const hints: TypeSystemHints = {};
[docs.summary, docs.remarks] = splitSummary(comments);
const tagNames = new Map<string, string | undefined>();
for (const tag of tags) {
// 'param' gets parsed as a tag and as a comment for a method
// 'jsii' is internal-only and shouldn't surface in the API doc
if (tag.name !== DocTag.PARAM && tag.name !== DocTag.JSII) {
tagNames.set(tag.name, tag.text && ts.displayPartsToString(tag.text));
}
}
function eatTag(...names: string[]): string | undefined {
for (const name of names) {
if (tagNames.has(name)) {
const ret = tagNames.get(name);
tagNames.delete(name);
return ret ?? '';
}
}
return undefined;
}
if (eatTag(DocTag.STRUCT) != null) {
hints.struct = true;
}
docs.default = eatTag(DocTag.DEFAULT, DocTag.DEFAULT_VALUE);
docs.deprecated = eatTag(DocTag.DEPRECATED);
docs.example = eatTag(DocTag.EXAMPLE);
docs.returns = eatTag(DocTag.RETURNS, DocTag.RETURN);
docs.see = eatTag(DocTag.SEE);
docs.subclassable = eatTag(DocTag.SUBCLASSABLE) !== undefined ? true : undefined;
docs.stability = parseStability(eatTag(DocTag.STABILITY), diagnostics);
// @experimental is a shorthand for '@stability experimental', same for '@stable'
const experimental = eatTag(DocTag.EXPERIMENTAL) !== undefined;
const stable = eatTag(DocTag.STABLE) !== undefined;
// Can't combine them
if (countBools(docs.stability !== undefined, experimental, stable) > 1) {
diagnostics.push('Use only one of @stability, @experimental or @stable');
}
if (experimental) {
docs.stability = spec.Stability.Experimental;
}
if (stable) {
docs.stability = spec.Stability.Stable;
}
// Can combine '@stability deprecated' with '@deprecated <reason>'
if (docs.deprecated !== undefined) {
if (docs.stability !== undefined && docs.stability !== spec.Stability.Deprecated) {
diagnostics.push("@deprecated tag requires '@stability deprecated' or no @stability at all.");
}
docs.stability = spec.Stability.Deprecated;
}
if (docs.example?.includes('```')) {
// This is currently what the JSDoc standard expects, and VSCode highlights it in
// this way as well. TSDoc disagrees and says that examples start in text mode
// which I tend to agree with, but that hasn't become a widely used standard yet.
//
// So we conform to existing reality.
diagnostics.push('@example must be code only, no code block fences allowed.');
}
if (docs.deprecated?.trim() === '') {
diagnostics.push('@deprecated tag needs a reason and/or suggested alternatives.');
}
if (tagNames.size > 0) {
docs.custom = {};
for (const [key, value] of tagNames.entries()) {
docs.custom[key] = value ?? 'true'; // Key must have a value or it will be stripped from the assembly
}
}
return { docs, diagnostics, hints };
}