Skip to content

Commit 604e5fc

Browse files
authored
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
1 parent 69214c0 commit 604e5fc

9 files changed

+721
-7
lines changed

src/services/jsDoc.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,23 @@ namespace ts.JsDoc {
9393
const parts: SymbolDisplayPart[][] = [];
9494
forEachUnique(declarations, declaration => {
9595
for (const jsdoc of getCommentHavingNodes(declaration)) {
96+
const inheritDoc = isJSDoc(jsdoc) && jsdoc.tags && find(jsdoc.tags, t => t.kind === SyntaxKind.JSDocTag && (t.tagName.escapedText === "inheritDoc" || t.tagName.escapedText === "inheritdoc"));
9697
// skip comments containing @typedefs since they're not associated with particular declarations
9798
// Exceptions:
9899
// - @typedefs are themselves declarations with associated comments
99100
// - @param or @return indicate that the author thinks of it as a 'local' @typedef that's part of the function documentation
100-
if (jsdoc.comment === undefined
101+
if (jsdoc.comment === undefined && !inheritDoc
101102
|| isJSDoc(jsdoc)
102103
&& declaration.kind !== SyntaxKind.JSDocTypedefTag && declaration.kind !== SyntaxKind.JSDocCallbackTag
103104
&& jsdoc.tags
104105
&& jsdoc.tags.some(t => t.kind === SyntaxKind.JSDocTypedefTag || t.kind === SyntaxKind.JSDocCallbackTag)
105106
&& !jsdoc.tags.some(t => t.kind === SyntaxKind.JSDocParameterTag || t.kind === SyntaxKind.JSDocReturnTag)) {
106107
continue;
107108
}
108-
const newparts = getDisplayPartsFromComment(jsdoc.comment, checker);
109+
let newparts = jsdoc.comment ? getDisplayPartsFromComment(jsdoc.comment, checker) : [];
110+
if (inheritDoc && inheritDoc.comment) {
111+
newparts = newparts.concat(getDisplayPartsFromComment(inheritDoc.comment, checker));
112+
}
109113
if (!contains(parts, newparts, isIdenticalListOfDisplayParts)) {
110114
parts.push(newparts);
111115
}

src/services/services.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ namespace ts {
592592
* @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`.
593593
*/
594594
function hasJSDocInheritDocTag(node: Node) {
595-
return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc");
595+
return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc" || tag.tagName.text === "inheritdoc");
596596
}
597597

598598
function getJsDocTagsOfDeclarations(declarations: Declaration[] | undefined, checker: TypeChecker | undefined): JSDocTagInfo[] {
@@ -643,13 +643,15 @@ namespace ts {
643643
}
644644

645645
function findBaseOfDeclaration<T>(checker: TypeChecker, declaration: Declaration, cb: (symbol: Symbol) => T[] | undefined): T[] | undefined {
646-
if (hasStaticModifier(declaration)) return;
647-
648646
const classOrInterfaceDeclaration = declaration.parent?.kind === SyntaxKind.Constructor ? declaration.parent.parent : declaration.parent;
649647
if (!classOrInterfaceDeclaration) return;
650648

649+
const isStaticMember = hasStaticModifier(declaration);
651650
return firstDefined(getAllSuperTypeNodes(classOrInterfaceDeclaration), superTypeNode => {
652-
const symbol = checker.getPropertyOfType(checker.getTypeAtLocation(superTypeNode), declaration.symbol.name);
651+
const baseType = checker.getTypeAtLocation(superTypeNode);
652+
const symbol = isStaticMember
653+
? find(checker.getExportsOfModule(baseType.symbol), s => s.escapedName === declaration.symbol.name)
654+
: checker.getPropertyOfType(baseType, declaration.symbol.name);
653655
return symbol ? cb(symbol) : undefined;
654656
});
655657
}

0 commit comments

Comments
 (0)