Files
Markus Ecker b6f206dde0 Autogenerate reference docs (#525)
* automate doc generation

* write files

* Actually write files

* update docs (autogenerated)

* remove body (obsolete)

* fix build errors

* clean up

* test

* feat(docs): add pre commit hook with husky

---------

Co-authored-by: Ariel Weinberger <weinberger.ariel@gmail.com>
2024-08-06 12:35:36 +02:00

99 lines
2.9 KiB
TypeScript

import * as ts from "typescript";
export class Comments {
static getCleanedCommentsForNode(node: ts.Node, sourceFile: ts.SourceFile): string {
const fullText = sourceFile.getFullText();
const commentRanges = ts.getLeadingCommentRanges(fullText, node.getFullStart());
if (!commentRanges) return "";
return commentRanges
.map((comment) => {
let commentText = fullText.substring(comment.pos, comment.end);
commentText = Comments.removeCommentSyntax(commentText);
// for now, remove @default annotations
commentText = commentText
.split("\n")
.filter((line) => !line.includes("@default"))
.join("\n");
return commentText;
})
.join("\n")
.trim();
}
static getDefaultValueForNode(node: ts.Node, sourceFile: ts.SourceFile): string | undefined {
const fullText = sourceFile.getFullText();
const commentRanges = ts.getLeadingCommentRanges(fullText, node.getFullStart());
if (!commentRanges) return "";
let defaultValue: string | undefined = undefined;
for (const comment of commentRanges) {
let commentText = fullText.substring(comment.pos, comment.end);
commentText = Comments.removeCommentSyntax(commentText);
for (const line of commentText.split("\n")) {
if (line.includes("@default")) {
defaultValue = line.split("@default")[1].trim();
break;
}
}
if (defaultValue !== undefined) break;
}
return defaultValue;
}
static removeCommentSyntax(commentText: string): string {
return commentText
.replace(/\/\*\*|\*\/|\*|\/\* ?/gm, "")
.replace(/^ /gm, "")
.trim();
}
static getFirstCommentBlock(sourceFile: ts.SourceFile): string | null {
for (const statement of sourceFile.statements) {
const comments = Comments.getCleanedCommentsForNode(statement, sourceFile);
if (comments) return comments;
}
return null;
}
static getTsDocCommentsForFunction(node: ts.Node, sourceFile: ts.SourceFile) {
const params: Record<string, string> = {};
const trivia = ts.getLeadingCommentRanges(sourceFile.text, node.getFullStart()) || [];
let comment = "";
for (const range of trivia) {
const commentText = Comments.removeCommentSyntax(
sourceFile.text.substring(range.pos, range.end),
);
const lines = commentText.split("\n").map((line) => line.trim());
if (lines.length && !lines[0].startsWith("@param")) {
comment = lines[0];
}
lines.forEach((line) => {
if (line.startsWith("@param")) {
const parts = line.split(/\s+/);
if (parts.length >= 3) {
const paramName = parts[1];
const description = parts.slice(2).join(" ");
params[paramName] = description.trim();
}
}
});
}
return { comment, params };
}
}