Skip to content

Commit 1ad7b0f

Browse files
ajafffsandersn
authored andcommitted
forEachToken: correctly handle JSDocTag (microsoft#28369)
* forEachChild: handle JSDocTags and all their children * fix codefix for unused identifier * fix lint * fix build * Fix test failures
1 parent 6cee7c3 commit 1ad7b0f

File tree

5 files changed

+37
-38
lines changed

5 files changed

+37
-38
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,7 @@ namespace ts {
13791379
}
13801380

13811381
function bindJSDocTypeAlias(node: JSDocTypedefTag | JSDocCallbackTag) {
1382+
node.tagName.parent = node;
13821383
if (node.fullName) {
13831384
setParentPointers(node, node.fullName);
13841385
}

src/compiler/parser.ts

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -462,52 +462,46 @@ namespace ts {
462462
return visitNodes(cbNode, cbNodes, (<JSDoc>node).tags);
463463
case SyntaxKind.JSDocParameterTag:
464464
case SyntaxKind.JSDocPropertyTag:
465-
if ((node as JSDocPropertyLikeTag).isNameFirst) {
466-
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
467-
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression);
468-
}
469-
else {
470-
return visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
471-
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name);
472-
}
473-
case SyntaxKind.JSDocReturnTag:
474-
return visitNode(cbNode, (<JSDocReturnTag>node).typeExpression);
475-
case SyntaxKind.JSDocTypeTag:
476-
return visitNode(cbNode, (<JSDocTypeTag>node).typeExpression);
465+
return visitNode(cbNode, (node as JSDocTag).tagName) ||
466+
((node as JSDocPropertyLikeTag).isNameFirst
467+
? visitNode(cbNode, (<JSDocPropertyLikeTag>node).name) ||
468+
visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression)
469+
: visitNode(cbNode, (<JSDocPropertyLikeTag>node).typeExpression) ||
470+
visitNode(cbNode, (<JSDocPropertyLikeTag>node).name));
477471
case SyntaxKind.JSDocAugmentsTag:
478-
return visitNode(cbNode, (<JSDocAugmentsTag>node).class);
472+
return visitNode(cbNode, (node as JSDocTag).tagName) ||
473+
visitNode(cbNode, (<JSDocAugmentsTag>node).class);
479474
case SyntaxKind.JSDocTemplateTag:
480-
return visitNode(cbNode, (<JSDocTemplateTag>node).constraint) || visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
475+
return visitNode(cbNode, (node as JSDocTag).tagName) ||
476+
visitNode(cbNode, (<JSDocTemplateTag>node).constraint) ||
477+
visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
481478
case SyntaxKind.JSDocTypedefTag:
482-
if ((node as JSDocTypedefTag).typeExpression &&
483-
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression) {
484-
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
485-
visitNode(cbNode, (<JSDocTypedefTag>node).fullName);
486-
}
487-
else {
488-
return visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
489-
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression);
490-
}
479+
return visitNode(cbNode, (node as JSDocTag).tagName) ||
480+
((node as JSDocTypedefTag).typeExpression &&
481+
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression
482+
? visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
483+
visitNode(cbNode, (<JSDocTypedefTag>node).fullName)
484+
: visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
485+
visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression));
491486
case SyntaxKind.JSDocCallbackTag:
492-
return visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
487+
return visitNode(cbNode, (node as JSDocTag).tagName) ||
488+
visitNode(cbNode, (node as JSDocCallbackTag).fullName) ||
493489
visitNode(cbNode, (node as JSDocCallbackTag).typeExpression);
490+
case SyntaxKind.JSDocReturnTag:
491+
case SyntaxKind.JSDocTypeTag:
494492
case SyntaxKind.JSDocThisTag:
495-
return visitNode(cbNode, (node as JSDocThisTag).typeExpression);
496493
case SyntaxKind.JSDocEnumTag:
497-
return visitNode(cbNode, (node as JSDocEnumTag).typeExpression);
494+
return visitNode(cbNode, (node as JSDocTag).tagName) ||
495+
visitNode(cbNode, (node as JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag).typeExpression);
498496
case SyntaxKind.JSDocSignature:
499-
return visitNodes(cbNode, cbNodes, node.decorators) ||
500-
visitNodes(cbNode, cbNodes, node.modifiers) ||
501-
forEach((<JSDocSignature>node).typeParameters, cbNode) ||
497+
return forEach((<JSDocSignature>node).typeParameters, cbNode) ||
502498
forEach((<JSDocSignature>node).parameters, cbNode) ||
503499
visitNode(cbNode, (<JSDocSignature>node).type);
504500
case SyntaxKind.JSDocTypeLiteral:
505-
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
506-
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags!) {
507-
visitNode(cbNode, tag);
508-
}
509-
}
510-
return;
501+
return forEach((node as JSDocTypeLiteral).jsDocPropertyTags, cbNode);
502+
case SyntaxKind.JSDocTag:
503+
case SyntaxKind.JSDocClassTag:
504+
return visitNode(cbNode, (node as JSDocTag).tagName);
511505
case SyntaxKind.PartiallyEmittedExpression:
512506
return visitNode(cbNode, (<PartiallyEmittedExpression>node).expression);
513507
}

src/compiler/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6841,7 +6841,7 @@ namespace ts {
68416841

68426842
// TODO: determine what this does before making it public.
68436843
/* @internal */
6844-
export function isJSDocTag(node: Node): boolean {
6844+
export function isJSDocTag(node: Node): node is JSDocTag {
68456845
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
68466846
}
68476847

src/services/services.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,7 @@ namespace ts {
14811481
function shouldGetType(sourceFile: SourceFile, node: Node, position: number): boolean {
14821482
switch (node.kind) {
14831483
case SyntaxKind.Identifier:
1484-
return !isLabelName(node);
1484+
return !isLabelName(node) && !isTagName(node);
14851485
case SyntaxKind.PropertyAccessExpression:
14861486
case SyntaxKind.QualifiedName:
14871487
// Don't return quickInfo if inside the comment in `a/**/.b`
@@ -2159,7 +2159,7 @@ namespace ts {
21592159
function initializeNameTable(sourceFile: SourceFile): void {
21602160
const nameTable = sourceFile.nameTable = createUnderscoreEscapedMap<number>();
21612161
sourceFile.forEachChild(function walk(node) {
2162-
if (isIdentifier(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) {
2162+
if (isIdentifier(node) && !isTagName(node) && node.escapedText || isStringOrNumericLiteralLike(node) && literalIsName(node)) {
21632163
const text = getEscapedTextOfIdentifierOrLiteral(node);
21642164
nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1);
21652165
}

src/services/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ namespace ts {
246246
return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
247247
}
248248

249+
export function isTagName(node: Node): boolean {
250+
return isJSDocTag(node.parent) && node.parent.tagName === node;
251+
}
252+
249253
export function isRightSideOfQualifiedName(node: Node) {
250254
return node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node;
251255
}

0 commit comments

Comments
 (0)