Skip to content

Commit 9684ba6

Browse files
Cherry-pick fix for cross-file inlay hints (#55476) to release-5.2 and LKG (#55487)
Co-authored-by: Maria José Solano <[email protected]>
1 parent 555ef99 commit 9684ba6

File tree

7 files changed

+112
-42
lines changed

7 files changed

+112
-42
lines changed

lib/tsserver.js

+20-12
Original file line numberDiff line numberDiff line change
@@ -164760,11 +164760,11 @@ function provideInlayHints(context) {
164760164760
function isSignatureSupportingReturnAnnotation(node) {
164761164761
return isArrowFunction(node) || isFunctionExpression(node) || isFunctionDeclaration(node) || isMethodDeclaration(node) || isGetAccessorDeclaration(node);
164762164762
}
164763-
function addParameterHints(text, parameter, position, isFirstVariadicArgument, sourceFile) {
164763+
function addParameterHints(text, parameter, position, isFirstVariadicArgument) {
164764164764
let hintText = `${isFirstVariadicArgument ? "..." : ""}${text}`;
164765164765
let displayParts;
164766164766
if (shouldUseInteractiveInlayHints(preferences)) {
164767-
displayParts = [getNodeDisplayPart(hintText, parameter, sourceFile), { text: ":" }];
164767+
displayParts = [getNodeDisplayPart(hintText, parameter), { text: ":" }];
164768164768
hintText = "";
164769164769
} else {
164770164770
hintText += ":";
@@ -164837,7 +164837,6 @@ function provideInlayHints(context) {
164837164837
return;
164838164838
}
164839164839
let signatureParamPos = 0;
164840-
const sourceFile = shouldUseInteractiveInlayHints(preferences) ? expr.getSourceFile() : void 0;
164841164840
for (const originalArg of args) {
164842164841
const arg = skipParentheses(originalArg);
164843164842
if (shouldShowLiteralParameterNameHintsOnly(preferences) && !isHintableLiteral(arg)) {
@@ -164870,7 +164869,7 @@ function provideInlayHints(context) {
164870164869
if (leadingCommentsContainsParameterName(arg, name)) {
164871164870
continue;
164872164871
}
164873-
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument, sourceFile);
164872+
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument);
164874164873
}
164875164874
}
164876164875
}
@@ -165006,7 +165005,8 @@ function provideInlayHints(context) {
165006165005
}
165007165006
return true;
165008165007
}
165009-
function getNodeDisplayPart(text, node, sourceFile) {
165008+
function getNodeDisplayPart(text, node) {
165009+
const sourceFile = node.getSourceFile();
165010165010
return {
165011165011
text,
165012165012
span: createTextSpanFromNode(node, sourceFile),
@@ -183666,14 +183666,22 @@ Project '${project.projectName}' (${ProjectKind[project.projectKind]}) ${counter
183666183666
return {
183667183667
...hint,
183668183668
position: scriptInfo.positionToLineOffset(position),
183669-
displayParts: displayParts == null ? void 0 : displayParts.map(({ text, span, file: file2 }) => ({
183670-
text,
183671-
span: span && {
183672-
start: scriptInfo.positionToLineOffset(span.start),
183673-
end: scriptInfo.positionToLineOffset(span.start + span.length),
183674-
file: file2
183669+
displayParts: displayParts == null ? void 0 : displayParts.map(({ text, span, file: file2 }) => {
183670+
if (span) {
183671+
Debug.assertIsDefined(file2, "Target file should be defined together with its span.");
183672+
const scriptInfo2 = this.projectService.getScriptInfo(file2);
183673+
return {
183674+
text,
183675+
span: {
183676+
start: scriptInfo2.positionToLineOffset(span.start),
183677+
end: scriptInfo2.positionToLineOffset(span.start + span.length),
183678+
file: file2
183679+
}
183680+
};
183681+
} else {
183682+
return { text };
183675183683
}
183676-
}))
183684+
})
183677183685
};
183678183686
});
183679183687
}

lib/tsserverlibrary.js

+20-12
Original file line numberDiff line numberDiff line change
@@ -164108,11 +164108,11 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164108164108
function isSignatureSupportingReturnAnnotation(node) {
164109164109
return isArrowFunction(node) || isFunctionExpression(node) || isFunctionDeclaration(node) || isMethodDeclaration(node) || isGetAccessorDeclaration(node);
164110164110
}
164111-
function addParameterHints(text, parameter, position, isFirstVariadicArgument, sourceFile) {
164111+
function addParameterHints(text, parameter, position, isFirstVariadicArgument) {
164112164112
let hintText = `${isFirstVariadicArgument ? "..." : ""}${text}`;
164113164113
let displayParts;
164114164114
if (shouldUseInteractiveInlayHints(preferences)) {
164115-
displayParts = [getNodeDisplayPart(hintText, parameter, sourceFile), { text: ":" }];
164115+
displayParts = [getNodeDisplayPart(hintText, parameter), { text: ":" }];
164116164116
hintText = "";
164117164117
} else {
164118164118
hintText += ":";
@@ -164185,7 +164185,6 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164185164185
return;
164186164186
}
164187164187
let signatureParamPos = 0;
164188-
const sourceFile = shouldUseInteractiveInlayHints(preferences) ? expr.getSourceFile() : void 0;
164189164188
for (const originalArg of args) {
164190164189
const arg = skipParentheses(originalArg);
164191164190
if (shouldShowLiteralParameterNameHintsOnly(preferences) && !isHintableLiteral(arg)) {
@@ -164218,7 +164217,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164218164217
if (leadingCommentsContainsParameterName(arg, name)) {
164219164218
continue;
164220164219
}
164221-
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument, sourceFile);
164220+
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument);
164222164221
}
164223164222
}
164224164223
}
@@ -164354,7 +164353,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164354164353
}
164355164354
return true;
164356164355
}
164357-
function getNodeDisplayPart(text, node, sourceFile) {
164356+
function getNodeDisplayPart(text, node) {
164357+
const sourceFile = node.getSourceFile();
164358164358
return {
164359164359
text,
164360164360
span: createTextSpanFromNode(node, sourceFile),
@@ -181073,14 +181073,22 @@ Project '${project.projectName}' (${ProjectKind[project.projectKind]}) ${counter
181073181073
return {
181074181074
...hint,
181075181075
position: scriptInfo.positionToLineOffset(position),
181076-
displayParts: displayParts == null ? void 0 : displayParts.map(({ text, span, file: file2 }) => ({
181077-
text,
181078-
span: span && {
181079-
start: scriptInfo.positionToLineOffset(span.start),
181080-
end: scriptInfo.positionToLineOffset(span.start + span.length),
181081-
file: file2
181076+
displayParts: displayParts == null ? void 0 : displayParts.map(({ text, span, file: file2 }) => {
181077+
if (span) {
181078+
Debug.assertIsDefined(file2, "Target file should be defined together with its span.");
181079+
const scriptInfo2 = this.projectService.getScriptInfo(file2);
181080+
return {
181081+
text,
181082+
span: {
181083+
start: scriptInfo2.positionToLineOffset(span.start),
181084+
end: scriptInfo2.positionToLineOffset(span.start + span.length),
181085+
file: file2
181086+
}
181087+
};
181088+
} else {
181089+
return { text };
181082181090
}
181083-
}))
181091+
})
181084181092
};
181085181093
});
181086181094
}

lib/typescript.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -164123,11 +164123,11 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164123164123
function isSignatureSupportingReturnAnnotation(node) {
164124164124
return isArrowFunction(node) || isFunctionExpression(node) || isFunctionDeclaration(node) || isMethodDeclaration(node) || isGetAccessorDeclaration(node);
164125164125
}
164126-
function addParameterHints(text, parameter, position, isFirstVariadicArgument, sourceFile) {
164126+
function addParameterHints(text, parameter, position, isFirstVariadicArgument) {
164127164127
let hintText = `${isFirstVariadicArgument ? "..." : ""}${text}`;
164128164128
let displayParts;
164129164129
if (shouldUseInteractiveInlayHints(preferences)) {
164130-
displayParts = [getNodeDisplayPart(hintText, parameter, sourceFile), { text: ":" }];
164130+
displayParts = [getNodeDisplayPart(hintText, parameter), { text: ":" }];
164131164131
hintText = "";
164132164132
} else {
164133164133
hintText += ":";
@@ -164200,7 +164200,6 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164200164200
return;
164201164201
}
164202164202
let signatureParamPos = 0;
164203-
const sourceFile = shouldUseInteractiveInlayHints(preferences) ? expr.getSourceFile() : void 0;
164204164203
for (const originalArg of args) {
164205164204
const arg = skipParentheses(originalArg);
164206164205
if (shouldShowLiteralParameterNameHintsOnly(preferences) && !isHintableLiteral(arg)) {
@@ -164233,7 +164232,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164233164232
if (leadingCommentsContainsParameterName(arg, name)) {
164234164233
continue;
164235164234
}
164236-
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument, sourceFile);
164235+
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument);
164237164236
}
164238164237
}
164239164238
}
@@ -164369,7 +164368,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
164369164368
}
164370164369
return true;
164371164370
}
164372-
function getNodeDisplayPart(text, node, sourceFile) {
164371+
function getNodeDisplayPart(text, node) {
164372+
const sourceFile = node.getSourceFile();
164373164373
return {
164374164374
text,
164375164375
span: createTextSpanFromNode(node, sourceFile),

src/server/session.ts

+17-7
Original file line numberDiff line numberDiff line change
@@ -1850,14 +1850,24 @@ export class Session<TMessage = string> implements EventSender {
18501850
return {
18511851
...hint,
18521852
position: scriptInfo.positionToLineOffset(position),
1853-
displayParts: displayParts?.map(({ text, span, file }) => ({
1854-
text,
1855-
span: span && {
1856-
start: scriptInfo.positionToLineOffset(span.start),
1857-
end: scriptInfo.positionToLineOffset(span.start + span.length),
1858-
file: file!
1853+
displayParts: displayParts?.map(({ text, span, file }) => {
1854+
if (span) {
1855+
Debug.assertIsDefined(file, "Target file should be defined together with its span.");
1856+
const scriptInfo = this.projectService.getScriptInfo(file)!;
1857+
1858+
return {
1859+
text,
1860+
span: {
1861+
start: scriptInfo.positionToLineOffset(span.start),
1862+
end: scriptInfo.positionToLineOffset(span.start + span.length),
1863+
file,
1864+
},
1865+
};
18591866
}
1860-
})),
1867+
else {
1868+
return { text };
1869+
}
1870+
}),
18611871
};
18621872
});
18631873
}

src/services/inlayHints.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ import {
6262
Signature,
6363
skipParentheses,
6464
some,
65-
SourceFile,
6665
Symbol,
6766
SymbolFlags,
6867
SyntaxKind,
@@ -158,11 +157,11 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
158157
return isArrowFunction(node) || isFunctionExpression(node) || isFunctionDeclaration(node) || isMethodDeclaration(node) || isGetAccessorDeclaration(node);
159158
}
160159

161-
function addParameterHints(text: string, parameter: Identifier, position: number, isFirstVariadicArgument: boolean, sourceFile: SourceFile | undefined) {
160+
function addParameterHints(text: string, parameter: Identifier, position: number, isFirstVariadicArgument: boolean) {
162161
let hintText = `${isFirstVariadicArgument ? "..." : ""}${text}`;
163162
let displayParts: InlayHintDisplayPart[] | undefined;
164163
if (shouldUseInteractiveInlayHints(preferences)) {
165-
displayParts = [getNodeDisplayPart(hintText, parameter, sourceFile!), { text: ":" }];
164+
displayParts = [getNodeDisplayPart(hintText, parameter), { text: ":" }];
166165
hintText = "";
167166
}
168167
else {
@@ -249,7 +248,6 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
249248
}
250249

251250
let signatureParamPos = 0;
252-
const sourceFile = shouldUseInteractiveInlayHints(preferences) ? expr.getSourceFile() : undefined;
253251
for (const originalArg of args) {
254252
const arg = skipParentheses(originalArg);
255253
if (shouldShowLiteralParameterNameHintsOnly(preferences) && !isHintableLiteral(arg)) {
@@ -286,7 +284,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
286284
continue;
287285
}
288286

289-
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument, sourceFile);
287+
addParameterHints(name, parameter, originalArg.getStart(), isFirstVariadicArgument);
290288
}
291289
}
292290
}
@@ -436,7 +434,8 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
436434
return true;
437435
}
438436

