2
2
3
3
/* @internal */
4
4
namespace ts {
5
+ export const emptyArray : never [ ] = [ ] as never [ ] ;
6
+
5
7
export const externalHelpersModuleNameText = "tslib" ;
6
8
7
9
export interface ReferencePathMatchResult {
@@ -1445,39 +1447,37 @@ namespace ts {
1445
1447
( < JSDocFunctionType > node ) . parameters [ 0 ] . type . kind === SyntaxKind . JSDocConstructorType ;
1446
1448
}
1447
1449
1448
- export function getCommentsFromJSDoc ( node : Node ) : string [ ] {
1449
- return map ( getJSDocs ( node ) , doc => doc . comment ) ;
1450
- }
1451
-
1452
- export function hasJSDocParameterTags ( node : FunctionLikeDeclaration | SignatureDeclaration ) {
1453
- const parameterTags = getJSDocTags ( node , SyntaxKind . JSDocParameterTag ) ;
1454
- return parameterTags && parameterTags . length > 0 ;
1450
+ export function hasJSDocParameterTags ( node : FunctionLikeDeclaration | SignatureDeclaration ) : boolean {
1451
+ return ! ! getFirstJSDocTag ( node , SyntaxKind . JSDocParameterTag ) ;
1455
1452
}
1456
1453
1457
- function getJSDocTags ( node : Node , kind : SyntaxKind ) : JSDocTag [ ] {
1458
- return flatMap ( getJSDocs ( node ) , doc =>
1459
- doc . kind === SyntaxKind . JSDocComment
1460
- ? filter ( ( doc as JSDoc ) . tags , tag => tag . kind === kind )
1461
- : doc . kind === kind && doc ) ;
1454
+ function getFirstJSDocTag ( node : Node , kind : SyntaxKind ) : JSDocTag | undefined {
1455
+ const tags = getJSDocTags ( node ) ;
1456
+ return find ( tags , doc => doc . kind === kind ) ;
1462
1457
}
1463
1458
1464
- function getFirstJSDocTag ( node : Node , kind : SyntaxKind ) : JSDocTag {
1465
- return node && firstOrUndefined ( getJSDocTags ( node , kind ) ) ;
1466
- }
1467
-
1468
- export function getJSDocs ( node : Node ) : ( JSDoc | JSDocTag ) [ ] {
1459
+ export function getAllJSDocs ( node : Node ) : ( JSDoc | JSDocTag ) [ ] {
1469
1460
if ( isJSDocTypedefTag ( node ) ) {
1470
1461
return [ node . parent ] ;
1471
1462
}
1463
+ return getJSDocCommentsAndTags ( node ) ;
1464
+ }
1472
1465
1473
- let cache : ( JSDoc | JSDocTag ) [ ] = node . jsDocCache ;
1474
- if ( ! cache ) {
1475
- getJSDocsWorker ( node ) ;
1476
- node . jsDocCache = cache ;
1466
+ export function getJSDocTags ( node : Node ) : JSDocTag [ ] | undefined {
1467
+ let tags = node . jsDocCache ;
1468
+ // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
1469
+ if ( tags === undefined ) {
1470
+ node . jsDocCache = tags = flatMap ( getJSDocCommentsAndTags ( node ) , j => isJSDoc ( j ) ? j . tags : j ) ;
1477
1471
}
1478
- return cache ;
1472
+ return tags ;
1473
+ }
1474
+
1475
+ function getJSDocCommentsAndTags ( node : Node ) : ( JSDoc | JSDocTag ) [ ] {
1476
+ let result : Array < JSDoc | JSDocTag > | undefined ;
1477
+ getJSDocCommentsAndTagsWorker ( node ) ;
1478
+ return result || emptyArray ;
1479
1479
1480
- function getJSDocsWorker ( node : Node ) {
1480
+ function getJSDocCommentsAndTagsWorker ( node : Node ) : void {
1481
1481
const parent = node . parent ;
1482
1482
// Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
1483
1483
// /**
@@ -1496,7 +1496,7 @@ namespace ts {
1496
1496
isVariableOfVariableDeclarationStatement ? parent . parent :
1497
1497
undefined ;
1498
1498
if ( variableStatementNode ) {
1499
- getJSDocsWorker ( variableStatementNode ) ;
1499
+ getJSDocCommentsAndTagsWorker ( variableStatementNode ) ;
1500
1500
}
1501
1501
1502
1502
// Also recognize when the node is the RHS of an assignment expression
@@ -1506,43 +1506,51 @@ namespace ts {
1506
1506
( parent as BinaryExpression ) . operatorToken . kind === SyntaxKind . EqualsToken &&
1507
1507
parent . parent . kind === SyntaxKind . ExpressionStatement ;
1508
1508
if ( isSourceOfAssignmentExpressionStatement ) {
1509
- getJSDocsWorker ( parent . parent ) ;
1509
+ getJSDocCommentsAndTagsWorker ( parent . parent ) ;
1510
1510
}
1511
1511
1512
1512
const isModuleDeclaration = node . kind === SyntaxKind . ModuleDeclaration &&
1513
1513
parent && parent . kind === SyntaxKind . ModuleDeclaration ;
1514
1514
const isPropertyAssignmentExpression = parent && parent . kind === SyntaxKind . PropertyAssignment ;
1515
1515
if ( isModuleDeclaration || isPropertyAssignmentExpression ) {
1516
- getJSDocsWorker ( parent ) ;
1516
+ getJSDocCommentsAndTagsWorker ( parent ) ;
1517
1517
}
1518
1518
1519
1519
// Pull parameter comments from declaring function as well
1520
1520
if ( node . kind === SyntaxKind . Parameter ) {
1521
- cache = concatenate ( cache , getJSDocParameterTags ( node as ParameterDeclaration ) ) ;
1521
+ result = addRange ( result , getJSDocParameterTags ( node as ParameterDeclaration ) ) ;
1522
1522
}
1523
1523
1524
1524
if ( isVariableLike ( node ) && node . initializer ) {
1525
- cache = concatenate ( cache , node . initializer . jsDoc ) ;
1525
+ result = addRange ( result , node . initializer . jsDoc ) ;
1526
1526
}
1527
1527
1528
- cache = concatenate ( cache , node . jsDoc ) ;
1528
+ result = addRange ( result , node . jsDoc ) ;
1529
1529
}
1530
1530
}
1531
1531
1532
- export function getJSDocParameterTags ( param : ParameterDeclaration ) : JSDocParameterTag [ ] {
1532
+ export function getJSDocParameterTags ( param : ParameterDeclaration ) : JSDocParameterTag [ ] | undefined {
1533
1533
const func = param . parent ;
1534
- const tags = getJSDocTags ( func , SyntaxKind . JSDocParameterTag ) as JSDocParameterTag [ ] ;
1534
+ const tags = getJSDocTags ( func ) ;
1535
+ if ( ! tags ) return undefined ;
1536
+
1535
1537
if ( ! param . name ) {
1536
1538
// this is an anonymous jsdoc param from a `function(type1, type2): type3` specification
1537
- const i = func . parameters . indexOf ( param ) ;
1538
- const paramTags = filter ( tags , tag => tag . kind === SyntaxKind . JSDocParameterTag ) ;
1539
- if ( paramTags && 0 <= i && i < paramTags . length ) {
1540
- return [ paramTags [ i ] ] ;
1539
+ const paramIndex = func . parameters . indexOf ( param ) ;
1540
+ Debug . assert ( paramIndex !== - 1 ) ;
1541
+ let curParamIndex = 0 ;
1542
+ for ( const tag of tags ) {
1543
+ if ( isJSDocParameterTag ( tag ) ) {
1544
+ if ( curParamIndex === paramIndex ) {
1545
+ return [ tag ] ;
1546
+ }
1547
+ curParamIndex ++ ;
1548
+ }
1541
1549
}
1542
1550
}
1543
1551
else if ( param . name . kind === SyntaxKind . Identifier ) {
1544
1552
const name = ( param . name as Identifier ) . text ;
1545
- return filter ( tags , tag => tag . kind === SyntaxKind . JSDocParameterTag && tag . name . text === name ) ;
1553
+ return tags . filter ( ( tag ) : tag is JSDocParameterTag => isJSDocParameterTag ( tag ) && tag . name . text === name ) as JSDocParameterTag [ ] ;
1546
1554
}
1547
1555
else {
1548
1556
// TODO: it's a destructured parameter, so it should look up an "object type" series of multiple lines
0 commit comments