From 18c4661f460171f5fd4b6c1b32bde4de2535bee9 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 27 Oct 2024 13:46:30 -0600 Subject: [PATCH] Consider overload position when discovering comments Resolves #2755 --- CHANGELOG.md | 1 + src/lib/converter/comments/discovery.ts | 28 +++++++++++++++++++++---- src/test/converter2/issues/gh2755.ts | 27 ++++++++++++++++++++++++ src/test/issues.c2.test.ts | 12 +++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 src/test/converter2/issues/gh2755.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 583bfc061..5b7583b75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix support for ESM config files with Node 23, #2752. - Fix type errors when using `"module": "ESNext"` and importing TypeDoc, #2747. +- Inherited comments on overloaded methods now consider the overload position when inheriting a comment, #2755. ## v0.26.10 (2024-10-16) diff --git a/src/lib/converter/comments/discovery.ts b/src/lib/converter/comments/discovery.ts index f5216f553..2fb38d92b 100644 --- a/src/lib/converter/comments/discovery.ts +++ b/src/lib/converter/comments/discovery.ts @@ -3,7 +3,7 @@ import { ReflectionKind } from "../../models"; import { assertNever, type Logger } from "../../utils"; import { CommentStyle } from "../../utils/options/declaration"; import { nicePath } from "../../utils/paths"; -import { ok } from "assert"; +import assert, { ok } from "assert"; import { filter, firstDefined } from "../../utils/array"; const variablePropertyKinds = [ @@ -499,13 +499,33 @@ function declarationToCommentNodes( }, ]; + let overloadIndex: number | undefined = undefined; + if (ts.isMethodDeclaration(node)) { + const symbol = checker.getSymbolAtLocation(node.name || node); + if (symbol) { + overloadIndex = symbol.declarations + ?.filter((d) => d.kind === node.kind) + .indexOf(node); + assert(overloadIndex !== -1, "Should always find declaration"); + } + } + const seenSymbols = new Set(); const bases = findBaseOfDeclaration(checker, node, (symbol) => { if (!seenSymbols.has(symbol)) { seenSymbols.add(symbol); - return symbol.declarations?.map( - (node) => declarationToCommentNodeIgnoringParents(node) || node, - ); + if (overloadIndex === undefined) { + return symbol.declarations?.map( + (node) => + declarationToCommentNodeIgnoringParents(node) || node, + ); + } else if (symbol.declarations?.[overloadIndex]) { + const parentSigNode = symbol.declarations[overloadIndex]; + return [ + declarationToCommentNodeIgnoringParents(parentSigNode) || + parentSigNode, + ]; + } } }); diff --git a/src/test/converter2/issues/gh2755.ts b/src/test/converter2/issues/gh2755.ts new file mode 100644 index 000000000..c0f35bceb --- /dev/null +++ b/src/test/converter2/issues/gh2755.ts @@ -0,0 +1,27 @@ +export interface Test { + /** A */ + method(a: string): boolean; + + /** B */ + method(a: number): number; +} + +export class Class implements Test { + method(a: string): boolean; + method(a: number): number; + method(a: string | number): number | boolean { + if (typeof a === "string") { + return false; + } + return 1; + } +} + +export interface MultiCallSignature { + /** A */ + (): string; + /** B */ + (x: string): string; +} + +export const Callable: MultiCallSignature = () => ""; diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index 648e6c06f..c169c8996 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -1798,4 +1798,16 @@ describe("Issue Tests", () => { { display: "Node", target: "https://typescriptlang.org" }, ]); }); + + it("#2755 handles multiple signature when discovering inherited comments", () => { + const project = convert(); + equal(getSigComment(project, "Test.method", 0), "A"); + equal(getSigComment(project, "Test.method", 1), "B"); + + equal(getSigComment(project, "Class.method", 0), "A"); + equal(getSigComment(project, "Class.method", 1), "B"); + + equal(getSigComment(project, "Callable", 0), "A"); + equal(getSigComment(project, "Callable", 1), "B"); + }); });