439-
function getNodeDisplayPart(text: string, node: Node, sourceFile: SourceFile): InlayHintDisplayPart {
437+
function getNodeDisplayPart(text: string, node: Node): InlayHintDisplayPart {
438+
const sourceFile = node.getSourceFile();
440439
return {
441440
text,
442441
span: createTextSpanFromNode(node, sourceFile),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
helperB("hello, world!");
2+
^
3+
{
4+
"text": "",
5+
"position": 45,
6+
"kind": "Parameter",
7+
"whitespaceAfter": true,
8+
"displayParts": [
9+
{
10+
"text": "bParam",
11+
"span": {
12+
"start": 61,
13+
"length": 6
14+
},
15+
"file": "/tests/cases/fourslash/bbb.mts"
16+
},
17+
{
18+
"text": ":"
19+
}
20+
]
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Target: esnext
4+
// @module: nodenext
5+
6+
// @Filename: aaa.mts
7+
////import { helperB } from "./bbb.mjs";
8+
////helperB("hello, world!");
9+
10+
// @Filename: bbb.mts
11+
////import { helperC } from "./ccc.mjs";
12+
13+
////export function helperB(bParam: string) {
14+
//// helperC(bParam);
15+
////}
16+
17+
// @Filename: ccc.mts
18+
////export function helperC(cParam: string) {}
19+
20+
goTo.file("./aaa.mts");
21+
verify.baselineInlayHints(undefined, {
22+
includeInlayParameterNameHints: "all",
23+
interactiveInlayHints: true
24+
});

0 commit comments

Comments
 (0)