Bundle fileName with CodeActionCommand (#19881)

* Bundle fileName with CodeActionCommand

* Update test

* Fix API tests

* Add new overloads in services

* Fix overload

* Update API baselines
This commit is contained in:
Andy
2017-11-17 14:16:38 -08:00
committed by GitHub
parent 0c0f4b81ae
commit e7adb1ce79
10 changed files with 46 additions and 20 deletions

View File

@@ -1324,6 +1324,10 @@ namespace ts {
return Array.isArray ? Array.isArray(value) : value instanceof Array;
}
export function toArray<T>(value: T | T[]): T[] {
return isArray(value) ? value : [value];
}
/**
* Tests whether a value is string
*/

View File

@@ -585,7 +585,7 @@ namespace ts.server.protocol {
errorCodes?: number[];
}
export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
export interface ApplyCodeActionCommandRequestArgs {
/** May also be an array of commands. */
command: {};
}

View File

@@ -1569,15 +1569,14 @@ namespace ts.server {
}
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
const { file, project } = this.getFileAndProject(args);
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
project.getLanguageService().applyCodeActionCommand(file, command).then(
result => {
output(/*success*/ true, isArray(result) ? result.map(res => res.successMessage).join(`${this.host.newLine}${this.host.newLine}`) : result.successMessage);
},
error => { output(/*success*/ false, error); });
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
for (const command of toArray(commands)) {
const { project } = this.getFileAndProject(command);
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
project.getLanguageService().applyCodeActionCommand(command).then(
result => { output(/*success*/ true, result.successMessage); },
error => { output(/*success*/ false, error); });
}
}
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {

View File

@@ -11,12 +11,12 @@ namespace ts.codefix {
throw Debug.fail(); // These errors should only happen on the module name.
}
const action = tryGetCodeActionForInstallPackageTypes(context.host, token.text);
const action = tryGetCodeActionForInstallPackageTypes(context.host, sourceFile.fileName, token.text);
return action && [action];
},
});
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, moduleName: string): CodeAction | undefined {
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, fileName: string, moduleName: string): CodeAction | undefined {
const { packageName } = getPackageName(moduleName);
if (!host.isKnownTypesPackageName(packageName)) {
@@ -28,7 +28,7 @@ namespace ts.codefix {
return {
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [typesPackageName]),
changes: [],
commands: [{ type: "install package", packageName: typesPackageName }],
commands: [{ type: "install package", file: fileName, packageName: typesPackageName }],
};
}
}

View File

@@ -47,7 +47,7 @@ namespace ts.refactor.installTypesForPackage {
const { file, startPosition } = context;
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
if (isStringLiteral(node) && isModuleIdentifier(node) && getResolvedModule(file, node.text) === undefined) {
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, file.fileName, node.text);
}
}

View File

@@ -1887,18 +1887,21 @@ namespace ts {
});
}
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action);
function applyCodeActionCommand(fileName: Path | CodeActionCommand | CodeActionCommand[], actionOrUndefined?: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]> {
const action = typeof fileName === "string" ? actionOrUndefined! : fileName as CodeActionCommand[];
return isArray(action) ? Promise.all(action.map(applySingleCodeActionCommand)) : applySingleCodeActionCommand(action);
}
function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
function applySingleCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult> {
switch (action.type) {
case "install package":
return host.installPackage
? host.installPackage({ fileName, packageName: action.packageName })
? host.installPackage({ fileName: toPath(action.file, currentDirectory, getCanonicalFileName), packageName: action.packageName })
: Promise.reject("Host does not implement `installPackage`");
default:
Debug.fail();

View File

@@ -293,8 +293,14 @@ namespace ts {
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[];
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined;
@@ -406,6 +412,7 @@ namespace ts {
export type CodeActionCommand = InstallPackageAction;
export interface InstallPackageAction {
/* @internal */ file: string;
/* @internal */ type: "install package";
/* @internal */ packageName: string;
}