Skip to content

Commit e149641

Browse files
author
Andy
authored
Combine getDocumentationComment implementations (#22722)
1 parent a5df301 commit e149641

File tree

2 files changed

+25
-62
lines changed

2 files changed

+25
-62
lines changed

src/services/jsDoc.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace ts.JsDoc {
4646
let jsDocTagNameCompletionEntries: CompletionEntry[];
4747
let jsDocTagCompletionEntries: CompletionEntry[];
4848

49-
export function getJsDocCommentsFromDeclarations(declarations?: Declaration[]) {
49+
export function getJsDocCommentsFromDeclarations(declarations: ReadonlyArray<Declaration>): SymbolDisplayPart[] {
5050
// Only collect doc comments from duplicate declarations once:
5151
// In case of a union property there might be same declaration multiple times
5252
// which only varies in type parameter
@@ -124,7 +124,7 @@ namespace ts.JsDoc {
124124
* returns a truthy value, then returns that value.
125125
* If no such value is found, the callback is applied to each element of array and undefined is returned.
126126
*/
127-
function forEachUnique<T, U>(array: T[], callback: (element: T, index: number) => U): U {
127+
function forEachUnique<T, U>(array: ReadonlyArray<T>, callback: (element: T, index: number) => U): U {
128128
if (array) {
129129
for (let i = 0; i < array.length; i++) {
130130
if (array.indexOf(array[i]) === i) {

src/services/services.ts

Lines changed: 23 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -347,30 +347,10 @@ namespace ts {
347347
}
348348

349349
getDocumentationComment(checker: TypeChecker | undefined): SymbolDisplayPart[] {
350-
if (this.documentationComment === undefined) {
351-
if (this.declarations) {
352-
this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations(this.declarations);
353-
354-
if (this.documentationComment.length === 0 || this.declarations.some(hasJSDocInheritDocTag)) {
355-
if (checker) {
356-
for (const declaration of this.declarations) {
357-
const inheritedDocs = findInheritedJSDocComments(declaration, this.getName(), checker);
358-
if (inheritedDocs.length > 0) {
359-
if (this.documentationComment.length > 0) {
360-
inheritedDocs.push(lineBreakPart());
361-
}
362-
this.documentationComment = concatenate(inheritedDocs, this.documentationComment);
363-
break;
364-
}
365-
}
366-
}
367-
}
368-
}
369-
else {
370-
this.documentationComment = [];
371-
}
350+
if (!this.documentationComment) {
351+
this.documentationComment = emptyArray; // Set temporarily to avoid an infinite loop finding inherited docs
352+
this.documentationComment = getDocumentationComment(this.declarations, checker);
372353
}
373-
374354
return this.documentationComment;
375355
}
376356

@@ -504,27 +484,7 @@ namespace ts {
504484
}
505485

506486
getDocumentationComment(): SymbolDisplayPart[] {
507-
if (this.documentationComment === undefined) {
508-
if (this.declaration) {
509-
this.documentationComment = JsDoc.getJsDocCommentsFromDeclarations([this.declaration]);
510-
511-
if (this.documentationComment.length === 0 || hasJSDocInheritDocTag(this.declaration)) {
512-
const inheritedDocs = findInheritedJSDocComments(this.declaration, this.declaration.symbol.getName(), this.checker);
513-
if (this.documentationComment.length > 0) {
514-
inheritedDocs.push(lineBreakPart());
515-
}
516-
this.documentationComment = concatenate(
517-
inheritedDocs,
518-
this.documentationComment
519-
);
520-
}
521-
}
522-
else {
523-
this.documentationComment = [];
524-
}
525-
}
526-
527-
return this.documentationComment;
487+
return this.documentationComment || (this.documentationComment = getDocumentationComment(singleElementArray(this.declaration), this.checker));
528488
}
529489

530490
getJsDocTags(): JSDocTagInfo[] {
@@ -545,6 +505,20 @@ namespace ts {
545505
return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc");
546506
}
547507

508+
function getDocumentationComment(declarations: ReadonlyArray<Declaration> | undefined, checker: TypeChecker | undefined): SymbolDisplayPart[] {
509+
if (!declarations) return emptyArray;
510+
511+
let doc = JsDoc.getJsDocCommentsFromDeclarations(declarations);
512+
if (doc.length === 0 || declarations.some(hasJSDocInheritDocTag)) {
513+
for (const declaration of declarations) {
514+
const inheritedDocs = findInheritedJSDocComments(declaration, declaration.symbol.name, checker);
515+
// TODO: GH#16312 Return a ReadonlyArray, avoid copying inheritedDocs
516+
if (inheritedDocs) doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(lineBreakPart(), doc);
517+
}
518+
}
519+
return doc;
520+
}
521+
548522
/**
549523
* Attempts to find JSDoc comments for possibly-inherited properties. Checks superclasses then traverses
550524
* implemented interfaces until a symbol is found with the same name and with documentation.
@@ -553,23 +527,12 @@ namespace ts {
553527
* @param typeChecker A TypeChecker, used to find inherited properties.
554528
* @returns A filled array of documentation comments if any were found, otherwise an empty array.
555529
*/
556-
function findInheritedJSDocComments(declaration: Declaration, propertyName: string, typeChecker: TypeChecker): SymbolDisplayPart[] {
557-
let foundDocs = false;
558-
return flatMap(declaration.parent ? getAllSuperTypeNodes(declaration.parent) : emptyArray, superTypeNode => {
559-
if (foundDocs) {
560-
return emptyArray;
561-
}
530+
function findInheritedJSDocComments(declaration: Declaration, propertyName: string, typeChecker: TypeChecker): ReadonlyArray<SymbolDisplayPart> | undefined {
531+
return firstDefined(declaration.parent ? getAllSuperTypeNodes(declaration.parent) : emptyArray, superTypeNode => {
562532
const superType = typeChecker.getTypeAtLocation(superTypeNode);
563-
if (!superType) {
564-
return emptyArray;
565-
}
566-
const baseProperty = typeChecker.getPropertyOfType(superType, propertyName);
567-
if (!baseProperty) {
568-
return emptyArray;
569-
}
570-
const inheritedDocs = baseProperty.getDocumentationComment(typeChecker);
571-
foundDocs = inheritedDocs.length > 0;
572-
return inheritedDocs;
533+
const baseProperty = superType && typeChecker.getPropertyOfType(superType, propertyName);
534+
const inheritedDocs = baseProperty && baseProperty.getDocumentationComment(typeChecker);
535+
return inheritedDocs && inheritedDocs.length ? inheritedDocs : undefined;
573536
});
574537
}
575538

0 commit comments

Comments
 (0)