diff --git a/packages/typescript/src/api/node/node.generated.ts b/packages/typescript/src/api/node/node.generated.ts index 035c8d308e737..a601319e3d9b0 100644 --- a/packages/typescript/src/api/node/node.generated.ts +++ b/packages/typescript/src/api/node/node.generated.ts @@ -369,6 +369,7 @@ export class RemoteNode extends RemoteNodeBase implements Node { } private getChildAtOrder(order: number): RemoteNode | RemoteNodeList | undefined { + if (!this.hasChildren()) return undefined; const mask = this.childMask; if (!(mask & (1 << order))) { // Property is not present diff --git a/packages/typescript/test/sync/ast.test.ts b/packages/typescript/test/sync/ast.test.ts index 7754f97972a2c..254e8d6c63d31 100644 --- a/packages/typescript/test/sync/ast.test.ts +++ b/packages/typescript/test/sync/ast.test.ts @@ -1,6 +1,7 @@ import type { ExpressionStatement, Identifier, + JSDoc, Node, NodeArray, SourceFile, @@ -12,6 +13,7 @@ import { isClassDeclaration, isImportDeclaration, isInterfaceDeclaration, + isJSDocLink, isNamedImports, isValidTypeOnlyAliasUseSite, SyntaxKind, @@ -579,6 +581,29 @@ function getRemoteSourceFile(api: API, configPath: string, filePath: string) { } describe("RemoteNode + cloneNode", () => { + test("does not read a sibling as an invalid JSDoc link name", () => { + const api = spawnAPI({ + "/tsconfig.json": "{}", + "/src/index.ts": `/** + * {@link #toggled} property + */ +export const x = 1;`, + }); + try { + const sf = getRemoteSourceFile(api, "/tsconfig.json", "/src/index.ts"); + const jsDoc = sf.statements[0].jsDoc?.[0] as JSDoc | undefined; + assert.ok(jsDoc?.kind === SyntaxKind.JSDoc); + const comment = jsDoc.comment; + assert.ok(typeof comment !== "string"); + const link = comment?.[1]; + assert.ok(link && isJSDocLink(link)); + assert.strictEqual(link.name, undefined); + } + finally { + api.close(); + } + }); + test("uses distinct nodes for expression and type heritage", () => { const api = spawnAPI({ "/tsconfig.json": "{}", diff --git a/tools/scripts/tsc/generate-encoder.ts b/tools/scripts/tsc/generate-encoder.ts index fc1a67022a39d..239ab7021b193 100644 --- a/tools/scripts/tsc/generate-encoder.ts +++ b/tools/scripts/tsc/generate-encoder.ts @@ -1806,6 +1806,7 @@ function emitRemoteNodeClassOpen(w: CodeWriter) { w.write(` }`); w.write(``); w.write(` private getChildAtOrder(order: number): RemoteNode | RemoteNodeList | undefined {`); + w.write(` if (!this.hasChildren()) return undefined;`); w.write(` const mask = this.childMask;`); w.write(` if (!(mask & (1 << order))) {`); w.write(` // Property is not present`);