@@ -1494,32 +1494,14 @@ namespace ts {
14941494 ( ( node as JSDocFunctionType ) . parameters [ 0 ] . name as Identifier ) . escapedText === "new" ;
14951495 }
14961496
1497- export function hasJSDocParameterTags ( node : FunctionLikeDeclaration | SignatureDeclaration ) : boolean {
1498- return ! ! getFirstJSDocTag ( node , SyntaxKind . JSDocParameterTag ) ;
1499- }
1500-
1501- function getFirstJSDocTag ( node : Node , kind : SyntaxKind ) : JSDocTag | undefined {
1502- const tags = getJSDocTags ( node ) ;
1503- return find ( tags , doc => doc . kind === kind ) ;
1504- }
1505-
15061497 export function getAllJSDocs ( node : Node ) : ( JSDoc | JSDocTag ) [ ] {
15071498 if ( isJSDocTypedefTag ( node ) ) {
15081499 return [ node . parent ] ;
15091500 }
15101501 return getJSDocCommentsAndTags ( node ) ;
15111502 }
15121503
1513- export function getJSDocTags ( node : Node ) : ReadonlyArray < JSDocTag > | undefined {
1514- let tags = ( node as JSDocContainer ) . jsDocCache ;
1515- // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
1516- if ( tags === undefined ) {
1517- ( node as JSDocContainer ) . jsDocCache = tags = flatMap ( getJSDocCommentsAndTags ( node ) , j => isJSDoc ( j ) ? j . tags : j ) ;
1518- }
1519- return tags ;
1520- }
1521-
1522- function getJSDocCommentsAndTags ( node : Node ) : ( JSDoc | JSDocTag ) [ ] {
1504+ export function getJSDocCommentsAndTags ( node : Node ) : ( JSDoc | JSDocTag ) [ ] {
15231505 let result : Array < JSDoc | JSDocTag > | undefined ;
15241506 getJSDocCommentsAndTagsWorker ( node ) ;
15251507 return result || emptyArray ;
@@ -1578,15 +1560,6 @@ namespace ts {
15781560 }
15791561 }
15801562
1581- export function getJSDocParameterTags ( param : ParameterDeclaration ) : JSDocParameterTag [ ] | undefined {
1582- if ( param . name && isIdentifier ( param . name ) ) {
1583- const name = param . name . escapedText ;
1584- return getJSDocTags ( param . parent ) . filter ( ( tag ) : tag is JSDocParameterTag => isJSDocParameterTag ( tag ) && isIdentifier ( tag . name ) && tag . name . escapedText === name ) as JSDocParameterTag [ ] ;
1585- }
1586- // a binding pattern doesn't have a name, so it's not possible to match it a jsdoc parameter, which is identified by name
1587- return undefined ;
1588- }
1589-
15901563 /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
15911564 export function getParameterSymbolFromJSDoc ( node : JSDocParameterTag ) : Symbol | undefined {
15921565 if ( node . symbol ) {
@@ -1612,39 +1585,6 @@ namespace ts {
16121585 return find ( typeParameters , p => p . name . escapedText === name ) ;
16131586 }
16141587
1615- export function getJSDocType ( node : Node ) : TypeNode {
1616- let tag : JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag ( node , SyntaxKind . JSDocTypeTag ) as JSDocTypeTag ;
1617- if ( ! tag && node . kind === SyntaxKind . Parameter ) {
1618- const paramTags = getJSDocParameterTags ( node as ParameterDeclaration ) ;
1619- if ( paramTags ) {
1620- tag = find ( paramTags , tag => ! ! tag . typeExpression ) ;
1621- }
1622- }
1623-
1624- return tag && tag . typeExpression && tag . typeExpression . type ;
1625- }
1626-
1627- export function getJSDocAugmentsTag ( node : Node ) : JSDocAugmentsTag {
1628- return getFirstJSDocTag ( node , SyntaxKind . JSDocAugmentsTag ) as JSDocAugmentsTag ;
1629- }
1630-
1631- export function getJSDocClassTag ( node : Node ) : JSDocClassTag {
1632- return getFirstJSDocTag ( node , SyntaxKind . JSDocClassTag ) as JSDocClassTag ;
1633- }
1634-
1635- export function getJSDocReturnTag ( node : Node ) : JSDocReturnTag {
1636- return getFirstJSDocTag ( node , SyntaxKind . JSDocReturnTag ) as JSDocReturnTag ;
1637- }
1638-
1639- export function getJSDocReturnType ( node : Node ) : TypeNode {
1640- const returnTag = getJSDocReturnTag ( node ) ;
1641- return returnTag && returnTag . typeExpression && returnTag . typeExpression . type ;
1642- }
1643-
1644- export function getJSDocTemplateTag ( node : Node ) : JSDocTemplateTag {
1645- return getFirstJSDocTag ( node , SyntaxKind . JSDocTemplateTag ) as JSDocTemplateTag ;
1646- }
1647-
16481588 export function hasRestParameter ( s : SignatureDeclaration ) : boolean {
16491589 return isRestParameter ( lastOrUndefined ( s . parameters ) ) ;
16501590 }
@@ -4086,6 +4026,114 @@ namespace ts {
40864026 return ( declaration as NamedDeclaration ) . name ;
40874027 }
40884028 }
4029+
4030+ /**
4031+ * Gets the JSDoc parameter tags for the node if present.
4032+ *
4033+ * @remarks Returns any JSDoc param tag that matches the provided
4034+ * parameter, whether a param tag on a containing function
4035+ * expression, or a param tag on a variable declaration whose
4036+ * initializer is the containing function. The tags closest to the
4037+ * node are returned first, so in the previous example, the param
4038+ * tag on the containing function expression would be first.
4039+ *
4040+ * Does not return tags for binding patterns, because JSDoc matches
4041+ * parameters by name and binding patterns do not have a name.
4042+ */
4043+ export function getJSDocParameterTags ( param : ParameterDeclaration ) : ReadonlyArray < JSDocParameterTag > | undefined {
4044+ if ( param . name && isIdentifier ( param . name ) ) {
4045+ const name = param . name . escapedText ;
4046+ return getJSDocTags ( param . parent ) . filter ( ( tag ) : tag is JSDocParameterTag => isJSDocParameterTag ( tag ) && isIdentifier ( tag . name ) && tag . name . escapedText === name ) as JSDocParameterTag [ ] ;
4047+ }
4048+ // a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name
4049+ return undefined ;
4050+ }
4051+
4052+ /**
4053+ * Return true if the node has JSDoc parameter tags.
4054+ *
4055+ * @remarks Includes parameter tags that are not directly on the node,
4056+ * for example on a variable declaration whose initializer is a function expression.
4057+ */
4058+ export function hasJSDocParameterTags ( node : FunctionLikeDeclaration | SignatureDeclaration ) : boolean {
4059+ return ! ! getFirstJSDocTag ( node , SyntaxKind . JSDocParameterTag ) ;
4060+ }
4061+
4062+ /** Gets the JSDoc augments tag for the node if present */
4063+ export function getJSDocAugmentsTag ( node : Node ) : JSDocAugmentsTag | undefined {
4064+ return getFirstJSDocTag ( node , SyntaxKind . JSDocAugmentsTag ) as JSDocAugmentsTag ;
4065+ }
4066+
4067+ /** Gets the JSDoc class tag for the node if present */
4068+ export function getJSDocClassTag ( node : Node ) : JSDocClassTag | undefined {
4069+ return getFirstJSDocTag ( node , SyntaxKind . JSDocClassTag ) as JSDocClassTag ;
4070+ }
4071+
4072+ /** Gets the JSDoc return tag for the node if present */
4073+ export function getJSDocReturnTag ( node : Node ) : JSDocReturnTag | undefined {
4074+ return getFirstJSDocTag ( node , SyntaxKind . JSDocReturnTag ) as JSDocReturnTag ;
4075+ }
4076+
4077+ /** Gets the JSDoc template tag for the node if present */
4078+ export function getJSDocTemplateTag ( node : Node ) : JSDocTemplateTag | undefined {
4079+ return getFirstJSDocTag ( node , SyntaxKind . JSDocTemplateTag ) as JSDocTemplateTag ;
4080+ }
4081+
4082+ /** Gets the JSDoc type tag for the node if present */
4083+ export function getJSDocTypeTag ( node : Node ) : JSDocTypeTag | undefined {
4084+ return getFirstJSDocTag ( node , SyntaxKind . JSDocTypeTag ) as JSDocTypeTag ;
4085+ }
4086+
4087+ /**
4088+ * Gets the type node for the node if provided via JSDoc.
4089+ *
4090+ * @remarks The search includes any JSDoc param tag that relates
4091+ * to the provided parameter, for example a type tag on the
4092+ * parameter itself, or a param tag on a containing function
4093+ * expression, or a param tag on a variable declaration whose
4094+ * initializer is the containing function. The tags closest to the
4095+ * node are examined first, so in the previous example, the type
4096+ * tag directly on the node would be returned.
4097+ */
4098+ export function getJSDocType ( node : Node ) : TypeNode | undefined {
4099+ let tag : JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag ( node , SyntaxKind . JSDocTypeTag ) as JSDocTypeTag ;
4100+ if ( ! tag && node . kind === SyntaxKind . Parameter ) {
4101+ const paramTags = getJSDocParameterTags ( node as ParameterDeclaration ) ;
4102+ if ( paramTags ) {
4103+ tag = find ( paramTags , tag => ! ! tag . typeExpression ) ;
4104+ }
4105+ }
4106+
4107+ return tag && tag . typeExpression && tag . typeExpression . type ;
4108+ }
4109+
4110+ /**
4111+ * Gets the return type node for the node if provided via JSDoc's return tag.
4112+ *
4113+ * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
4114+ * gets the type from inside the braces.
4115+ */
4116+ export function getJSDocReturnType ( node : Node ) : TypeNode | undefined {
4117+ const returnTag = getJSDocReturnTag ( node ) ;
4118+ return returnTag && returnTag . typeExpression && returnTag . typeExpression . type ;
4119+ }
4120+
4121+ /** Get all JSDoc tags related to a node, including those on parent nodes. */
4122+ export function getJSDocTags ( node : Node ) : ReadonlyArray < JSDocTag > | undefined {
4123+ let tags = ( node as JSDocContainer ) . jsDocCache ;
4124+ // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
4125+ if ( tags === undefined ) {
4126+ ( node as JSDocContainer ) . jsDocCache = tags = flatMap ( getJSDocCommentsAndTags ( node ) , j => isJSDoc ( j ) ? j . tags : j ) ;
4127+ }
4128+ return tags ;
4129+ }
4130+
4131+ /** Get the first JSDoc tag of a specified kind, or undefined if not present. */
4132+ function getFirstJSDocTag ( node : Node , kind : SyntaxKind ) : JSDocTag | undefined {
4133+ const tags = getJSDocTags ( node ) ;
4134+ return find ( tags , doc => doc . kind === kind ) ;
4135+ }
4136+
40894137}
40904138
40914139// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
0 commit comments