Add JSDoc's @inheritDoc Support for Static Class Members for TypeScript (#46719)

* Add JSDoc's @inheritDoc Support for Static Class Members for TypeScript

* use public api

* fix

* add tests

* simplify implementation

* extract comments from inherticDoc
This commit is contained in:
Zzzen
2022-05-10 06:57:27 +08:00
committed by GitHub
parent 69214c0e56
commit 604e5fca55
9 changed files with 721 additions and 7 deletions

View File

@@ -93,11 +93,12 @@ namespace ts.JsDoc {
const parts: SymbolDisplayPart[][] = [];
forEachUnique(declarations, declaration => {
for (const jsdoc of getCommentHavingNodes(declaration)) {
const inheritDoc = isJSDoc(jsdoc) && jsdoc.tags && find(jsdoc.tags, t => t.kind === SyntaxKind.JSDocTag && (t.tagName.escapedText === "inheritDoc" || t.tagName.escapedText === "inheritdoc"));
// skip comments containing @typedefs since they're not associated with particular declarations
// Exceptions:
// - @typedefs are themselves declarations with associated comments
// - @param or @return indicate that the author thinks of it as a 'local' @typedef that's part of the function documentation
if (jsdoc.comment === undefined
if (jsdoc.comment === undefined && !inheritDoc
|| isJSDoc(jsdoc)
&& declaration.kind !== SyntaxKind.JSDocTypedefTag && declaration.kind !== SyntaxKind.JSDocCallbackTag
&& jsdoc.tags
@@ -105,7 +106,10 @@ namespace ts.JsDoc {
&& !jsdoc.tags.some(t => t.kind === SyntaxKind.JSDocParameterTag || t.kind === SyntaxKind.JSDocReturnTag)) {
continue;
}
const newparts = getDisplayPartsFromComment(jsdoc.comment, checker);
let newparts = jsdoc.comment ? getDisplayPartsFromComment(jsdoc.comment, checker) : [];
if (inheritDoc && inheritDoc.comment) {
newparts = newparts.concat(getDisplayPartsFromComment(inheritDoc.comment, checker));
}
if (!contains(parts, newparts, isIdenticalListOfDisplayParts)) {
parts.push(newparts);
}

View File

@@ -592,7 +592,7 @@ namespace ts {
* @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`.
*/
function hasJSDocInheritDocTag(node: Node) {
return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc");
return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc" || tag.tagName.text === "inheritdoc");
}
function getJsDocTagsOfDeclarations(declarations: Declaration[] | undefined, checker: TypeChecker | undefined): JSDocTagInfo[] {
@@ -643,13 +643,15 @@ namespace ts {
}
function findBaseOfDeclaration<T>(checker: TypeChecker, declaration: Declaration, cb: (symbol: Symbol) => T[] | undefined): T[] | undefined {
if (hasStaticModifier(declaration)) return;
const classOrInterfaceDeclaration = declaration.parent?.kind === SyntaxKind.Constructor ? declaration.parent.parent : declaration.parent;
if (!classOrInterfaceDeclaration) return;
const isStaticMember = hasStaticModifier(declaration);
return firstDefined(getAllSuperTypeNodes(classOrInterfaceDeclaration), superTypeNode => {
const symbol = checker.getPropertyOfType(checker.getTypeAtLocation(superTypeNode), declaration.symbol.name);
const baseType = checker.getTypeAtLocation(superTypeNode);
const symbol = isStaticMember
? find(checker.getExportsOfModule(baseType.symbol), s => s.escapedName === declaration.symbol.name)
: checker.getPropertyOfType(baseType, declaration.symbol.name);
return symbol ? cb(symbol) : undefined;
});
}