Skip to content

Commit 33df18d

Browse files
author
Andy
authored
Consistently use ScriptInfo for converting positions to Locations (#25623) (#25777)
* Consistently use ScriptInfo for converting positions to Locations * Code review
1 parent 53d2400 commit 33df18d

File tree

3 files changed

+65
-48
lines changed

3 files changed

+65
-48
lines changed

src/server/session.ts

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ namespace ts.server {
14331433
return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source, this.getPreferences(file));
14341434
});
14351435
return simplifiedResult
1436-
? result.map(details => ({ ...details, codeActions: map(details.codeActions, action => this.mapCodeAction(project, action)) }))
1436+
? result.map(details => ({ ...details, codeActions: map(details.codeActions, action => this.mapCodeAction(action)) }))
14371437
: result;
14381438
}
14391439

@@ -1735,7 +1735,7 @@ namespace ts.server {
17351735
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename))!;
17361736
mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits);
17371737
}
1738-
return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(project, edits) };
1738+
return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(edits) };
17391739
}
17401740
else {
17411741
return result;
@@ -1747,7 +1747,7 @@ namespace ts.server {
17471747
const { file, project } = this.getFileAndProject(scope.args);
17481748
const changes = project.getLanguageService().organizeImports({ type: "file", fileName: file }, this.getFormatOptions(file), this.getPreferences(file));
17491749
if (simplifiedResult) {
1750-
return this.mapTextChangesToCodeEdits(project, changes);
1750+
return this.mapTextChangesToCodeEdits(changes);
17511751
}
17521752
else {
17531753
return changes;
@@ -1763,7 +1763,7 @@ namespace ts.server {
17631763
this.projectService,
17641764
project => project.getLanguageService().getEditsForFileRename(oldPath, newPath, formatOptions, preferences),
17651765
(a, b) => a.fileName === b.fileName);
1766-
return simplifiedResult ? changes.map(c => this.mapTextChangeToCodeEditUsingScriptInfoOrConfigFile(c)) : changes;
1766+
return simplifiedResult ? changes.map(c => this.mapTextChangeToCodeEdit(c)) : changes;
17671767
}
17681768

17691769
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> | undefined {
@@ -1776,15 +1776,15 @@ namespace ts.server {
17761776
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
17771777

17781778
const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes!, this.getFormatOptions(file), this.getPreferences(file));
1779-
return simplifiedResult ? codeActions.map(codeAction => this.mapCodeFixAction(project, codeAction)) : codeActions;
1779+
return simplifiedResult ? codeActions.map(codeAction => this.mapCodeFixAction(codeAction)) : codeActions;
17801780
}
17811781

17821782
private getCombinedCodeFix({ scope, fixId }: protocol.GetCombinedCodeFixRequestArgs, simplifiedResult: boolean): protocol.CombinedCodeActions | CombinedCodeActions {
17831783
Debug.assert(scope.type === "file");
17841784
const { file, project } = this.getFileAndProject(scope.args);
17851785
const res = project.getLanguageService().getCombinedCodeFix({ type: "file", fileName: file }, fixId, this.getFormatOptions(file), this.getPreferences(file));
17861786
if (simplifiedResult) {
1787-
return { changes: this.mapTextChangesToCodeEdits(project, res.changes), commands: res.commands };
1787+
return { changes: this.mapTextChangesToCodeEdits(res.changes), commands: res.commands };
17881788
}
17891789
else {
17901790
return res;
@@ -1824,28 +1824,20 @@ namespace ts.server {
18241824
return { startPosition, endPosition };
18251825
}
18261826

1827-
private mapCodeAction(project: Project, { description, changes, commands }: CodeAction): protocol.CodeAction {
1828-
return { description, changes: this.mapTextChangesToCodeEdits(project, changes), commands };
1827+
private mapCodeAction({ description, changes, commands }: CodeAction): protocol.CodeAction {
1828+
return { description, changes: this.mapTextChangesToCodeEdits(changes), commands };
18291829
}
18301830

1831-
private mapCodeFixAction(project: Project, { fixName, description, changes, commands, fixId, fixAllDescription }: CodeFixAction): protocol.CodeFixAction {
1832-
return { fixName, description, changes: this.mapTextChangesToCodeEdits(project, changes), commands, fixId, fixAllDescription };
1831+
private mapCodeFixAction({ fixName, description, changes, commands, fixId, fixAllDescription }: CodeFixAction): protocol.CodeFixAction {
1832+
return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription };
18331833
}
18341834

1835-
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
1836-
return textChanges.map(change => this.mapTextChangeToCodeEdit(project, change));
1835+
private mapTextChangesToCodeEdits(textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
1836+
return textChanges.map(change => this.mapTextChangeToCodeEdit(change));
18371837
}
18381838

1839-
private mapTextChangeToCodeEdit(project: Project, change: FileTextChanges): protocol.FileCodeEdits {
1840-
return mapTextChangesToCodeEditsForFile(change, project.getSourceFileOrConfigFile(this.normalizePath(change.fileName)));
1841-
}
1842-
1843-
private mapTextChangeToCodeEditUsingScriptInfoOrConfigFile(change: FileTextChanges): protocol.FileCodeEdits {
1844-
return mapTextChangesToCodeEditsUsingScriptInfoOrConfig(change, this.projectService.getScriptInfoOrConfig(this.normalizePath(change.fileName)));
1845-
}
1846-
1847-
private normalizePath(fileName: string) {
1848-
return normalizedPathToPath(toNormalizedPath(fileName), this.host.getCurrentDirectory(), fileName => this.getCanonicalFileName(fileName));
1839+
private mapTextChangeToCodeEdit(change: FileTextChanges): protocol.FileCodeEdits {
1840+
return mapTextChangesToCodeEdits(change, this.projectService.getScriptInfoOrConfig(change.fileName));
18491841
}
18501842

18511843
private convertTextChangeToCodeEdit(change: TextChange, scriptInfo: ScriptInfo): protocol.CodeEdit {
@@ -2357,35 +2349,14 @@ namespace ts.server {
23572349
return { file: fileName, start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) };
23582350
}
23592351

2360-
function mapTextChangesToCodeEditsForFile(textChanges: FileTextChanges, sourceFile: SourceFile | undefined): protocol.FileCodeEdits {
2361-
Debug.assert(!!textChanges.isNewFile === !sourceFile, "Expected isNewFile for (only) new files", () => JSON.stringify({ isNewFile: !!textChanges.isNewFile, hasSourceFile: !!sourceFile }));
2362-
if (sourceFile) {
2363-
return {
2364-
fileName: textChanges.fileName,
2365-
textChanges: textChanges.textChanges.map(textChange => convertTextChangeToCodeEdit(textChange, sourceFile)),
2366-
};
2367-
}
2368-
else {
2369-
return convertNewFileTextChangeToCodeEdit(textChanges);
2370-
}
2371-
}
2372-
2373-
function mapTextChangesToCodeEditsUsingScriptInfoOrConfig(textChanges: FileTextChanges, scriptInfo: ScriptInfoOrConfig | undefined): protocol.FileCodeEdits {
2352+
function mapTextChangesToCodeEdits(textChanges: FileTextChanges, scriptInfo: ScriptInfoOrConfig | undefined): protocol.FileCodeEdits {
23742353
Debug.assert(!!textChanges.isNewFile === !scriptInfo, "Expected isNewFile for (only) new files", () => JSON.stringify({ isNewFile: !!textChanges.isNewFile, hasScriptInfo: !!scriptInfo }));
23752354
return scriptInfo
2376-
? { fileName: textChanges.fileName, textChanges: textChanges.textChanges.map(textChange => convertTextChangeToCodeEditUsingScriptInfoOrConfig(textChange, scriptInfo)) }
2355+
? { fileName: textChanges.fileName, textChanges: textChanges.textChanges.map(textChange => convertTextChangeToCodeEdit(textChange, scriptInfo)) }
23772356
: convertNewFileTextChangeToCodeEdit(textChanges);
23782357
}
23792358

2380-
function convertTextChangeToCodeEdit(change: TextChange, sourceFile: SourceFile): protocol.CodeEdit {
2381-
return {
2382-
start: convertToLocation(sourceFile.getLineAndCharacterOfPosition(change.span.start)),
2383-
end: convertToLocation(sourceFile.getLineAndCharacterOfPosition(change.span.start + change.span.length)),
2384-
newText: change.newText ? change.newText : "",
2385-
};
2386-
}
2387-
2388-
function convertTextChangeToCodeEditUsingScriptInfoOrConfig(change: TextChange, scriptInfo: ScriptInfoOrConfig): protocol.CodeEdit {
2359+
function convertTextChangeToCodeEdit(change: TextChange, scriptInfo: ScriptInfoOrConfig): protocol.CodeEdit {
23892360
return { start: positionToLineOffset(scriptInfo, change.span.start), end: positionToLineOffset(scriptInfo, textSpanEnd(change.span)), newText: change.newText };
23902361
}
23912362

src/testRunner/unittests/tsserverProjectSystem.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,10 @@ namespace ts.projectSystem {
515515
return session.executeCommand(makeSessionRequest(command, args)).response as TResponse["body"];
516516
}
517517

518+
export function executeSessionRequestNoResponse<TRequest extends protocol.Request>(session: server.Session, command: TRequest["command"], args: TRequest["arguments"]): void {
519+
session.executeCommand(makeSessionRequest(command, args));
520+
}
521+
518522
export function openFilesForSession(files: ReadonlyArray<File | { readonly file: File | string, readonly projectRootPath: string }>, session: server.Session): void {
519523
for (const file of files) {
520524
session.executeCommand(makeSessionRequest<protocol.OpenRequestArgs>(CommandNames.Open,
@@ -9256,6 +9260,50 @@ export function Test2() {
92569260
});
92579261
});
92589262

9263+
describe("Untitled files", () => {
9264+
it("Can convert positions to locations", () => {
9265+
const aTs: File = { path: "/proj/a.ts", content: "" };
9266+
const tsconfig: File = { path: "/proj/tsconfig.json", content: "{}" };
9267+
const session = createSession(createServerHost([aTs, tsconfig]));
9268+
9269+
openFilesForSession([aTs], session);
9270+
9271+
const untitledFile = "untitled:^Untitled-1";
9272+
executeSessionRequestNoResponse<protocol.OpenRequest>(session, protocol.CommandTypes.Open, {
9273+
file: untitledFile,
9274+
fileContent: "let foo = 1;\nfooo/**/",
9275+
scriptKindName: "TS",
9276+
projectRootPath: "/proj",
9277+
});
9278+
9279+
const response = executeSessionRequest<protocol.CodeFixRequest, protocol.CodeFixResponse>(session, protocol.CommandTypes.GetCodeFixes, {
9280+
file: untitledFile,
9281+
startLine: 2,
9282+
startOffset: 1,
9283+
endLine: 2,
9284+
endOffset: 5,
9285+
errorCodes: [Diagnostics.Cannot_find_name_0_Did_you_mean_1.code],
9286+
});
9287+
assert.deepEqual<ReadonlyArray<protocol.CodeFixAction> | undefined>(response, [
9288+
{
9289+
description: "Change spelling to 'foo'",
9290+
fixAllDescription: "Fix all detected spelling errors",
9291+
fixId: "fixSpelling",
9292+
fixName: "spelling",
9293+
changes: [{
9294+
fileName: untitledFile,
9295+
textChanges: [{
9296+
start: { line: 2, offset: 1 },
9297+
end: { line: 2, offset: 5 },
9298+
newText: "foo",
9299+
}],
9300+
}],
9301+
commands: undefined,
9302+
},
9303+
]);
9304+
});
9305+
});
9306+
92599307
function makeReferenceItem(file: File, isDefinition: boolean, text: string, lineText: string, options?: SpanFromSubstringOptions): protocol.ReferencesResponseItem {
92609308
return {
92619309
...protocolFileSpanFromSubstring(file, text, options),

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8893,8 +8893,6 @@ declare namespace ts.server {
88938893
private mapCodeFixAction;
88948894
private mapTextChangesToCodeEdits;
88958895
private mapTextChangeToCodeEdit;
8896-
private mapTextChangeToCodeEditUsingScriptInfoOrConfigFile;
8897-
private normalizePath;
88988896
private convertTextChangeToCodeEdit;
88998897
private getBraceMatching;
89008898
private getDiagnosticsForProject;

0 commit comments

Comments
 (0)