From eb09afb2b85472b9f4e79cf0a7ca45856f6cb9d3 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 27 Dec 2023 01:41:56 +0200 Subject: [PATCH 1/2] fix(55650): show quick info in JSDoc @implements tag --- src/compiler/utilities.ts | 11 +- .../reference/quickInfoJsDocTags15.baseline | 106 ++++++++++++++++++ tests/cases/fourslash/quickInfoJsDocTags15.ts | 26 +++++ 3 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/quickInfoJsDocTags15.baseline create mode 100644 tests/cases/fourslash/quickInfoJsDocTags15.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 398b7f1e61305..23b4b3d0ddb5f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -282,6 +282,7 @@ import { isJSDoc, isJSDocAugmentsTag, isJSDocFunctionType, + isJSDocImplementsTag, isJSDocLinkLike, isJSDocMemberName, isJSDocNameReference, @@ -2452,7 +2453,7 @@ export function isPartOfTypeNode(node: Node): boolean { case SyntaxKind.VoidKeyword: return node.parent.kind !== SyntaxKind.VoidExpression; case SyntaxKind.ExpressionWithTypeArguments: - return isHeritageClause(node.parent) && !isExpressionWithTypeArgumentsInClassExtendsClause(node); + return isPartOfTypeExpressionWithTypeArguments(node); case SyntaxKind.TypeParameter: return node.parent.kind === SyntaxKind.MappedType || node.parent.kind === SyntaxKind.InferType; @@ -2491,7 +2492,7 @@ export function isPartOfTypeNode(node: Node): boolean { } switch (parent.kind) { case SyntaxKind.ExpressionWithTypeArguments: - return isHeritageClause(parent.parent) && !isExpressionWithTypeArgumentsInClassExtendsClause(parent); + return isPartOfTypeExpressionWithTypeArguments(parent); case SyntaxKind.TypeParameter: return node === (parent as TypeParameterDeclaration).constraint; case SyntaxKind.JSDocTemplateTag: @@ -2527,6 +2528,12 @@ export function isPartOfTypeNode(node: Node): boolean { return false; } +function isPartOfTypeExpressionWithTypeArguments(node: Node) { + return isJSDocImplementsTag(node.parent) + || isJSDocAugmentsTag(node.parent) + || isHeritageClause(node.parent) && !isExpressionWithTypeArgumentsInClassExtendsClause(node); +} + /** @internal */ export function isChildOfNodeWithKind(node: Node, kind: SyntaxKind): boolean { while (node) { diff --git a/tests/baselines/reference/quickInfoJsDocTags15.baseline b/tests/baselines/reference/quickInfoJsDocTags15.baseline new file mode 100644 index 0000000000000..4e02f51dcbbd9 --- /dev/null +++ b/tests/baselines/reference/quickInfoJsDocTags15.baseline @@ -0,0 +1,106 @@ +// === QuickInfo === +=== /b.js === +// import * as _a from "./a.js"; +// /** +// * @implements {_a.Foo} +// ^^^ +// | ---------------------------------------------------------------------- +// | type Foo = { +// | getName: _a.Bar; +// | } +// | ---------------------------------------------------------------------- +// */ +// class Foo { } + +[ + { + "marker": { + "fileName": "/b.js", + "position": 56, + "name": "2" + }, + "item": { + "kind": "type", + "kindModifiers": "", + "textSpan": { + "start": 53, + "length": 3 + }, + "displayParts": [ + { + "text": "type", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Foo", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "getName", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "_a", + "kind": "aliasName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "Bar", + "kind": "aliasName" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoJsDocTags15.ts b/tests/cases/fourslash/quickInfoJsDocTags15.ts new file mode 100644 index 0000000000000..c84761b314667 --- /dev/null +++ b/tests/cases/fourslash/quickInfoJsDocTags15.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true +// @checkJs: true +// @filename: /a.js +/////** +//// * @callback Bar +//// * @param {string} name +//// * @returns {string} +//// */ +//// +/////** +//// * @typedef Foo +//// * @property {Bar} getName +//// */ +////export const foo = 1; + +// @filename: /b.js +////import * as _a from "./a.js"; +/////** +//// * @implements {_a.Foo/*2*/} +//// */ +////class Foo { } + +goTo.file("/b.js") +verify.baselineQuickInfo(); From 75a86ca362f3d049697cf16752b916f230de6afe Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Sat, 6 Jan 2024 01:03:39 +0200 Subject: [PATCH 2/2] add tests --- .../reference/quickInfoJsDocTags15.baseline | 206 +++++++++++++++++- tests/cases/fourslash/quickInfoJsDocTags15.ts | 14 +- 2 files changed, 216 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/quickInfoJsDocTags15.baseline b/tests/baselines/reference/quickInfoJsDocTags15.baseline index 4e02f51dcbbd9..da5ff2162dba0 100644 --- a/tests/baselines/reference/quickInfoJsDocTags15.baseline +++ b/tests/baselines/reference/quickInfoJsDocTags15.baseline @@ -10,14 +10,36 @@ // | } // | ---------------------------------------------------------------------- // */ -// class Foo { } +// class C1 { } +// +// /** +// * @extends {_a.Foo} +// ^^^ +// | ---------------------------------------------------------------------- +// | type Foo = { +// | getName: _a.Bar; +// | } +// | ---------------------------------------------------------------------- +// */ +// class C2 { } +// +// /** +// * @augments {_a.Foo} +// ^^^ +// | ---------------------------------------------------------------------- +// | type Foo = { +// | getName: _a.Bar; +// | } +// | ---------------------------------------------------------------------- +// */ +// class C3 { } [ { "marker": { "fileName": "/b.js", "position": 56, - "name": "2" + "name": "1" }, "item": { "kind": "type", @@ -102,5 +124,185 @@ ], "documentation": [] } + }, + { + "marker": { + "fileName": "/b.js", + "position": 99, + "name": "2" + }, + "item": { + "kind": "type", + "kindModifiers": "", + "textSpan": { + "start": 96, + "length": 3 + }, + "displayParts": [ + { + "text": "type", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Foo", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "getName", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "_a", + "kind": "aliasName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "Bar", + "kind": "aliasName" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [] + } + }, + { + "marker": { + "fileName": "/b.js", + "position": 143, + "name": "3" + }, + "item": { + "kind": "type", + "kindModifiers": "", + "textSpan": { + "start": 140, + "length": 3 + }, + "displayParts": [ + { + "text": "type", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Foo", + "kind": "aliasName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "getName", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "_a", + "kind": "aliasName" + }, + { + "text": ".", + "kind": "punctuation" + }, + { + "text": "Bar", + "kind": "aliasName" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [] + } } ] \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoJsDocTags15.ts b/tests/cases/fourslash/quickInfoJsDocTags15.ts index c84761b314667..aa611224d8e89 100644 --- a/tests/cases/fourslash/quickInfoJsDocTags15.ts +++ b/tests/cases/fourslash/quickInfoJsDocTags15.ts @@ -18,9 +18,19 @@ // @filename: /b.js ////import * as _a from "./a.js"; /////** -//// * @implements {_a.Foo/*2*/} +//// * @implements {_a.Foo/*1*/} //// */ -////class Foo { } +////class C1 { } +//// +/////** +//// * @extends {_a.Foo/*2*/} +//// */ +////class C2 { } +//// +/////** +//// * @augments {_a.Foo/*3*/} +//// */ +////class C3 { } goTo.file("/b.js") verify.baselineQuickInfo();