From b94940525b77f31a8e7782c92fe3ea53371c93fb Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 9 Nov 2017 13:17:47 -0800 Subject: [PATCH] Allow applyCodeActionCommand to take an array (#19870) * Allow applyCodeActionCommand to take an array * Use this.host.newLine --- src/server/protocol.ts | 1 + src/server/session.ts | 7 +++++-- src/services/services.ts | 10 ++++++++-- src/services/types.ts | 2 ++ src/services/utilities.ts | 1 + tests/baselines/reference/api/tsserverlibrary.d.ts | 3 +++ tests/baselines/reference/api/typescript.d.ts | 2 ++ 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f44efa0db21..3761049017d 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -586,6 +586,7 @@ namespace ts.server.protocol { } export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs { + /** May also be an array of commands. */ command: {}; } diff --git a/src/server/session.ts b/src/server/session.ts index 6c97c3c8bd4..f9a145d16fd 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1571,9 +1571,12 @@ 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; // They should be sending back the command we sent them. + const command = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them. + project.getLanguageService().applyCodeActionCommand(file, command).then( - ({ successMessage }) => { output(/*success*/ true, successMessage); }, + 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); }); } diff --git a/src/services/services.ts b/src/services/services.ts index 37298c8eba8..06358d3a720 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1868,8 +1868,14 @@ namespace ts { }); } - function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise { - fileName = toPath(fileName, currentDirectory, getCanonicalFileName); + function applyCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise; + function applyCodeActionCommand(fileName: Path, action: CodeActionCommand[]): Promise; + function applyCodeActionCommand(fileName: Path, action: CodeActionCommand | CodeActionCommand[]): Promise { + const path = toPath(fileName, currentDirectory, getCanonicalFileName); + return isArray(action) ? Promise.all(action.map(a => applySingleCodeActionCommand(path, a))) : applySingleCodeActionCommand(path, action); + } + + function applySingleCodeActionCommand(fileName: Path, action: CodeActionCommand): Promise { switch (action.type) { case "install package": return host.installPackage diff --git a/src/services/types.ts b/src/services/types.ts index a9244982fbb..bcebc437892 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -294,6 +294,8 @@ namespace ts { getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 1ed44d29f95..cf71118292a 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -3,6 +3,7 @@ interface PromiseConstructor { new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; reject(reason: any): Promise; + all(values: (T | PromiseLike)[]): Promise; } /* @internal */ declare var Promise: PromiseConstructor; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a3499de08ab..78e8a377ec0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3965,6 +3965,8 @@ declare namespace ts { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; @@ -5263,6 +5265,7 @@ declare namespace ts.server.protocol { errorCodes?: number[]; } interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs { + /** May also be an array of commands. */ command: {}; } /** diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 98d7137ddeb..3344193d0ce 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3965,6 +3965,8 @@ declare namespace ts { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; applyCodeActionCommand(fileName: string, action: CodeActionCommand): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; + applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;