Skip to content

Commit 4eae150

Browse files
authored
fix(50303): Using @linkcode in combination with private methods causes TS1003 in JavaScript files. (#56338)
1 parent c250aed commit 4eae150

File tree

4 files changed

+91
-12
lines changed

4 files changed

+91
-12
lines changed

src/compiler/parser.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9210,18 +9210,7 @@ namespace Parser {
92109210
}
92119211
nextTokenJSDoc(); // start at token after link, then skip any whitespace
92129212
skipWhitespace();
9213-
// parseEntityName logs an error for non-identifier, so create a MissingNode ourselves to avoid the error
9214-
const p2 = getNodePos();
9215-
let name: EntityName | JSDocMemberName | undefined = tokenIsIdentifierOrKeyword(token())
9216-
? parseEntityName(/*allowReservedWords*/ true)
9217-
: undefined;
9218-
if (name) {
9219-
while (token() === SyntaxKind.PrivateIdentifier) {
9220-
reScanHashToken(); // rescan #id as # id
9221-
nextTokenJSDoc(); // then skip the #
9222-
name = finishNode(factory.createJSDocMemberName(name, parseIdentifier()), p2);
9223-
}
9224-
}
9213+
const name = parseJSDocLinkName();
92259214
const text = [];
92269215
while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.NewLineTrivia && token() !== SyntaxKind.EndOfFileToken) {
92279216
text.push(scanner.getTokenText());
@@ -9233,6 +9222,24 @@ namespace Parser {
92339222
return finishNode(create(name, text.join("")), start, scanner.getTokenEnd());
92349223
}
92359224

9225+
function parseJSDocLinkName() {
9226+
if (tokenIsIdentifierOrKeyword(token())) {
9227+
const pos = getNodePos();
9228+
9229+
let name: EntityName | JSDocMemberName = parseIdentifierName();
9230+
while (parseOptional(SyntaxKind.DotToken)) {
9231+
name = finishNode(factory.createQualifiedName(name, token() === SyntaxKind.PrivateIdentifier ? createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false) : parseIdentifier()), pos);
9232+
}
9233+
while (token() === SyntaxKind.PrivateIdentifier) {
9234+
reScanHashToken();
9235+
nextTokenJSDoc();
9236+
name = finishNode(factory.createJSDocMemberName(name, parseIdentifier()), pos);
9237+
}
9238+
return name;
9239+
}
9240+
return undefined;
9241+
}
9242+
92369243
function parseJSDocLinkPrefix() {
92379244
skipWhitespaceOrAsterisk();
92389245
if (
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [tests/cases/conformance/jsdoc/jsdocLinkTag7.ts] ////
2+
3+
=== /a.js ===
4+
class Foo {
5+
>Foo : Symbol(Foo, Decl(a.js, 0, 0))
6+
7+
/**
8+
* {@linkcode this.a}
9+
* {@linkcode this.#c}
10+
*
11+
* {@link this.a}
12+
* {@link this.#c}
13+
*
14+
* {@linkplain this.a}
15+
* {@linkplain this.#c}
16+
*/
17+
a() { }
18+
>a : Symbol(Foo.a, Decl(a.js, 0, 11))
19+
20+
b() { }
21+
>b : Symbol(Foo.b, Decl(a.js, 11, 11))
22+
23+
#c() { }
24+
>#c : Symbol(Foo.#c, Decl(a.js, 12, 11))
25+
}
26+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [tests/cases/conformance/jsdoc/jsdocLinkTag7.ts] ////
2+
3+
=== /a.js ===
4+
class Foo {
5+
>Foo : Foo
6+
7+
/**
8+
* {@linkcode this.a}
9+
* {@linkcode this.#c}
10+
*
11+
* {@link this.a}
12+
* {@link this.#c}
13+
*
14+
* {@linkplain this.a}
15+
* {@linkplain this.#c}
16+
*/
17+
a() { }
18+
>a : () => void
19+
20+
b() { }
21+
>b : () => void
22+
23+
#c() { }
24+
>#c : () => void
25+
}
26+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @checkJs: true
2+
// @allowJs: true
3+
// @target: esnext
4+
// @noEmit: true
5+
// @filename: /a.js
6+
class Foo {
7+
/**
8+
* {@linkcode this.a}
9+
* {@linkcode this.#c}
10+
*
11+
* {@link this.a}
12+
* {@link this.#c}
13+
*
14+
* {@linkplain this.a}
15+
* {@linkplain this.#c}
16+
*/
17+
a() { }
18+
b() { }
19+
#c() { }
20+
}

0 commit comments

Comments
 (0)