From a2ad9642cb4da1ec13740bf1e29f035abc2106e2 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 19 Oct 2021 08:57:44 -0700 Subject: [PATCH] @link: format trailing () as part of linkName Parsing separates the identifier part of the link tag from its text, but the editor should present an identifier followed by `()` as a single identifier since people use that syntax as a function sigil. I prefer `#'` personally, you know, xkcd 297, nudge nudge. --- src/services/utilities.ts | 13 +- tests/baselines/reference/jsdocLink1.baseline | 6 +- tests/baselines/reference/jsdocLink2.baseline | 6 +- tests/baselines/reference/jsdocLink3.baseline | 6 +- tests/baselines/reference/jsdocLink5.baseline | 319 ++++++++++++++++++ tests/cases/fourslash/jsdocLink5.ts | 11 + 6 files changed, 341 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/jsdocLink5.baseline create mode 100644 tests/cases/fourslash/jsdocLink5.ts diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5414814bd2eb0..05ed20effbad5 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2290,9 +2290,9 @@ namespace ts { return displayPart(text, SymbolDisplayPartKind.linkText); } - export function linkNamePart(name: EntityName | JSDocMemberName, target: Declaration): JSDocLinkDisplayPart { + export function linkNamePart(text: string, target: Declaration): JSDocLinkDisplayPart { return { - text: getTextOfNode(name), + text, kind: SymbolDisplayPartKind[SymbolDisplayPartKind.linkName], target: { fileName: getSourceFileOfNode(target).fileName, @@ -2315,13 +2315,16 @@ namespace ts { } else { const symbol = checker?.getSymbolAtLocation(link.name); + const trailingParen = link.text.indexOf("()") === 0; + const name = getTextOfNode(link.name) + (trailingParen ? "()" : ""); + const text = trailingParen ? link.text.slice(2) : link.text; const decl = symbol?.valueDeclaration || symbol?.declarations?.[0]; if (decl) { - parts.push(linkNamePart(link.name, decl)); - if (link.text) parts.push(linkTextPart(link.text)); + parts.push(linkNamePart(name, decl)); + if (text) parts.push(linkTextPart(text)); } else { - parts.push(linkTextPart(getTextOfNode(link.name) + " " + link.text)); + parts.push(linkTextPart(name + (trailingParen ? "" : " ") + text)); } } parts.push(linkPart("}")); diff --git a/tests/baselines/reference/jsdocLink1.baseline b/tests/baselines/reference/jsdocLink1.baseline index ccbabd7b5c364..ebe2a61a9b61f 100644 --- a/tests/baselines/reference/jsdocLink1.baseline +++ b/tests/baselines/reference/jsdocLink1.baseline @@ -107,7 +107,7 @@ "kind": "link" }, { - "text": "C", + "text": "C()", "kind": "linkName", "target": { "fileName": "/tests/cases/fourslash/jsdocLink1.ts", @@ -117,10 +117,6 @@ } } }, - { - "text": "()", - "kind": "linkText" - }, { "text": "}", "kind": "link" diff --git a/tests/baselines/reference/jsdocLink2.baseline b/tests/baselines/reference/jsdocLink2.baseline index 25697b456783f..ccf6e5e3173de 100644 --- a/tests/baselines/reference/jsdocLink2.baseline +++ b/tests/baselines/reference/jsdocLink2.baseline @@ -107,7 +107,7 @@ "kind": "link" }, { - "text": "C", + "text": "C()", "kind": "linkName", "target": { "fileName": "/tests/cases/fourslash/jsdocLink2.ts", @@ -117,10 +117,6 @@ } } }, - { - "text": "()", - "kind": "linkText" - }, { "text": "}", "kind": "link" diff --git a/tests/baselines/reference/jsdocLink3.baseline b/tests/baselines/reference/jsdocLink3.baseline index 56e65b430e71d..d8513ef3b4ca6 100644 --- a/tests/baselines/reference/jsdocLink3.baseline +++ b/tests/baselines/reference/jsdocLink3.baseline @@ -107,7 +107,7 @@ "kind": "link" }, { - "text": "C", + "text": "C()", "kind": "linkName", "target": { "fileName": "/jsdocLink3.ts", @@ -117,10 +117,6 @@ } } }, - { - "text": "()", - "kind": "linkText" - }, { "text": "}", "kind": "link" diff --git a/tests/baselines/reference/jsdocLink5.baseline b/tests/baselines/reference/jsdocLink5.baseline new file mode 100644 index 0000000000000..ddb421a4830f0 --- /dev/null +++ b/tests/baselines/reference/jsdocLink5.baseline @@ -0,0 +1,319 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "position": 210, + "name": "3" + }, + "quickInfo": { + "kind": "function", + "kindModifiers": "", + "textSpan": { + "start": 209, + "length": 1 + }, + "displayParts": [ + { + "text": "function", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "f", + "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": "", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": " ", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": " 0", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": "1", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "g()", + "kind": "linkName", + "target": { + "fileName": "/tests/cases/fourslash/jsdocLink5.ts", + "textSpan": { + "start": 0, + "length": 16 + } + } + }, + { + "text": " 2", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": "\n", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u()", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u() ", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u()", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u() 0", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u()1", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + }, + { + "text": " ", + "kind": "text" + }, + { + "text": "{@link ", + "kind": "link" + }, + { + "text": "u() 2", + "kind": "linkText" + }, + { + "text": "}", + "kind": "link" + } + ] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/jsdocLink5.ts b/tests/cases/fourslash/jsdocLink5.ts new file mode 100644 index 0000000000000..d233aff2d6f13 --- /dev/null +++ b/tests/cases/fourslash/jsdocLink5.ts @@ -0,0 +1,11 @@ +/// + +//// function g() { } +//// /** +//// * {@link g()} {@link g() } {@link g ()} {@link g () 0} {@link g()1} {@link g() 2} +//// * {@link u()} {@link u() } {@link u ()} {@link u () 0} {@link u()1} {@link u() 2} +//// */ +//// function f(x) { +//// } +//// f/*3*/() +verify.baselineQuickInfo();