mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-01 22:12:26 +01:00
Remove duplicate code for applying a code action
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands, workspace, WorkspaceEdit } from 'vscode';
|
||||
import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionContext, Command, commands } from 'vscode';
|
||||
|
||||
import * as Proto from '../protocol';
|
||||
import { ITypescriptServiceClient } from '../typescriptService';
|
||||
import { tsTextSpanToVsRange, vsRangeToTsFileRange } from '../utils/convert';
|
||||
import { vsRangeToTsFileRange } from '../utils/convert';
|
||||
import FormattingConfigurationManager from './formattingConfigurationManager';
|
||||
import { applyCodeAction } from '../utils/codeAction';
|
||||
|
||||
interface NumberSet {
|
||||
[key: number]: boolean;
|
||||
@@ -87,30 +88,7 @@ export default class TypeScriptCodeActionProvider implements CodeActionProvider
|
||||
};
|
||||
}
|
||||
|
||||
private async onCodeAction(action: Proto.CodeAction, file: string): Promise<boolean> {
|
||||
if (action.changes && action.changes.length) {
|
||||
const workspaceEdit = new WorkspaceEdit();
|
||||
for (const change of action.changes) {
|
||||
for (const textChange of change.textChanges) {
|
||||
workspaceEdit.replace(this.client.asUrl(change.fileName),
|
||||
tsTextSpanToVsRange(textChange),
|
||||
textChange.newText);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(await workspace.applyEdit(workspaceEdit))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (action.commands && action.commands.length) {
|
||||
for (const command of action.commands) {
|
||||
const response = await this.client.execute('applyCodeActionCommand', { file, command });
|
||||
if (!response || !response.body) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
private onCodeAction(action: Proto.CodeAction, file: string): Promise<boolean> {
|
||||
return applyCodeAction(this.client, action, file);
|
||||
}
|
||||
}
|
||||
@@ -3,17 +3,18 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CompletionItem, TextDocument, Position, CompletionItemKind, CompletionItemProvider, CancellationToken, TextEdit, Range, SnippetString, workspace, ProviderResult, CompletionContext } from 'vscode';
|
||||
import { CompletionItem, TextDocument, Position, CompletionItemKind, CompletionItemProvider, CancellationToken, TextEdit, Range, SnippetString, workspace, ProviderResult, CompletionContext, commands } from 'vscode';
|
||||
|
||||
import { ITypescriptServiceClient } from '../typescriptService';
|
||||
import TypingsStatus from '../utils/typingsStatus';
|
||||
|
||||
import * as PConst from '../protocol.const';
|
||||
import { CompletionEntry, CompletionsRequestArgs, CompletionDetailsRequestArgs, CompletionEntryDetails } from '../protocol';
|
||||
import { CompletionEntry, CompletionsRequestArgs, CompletionDetailsRequestArgs, CompletionEntryDetails, CodeAction } from '../protocol';
|
||||
import * as Previewer from './previewer';
|
||||
import { tsTextSpanToVsRange, vsPositionToTsFileLocation, tsLocationToVsPosition } from '../utils/convert';
|
||||
import { tsTextSpanToVsRange, vsPositionToTsFileLocation } from '../utils/convert';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import { applyCodeAction } from '../utils/codeAction';
|
||||
let localize = nls.loadMessageBundle();
|
||||
|
||||
class MyCompletionItem extends CompletionItem {
|
||||
@@ -132,6 +133,7 @@ namespace Configuration {
|
||||
}
|
||||
|
||||
export default class TypeScriptCompletionItemProvider implements CompletionItemProvider {
|
||||
private readonly commandId: string;
|
||||
|
||||
private config: Configuration = {
|
||||
useCodeSnippetsOnMethodSuggest: false,
|
||||
@@ -141,8 +143,12 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||
|
||||
constructor(
|
||||
private client: ITypescriptServiceClient,
|
||||
mode: string,
|
||||
private typingsStatus: TypingsStatus
|
||||
) { }
|
||||
) {
|
||||
this.commandId = `_typescript.applyCompletionCodeAction.${mode}`;
|
||||
commands.registerCommand(this.commandId, this.applyCompletionCodeAction, this);
|
||||
}
|
||||
|
||||
public updateConfiguration(): void {
|
||||
// Use shared setting for js and ts
|
||||
@@ -280,20 +286,11 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||
item.documentation = Previewer.markdownDocumentation(detail.documentation, detail.tags);
|
||||
|
||||
if (detail.codeActions && detail.codeActions.length) {
|
||||
const additionalEdits: TextEdit[] = [];
|
||||
for (const action of detail.codeActions) {
|
||||
for (const change of action.changes) {
|
||||
if (change.fileName !== filepath) {
|
||||
continue;
|
||||
}
|
||||
for (const edit of change.textChanges) {
|
||||
additionalEdits.push(new TextEdit(
|
||||
new Range(tsLocationToVsPosition(edit.start), tsLocationToVsPosition(edit.end)),
|
||||
edit.newText));
|
||||
}
|
||||
}
|
||||
}
|
||||
item.additionalTextEdits = additionalEdits;
|
||||
item.command = {
|
||||
title: '',
|
||||
command: this.commandId,
|
||||
arguments: [filepath, detail.codeActions]
|
||||
};
|
||||
}
|
||||
|
||||
if (detail && this.config.useCodeSnippetsOnMethodSuggest && (item.kind === CompletionItemKind.Function || item.kind === CompletionItemKind.Method)) {
|
||||
@@ -357,4 +354,13 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||
|
||||
return new SnippetString(codeSnippet);
|
||||
}
|
||||
|
||||
private async applyCompletionCodeAction(file: string, codeActions: CodeAction[]): Promise<boolean> {
|
||||
for (const action of codeActions) {
|
||||
if (!(await applyCodeAction(this.client, action, file))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class LanguageProvider {
|
||||
const selector = this.description.modeIds;
|
||||
const config = workspace.getConfiguration(this.id);
|
||||
|
||||
const completionItemProvider = new (await import('./features/completionItemProvider')).default(client, this.typingsStatus);
|
||||
const completionItemProvider = new (await import('./features/completionItemProvider')).default(client, this.description.id, this.typingsStatus);
|
||||
completionItemProvider.updateConfiguration();
|
||||
this.toUpdateOnConfigurationChanged.push(completionItemProvider);
|
||||
this.disposables.push(languages.registerCompletionItemProvider(selector, completionItemProvider, '.', '"', '\'', '/', '@'));
|
||||
|
||||
41
extensions/typescript/src/utils/codeAction.ts
Normal file
41
extensions/typescript/src/utils/codeAction.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { WorkspaceEdit, workspace } from 'vscode';
|
||||
import * as Proto from '../protocol';
|
||||
import { tsTextSpanToVsRange } from './convert';
|
||||
import { ITypescriptServiceClient } from '../typescriptService';
|
||||
|
||||
|
||||
export async function applyCodeAction(
|
||||
client: ITypescriptServiceClient,
|
||||
action: Proto.CodeAction,
|
||||
file: string
|
||||
): Promise<boolean> {
|
||||
if (action.changes && action.changes.length) {
|
||||
const workspaceEdit = new WorkspaceEdit();
|
||||
for (const change of action.changes) {
|
||||
for (const textChange of change.textChanges) {
|
||||
workspaceEdit.replace(client.asUrl(change.fileName),
|
||||
tsTextSpanToVsRange(textChange),
|
||||
textChange.newText);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(await workspace.applyEdit(workspaceEdit))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (action.commands && action.commands.length) {
|
||||
for (const command of action.commands) {
|
||||
const response = await client.execute('applyCodeActionCommand', { file, command });
|
||||
if (!response || !response.body) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user