Dedupe inherited jsdoc comments (#34522)

JSDoc on own properties was already deduped, but inherited jsdoc was
incorrectly not deduped.

Fixes #32708
This commit is contained in:
Nathan Shively-Sanders 2019-10-16 15:56:01 -07:00 committed by GitHub
parent d020ac6dd1
commit f3a234caac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 21 deletions

View File

@ -158,25 +158,6 @@ namespace ts.JsDoc {
}
}
/**
* Iterates through 'array' by index and performs the callback on each element of array until the callback
* returns a truthy value, then returns that value.
* If no such value is found, the callback is applied to each element of array and undefined is returned.
*/
function forEachUnique<T, U>(array: readonly T[] | undefined, callback: (element: T, index: number) => U): U | undefined {
if (array) {
for (let i = 0; i < array.length; i++) {
if (array.indexOf(array[i]) === i) {
const result = callback(array[i], i);
if (result) {
return result;
}
}
}
}
return undefined;
}
export function getJSDocTagNameCompletions(): CompletionEntry[] {
return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = map(jsDocTagNames, tagName => {
return {

View File

@ -527,11 +527,11 @@ namespace ts {
let doc = JsDoc.getJsDocCommentsFromDeclarations(declarations);
if (doc.length === 0 || declarations.some(hasJSDocInheritDocTag)) {
for (const declaration of declarations) {
forEachUnique(declarations, declaration => {
const inheritedDocs = findInheritedJSDocComments(declaration, declaration.symbol.name, checker!); // TODO: GH#18217
// TODO: GH#16312 Return a ReadonlyArray, avoid copying inheritedDocs
if (inheritedDocs) doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(lineBreakPart(), doc);
}
});
}
return doc;
}

View File

@ -1458,6 +1458,25 @@ namespace ts {
export function documentSpansEqual(a: DocumentSpan, b: DocumentSpan): boolean {
return a.fileName === b.fileName && textSpansEqual(a.textSpan, b.textSpan);
}
/**
* Iterates through 'array' by index and performs the callback on each element of array until the callback
* returns a truthy value, then returns that value.
* If no such value is found, the callback is applied to each element of array and undefined is returned.
*/
export function forEachUnique<T, U>(array: readonly T[] | undefined, callback: (element: T, index: number) => U): U | undefined {
if (array) {
for (let i = 0; i < array.length; i++) {
if (array.indexOf(array[i]) === i) {
const result = callback(array[i], i);
if (result) {
return result;
}
}
}
}
return undefined;
}
}
// Display-part writer helpers

View File

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
// #32708
////interface I<T> {
//// /** only once please */
//// t: T
////}
////interface C<T> extends I<T> {
//// t: T
////}
////declare var cnsb: C<number> & C<string> & C<boolean>;
////cnsb.t/**/
verify.quickInfoAt("", "(property) C<T>.t: never", "only once please");