Skip to content

Commit 547fe42

Browse files
Fix accessing name on jsdoc link for invalid names (#64032)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
1 parent 0cfafa9 commit 547fe42

3 files changed

Lines changed: 27 additions & 0 deletions

File tree

packages/typescript/src/api/node/node.generated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ export class RemoteNode extends RemoteNodeBase implements Node {
369369
}
370370

371371
private getChildAtOrder(order: number): RemoteNode | RemoteNodeList | undefined {
372+
if (!this.hasChildren()) return undefined;
372373
const mask = this.childMask;
373374
if (!(mask & (1 << order))) {
374375
// Property is not present

packages/typescript/test/sync/ast.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
ExpressionStatement,
33
Identifier,
4+
JSDoc,
45
Node,
56
NodeArray,
67
SourceFile,
@@ -12,6 +13,7 @@ import {
1213
isClassDeclaration,
1314
isImportDeclaration,
1415
isInterfaceDeclaration,
16+
isJSDocLink,
1517
isNamedImports,
1618
isValidTypeOnlyAliasUseSite,
1719
SyntaxKind,
@@ -579,6 +581,29 @@ function getRemoteSourceFile(api: API, configPath: string, filePath: string) {
579581
}
580582

581583
describe("RemoteNode + cloneNode", () => {
584+
test("does not read a sibling as an invalid JSDoc link name", () => {
585+
const api = spawnAPI({
586+
"/tsconfig.json": "{}",
587+
"/src/index.ts": `/**
588+
* {@link #toggled} property
589+
*/
590+
export const x = 1;`,
591+
});
592+
try {
593+
const sf = getRemoteSourceFile(api, "/tsconfig.json", "/src/index.ts");
594+
const jsDoc = sf.statements[0].jsDoc?.[0] as JSDoc | undefined;
595+
assert.ok(jsDoc?.kind === SyntaxKind.JSDoc);
596+
const comment = jsDoc.comment;
597+
assert.ok(typeof comment !== "string");
598+
const link = comment?.[1];
599+
assert.ok(link && isJSDocLink(link));
600+
assert.strictEqual(link.name, undefined);
601+
}
602+
finally {
603+
api.close();
604+
}
605+
});
606+
582607
test("uses distinct nodes for expression and type heritage", () => {
583608
const api = spawnAPI({
584609
"/tsconfig.json": "{}",

tools/scripts/tsc/generate-encoder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,7 @@ function emitRemoteNodeClassOpen(w: CodeWriter) {
18061806
w.write(` }`);
18071807
w.write(``);
18081808
w.write(` private getChildAtOrder(order: number): RemoteNode | RemoteNodeList | undefined {`);
1809+
w.write(` if (!this.hasChildren()) return undefined;`);
18091810
w.write(` const mask = this.childMask;`);
18101811
w.write(` if (!(mask & (1 << order))) {`);
18111812
w.write(` // Property is not present`);

0 commit comments

Comments
 (0)