Skip to content

Commit e6b347a

Browse files
authored
Merge pull request #32138 from microsoft/jsdoc-match-backticks
Jsdoc: allow backticks to escape `@`
2 parents 9832899 + 2362dd4 commit e6b347a

File tree

5 files changed

+129
-2
lines changed

5 files changed

+129
-2
lines changed

src/compiler/parser.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6431,6 +6431,7 @@ namespace ts {
64316431
BeginningOfLine,
64326432
SawAsterisk,
64336433
SavingComments,
6434+
SavingBackticks, // NOTE: Only used when parsing tag comments
64346435
}
64356436

64366437
const enum PropertyLikeParse {
@@ -6691,18 +6692,23 @@ namespace ts {
66916692
case SyntaxKind.NewLineTrivia:
66926693
if (state >= JSDocState.SawAsterisk) {
66936694
state = JSDocState.BeginningOfLine;
6695+
// don't use pushComment here because we want to keep the margin unchanged
66946696
comments.push(scanner.getTokenText());
66956697
}
66966698
indent = 0;
66976699
break;
66986700
case SyntaxKind.AtToken:
6701+
if (state === JSDocState.SavingBackticks) {
6702+
comments.push(scanner.getTokenText());
6703+
break;
6704+
}
66996705
scanner.setTextPos(scanner.getTextPos() - 1);
67006706
// falls through
67016707
case SyntaxKind.EndOfFileToken:
67026708
// Done
67036709
break loop;
67046710
case SyntaxKind.WhitespaceTrivia:
6705-
if (state === JSDocState.SavingComments) {
6711+
if (state === JSDocState.SavingComments || state === JSDocState.SavingBackticks) {
67066712
pushComment(scanner.getTokenText());
67076713
}
67086714
else {
@@ -6724,6 +6730,15 @@ namespace ts {
67246730
}
67256731
pushComment(scanner.getTokenText());
67266732
break;
6733+
case SyntaxKind.BacktickToken:
6734+
if (state === JSDocState.SavingBackticks) {
6735+
state = JSDocState.SavingComments;
6736+
}
6737+
else {
6738+
state = JSDocState.SavingBackticks;
6739+
}
6740+
pushComment(scanner.getTokenText());
6741+
break;
67276742
case SyntaxKind.AsteriskToken:
67286743
if (state === JSDocState.BeginningOfLine) {
67296744
// leading asterisks start recording on the *next* (non-whitespace) token
@@ -6734,7 +6749,9 @@ namespace ts {
67346749
// record the * as a comment
67356750
// falls through
67366751
default:
6737-
state = JSDocState.SavingComments; // leading identifiers start recording as well
6752+
if (state !== JSDocState.SavingBackticks) {
6753+
state = JSDocState.SavingComments; // leading identifiers start recording as well
6754+
}
67386755
pushComment(scanner.getTokenText());
67396756
break;
67406757
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/conformance/jsdoc/jsdocParseMatchingBackticks.js ===
2+
/**
3+
* `@param` initial at-param is OK in title comment
4+
* @param {string} x hi there `@param`
5+
* @param {string} y hi there `@ * param
6+
* this is the margin
7+
* so we'll drop everything before it
8+
`@param` @param {string} z hello???
9+
* `@param` @param {string} alpha hello???
10+
* `@ * param` @param {string} beta hello???
11+
* @param {string} gamma
12+
*/
13+
export function f(x, y, z, alpha, beta, gamma) {
14+
>f : Symbol(f, Decl(jsdocParseMatchingBackticks.js, 0, 0))
15+
>x : Symbol(x, Decl(jsdocParseMatchingBackticks.js, 11, 18))
16+
>y : Symbol(y, Decl(jsdocParseMatchingBackticks.js, 11, 20))
17+
>z : Symbol(z, Decl(jsdocParseMatchingBackticks.js, 11, 23))
18+
>alpha : Symbol(alpha, Decl(jsdocParseMatchingBackticks.js, 11, 26))
19+
>beta : Symbol(beta, Decl(jsdocParseMatchingBackticks.js, 11, 33))
20+
>gamma : Symbol(gamma, Decl(jsdocParseMatchingBackticks.js, 11, 39))
21+
22+
return x + y + z + alpha + beta + gamma
23+
>x : Symbol(x, Decl(jsdocParseMatchingBackticks.js, 11, 18))
24+
>y : Symbol(y, Decl(jsdocParseMatchingBackticks.js, 11, 20))
25+
>z : Symbol(z, Decl(jsdocParseMatchingBackticks.js, 11, 23))
26+
>alpha : Symbol(alpha, Decl(jsdocParseMatchingBackticks.js, 11, 26))
27+
>beta : Symbol(beta, Decl(jsdocParseMatchingBackticks.js, 11, 33))
28+
>gamma : Symbol(gamma, Decl(jsdocParseMatchingBackticks.js, 11, 39))
29+
}
30+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/conformance/jsdoc/jsdocParseMatchingBackticks.js ===
2+
/**
3+
* `@param` initial at-param is OK in title comment
4+
* @param {string} x hi there `@param`
5+
* @param {string} y hi there `@ * param
6+
* this is the margin
7+
* so we'll drop everything before it
8+
`@param` @param {string} z hello???
9+
* `@param` @param {string} alpha hello???
10+
* `@ * param` @param {string} beta hello???
11+
* @param {string} gamma
12+
*/
13+
export function f(x, y, z, alpha, beta, gamma) {
14+
>f : (x: string, y: string, z: string, alpha: string, beta: string, gamma: string) => string
15+
>x : string
16+
>y : string
17+
>z : string
18+
>alpha : string
19+
>beta : string
20+
>gamma : string
21+
22+
return x + y + z + alpha + beta + gamma
23+
>x + y + z + alpha + beta + gamma : string
24+
>x + y + z + alpha + beta : string
25+
>x + y + z + alpha : string
26+
>x + y + z : string
27+
>x + y : string
28+
>x : string
29+
>y : string
30+
>z : string
31+
>alpha : string
32+
>beta : string
33+
>gamma : string
34+
}
35+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @noEmit: true
2+
// @allowJs: true
3+
// @checkJs: true
4+
// @strict: true
5+
// @Filename: jsdocParseMatchingBackticks.js
6+
7+
/**
8+
* `@param` initial at-param is OK in title comment
9+
* @param {string} x hi there `@param`
10+
* @param {string} y hi there `@ * param
11+
* this is the margin
12+
* so we'll drop everything before it
13+
`@param` @param {string} z hello???
14+
* `@param` @param {string} alpha hello???
15+
* `@ * param` @param {string} beta hello???
16+
* @param {string} gamma
17+
*/
18+
export function f(x, y, z, alpha, beta, gamma) {
19+
return x + y + z + alpha + beta + gamma
20+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
///<reference path="fourslash.ts" />
2+
3+
// @noEmit: true
4+
// @allowJs: true
5+
// @checkJs: true
6+
// @strict: true
7+
// @Filename: jsdocParseMatchingBackticks.js
8+
9+
/////**
10+
//// * `@param` initial at-param is OK in title comment
11+
//// * @param {string} x hi there `@param`
12+
//// * @param {string} y hi there `@ * param
13+
//// * this is the margin
14+
//// */
15+
////export function f(x, y) {
16+
//// return x/*x*/ + y/*y*/
17+
////}
18+
////f/*f*/
19+
20+
goTo.marker("f");
21+
verify.quickInfoIs("function f(x: string, y: string): string", "`@param` initial at-param is OK in title comment");
22+
goTo.marker("x");
23+
verify.quickInfoIs("(parameter) x: string", "hi there `@param`");
24+
goTo.marker("y");
25+
verify.quickInfoIs("(parameter) y: string", "hi there `@ * param\nthis is the margin");

0 commit comments

Comments
 (0)