Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2992,7 +2992,7 @@ namespace ts {
}

export function getEffectiveImplementsTypeNodes(node: ClassLikeDeclaration): undefined | readonly ExpressionWithTypeArguments[]{
if(isInJSFile(node)) {
if (isInJSFile(node)) {
return getJSDocImplementsTags(node).map(n => n.class);
}
else {
Expand Down
36 changes: 19 additions & 17 deletions src/services/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,9 +550,8 @@ namespace ts {

getJsDocTags(): JSDocTagInfo[] {
if (this.jsDocTags === undefined) {
this.jsDocTags = this.declaration ? JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : [];
this.jsDocTags = this.declaration ? getJsDocTags([this.declaration], this.checker) : [];
}

return this.jsDocTags;
}
}
Expand All @@ -566,34 +565,37 @@ namespace ts {
return getJSDocTags(node).some(tag => tag.tagName.text === "inheritDoc");
}

function getJsDocTags(declarations: Declaration[], checker: TypeChecker): JSDocTagInfo[] {
let tags = JsDoc.getJsDocTagsFromDeclarations(declarations);
if (tags.length === 0 || declarations.some(hasJSDocInheritDocTag)) {
forEachUnique(declarations, declaration => {
const inheritedTags = findBaseOfDeclaration(checker, declaration, symbol => symbol.getJsDocTags());
if (inheritedTags) {
tags = [...inheritedTags, ...tags];
}
});
}
return tags;
}

function getDocumentationComment(declarations: readonly Declaration[] | undefined, checker: TypeChecker | undefined): SymbolDisplayPart[] {
if (!declarations) return emptyArray;

let doc = JsDoc.getJsDocCommentsFromDeclarations(declarations);
if (doc.length === 0 || declarations.some(hasJSDocInheritDocTag)) {
if (checker && (doc.length === 0 || declarations.some(hasJSDocInheritDocTag))) {
forEachUnique(declarations, declaration => {
const inheritedDocs = findInheritedJSDocComments(declaration, declaration.symbol.name, checker!); // TODO: GH#18217
const inheritedDocs = findBaseOfDeclaration(checker, declaration, symbol => symbol.getDocumentationComment(checker));
// TODO: GH#16312 Return a ReadonlyArray, avoid copying inheritedDocs
if (inheritedDocs) doc = doc.length === 0 ? inheritedDocs.slice() : inheritedDocs.concat(lineBreakPart(), doc);
});
}
return doc;
}

/**
* Attempts to find JSDoc comments for possibly-inherited properties. Checks superclasses then traverses
* implemented interfaces until a symbol is found with the same name and with documentation.
* @param declaration The possibly-inherited declaration to find comments for.
* @param propertyName The name of the possibly-inherited property.
* @param typeChecker A TypeChecker, used to find inherited properties.
* @returns A filled array of documentation comments if any were found, otherwise an empty array.
*/
function findInheritedJSDocComments(declaration: Declaration, propertyName: string, typeChecker: TypeChecker): readonly SymbolDisplayPart[] | undefined {
function findBaseOfDeclaration<T>(checker: TypeChecker, declaration: Declaration, cb: (symbol: Symbol) => T[]): T[] | undefined {
return firstDefined(declaration.parent ? getAllSuperTypeNodes(declaration.parent) : emptyArray, superTypeNode => {
const superType = typeChecker.getTypeAtLocation(superTypeNode);
const baseProperty = superType && typeChecker.getPropertyOfType(superType, propertyName);
const inheritedDocs = baseProperty && baseProperty.getDocumentationComment(typeChecker);
return inheritedDocs && inheritedDocs.length ? inheritedDocs : undefined;
const symbol = checker.getPropertyOfType(checker.getTypeAtLocation(superTypeNode), declaration.symbol.name);
return symbol ? cb(symbol) : undefined;
});
}

Expand Down
110 changes: 110 additions & 0 deletions tests/baselines/reference/quickInfoJsDocTags1.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
[
{
"marker": {
"fileName": "/tests/cases/fourslash/quickInfoJsDocTags1.ts",
"position": 298
},
"quickInfo": {
"kind": "function",
"kindModifiers": "",
"textSpan": {
"start": 298,
"length": 3
},
"displayParts": [
{
"text": "function",
"kind": "keyword"
},
{
"text": " ",
"kind": "space"
},
{
"text": "foo",
"kind": "functionName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": "x",
"kind": "parameterName"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "any",
"kind": "keyword"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "void",
"kind": "keyword"
}
],
"documentation": [
{
"text": "Doc",
"kind": "text"
}
],
"tags": [
{
"name": "author",
"text": "Me <[email protected]>"
},
{
"name": "augments",
"text": "C<T> Augments it"
},
{
"name": "template",
"text": "T A template"
},
{
"name": "type",
"text": "{number | string} A type"
},
{
"name": "typedef",
"text": "NumOrStr"
},
{
"name": "property",
"text": "{number} x The prop"
},
{
"name": "param",
"text": "x The param"
},
{
"name": "returns",
"text": "The result"
},
{
"name": "see",
"text": "x (the parameter)"
}
]
}
}
]
94 changes: 94 additions & 0 deletions tests/baselines/reference/quickInfoJsDocTags3.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
[
{
"marker": {
"fileName": "/tests/cases/fourslash/quickInfoJsDocTags3.ts",
"position": 290
},
"quickInfo": {
"kind": "method",
"kindModifiers": "",
"textSpan": {
"start": 290,
"length": 6
},
"displayParts": [
{
"text": "(",
"kind": "punctuation"
},
{
"text": "method",
"kind": "text"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "Bar",
"kind": "className"
},
{
"text": ".",
"kind": "punctuation"
},
{
"text": "method",
"kind": "methodName"
},
{
"text": "(",
"kind": "punctuation"
},
{
"text": ")",
"kind": "punctuation"
},
{
"text": ":",
"kind": "punctuation"
},
{
"text": " ",
"kind": "space"
},
{
"text": "void",
"kind": "keyword"
}
],
"documentation": [
{
"text": "comment",
"kind": "text"
}
],
"tags": [
{
"name": "author",
"text": "Me <[email protected]>"
},
{
"name": "see",
"text": "x (the parameter)"
},
{
"name": "param",
"text": "x - x comment"
},
{
"name": "param",
"text": "y - y comment"
},
{
"name": "throws",
"text": "{Error} comment"
}
]
}
}
]
Loading