Skip to content

Commit 6513bed

Browse files
author
Andy
authored
Bundle fileName with CodeActionCommand (#19881) (#20118)
* Bundle fileName with CodeActionCommand * Update test * Fix API tests * Add new overloads in services * Fix overload * Update API baselines
1 parent 19b0a43 commit 6513bed

File tree

10 files changed

+46
-20
lines changed

10 files changed

+46
-20
lines changed

src/compiler/core.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,10 @@ namespace ts {
12711271
return Array.isArray ? Array.isArray(value) : value instanceof Array;
12721272
}
12731273

1274+
export function toArray<T>(value: T | T[]): T[] {
1275+
return isArray(value) ? value : [value];
1276+
}
1277+
12741278
/**
12751279
* Tests whether a value is string
12761280
*/

src/server/protocol.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ namespace ts.server.protocol {
582582
errorCodes?: number[];
583583
}
584584

585-
export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
585+
export interface ApplyCodeActionCommandRequestArgs {
586586
/** May also be an array of commands. */
587587
command: {};
588588
}

src/server/session.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -1555,15 +1555,14 @@ namespace ts.server {
15551555
}
15561556

15571557
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
1558-
const { file, project } = this.getFileAndProject(args);
1559-
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
1560-
const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
1561-
1562-
project.getLanguageService().applyCodeActionCommand(file, command).then(
1563-
result => {
1564-
output(/*success*/ true, isArray(result) ? result.map(res => res.successMessage).join(`${this.host.newLine}${this.host.newLine}`) : result.successMessage);
1565-
},
1566-
error => { output(/*success*/ false, error); });
1558+
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
1559+
for (const command of toArray(commands)) {
1560+
const { project } = this.getFileAndProject(command);
1561+
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
1562+
project.getLanguageService().applyCodeActionCommand(command).then(
1563+
result => { output(/*success*/ true, result.successMessage); },
1564+
error => { output(/*success*/ false, error); });
1565+
}
15671566
}
15681567

15691568
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {

src/services/codefixes/fixCannotFindModule.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ namespace ts.codefix {
1111
throw Debug.fail(); // These errors should only happen on the module name.
1212
}
1313

14-
const action = tryGetCodeActionForInstallPackageTypes(context.host, token.text);
14+
const action = tryGetCodeActionForInstallPackageTypes(context.host, sourceFile.fileName, token.text);
1515
return action && [action];
1616
},
1717
});
1818

19-
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, moduleName: string): CodeAction | undefined {
19+
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, fileName: string, moduleName: string): CodeAction | undefined {
2020
const { packageName } = getPackageName(moduleName);
2121

2222
if (!host.isKnownTypesPackageName(packageName)) {
@@ -28,7 +28,7 @@ namespace ts.codefix {
2828
return {
2929
description: `Install '${typesPackageName}'`,
3030
changes: [],
31-
commands: [{ type: "install package", packageName: typesPackageName }],
31+
commands: [{ type: "install package", file: fileName, packageName: typesPackageName }],
3232
};
3333
}
3434
}

src/services/refactors/installTypesForPackage.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace ts.refactor.installTypesForPackage {
4949
const { file, startPosition } = context;
5050
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
5151
if (isStringLiteral(node) && isModuleIdentifier(node) && getResolvedModule(file, node.text) === undefined) {
52-
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
52+
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, file.fileName, node.text);
5353
}
5454
}
5555

src/services/services.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -1787,18 +1787,21 @@ namespace ts {
17871787
});
17881788
}
17891789

1790+
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
1791+
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
1792+
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
17901793
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
17911794
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
1792-
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
1793-
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
1794-
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action);
1795+
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrUndefined?: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
1796+
const action = typeof fileName === "string" ? actionOrUndefined! : fileName as CodeActionCommand[];
1797+
return isArray(action) ? Promise.all(action.map(applySingleCodeActionCommand)) : applySingleCodeActionCommand(action);
17951798
}
17961799

1797-
function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
1800+
function applySingleCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
17981801
switch (action.type) {
17991802
case "install package":
18001803
return host.installPackage
1801-
? host.installPackage({ fileName, packageName: action.packageName })
1804+
? host.installPackage({ fileName: toPath(action.file, currentDirectory, getCanonicalFileName), packageName: action.packageName })
18021805
: Promise.reject("Host does not implement `installPackage`");
18031806
default:
18041807
Debug.fail();

src/services/types.ts

+7
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,14 @@ namespace ts {
289289
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
290290

291291
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
292+
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
293+
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
294+
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
295+
/** @deprecated `fileName` will be ignored */
292296
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
297+
/** @deprecated `fileName` will be ignored */
293298
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
299+
/** @deprecated `fileName` will be ignored */
294300
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
295301
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
296302
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
@@ -402,6 +408,7 @@ namespace ts {
402408
export type CodeActionCommand = InstallPackageAction;
403409

404410
export interface InstallPackageAction {
411+
/* @internal */ file: string;
405412
/* @internal */ type: "install package";
406413
/* @internal */ packageName: string;
407414
}

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -3967,8 +3967,14 @@ declare namespace ts {
39673967
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
39683968
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
39693969
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
3970+
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3971+
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3972+
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
3973+
/** @deprecated `fileName` will be ignored */
39703974
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3975+
/** @deprecated `fileName` will be ignored */
39713976
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3977+
/** @deprecated `fileName` will be ignored */
39723978
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
39733979
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
39743980
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
@@ -5262,7 +5268,7 @@ declare namespace ts.server.protocol {
52625268
*/
52635269
errorCodes?: number[];
52645270
}
5265-
interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
5271+
interface ApplyCodeActionCommandRequestArgs {
52665272
/** May also be an array of commands. */
52675273
command: {};
52685274
}

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

+6
Original file line numberDiff line numberDiff line change
@@ -3967,8 +3967,14 @@ declare namespace ts {
39673967
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
39683968
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
39693969
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
3970+
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3971+
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3972+
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
3973+
/** @deprecated `fileName` will be ignored */
39703974
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3975+
/** @deprecated `fileName` will be ignored */
39713976
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3977+
/** @deprecated `fileName` will be ignored */
39723978
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
39733979
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
39743980
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;

tests/cases/fourslash/codeFixCannotFindModule.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ verify.codeFixAvailable([{
1919
description: "Install '@types/abs'",
2020
commands: [{
2121
type: "install package",
22+
file: "/a.ts",
2223
packageName: "@types/abs",
2324
}],
2425
}]);

0 commit comments

Comments
 (0)