Skip to content

Commit e7adb1c

Browse files
author
Andy
authored
Bundle fileName with CodeActionCommand (#19881)
* Bundle fileName with CodeActionCommand * Update test * Fix API tests * Add new overloads in services * Fix overload * Update API baselines
1 parent 0c0f4b8 commit e7adb1c

File tree

10 files changed

+46
-20
lines changed

10 files changed

+46
-20
lines changed

src/compiler/core.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,10 @@ namespace ts {
13241324
return Array.isArray ? Array.isArray(value) : value instanceof Array;
13251325
}
13261326

1327+
export function toArray<T>(value: T | T[]): T[] {
1328+
return isArray(value) ? value : [value];
1329+
}
1330+
13271331
/**
13281332
* Tests whether a value is string
13291333
*/

src/server/protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ namespace ts.server.protocol {
585585
errorCodes?: number[];
586586
}
587587

588-
export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
588+
export interface ApplyCodeActionCommandRequestArgs {
589589
/** May also be an array of commands. */
590590
command: {};
591591
}

src/server/session.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,15 +1569,14 @@ namespace ts.server {
15691569
}
15701570

15711571
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
1572-
const { file, project } = this.getFileAndProject(args);
1573-
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
1574-
const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
1575-
1576-
project.getLanguageService().applyCodeActionCommand(file, command).then(
1577-
result => {
1578-
output(/*success*/ true, isArray(result) ? result.map(res => res.successMessage).join(`${this.host.newLine}${this.host.newLine}`) : result.successMessage);
1579-
},
1580-
error => { output(/*success*/ false, error); });
1572+
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
1573+
for (const command of toArray(commands)) {
1574+
const { project } = this.getFileAndProject(command);
1575+
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
1576+
project.getLanguageService().applyCodeActionCommand(command).then(
1577+
result => { output(/*success*/ true, result.successMessage); },
1578+
error => { output(/*success*/ false, error); });
1579+
}
15811580
}
15821581

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

src/services/codefixes/fixCannotFindModule.ts

Lines changed: 3 additions & 3 deletions
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: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace ts.refactor.installTypesForPackage {
4747
const { file, startPosition } = context;
4848
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
4949
if (isStringLiteral(node) && isModuleIdentifier(node) && getResolvedModule(file, node.text) === undefined) {
50-
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
50+
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, file.fileName, node.text);
5151
}
5252
}
5353

src/services/services.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,18 +1887,21 @@ namespace ts {
18871887
});
18881888
}
18891889

1890+
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
1891+
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
1892+
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
18901893
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
18911894
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
1892-
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
1893-
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
1894-
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action);
1895+
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrUndefined?: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
1896+
const action = typeof fileName === "string" ? actionOrUndefined! : fileName as CodeActionCommand[];
1897+
return isArray(action) ? Promise.all(action.map(applySingleCodeActionCommand)) : applySingleCodeActionCommand(action);
18951898
}
18961899

1897-
function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
1900+
function applySingleCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
18981901
switch (action.type) {
18991902
case "install package":
19001903
return host.installPackage
1901-
? host.installPackage({ fileName, packageName: action.packageName })
1904+
? host.installPackage({ fileName: toPath(action.file, currentDirectory, getCanonicalFileName), packageName: action.packageName })
19021905
: Promise.reject("Host does not implement `installPackage`");
19031906
default:
19041907
Debug.fail();

src/services/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,14 @@ namespace ts {
293293
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
294294

295295
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
296+
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
297+
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
298+
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
299+
/** @deprecated `fileName` will be ignored */
296300
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
301+
/** @deprecated `fileName` will be ignored */
297302
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
303+
/** @deprecated `fileName` will be ignored */
298304
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
299305
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
300306
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
@@ -406,6 +412,7 @@ namespace ts {
406412
export type CodeActionCommand = InstallPackageAction;
407413

408414
export interface InstallPackageAction {
415+
/* @internal */ file: string;
409416
/* @internal */ type: "install package";
410417
/* @internal */ packageName: string;
411418
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3975,8 +3975,14 @@ declare namespace ts {
39753975
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
39763976
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
39773977
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
3978+
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3979+
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3980+
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
3981+
/** @deprecated `fileName` will be ignored */
39783982
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3983+
/** @deprecated `fileName` will be ignored */
39793984
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3985+
/** @deprecated `fileName` will be ignored */
39803986
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
39813987
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
39823988
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
@@ -5275,7 +5281,7 @@ declare namespace ts.server.protocol {
52755281
*/
52765282
errorCodes?: number[];
52775283
}
5278-
interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
5284+
interface ApplyCodeActionCommandRequestArgs {
52795285
/** May also be an array of commands. */
52805286
command: {};
52815287
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3975,8 +3975,14 @@ declare namespace ts {
39753975
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
39763976
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
39773977
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
3978+
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3979+
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3980+
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
3981+
/** @deprecated `fileName` will be ignored */
39783982
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
3983+
/** @deprecated `fileName` will be ignored */
39793984
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
3985+
/** @deprecated `fileName` will be ignored */
39803986
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
39813987
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
39823988
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;

tests/cases/fourslash/codeFixCannotFindModule.ts

Lines changed: 1 addition & 0 deletions
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)