feat(49323): Render JSDoc @throws {type} as a link (#49891)

* feat(49323): add support throws jsdoc tag

* change "name" to "typeExpression". parse "exception" as a synonym for "throws"

* include typeExpression from the throws tag in the quick info

* add JSDocThrowsTag to ForEachChildNodes
This commit is contained in:
Oleksandr T
2022-12-13 00:44:38 +02:00
committed by GitHub
parent f1288c33a1
commit 355991c806
30 changed files with 752 additions and 29 deletions
+1
View File
@@ -2122,6 +2122,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
case SyntaxKind.JSDocReturnTag:
case SyntaxKind.JSDocThisTag:
case SyntaxKind.JSDocTypeTag:
case SyntaxKind.JSDocThrowsTag:
return emitJSDocSimpleTypedTag(node as JSDocTypeTag);
case SyntaxKind.JSDocTemplateTag:
return emitJSDocTemplateTag(node as JSDocTemplateTag);
+3
View File
@@ -255,6 +255,7 @@ import {
JSDocTemplateTag,
JSDocText,
JSDocThisTag,
JSDocThrowsTag,
JSDocType,
JSDocTypedefTag,
JSDocTypeExpression,
@@ -871,6 +872,8 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
get updateJSDocOverrideTag() { return getJSDocSimpleTagUpdateFunction<JSDocOverrideTag>(SyntaxKind.JSDocOverrideTag); },
get createJSDocDeprecatedTag() { return getJSDocSimpleTagCreateFunction<JSDocDeprecatedTag>(SyntaxKind.JSDocDeprecatedTag); },
get updateJSDocDeprecatedTag() { return getJSDocSimpleTagUpdateFunction<JSDocDeprecatedTag>(SyntaxKind.JSDocDeprecatedTag); },
get createJSDocThrowsTag() { return getJSDocTypeLikeTagCreateFunction<JSDocThrowsTag>(SyntaxKind.JSDocThrowsTag); },
get updateJSDocThrowsTag() { return getJSDocTypeLikeTagUpdateFunction<JSDocThrowsTag>(SyntaxKind.JSDocThrowsTag); },
createJSDocUnknownTag,
updateJSDocUnknownTag,
createJSDocText,
+5
View File
@@ -109,6 +109,7 @@ import {
JSDocSignature,
JSDocTemplateTag,
JSDocThisTag,
JSDocThrowsTag,
JSDocTypedefTag,
JSDocTypeExpression,
JSDocTypeLiteral,
@@ -1176,6 +1177,10 @@ export function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag {
return node.kind === SyntaxKind.JSDocImplementsTag;
}
export function isJSDocThrowsTag(node: Node): node is JSDocThrowsTag {
return node.kind === SyntaxKind.JSDocThrowsTag;
}
// Synthesized list
/** @internal */
+17 -5
View File
@@ -196,6 +196,7 @@ import {
JSDocTemplateTag,
JSDocText,
JSDocThisTag,
JSDocThrowsTag,
JSDocTypedefTag,
JSDocTypeExpression,
JSDocTypeLiteral,
@@ -1100,10 +1101,11 @@ const forEachChildTable: ForEachChildTable = {
visitNode(cbNode, node.typeExpression) ||
(typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment));
},
[SyntaxKind.JSDocReturnTag]: forEachChildInJSDocReturnTag,
[SyntaxKind.JSDocTypeTag]: forEachChildInJSDocReturnTag,
[SyntaxKind.JSDocThisTag]: forEachChildInJSDocReturnTag,
[SyntaxKind.JSDocEnumTag]: forEachChildInJSDocReturnTag,
[SyntaxKind.JSDocReturnTag]: forEachChildInJSDocTypeLikeTag,
[SyntaxKind.JSDocTypeTag]: forEachChildInJSDocTypeLikeTag,
[SyntaxKind.JSDocThisTag]: forEachChildInJSDocTypeLikeTag,
[SyntaxKind.JSDocEnumTag]: forEachChildInJSDocTypeLikeTag,
[SyntaxKind.JSDocThrowsTag]: forEachChildInJSDocTypeLikeTag,
[SyntaxKind.JSDocSignature]: function forEachChildInJSDocSignature<T>(node: JSDocSignature, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray<Node>) => T | undefined): T | undefined {
return forEach(node.typeParameters, cbNode) ||
forEach(node.parameters, cbNode) ||
@@ -1197,7 +1199,7 @@ function forEachChildInJSDocParameterOrPropertyTag<T>(node: JSDocParameterTag |
(typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment));
}
function forEachChildInJSDocReturnTag<T>(node: JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray<Node>) => T | undefined): T | undefined {
function forEachChildInJSDocTypeLikeTag<T>(node: JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag | JSDocThrowsTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray<Node>) => T | undefined): T | undefined {
return visitNode(cbNode, node.tagName) ||
visitNode(cbNode, node.typeExpression) ||
(typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment));
@@ -8785,6 +8787,10 @@ namespace Parser {
case "see":
tag = parseSeeTag(start, tagName, margin, indentText);
break;
case "exception":
case "throws":
tag = parseThrowsTag(start, tagName, margin, indentText);
break;
default:
tag = parseUnknownTag(start, tagName, margin, indentText);
break;
@@ -9090,6 +9096,12 @@ namespace Parser {
return finishNode(factory.createJSDocSeeTag(tagName, nameExpression, comments), start);
}
function parseThrowsTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocThrowsTag {
const typeExpression = tryParseTypeExpression();
const comment = parseTrailingTagComments(start, getNodePos(), indent, indentText);
return finishNode(factory.createJSDocThrowsTag(tagName, typeExpression, comment), start);
}
function parseAuthorTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocAuthorTag {
const commentStart = getNodePos();
const textOnly = parseAuthorNameAndEmail();
+11 -2
View File
@@ -431,6 +431,7 @@ export const enum SyntaxKind {
JSDocTypedefTag,
JSDocSeeTag,
JSDocPropertyTag,
JSDocThrowsTag,
// Synthesized list
SyntaxList,
@@ -475,9 +476,9 @@ export const enum SyntaxKind {
LastStatement = DebuggerStatement,
FirstNode = QualifiedName,
FirstJSDocNode = JSDocTypeExpression,
LastJSDocNode = JSDocPropertyTag,
LastJSDocNode = JSDocThrowsTag,
FirstJSDocTagNode = JSDocTag,
LastJSDocTagNode = JSDocPropertyTag,
LastJSDocTagNode = JSDocThrowsTag,
/** @internal */ FirstContextualKeyword = AbstractKeyword,
/** @internal */ LastContextualKeyword = OfKeyword,
}
@@ -954,6 +955,7 @@ export type ForEachChildNodes =
| JSDocProtectedTag
| JSDocReadonlyTag
| JSDocDeprecatedTag
| JSDocThrowsTag
| JSDocOverrideTag
;
@@ -3827,6 +3829,11 @@ export interface JSDocCallbackTag extends JSDocTag, NamedDeclaration {
readonly typeExpression: JSDocSignature;
}
export interface JSDocThrowsTag extends JSDocTag {
readonly kind: SyntaxKind.JSDocThrowsTag;
readonly typeExpression?: JSDocTypeExpression;
}
export interface JSDocSignature extends JSDocType, Declaration {
readonly kind: SyntaxKind.JSDocSignature;
readonly typeParameters?: readonly JSDocTemplateTag[];
@@ -8257,6 +8264,8 @@ export interface NodeFactory {
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocThrowsTag(tagName: Identifier, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment>): JSDocThrowsTag;
updateJSDocThrowsTag(node: JSDocThrowsTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment> | undefined): JSDocThrowsTag;
createJSDocText(text: string): JSDocText;
updateJSDocText(node: JSDocText, text: string): JSDocText;
createJSDocComment(comment?: string | NodeArray<JSDocComment> | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc;
+6
View File
@@ -47,6 +47,7 @@ import {
JSDocSeeTag,
JSDocTemplateTag,
JSDocThisTag,
JSDocThrowsTag,
JSDocTypedefTag,
JSDocTypeTag,
JsxAttribute,
@@ -847,6 +848,11 @@ export function getEncodedSyntacticClassifications(cancellationToken: Cancellati
case SyntaxKind.JSDocImplementsTag:
commentStart = (tag as JSDocImplementsTag | JSDocAugmentsTag).class.end;
break;
case SyntaxKind.JSDocThrowsTag:
processElement((tag as JSDocThrowsTag).typeExpression);
pos = tag.end;
commentStart = (tag as JSDocThrowsTag).typeExpression?.end || commentStart;
break;
}
if (typeof tag.comment === "object") {
pushCommentRange(tag.comment.pos, tag.comment.end - tag.comment.pos);
+10 -1
View File
@@ -237,6 +237,7 @@ import {
JSDocTag,
JSDocTagInfo,
JSDocTemplateTag,
JSDocThrowsTag,
JSDocTypedefTag,
JSDocTypeExpression,
JSDocTypeTag,
@@ -2955,7 +2956,14 @@ function getCompletionData(
flags,
};
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag | JSDocTemplateTag;
type JSDocTagWithTypeExpression =
| JSDocParameterTag
| JSDocPropertyTag
| JSDocReturnTag
| JSDocTypeTag
| JSDocTypedefTag
| JSDocTemplateTag
| JSDocThrowsTag;
function isTagWithTypeExpression(tag: JSDocTag): tag is JSDocTagWithTypeExpression {
switch (tag.kind) {
@@ -2964,6 +2972,7 @@ function getCompletionData(
case SyntaxKind.JSDocReturnTag:
case SyntaxKind.JSDocTypeTag:
case SyntaxKind.JSDocTypedefTag:
case SyntaxKind.JSDocThrowsTag:
return true;
case SyntaxKind.JSDocTemplateTag:
return !!(tag as JSDocTemplateTag).constraint;
+5
View File
@@ -56,6 +56,7 @@ import {
JSDocTag,
JSDocTagInfo,
JSDocTemplateTag,
JSDocThrowsTag,
JSDocTypedefTag,
JSDocTypeTag,
lastOrUndefined,
@@ -258,6 +259,10 @@ function getCommentDisplayParts(tag: JSDocTag, checker?: TypeChecker): SymbolDis
const { comment, kind } = tag;
const namePart = getTagNameDisplayPart(kind);
switch (kind) {
case SyntaxKind.JSDocThrowsTag:
const typeExpression = (tag as JSDocThrowsTag).typeExpression;
return typeExpression ? withNode(typeExpression) :
comment === undefined ? undefined : getDisplayPartsFromComment(comment, checker);
case SyntaxKind.JSDocImplementsTag:
return withNode((tag as JSDocImplementsTag).class);
case SyntaxKind.JSDocAugmentsTag:
+29
View File
@@ -294,6 +294,35 @@ describe("unittests:: JSDocParsing", () => {
parsesCorrectly("paramWithoutType",
`/**
* @param foo
*/`);
parsesCorrectly("throwsTag1",
`/**
* @throws {Error}
*/`);
parsesCorrectly("throwsTag2",
`/**
* @throws free-form description
*/`);
parsesCorrectly("throwsTag3",
`/**
* @throws {Error} description
*/`);
parsesCorrectly("exceptionTag1",
`/**
* @exception {Error}
*/`);
parsesCorrectly("exceptionTag2",
`/**
* @exception free-form description
*/`);
parsesCorrectly("exceptionTag3",
`/**
* @exception {Error} description
*/`);
parsesCorrectly("typedefTagWithChildrenTags",
`/**
@@ -0,0 +1,52 @@
{
"kind": "JSDoc",
"pos": 0,
"end": 31,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"tags": {
"0": {
"kind": "JSDocThrowsTag",
"pos": 8,
"end": 29,
"modifierFlagsCache": 0,
"transformFlags": 0,
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 18,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "exception"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 19,
"end": 26,
"modifierFlagsCache": 0,
"transformFlags": 0,
"type": {
"kind": "TypeReference",
"pos": 20,
"end": 25,
"modifierFlagsCache": 0,
"transformFlags": 1,
"typeName": {
"kind": "Identifier",
"pos": 20,
"end": 25,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "Error"
}
}
}
},
"length": 1,
"pos": 8,
"end": 29,
"hasTrailingComma": false,
"transformFlags": 0
}
}
@@ -0,0 +1,31 @@
{
"kind": "JSDoc",
"pos": 0,
"end": 45,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"tags": {
"0": {
"kind": "JSDocThrowsTag",
"pos": 8,
"end": 43,
"modifierFlagsCache": 0,
"transformFlags": 0,
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 18,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "exception"
},
"comment": "free-form description"
},
"length": 1,
"pos": 8,
"end": 43,
"hasTrailingComma": false,
"transformFlags": 0
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDoc",
"pos": 0,
"end": 43,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"tags": {
"0": {
"kind": "JSDocThrowsTag",
"pos": 8,
"end": 41,
"modifierFlagsCache": 0,
"transformFlags": 0,
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 18,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "exception"
},
"comment": "description",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 19,
"end": 26,
"modifierFlagsCache": 0,
"transformFlags": 0,
"type": {
"kind": "TypeReference",
"pos": 20,
"end": 25,
"modifierFlagsCache": 0,
"transformFlags": 1,
"typeName": {
"kind": "Identifier",
"pos": 20,
"end": 25,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "Error"
}
}
}
},
"length": 1,
"pos": 8,
"end": 41,
"hasTrailingComma": false,
"transformFlags": 0
}
}
@@ -0,0 +1,52 @@
{
"kind": "JSDoc",
"pos": 0,
"end": 28,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"tags": {
"0": {
"kind": "JSDocThrowsTag",
"pos": 8,
"end": 26,
"modifierFlagsCache": 0,
"transformFlags": 0,
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 15,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "throws"
},
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 16,
"end": 23,
"modifierFlagsCache": 0,
"transformFlags": 0,
"type": {
"kind": "TypeReference",
"pos": 17,
"end": 22,
"modifierFlagsCache": 0,
"transformFlags": 1,
"typeName": {
"kind": "Identifier",
"pos": 17,
"end": 22,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "Error"
}
}
}
},
"length": 1,
"pos": 8,
"end": 26,
"hasTrailingComma": false,
"transformFlags": 0
}
}
@@ -0,0 +1,31 @@
{
"kind": "JSDoc",
"pos": 0,
"end": 42,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"tags": {
"0": {
"kind": "JSDocThrowsTag",
"pos": 8,
"end": 40,
"modifierFlagsCache": 0,
"transformFlags": 0,
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 15,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "throws"
},
"comment": "free-form description"
},
"length": 1,
"pos": 8,
"end": 40,
"hasTrailingComma": false,
"transformFlags": 0
}
}
@@ -0,0 +1,53 @@
{
"kind": "JSDoc",
"pos": 0,
"end": 40,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0,
"tags": {
"0": {
"kind": "JSDocThrowsTag",
"pos": 8,
"end": 38,
"modifierFlagsCache": 0,
"transformFlags": 0,
"tagName": {
"kind": "Identifier",
"pos": 9,
"end": 15,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "throws"
},
"comment": "description",
"typeExpression": {
"kind": "JSDocTypeExpression",
"pos": 16,
"end": 23,
"modifierFlagsCache": 0,
"transformFlags": 0,
"type": {
"kind": "TypeReference",
"pos": 17,
"end": 22,
"modifierFlagsCache": 0,
"transformFlags": 1,
"typeName": {
"kind": "Identifier",
"pos": 17,
"end": 22,
"modifierFlagsCache": 0,
"transformFlags": 0,
"escapedText": "Error"
}
}
}
},
"length": 1,
"pos": 8,
"end": 38,
"hasTrailingComma": false,
"transformFlags": 0
}
}
+18 -10
View File
@@ -4347,14 +4347,15 @@ declare namespace ts {
JSDocTypedefTag = 348,
JSDocSeeTag = 349,
JSDocPropertyTag = 350,
SyntaxList = 351,
NotEmittedStatement = 352,
PartiallyEmittedExpression = 353,
CommaListExpression = 354,
MergeDeclarationMarker = 355,
EndOfDeclarationMarker = 356,
SyntheticReferenceExpression = 357,
Count = 358,
JSDocThrowsTag = 351,
SyntaxList = 352,
NotEmittedStatement = 353,
PartiallyEmittedExpression = 354,
CommaListExpression = 355,
MergeDeclarationMarker = 356,
EndOfDeclarationMarker = 357,
SyntheticReferenceExpression = 358,
Count = 359,
FirstAssignment = 63,
LastAssignment = 78,
FirstCompoundAssignment = 64,
@@ -4383,9 +4384,9 @@ declare namespace ts {
LastStatement = 256,
FirstNode = 163,
FirstJSDocNode = 312,
LastJSDocNode = 350,
LastJSDocNode = 351,
FirstJSDocTagNode = 330,
LastJSDocTagNode = 350
LastJSDocTagNode = 351
}
type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia;
type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral;
@@ -5938,6 +5939,10 @@ declare namespace ts {
readonly name?: Identifier;
readonly typeExpression: JSDocSignature;
}
interface JSDocThrowsTag extends JSDocTag {
readonly kind: SyntaxKind.JSDocThrowsTag;
readonly typeExpression?: JSDocTypeExpression;
}
interface JSDocSignature extends JSDocType, Declaration {
readonly kind: SyntaxKind.JSDocSignature;
readonly typeParameters?: readonly JSDocTemplateTag[];
@@ -7799,6 +7804,8 @@ declare namespace ts {
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocThrowsTag(tagName: Identifier, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment>): JSDocThrowsTag;
updateJSDocThrowsTag(node: JSDocThrowsTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment> | undefined): JSDocThrowsTag;
createJSDocText(text: string): JSDocText;
updateJSDocText(node: JSDocText, text: string): JSDocText;
createJSDocComment(comment?: string | NodeArray<JSDocComment> | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc;
@@ -9039,6 +9046,7 @@ declare namespace ts {
function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag;
function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag;
function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag;
function isJSDocThrowsTag(node: Node): node is JSDocThrowsTag;
function setTextRange<T extends TextRange>(range: T, location: TextRange | undefined): T;
function canHaveModifiers(node: Node): node is HasModifiers;
function canHaveDecorators(node: Node): node is HasDecorators;
+18 -10
View File
@@ -413,14 +413,15 @@ declare namespace ts {
JSDocTypedefTag = 348,
JSDocSeeTag = 349,
JSDocPropertyTag = 350,
SyntaxList = 351,
NotEmittedStatement = 352,
PartiallyEmittedExpression = 353,
CommaListExpression = 354,
MergeDeclarationMarker = 355,
EndOfDeclarationMarker = 356,
SyntheticReferenceExpression = 357,
Count = 358,
JSDocThrowsTag = 351,
SyntaxList = 352,
NotEmittedStatement = 353,
PartiallyEmittedExpression = 354,
CommaListExpression = 355,
MergeDeclarationMarker = 356,
EndOfDeclarationMarker = 357,
SyntheticReferenceExpression = 358,
Count = 359,
FirstAssignment = 63,
LastAssignment = 78,
FirstCompoundAssignment = 64,
@@ -449,9 +450,9 @@ declare namespace ts {
LastStatement = 256,
FirstNode = 163,
FirstJSDocNode = 312,
LastJSDocNode = 350,
LastJSDocNode = 351,
FirstJSDocTagNode = 330,
LastJSDocTagNode = 350
LastJSDocTagNode = 351
}
type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia;
type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral;
@@ -2004,6 +2005,10 @@ declare namespace ts {
readonly name?: Identifier;
readonly typeExpression: JSDocSignature;
}
interface JSDocThrowsTag extends JSDocTag {
readonly kind: SyntaxKind.JSDocThrowsTag;
readonly typeExpression?: JSDocTypeExpression;
}
interface JSDocSignature extends JSDocType, Declaration {
readonly kind: SyntaxKind.JSDocSignature;
readonly typeParameters?: readonly JSDocTemplateTag[];
@@ -3865,6 +3870,8 @@ declare namespace ts {
updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocDeprecatedTag;
createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray<JSDocComment>): JSDocOverrideTag;
createJSDocThrowsTag(tagName: Identifier, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment>): JSDocThrowsTag;
updateJSDocThrowsTag(node: JSDocThrowsTag, tagName: Identifier | undefined, typeExpression: JSDocTypeExpression | undefined, comment?: string | NodeArray<JSDocComment> | undefined): JSDocThrowsTag;
createJSDocText(text: string): JSDocText;
updateJSDocText(node: JSDocText, text: string): JSDocText;
createJSDocComment(comment?: string | NodeArray<JSDocComment> | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc;
@@ -5105,6 +5112,7 @@ declare namespace ts {
function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag;
function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag;
function isJSDocImplementsTag(node: Node): node is JSDocImplementsTag;
function isJSDocThrowsTag(node: Node): node is JSDocThrowsTag;
function setTextRange<T extends TextRange>(range: T, location: TextRange | undefined): T;
function canHaveModifiers(node: Node): node is HasModifiers;
function canHaveDecorators(node: Node): node is HasDecorators;
@@ -0,0 +1,64 @@
// === /tests/cases/fourslash/jsdocThrowsTag_findAllReferences.ts ===
// class /*FIND ALL REFS*/[|E|] extends Error {}
// /**
// * @throws {[|E|]}
// */
// function f() {}
[
{
"definition": {
"containerKind": "",
"containerName": "",
"fileName": "/tests/cases/fourslash/jsdocThrowsTag_findAllReferences.ts",
"kind": "class",
"name": "class E",
"textSpan": {
"start": 6,
"length": 1
},
"displayParts": [
{
"text": "class",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "E",
"kind": "className"
}
],
"contextSpan": {
"start": 0,
"length": 24
}
},
"references": [
{
"textSpan": {
"start": 6,
"length": 1
},
"fileName": "/tests/cases/fourslash/jsdocThrowsTag_findAllReferences.ts",
"contextSpan": {
"start": 0,
"length": 24
},
"isWriteAccess": true,
"isDefinition": true
},
{
"textSpan": {
"start": 41,
"length": 1
},
"fileName": "/tests/cases/fourslash/jsdocThrowsTag_findAllReferences.ts",
"isWriteAccess": false,
"isDefinition": false
}
]
}
]
@@ -0,0 +1,7 @@
/*====== /tests/cases/fourslash/jsdocThrowsTag_rename.ts ======*/
class [|RENAME|] extends Error {}
/**
* @throws {RENAME}
*/
function f() {}
@@ -0,0 +1,8 @@
//// [parseThrowsTag.ts]
/** @throws {Error} comment */
function f() {}
//// [parseThrowsTag.js]
/** @throws {Error} comment */
function f() { }
@@ -0,0 +1,5 @@
=== tests/cases/conformance/jsdoc/parseThrowsTag.ts ===
/** @throws {Error} comment */
function f() {}
>f : Symbol(f, Decl(parseThrowsTag.ts, 0, 0))
@@ -0,0 +1,5 @@
=== tests/cases/conformance/jsdoc/parseThrowsTag.ts ===
/** @throws {Error} comment */
function f() {}
>f : () => void
@@ -133,7 +133,15 @@
"name": "throws",
"text": [
{
"text": "{Error} comment",
"text": "{Error}",
"kind": "text"
},
{
"text": " ",
"kind": "space"
},
{
"text": "comment",
"kind": "text"
}
]
@@ -0,0 +1,193 @@
[
{
"marker": {
"fileName": "/tests/cases/fourslash/quickInfoThrowsTag.ts",
"position": 170,
"name": "1"
},
"quickInfo": {
"kind": "function",
"kindModifiers": "",
"textSpan": {
"start": 168,
"length": 2
},
"displayParts": [
{
"text": "function",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "f1",
"kind": "functionName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "void",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "throws",
"text": [
{
"text": "{E}",
"kind": "text"
}
]
}
]
}
},
{
"marker": {
"fileName": "/tests/cases/fourslash/quickInfoThrowsTag.ts",
"position": 175,
"name": "2"
},
"quickInfo": {
"kind": "function",
"kindModifiers": "",
"textSpan": {
"start": 173,
"length": 2
},
"displayParts": [
{
"text": "function",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "f2",
"kind": "functionName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "void",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "throws",
"text": [
{
"text": "{E}",
"kind": "text"
},
{
"text": " ",
"kind": "space"
},
{
"text": "description",
"kind": "text"
}
]
}
]
}
},
{
"marker": {
"fileName": "/tests/cases/fourslash/quickInfoThrowsTag.ts",
"position": 180,
"name": "3"
},
"quickInfo": {
"kind": "function",
"kindModifiers": "",
"textSpan": {
"start": 178,
"length": 2
},
"displayParts": [
{
"text": "function",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "f3",
"kind": "functionName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "void",
"kind": "keyword"
}
],
"documentation": [],
"tags": [
{
"name": "throws",
"text": [
{
"text": "description",
"kind": "text"
}
]
}
]
}
}
]
@@ -0,0 +1,2 @@
/** @throws {Error} comment */
function f() {}
@@ -0,0 +1,11 @@
///<reference path="fourslash.ts" />
////class [|/*def*/E|] extends Error {}
////
/////**
//// * @throws {/*use*/[|E|]}
//// */
////function f() {}
goTo.marker("use");
verify.goToDefinitionIs("def");
@@ -0,0 +1,10 @@
///<reference path="fourslash.ts" />
/////**
//// * @throws {/**/} description
//// */
////function fn() {}
verify.completions(
{ marker: "", exact: completion.globalTypes },
);
@@ -0,0 +1,9 @@
/// <reference path="fourslash.ts" />
////class /**/E extends Error {}
/////**
//// * @throws {E}
//// */
////function f() {}
verify.baselineFindAllReferences("");
@@ -0,0 +1,9 @@
/// <reference path="fourslash.ts" />
////class /**/E extends Error {}
/////**
//// * @throws {E}
//// */
////function f() {}
verify.baselineRename("", {});
@@ -0,0 +1,25 @@
///<reference path="fourslash.ts" />
////class E extends Error {}
////
/////**
//// * @throws {E}
//// */
////function f1() {}
////
/////**
//// * @throws {E} description
//// */
////function f2() {}
////
/////**
//// * @throws description
//// */
////function f3() {}
////f1/*1*/()
////f2/*2*/()
////f3/*3*/()
verify.noErrors()
verify.baselineQuickInfo();