Skip to content

Commit c4c6a83

Browse files
authored
Add @linkcode and @linkplain tags (#44208)
* Add @linkcode and @linkplain tags They are just like @link tags but request fixed-width and normal presentation, respectively. Fixes #43935 * revert JSDocComment -> JSDoc SyntaxKind rename * update API baselines * fix lint
1 parent fb5f855 commit c4c6a83

17 files changed

+1454
-307
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -39316,7 +39316,7 @@ namespace ts {
3931639316
return undefined;
3931739317
}
3931839318

39319-
const isJSDoc = findAncestor(name, or(isJSDocLink, isJSDocNameReference, isJSDocMemberName));
39319+
const isJSDoc = findAncestor(name, or(isJSDocLinkLike, isJSDocNameReference, isJSDocMemberName));
3932039320
const meaning = isJSDoc ? SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Value : SymbolFlags.Value;
3932139321
if (name.kind === SyntaxKind.Identifier) {
3932239322
if (isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) {

src/compiler/emitter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3785,7 +3785,7 @@ namespace ts {
37853785
emit(tagName);
37863786
}
37873787

3788-
function emitJSDocComment(comment: string | NodeArray<JSDocText | JSDocLink> | undefined) {
3788+
function emitJSDocComment(comment: string | NodeArray<JSDocComment> | undefined) {
37893789
const text = getTextOfJSDocComment(comment);
37903790
if (text) {
37913791
writeSpace();

src/compiler/factory/nodeFactory.ts

+63-29
Large diffs are not rendered by default.

src/compiler/factory/nodeTests.ts

+8
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,14 @@ namespace ts {
778778
return node.kind === SyntaxKind.JSDocLink;
779779
}
780780

781+
export function isJSDocLinkCode(node: Node): node is JSDocLinkCode {
782+
return node.kind === SyntaxKind.JSDocLinkCode;
783+
}
784+
785+
export function isJSDocLinkPlain(node: Node): node is JSDocLinkPlain {
786+
return node.kind === SyntaxKind.JSDocLinkPlain;
787+
}
788+
781789
export function isJSDocAllType(node: Node): node is JSDocAllType {
782790
return node.kind === SyntaxKind.JSDocAllType;
783791
}

src/compiler/parser.ts

+34-24
Original file line numberDiff line numberDiff line change
@@ -481,12 +481,12 @@ namespace ts {
481481
return visitNodes(cbNode, cbNodes, (node as JSDocFunctionType).parameters) ||
482482
visitNode(cbNode, (node as JSDocFunctionType).type);
483483
case SyntaxKind.JSDocComment:
484-
return (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined))
484+
return (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined))
485485
|| visitNodes(cbNode, cbNodes, (node as JSDoc).tags);
486486
case SyntaxKind.JSDocSeeTag:
487487
return visitNode(cbNode, (node as JSDocSeeTag).tagName) ||
488488
visitNode(cbNode, (node as JSDocSeeTag).name) ||
489-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
489+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
490490
case SyntaxKind.JSDocNameReference:
491491
return visitNode(cbNode, (node as JSDocNameReference).name);
492492
case SyntaxKind.JSDocMemberName:
@@ -498,54 +498,56 @@ namespace ts {
498498
((node as JSDocPropertyLikeTag).isNameFirst
499499
? visitNode(cbNode, (node as JSDocPropertyLikeTag).name) ||
500500
visitNode(cbNode, (node as JSDocPropertyLikeTag).typeExpression) ||
501-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined))
501+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined))
502502
: visitNode(cbNode, (node as JSDocPropertyLikeTag).typeExpression) ||
503503
visitNode(cbNode, (node as JSDocPropertyLikeTag).name)) ||
504-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
504+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
505505
case SyntaxKind.JSDocAuthorTag:
506506
return visitNode(cbNode, (node as JSDocTag).tagName) ||
507-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
507+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
508508
case SyntaxKind.JSDocImplementsTag:
509509
return visitNode(cbNode, (node as JSDocTag).tagName) ||
510510
visitNode(cbNode, (node as JSDocImplementsTag).class) ||
511-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
511+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
512512
case SyntaxKind.JSDocAugmentsTag:
513513
return visitNode(cbNode, (node as JSDocTag).tagName) ||
514514
visitNode(cbNode, (node as JSDocAugmentsTag).class) ||
515-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
515+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
516516
case SyntaxKind.JSDocTemplateTag:
517517
return visitNode(cbNode, (node as JSDocTag).tagName) ||
518518
visitNode(cbNode, (node as JSDocTemplateTag).constraint) ||
519519
visitNodes(cbNode, cbNodes, (node as JSDocTemplateTag).typeParameters) ||
520-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
520+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
521521
case SyntaxKind.JSDocTypedefTag:
522522
return visitNode(cbNode, (node as JSDocTag).tagName) ||
523523
((node as JSDocTypedefTag).typeExpression &&
524524
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression
525525
? visitNode(cbNode, (node as JSDocTypedefTag).typeExpression) ||
526526
visitNode(cbNode, (node as JSDocTypedefTag).fullName) ||
527-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined))
527+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined))
528528
: visitNode(cbNode, (node as JSDocTypedefTag).fullName) ||
529529
visitNode(cbNode, (node as JSDocTypedefTag).typeExpression)) ||
530-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
530+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
531531
case SyntaxKind.JSDocCallbackTag:
532532
return visitNode(cbNode, (node as JSDocTag).tagName) ||
533533
visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
534534
visitNode(cbNode, (node as JSDocCallbackTag).typeExpression) ||
535-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
535+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
536536
case SyntaxKind.JSDocReturnTag:
537537
case SyntaxKind.JSDocTypeTag:
538538
case SyntaxKind.JSDocThisTag:
539539
case SyntaxKind.JSDocEnumTag:
540540
return visitNode(cbNode, (node as JSDocTag).tagName) ||
541541
visitNode(cbNode, (node as JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag).typeExpression) ||
542-
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
542+
(typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
543543
case SyntaxKind.JSDocSignature:
544544
return forEach((node as JSDocSignature).typeParameters, cbNode) ||
545545
forEach((node as JSDocSignature).parameters, cbNode) ||
546546
visitNode(cbNode, (node as JSDocSignature).type);
547547
case SyntaxKind.JSDocLink:
548-
return visitNode(cbNode, (node as JSDocLink).name);
548+
case SyntaxKind.JSDocLinkCode:
549+
case SyntaxKind.JSDocLinkPlain:
550+
return visitNode(cbNode, (node as JSDocLink | JSDocLinkCode | JSDocLinkPlain).name);
549551
case SyntaxKind.JSDocTypeLiteral:
550552
return forEach((node as JSDocTypeLiteral).jsDocPropertyTags, cbNode);
551553
case SyntaxKind.JSDocTag:
@@ -556,7 +558,7 @@ namespace ts {
556558
case SyntaxKind.JSDocReadonlyTag:
557559
case SyntaxKind.JSDocDeprecatedTag:
558560
return visitNode(cbNode, (node as JSDocTag).tagName)
559-
|| (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocText | JSDocLink> | undefined));
561+
|| (typeof (node as JSDoc).comment === "string" ? undefined : visitNodes(cbNode, cbNodes, (node as JSDoc).comment as NodeArray<JSDocComment> | undefined));
560562
case SyntaxKind.PartiallyEmittedExpression:
561563
return visitNode(cbNode, (node as PartiallyEmittedExpression).expression);
562564
}
@@ -7425,7 +7427,7 @@ namespace ts {
74257427
let linkEnd: number;
74267428
let commentsPos: number | undefined;
74277429
let comments: string[] = [];
7428-
const parts: (JSDocLink | JSDocText)[] = [];
7430+
const parts: JSDocComment[] = [];
74297431

74307432
// + 3 for leading /**, - 5 in total for /** */
74317433
return scanner.scanRange(start + 3, length - 5, () => {
@@ -7681,10 +7683,10 @@ namespace ts {
76817683
return parseTagComments(margin, indentText.slice(margin));
76827684
}
76837685

7684-
function parseTagComments(indent: number, initialMargin?: string): string | NodeArray<JSDocText | JSDocLink> | undefined {
7686+
function parseTagComments(indent: number, initialMargin?: string): string | NodeArray<JSDocComment> | undefined {
76857687
const commentsPos = getNodePos();
76867688
let comments: string[] = [];
7687-
const parts: (JSDocLink | JSDocText)[] = [];
7689+
const parts: JSDocComment[] = [];
76887690
let linkEnd;
76897691
let state = JSDocState.BeginningOfLine;
76907692
let previousWhitespace = true;
@@ -7800,7 +7802,8 @@ namespace ts {
78007802
}
78017803

78027804
function parseJSDocLink(start: number) {
7803-
if (!tryParse(parseJSDocLinkPrefix)) {
7805+
const linkType = tryParse(parseJSDocLinkPrefix);
7806+
if (!linkType) {
78047807
return undefined;
78057808
}
78067809
nextTokenJSDoc(); // start at token after link, then skip any whitespace
@@ -7822,15 +7825,22 @@ namespace ts {
78227825
text.push(scanner.getTokenText());
78237826
nextTokenJSDoc();
78247827
}
7825-
return finishNode(factory.createJSDocLink(name, text.join("")), start, scanner.getTextPos());
7828+
const create = linkType === "link" ? factory.createJSDocLink
7829+
: linkType === "linkcode" ? factory.createJSDocLinkCode
7830+
: factory.createJSDocLinkPlain;
7831+
return finishNode(create(name, text.join("")), start, scanner.getTextPos());
78267832
}
78277833

78287834
function parseJSDocLinkPrefix() {
78297835
skipWhitespaceOrAsterisk();
7830-
return token() === SyntaxKind.OpenBraceToken
7836+
if (token() === SyntaxKind.OpenBraceToken
78317837
&& nextTokenJSDoc() === SyntaxKind.AtToken
7832-
&& tokenIsIdentifierOrKeyword(nextTokenJSDoc())
7833-
&& scanner.getTokenValue() === "link";
7838+
&& tokenIsIdentifierOrKeyword(nextTokenJSDoc())) {
7839+
const kind = scanner.getTokenValue();
7840+
if(kind === "link" || kind === "linkcode" || kind === "linkplain") {
7841+
return kind;
7842+
}
7843+
}
78347844
}
78357845

78367846
function parseUnknownTag(start: number, tagName: Identifier, indent: number, indentText: string) {
@@ -7969,7 +7979,7 @@ namespace ts {
79697979
commentEnd = scanner.getStartPos();
79707980
}
79717981
const allParts = typeof comments !== "string"
7972-
? createNodeArray(concatenate([finishNode(textOnly, commentStart, commentEnd)], comments) as (JSDocText | JSDocLink)[], commentStart) // cast away readonly
7982+
? createNodeArray(concatenate([finishNode(textOnly, commentStart, commentEnd)], comments) as JSDocComment[], commentStart) // cast away readonly
79737983
: textOnly.text + comments;
79747984
return finishNode(factory.createJSDocAuthorTag(tagName, allParts), start);
79757985
}
@@ -8030,7 +8040,7 @@ namespace ts {
80308040
return node;
80318041
}
80328042

8033-
function parseSimpleTag(start: number, createTag: (tagName: Identifier | undefined, comment?: string | NodeArray<JSDocText | JSDocLink>) => JSDocTag, tagName: Identifier, margin: number, indentText: string): JSDocTag {
8043+
function parseSimpleTag(start: number, createTag: (tagName: Identifier | undefined, comment?: string | NodeArray<JSDocComment>) => JSDocTag, tagName: Identifier, margin: number, indentText: string): JSDocTag {
80348044
return finishNode(createTag(tagName, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start);
80358045
}
80368046

0 commit comments

Comments
 (0)