Skip to content

Commit 8274699

Browse files
committed
Use ts.getJSDocTags as per @Andy-MS 's recommendation
1 parent a46713e commit 8274699

File tree

2 files changed

+64
-46
lines changed

2 files changed

+64
-46
lines changed

src/services/jsDoc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ namespace ts.JsDoc {
7171
const tags: JSDocTagInfo[] = [];
7272
forEachUnique(declarations, declaration => {
7373
for (const tag of getJSDocTags(declaration)) {
74-
if (tag.kind === SyntaxKind.JSDocTag || tag.kind === SyntaxKind.JSDocInheritDocTag) {
74+
if (tag.kind === SyntaxKind.JSDocTag) {
7575
tags.push({ name: tag.tagName.text, text: tag.comment });
7676
}
7777
}

src/services/services.ts

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -342,19 +342,24 @@ namespace ts {
342342
return this.declarations;
343343
}
344344

345-
getDocumentationComment(typeChecker?: TypeChecker): SymbolDisplayPart[] {
345+
getDocumentationComment(checker: TypeChecker): SymbolDisplayPart[] {
346346
if (this.documentationComment === undefined) {
347-
this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations(this.declarations);
348-
349-
if (this.documentationComment.length === 0 && hasJSDocInheritDocTag(this) && typeChecker) {
350-
for (const declaration of this.getDeclarations()) {
351-
const inheritedDocs = findInheritedJSDocComments(declaration, this.getName(), typeChecker);
352-
if (inheritedDocs.length > 0) {
353-
this.documentationComment = inheritedDocs;
354-
break;
347+
if (this.declarations) {
348+
this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations(this.declarations);
349+
350+
if (this.documentationComment.length === 0 || this.declarations.some(dec => hasJSDocInheritDocTag(dec))) {
351+
for (const declaration of this.declarations) {
352+
const inheritedDocs = findInheritedJSDocComments(declaration, this.getName(), checker);
353+
if (inheritedDocs.length > 0) {
354+
this.documentationComment = inheritedDocs;
355+
break;
356+
}
355357
}
356358
}
357359
}
360+
else {
361+
this.documentationComment = [];
362+
}
358363
}
359364

360365
return this.documentationComment;
@@ -481,12 +486,17 @@ namespace ts {
481486
return this.checker.getReturnTypeOfSignature(this);
482487
}
483488

484-
getDocumentationComment(typeChecker?: TypeChecker): SymbolDisplayPart[] {
489+
getDocumentationComment(): SymbolDisplayPart[] {
485490
if (this.documentationComment === undefined) {
486-
this.documentationComment = this.declaration ? JsDoc.getJsDocCommentsFromDeclarations([this.declaration]) : [];
491+
if (this.declaration) {
492+
this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations([this.declaration]);
487493

488-
if (this.declaration && this.documentationComment.length === 0 && hasJSDocInheritDocTag(this) && typeChecker) {
489-
this.documentationComment = findInheritedJSDocComments(this.declaration, this.declaration.symbol.getName(), typeChecker);
494+
if (this.documentationComment.length === 0) {
495+
this.documentationComment = findInheritedJSDocComments(this.declaration, this.declaration.symbol.getName(), this.checker);
496+
}
497+
}
498+
else {
499+
this.documentationComment = [];
490500
}
491501
}
492502

@@ -503,12 +513,12 @@ namespace ts {
503513
}
504514

505515
/**
506-
* Returns whether or not the given symbol or signature has a JSDoc "inheritDoc" tag on it.
507-
* @param symbol the Symbol or Signature in question.
508-
* @returns `true` if `symbol` has a JSDoc "inheritDoc" tag on it, otherwise `false`.
516+
* Returns whether or not the given node has a JSDoc "inheritDoc" tag on it.
517+
* @param node the Node in question.
518+
* @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`.
509519
*/
510-
function hasJSDocInheritDocTag(symbol: Signature | Symbol) {
511-
return !!find(symbol.getJsDocTags(), tag => tag.name === "inheritDoc");
520+
function hasJSDocInheritDocTag(node: Node) {
521+
return ts.getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc");
512522
}
513523

514524
/**
@@ -522,41 +532,49 @@ namespace ts {
522532
function findInheritedJSDocComments(declaration: Declaration, propertyName: string, typeChecker: TypeChecker): SymbolDisplayPart[] {
523533
let documentationComment: SymbolDisplayPart[] = [];
524534

525-
if (isClassDeclaration(declaration.parent) || isInterfaceDeclaration(declaration.parent)) {
526-
const container: ClassDeclaration | InterfaceDeclaration = declaration.parent;
535+
const container = declaration.parent;
536+
537+
if (!container || (!isClassDeclaration(container) && !isInterfaceDeclaration(container))) {
538+
return documentationComment;
539+
}
540+
else {
527541
const baseTypeNode = getClassExtendsHeritageClauseElement(container);
542+
if (!baseTypeNode) {
543+
return documentationComment;
544+
}
528545

529-
if (baseTypeNode) {
530-
const baseType = typeChecker.getTypeAtLocation(baseTypeNode);
546+
const baseType = typeChecker.getTypeAtLocation(baseTypeNode);
547+
if (!baseType) {
548+
return documentationComment;
549+
}
531550

532-
// First check superclasses for a property of the same name
533-
let baseProperty = typeChecker.getPropertyOfType(baseType, propertyName);
534-
let baseDocs = baseProperty ? baseProperty.getDocumentationComment(typeChecker) : [];
535-
if (baseDocs.length > 0) {
536-
documentationComment = baseDocs;
537-
}
551+
// First check superclasses for a property of the same name
552+
let baseProperty = typeChecker.getPropertyOfType(baseType, propertyName);
553+
let baseDocs = baseProperty ? baseProperty.getDocumentationComment(typeChecker) : [];
554+
if (baseDocs.length > 0) {
555+
documentationComment = baseDocs;
556+
}
538557

539-
// If there's nothing in the superclass, walk through implemented interfaces left-to-right
540-
if (documentationComment.length === 0) {
541-
const implementedInterfaces = map(
542-
getClassImplementsHeritageClauseElements(container as ClassLikeDeclaration),
543-
interfaceNode => typeChecker.getTypeAtLocation(interfaceNode)
544-
);
545-
546-
for (const implementedInterface of implementedInterfaces) {
547-
// Use the docs from the first implemented interface to have this property and documentation
548-
baseProperty = typeChecker.getPropertyOfType(implementedInterface, propertyName);
549-
baseDocs = baseProperty ? baseProperty.getDocumentationComment(typeChecker) : [];
550-
if (baseDocs.length > 0) {
551-
documentationComment = baseDocs;
552-
break;
553-
}
558+
// If there's nothing in the superclass, walk through implemented interfaces left-to-right
559+
if (documentationComment.length === 0) {
560+
const implementedInterfaces = map(
561+
getClassImplementsHeritageClauseElements(container as ClassLikeDeclaration),
562+
interfaceNode => typeChecker.getTypeAtLocation(interfaceNode)
563+
) || [];
564+
565+
for (const implementedInterface of implementedInterfaces) {
566+
// Use the docs from the first implemented interface to have this property and documentation
567+
baseProperty = typeChecker.getPropertyOfType(implementedInterface, propertyName);
568+
baseDocs = baseProperty ? baseProperty.getDocumentationComment(typeChecker) : [];
569+
if (baseDocs.length > 0) {
570+
documentationComment = baseDocs;
571+
break;
554572
}
555573
}
556574
}
557-
}
558575

559-
return documentationComment;
576+
return documentationComment;
577+
}
560578
}
561579

562580
class SourceFileObject extends NodeObject implements SourceFile {

0 commit comments

Comments
 (0)