提交 74b52475 编写于 作者: M Matt Bierner

Use more explicit types for ts server execute

- Only allow known strings to be used as commands
- Simplify overloading. Introduce new `executeWithoutWaitingForResponse` function for calls that are fire and forget
- Always require a token for execture calls
上级 9e411a5f
......@@ -63,7 +63,7 @@ class SyncedBuffer {
}
}
this.client.execute('open', args, false);
this.client.executeWithoutWaitingForResponse('open', args);
}
public get resource(): vscode.Uri {
......@@ -91,7 +91,7 @@ class SyncedBuffer {
const args: Proto.FileRequestArgs = {
file: this.filepath
};
this.client.execute('close', args, false);
this.client.executeWithoutWaitingForResponse('close', args);
}
public onContentChanged(events: vscode.TextDocumentContentChangeEvent[]): void {
......@@ -100,7 +100,7 @@ class SyncedBuffer {
insertString: text,
...typeConverters.Range.toFormattingRequestArgs(this.filepath, range)
};
this.client.execute('change', args, false);
this.client.executeWithoutWaitingForResponse('change', args);
}
}
}
......
......@@ -16,6 +16,7 @@ import * as typeConverters from '../utils/typeConverters';
import TypingsStatus from '../utils/typingsStatus';
import FileConfigurationManager from './fileConfigurationManager';
import { memoize } from '../utils/memoize';
import { nulToken } from '../utils/cancellation';
const localize = nls.loadMessageBundle();
......@@ -205,7 +206,7 @@ class ApplyCompletionCodeActionCommand implements Command {
}
if (codeActions.length === 1) {
return applyCodeAction(this.client, codeActions[0]);
return applyCodeAction(this.client, codeActions[0], nulToken);
}
interface MyQuickPickItem extends vscode.QuickPickItem {
......@@ -230,7 +231,7 @@ class ApplyCompletionCodeActionCommand implements Command {
if (!action) {
return false;
}
return applyCodeAction(this.client, action);
return applyCodeAction(this.client, action, nulToken);
}
}
......@@ -384,7 +385,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
item.additionalTextEdits = additionalTextEdits;
if (detail && item.useCodeSnippet) {
const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position);
const shouldCompleteFunction = await this.isValidFunctionCompletionContext(filepath, item.position, token);
if (shouldCompleteFunction) {
item.insertText = this.snippetForFunctionCall(item, detail);
}
......@@ -524,12 +525,13 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider
private async isValidFunctionCompletionContext(
filepath: string,
position: vscode.Position
position: vscode.Position,
token: vscode.CancellationToken
): Promise<boolean> {
// Workaround for https://github.com/Microsoft/TypeScript/issues/12677
// Don't complete function calls inside of destructive assigments or imports
try {
const { body } = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position));
const { body } = await this.client.execute('quickinfo', typeConverters.Position.toFileLocationRequestArgs(filepath, position), token);
switch (body && body.kind) {
case 'var':
case 'let':
......
......@@ -18,7 +18,7 @@ export default class TypeScriptDefinitionProviderBase {
definitionType: 'definition' | 'implementation' | 'typeDefinition',
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken | boolean
token: vscode.CancellationToken
): Promise<vscode.Location[] | undefined> {
const filepath = this.client.toPath(document.uri);
if (!filepath) {
......
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as Proto from '../protocol';
import { ITypeScriptServiceClient } from '../typescriptService';
import API from '../utils/api';
import * as typeConverters from '../utils/typeConverters';
......@@ -20,7 +19,7 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase
public async provideDefinition(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken | boolean
token: vscode.CancellationToken
): Promise<vscode.DefinitionLink[] | vscode.Definition | undefined> {
if (this.client.apiVersion.gte(API.v270)) {
const filepath = this.client.toPath(document.uri);
......@@ -30,14 +29,13 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase
const args = typeConverters.Position.toFileLocationRequestArgs(filepath, position);
try {
const response = await this.client.execute('definitionAndBoundSpan', args, token);
const locations: Proto.FileSpan[] = (response && response.body && response.body.definitions) || [];
if (!locations) {
const { body } = await this.client.execute('definitionAndBoundSpan', args, token);
if (!body) {
return undefined;
}
const span = response.body.textSpan ? typeConverters.Range.fromTextSpan(response.body.textSpan) : undefined;
return locations
const span = body.textSpan ? typeConverters.Range.fromTextSpan(body.textSpan) : undefined;
return body.definitions
.map(location => {
const target = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location);
return <vscode.DefinitionLink>{
......
......@@ -59,7 +59,7 @@ export default class FileConfigurationManager {
public async ensureConfigurationForDocument(
document: vscode.TextDocument,
token: vscode.CancellationToken | undefined
token: vscode.CancellationToken
): Promise<void> {
const editor = vscode.window.visibleTextEditors.find(editor => editor.document.fileName === document.fileName);
if (editor) {
......@@ -74,7 +74,7 @@ export default class FileConfigurationManager {
public async ensureConfigurationOptions(
document: vscode.TextDocument,
options: vscode.FormattingOptions,
token: vscode.CancellationToken | undefined
token: vscode.CancellationToken
): Promise<void> {
const file = this.client.toPath(document.uri);
if (!file) {
......
......@@ -10,7 +10,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration';
import DefinitionProviderBase from './definitionProviderBase';
class TypeScriptImplementationProvider extends DefinitionProviderBase implements vscode.ImplementationProvider {
public provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken | boolean): Promise<vscode.Definition | undefined> {
public provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Definition | undefined> {
return this.getSymbolLocations('implementation', document, position, token);
}
}
......
......@@ -161,9 +161,13 @@ class TryCompleteJsDocCommand implements Command {
public static getSnippetTemplate(client: ITypeScriptServiceClient, file: string, position: vscode.Position): Promise<vscode.SnippetString | undefined> {
const args = typeConverters.Position.toFileLocationRequestArgs(file, position);
const tokenSource = new vscode.CancellationTokenSource();
return Promise.race([
client.execute('docCommentTemplate', args),
new Promise<Proto.DocCommandTemplateResponse>((_, reject) => setTimeout(reject, 250))
client.execute('docCommentTemplate', args, tokenSource.token),
new Promise<Proto.DocCommandTemplateResponse>((_, reject) => setTimeout(() => {
tokenSource.cancel();
reject();
}, 250))
]).then((res: Proto.DocCommandTemplateResponse) => {
if (!res || !res.body) {
return undefined;
......
......@@ -13,6 +13,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration';
import * as typeconverts from '../utils/typeConverters';
import FileConfigurationManager from './fileConfigurationManager';
import TelemetryReporter from '../utils/telemetry';
import { nulToken } from '../utils/cancellation';
const localize = nls.loadMessageBundle();
......@@ -45,7 +46,7 @@ class OrganizeImportsCommand implements Command {
}
}
};
const { body } = await this.client.execute('organizeImports', args);
const { body } = await this.client.execute('organizeImports', args, nulToken);
const edits = typeconverts.WorkspaceEdit.fromFileCodeEdits(this.client, body);
return vscode.workspace.applyEdit(edits);
}
......
......@@ -15,6 +15,7 @@ import TelemetryReporter from '../utils/telemetry';
import * as typeConverters from '../utils/typeConverters';
import { DiagnosticsManager } from './diagnostics';
import FileConfigurationManager from './fileConfigurationManager';
import { nulToken } from '../utils/cancellation';
const localize = nls.loadMessageBundle();
......@@ -42,7 +43,7 @@ class ApplyCodeActionCommand implements Command {
fixName: action.fixName
});
return applyCodeActionCommands(this.client, action.commands);
return applyCodeActionCommands(this.client, action.commands, nulToken);
}
}
......@@ -85,14 +86,14 @@ class ApplyFixAllCodeAction implements Command {
};
try {
const { body } = await this.client.execute('getCombinedCodeFix', args);
const { body } = await this.client.execute('getCombinedCodeFix', args, nulToken);
if (!body) {
return;
}
const edit = typeConverters.WorkspaceEdit.fromFileCodeEdits(this.client, body.changes);
await vscode.workspace.applyEdit(edit);
await applyCodeActionCommands(this.client, body.commands);
await applyCodeActionCommands(this.client, body.commands, nulToken);
} catch {
// noop
}
......@@ -167,7 +168,7 @@ class SupportedCodeActionProvider {
private get supportedCodeActions(): Thenable<Set<number>> {
if (!this._supportedCodeActions) {
this._supportedCodeActions = this.client.execute('getSupportedCodeFixes', null, undefined)
this._supportedCodeActions = this.client.execute('getSupportedCodeFixes', null, nulToken)
.then(response => response.body || [])
.then(codes => codes.map(code => +code).filter(code => !isNaN(code)))
.then(codes => new Set(codes));
......
......@@ -12,6 +12,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration';
import TelemetryReporter from '../utils/telemetry';
import * as typeConverters from '../utils/typeConverters';
import FormattingOptionsManager from './fileConfigurationManager';
import { nulToken } from '../utils/cancellation';
class ApplyRefactoringCommand implements Command {
......@@ -47,7 +48,7 @@ class ApplyRefactoringCommand implements Command {
refactor,
action
};
const { body } = await this.client.execute('getEditsForRefactor', args);
const { body } = await this.client.execute('getEditsForRefactor', args, nulToken);
if (!body || !body.edits.length) {
return false;
}
......@@ -136,7 +137,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider {
return undefined;
}
await this.formattingOptionsManager.ensureConfigurationForDocument(document, undefined);
await this.formattingOptionsManager.ensureConfigurationForDocument(document, token);
const args: Proto.GetApplicableRefactorsRequestArgs = typeConverters.Range.toFileRangeRequestArgs(file, rangeOrSelection);
let refactorings: Proto.ApplicableRefactorInfo[];
......
......@@ -10,7 +10,7 @@ import { VersionDependentRegistration } from '../utils/dependentRegistration';
import DefinitionProviderBase from './definitionProviderBase';
export default class TypeScriptTypeDefinitionProvider extends DefinitionProviderBase implements vscode.TypeDefinitionProvider {
public provideTypeDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken | boolean): Promise<vscode.Definition | undefined> {
public provideTypeDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Definition | undefined> {
return this.getSymbolLocations('typeDefinition', document, position, token);
}
}
......
......@@ -16,6 +16,7 @@ import { escapeRegExp } from '../utils/regexp';
import * as typeConverters from '../utils/typeConverters';
import FileConfigurationManager from './fileConfigurationManager';
import { VersionDependentRegistration } from '../utils/dependentRegistration';
import { nulToken } from '../utils/cancellation';
const localize = nls.loadMessageBundle();
......@@ -84,7 +85,7 @@ class UpdateImportsOnFileRenameHandler {
// Workaround for https://github.com/Microsoft/vscode/issues/52967
// Never attempt to update import paths if the file does not contain something the looks like an export
try {
const { body } = await this.client.execute('navtree', { file: newFile });
const { body } = await this.client.execute('navtree', { file: newFile }, nulToken);
const hasExport = (node: Proto.NavigationTree): boolean => {
return !!node.kindModifiers.match(/\bexports?\b/g) || !!(node.childItems && node.childItems.some(hasExport));
};
......@@ -229,14 +230,14 @@ class UpdateImportsOnFileRenameHandler {
newFile: string,
) {
const isDirectoryRename = fs.lstatSync(newFile).isDirectory();
await this.fileConfigurationManager.ensureConfigurationForDocument(document, undefined);
await this.fileConfigurationManager.ensureConfigurationForDocument(document, nulToken);
const args: Proto.GetEditsForFileRenameRequestArgs & { file: string } = {
file: targetResource,
oldFilePath: oldFile,
newFilePath: newFile,
};
const response = await this.client.execute('getEditsForFileRename', args);
const response = await this.client.execute('getEditsForFileRename', args, nulToken);
if (!response || !response.body) {
return;
}
......
......@@ -55,7 +55,7 @@ export default class TypeScriptServiceClientHost extends Disposable {
) {
super();
const handleProjectCreateOrDelete = () => {
this.client.execute('reloadProjects', null, false);
this.client.executeWithoutWaitingForResponse('reloadProjects', null);
this.triggerAllDiagnostics();
};
const handleProjectChange = () => {
......@@ -150,7 +150,7 @@ export default class TypeScriptServiceClientHost extends Disposable {
}
public reloadProjects(): void {
this.client.execute('reloadProjects', null, false);
this.client.executeWithoutWaitingForResponse('reloadProjects', null);
this.triggerAllDiagnostics();
}
......
......@@ -11,6 +11,70 @@ import { TypeScriptServiceConfiguration } from './utils/configuration';
import Logger from './utils/logger';
import { TypeScriptServerPlugin } from './utils/plugins';
interface TypeScriptArgsMap {
'configure': Proto.ConfigureRequestArguments;
'quickinfo': Proto.FileLocationRequestArgs;
'completions': Proto.CompletionsRequestArgs;
'completionInfo': Proto.CompletionsRequestArgs;
'completionEntryDetails': Proto.CompletionDetailsRequestArgs;
'signatureHelp': Proto.SignatureHelpRequestArgs;
'definition': Proto.FileLocationRequestArgs;
'definitionAndBoundSpan': Proto.FileLocationRequestArgs;
'implementation': Proto.FileLocationRequestArgs;
'typeDefinition': Proto.FileLocationRequestArgs;
'references': Proto.FileLocationRequestArgs;
'navto': Proto.NavtoRequestArgs;
'format': Proto.FormatRequestArgs;
'formatonkey': Proto.FormatOnKeyRequestArgs;
'rename': Proto.RenameRequestArgs;
'occurrences': Proto.FileLocationRequestArgs;
'projectInfo': Proto.ProjectInfoRequestArgs;
'navtree': Proto.FileRequestArgs;
'getCodeFixes': Proto.CodeFixRequestArgs;
'getSupportedCodeFixes': null;
'getCombinedCodeFix': Proto.GetCombinedCodeFixRequestArgs;
'docCommentTemplate': Proto.FileLocationRequestArgs;
'getApplicableRefactors': Proto.GetApplicableRefactorsRequestArgs;
'getEditsForRefactor': Proto.GetEditsForRefactorRequestArgs;
'applyCodeActionCommand': Proto.ApplyCodeActionCommandRequestArgs;
'organizeImports': Proto.OrganizeImportsRequestArgs;
'getOutliningSpans': Proto.FileRequestArgs;
'getEditsForFileRename': Proto.GetEditsForFileRenameRequestArgs;
'jsxClosingTag': Proto.JsxClosingTagRequestArgs;
}
interface TypeScriptResultMap {
'configure': Proto.ConfigureResponse;
'quickinfo': Proto.QuickInfoResponse;
'completions': Proto.CompletionsResponse;
'completionInfo': Proto.CompletionInfoResponse;
'completionEntryDetails': Proto.CompletionDetailsResponse;
'signatureHelp': Proto.SignatureHelpResponse;
'definition': Proto.DefinitionResponse;
'definitionAndBoundSpan': Proto.DefinitionInfoAndBoundSpanReponse;
'implementation': Proto.ImplementationResponse;
'typeDefinition': Proto.TypeDefinitionResponse;
'references': Proto.ReferencesResponse;
'navto': Proto.NavtoResponse;
'format': Proto.FormatResponse;
'formatonkey': Proto.FormatResponse;
'rename': Proto.RenameResponse;
'occurrences': Proto.OccurrencesResponse;
'projectInfo': Proto.ProjectInfoResponse;
'navtree': Proto.NavTreeResponse;
'getCodeFixes': Proto.GetCodeFixesResponse;
'getSupportedCodeFixes': Proto.GetSupportedCodeFixesResponse;
'getCombinedCodeFix': Proto.GetCombinedCodeFixResponse;
'docCommentTemplate': Proto.DocCommandTemplateResponse;
'getApplicableRefactors': Proto.GetApplicableRefactorsResponse;
'getEditsForRefactor': Proto.GetEditsForRefactorResponse;
'applyCodeActionCommand': Proto.ApplyCodeActionCommandResponse;
'organizeImports': Proto.OrganizeImportsResponse;
'getOutliningSpans': Proto.OutliningSpansResponse;
'getEditsForFileRename': Proto.GetEditsForFileRenameResponse;
'jsxClosingTag': Proto.JsxClosingTagResponse;
}
export interface ITypeScriptServiceClient {
/**
* Convert a resource (VS Code) to a normalized path (TypeScript).
......@@ -45,42 +109,17 @@ export interface ITypeScriptServiceClient {
readonly logger: Logger;
readonly bufferSyncSupport: BufferSyncSupport;
execute(command: 'configure', args: Proto.ConfigureRequestArguments, token?: vscode.CancellationToken): Promise<Proto.ConfigureResponse>;
execute(command: 'open', args: Proto.OpenRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise<any>;
execute(command: 'close', args: Proto.FileRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise<any>;
execute(command: 'change', args: Proto.ChangeRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise<any>;
execute(command: 'quickinfo', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.QuickInfoResponse>;
execute(command: 'completions', args: Proto.CompletionsRequestArgs, token?: vscode.CancellationToken): Promise<Proto.CompletionsResponse>;
execute(command: 'completionInfo', args: Proto.CompletionsRequestArgs, token?: vscode.CancellationToken): Promise<Proto.CompletionInfoResponse>;
execute(command: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: vscode.CancellationToken): Promise<Proto.CompletionDetailsResponse>;
execute(command: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: vscode.CancellationToken): Promise<Proto.SignatureHelpResponse>;
execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.DefinitionResponse>;
execute(command: 'definitionAndBoundSpan', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.DefinitionInfoAndBoundSpanReponse>;
execute(command: 'implementation', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.ImplementationResponse>;
execute(command: 'typeDefinition', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.TypeDefinitionResponse>;
execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.ReferencesResponse>;
execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: vscode.CancellationToken): Promise<Proto.NavtoResponse>;
execute(command: 'format', args: Proto.FormatRequestArgs, token?: vscode.CancellationToken): Promise<Proto.FormatResponse>;
execute(command: 'formatonkey', args: Proto.FormatOnKeyRequestArgs, token?: vscode.CancellationToken): Promise<Proto.FormatResponse>;
execute(command: 'rename', args: Proto.RenameRequestArgs, token?: vscode.CancellationToken): Promise<Proto.RenameResponse>;
execute(command: 'occurrences', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.OccurrencesResponse>;
execute(command: 'projectInfo', args: Proto.ProjectInfoRequestArgs, token?: vscode.CancellationToken): Promise<Proto.ProjectInfoResponse>;
execute(command: 'reloadProjects', args: any, expectedResult: boolean, token?: vscode.CancellationToken): Promise<any>;
execute(command: 'reload', args: Proto.ReloadRequestArgs, expectedResult: boolean, token?: vscode.CancellationToken): Promise<any>;
execute(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs, token?: vscode.CancellationToken): Promise<any>;
execute(command: 'navtree', args: Proto.FileRequestArgs, token?: vscode.CancellationToken): Promise<Proto.NavTreeResponse>;
execute(command: 'getCodeFixes', args: Proto.CodeFixRequestArgs, token?: vscode.CancellationToken): Promise<Proto.GetCodeFixesResponse>;
execute(command: 'getSupportedCodeFixes', args: null, token?: vscode.CancellationToken): Promise<Proto.GetSupportedCodeFixesResponse>;
execute(command: 'getCombinedCodeFix', args: Proto.GetCombinedCodeFixRequestArgs, token?: vscode.CancellationToken): Promise<Proto.GetCombinedCodeFixResponse>;
execute(command: 'docCommentTemplate', args: Proto.FileLocationRequestArgs, token?: vscode.CancellationToken): Promise<Proto.DocCommandTemplateResponse>;
execute(command: 'getApplicableRefactors', args: Proto.GetApplicableRefactorsRequestArgs, token?: vscode.CancellationToken): Promise<Proto.GetApplicableRefactorsResponse>;
execute(command: 'getEditsForRefactor', args: Proto.GetEditsForRefactorRequestArgs, token?: vscode.CancellationToken): Promise<Proto.GetEditsForRefactorResponse>;
execute(command: 'applyCodeActionCommand', args: Proto.ApplyCodeActionCommandRequestArgs, token?: vscode.CancellationToken): Promise<Proto.ApplyCodeActionCommandResponse>;
execute(command: 'organizeImports', args: Proto.OrganizeImportsRequestArgs, token?: vscode.CancellationToken): Promise<Proto.OrganizeImportsResponse>;
execute(command: 'getOutliningSpans', args: Proto.FileRequestArgs, token: vscode.CancellationToken): Promise<Proto.OutliningSpansResponse>;
execute(command: 'getEditsForFileRename', args: Proto.GetEditsForFileRenameRequestArgs): Promise<Proto.GetEditsForFileRenameResponse>;
execute(command: 'jsxClosingTag', args: Proto.JsxClosingTagRequestArgs, token: vscode.CancellationToken): Promise<Proto.JsxClosingTagResponse>;
execute(command: string, args: any, expectedResult: boolean | vscode.CancellationToken, token?: vscode.CancellationToken): Promise<any>;
execute<K extends keyof TypeScriptArgsMap>(
command: K,
args: TypeScriptArgsMap[K],
token: vscode.CancellationToken
): Promise<TypeScriptResultMap[K]>;
executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void;
executeWithoutWaitingForResponse(command: 'close', args: Proto.FileRequestArgs): void;
executeWithoutWaitingForResponse(command: 'change', args: Proto.ChangeRequestArgs): void;
executeWithoutWaitingForResponse(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs): void;
executeWithoutWaitingForResponse(command: 'reloadProjects', args: null): void;
executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise<any>;
}
\ No newline at end of file
......@@ -521,7 +521,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
const configureOptions: Proto.ConfigureRequestArguments = {
hostInfo: 'vscode'
};
this.execute('configure', configureOptions);
this.executeWithoutWaitingForResponse('configure', configureOptions);
this.setCompilerOptionsForInferredProjects(this._configuration);
if (resendModels) {
this._onResendModelsRequested.fire();
......@@ -536,7 +536,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
const args: Proto.SetCompilerOptionsForInferredProjectsArgs = {
options: this.getCompilerOptionsForInferredProjects(configuration)
};
this.execute('compilerOptionsForInferredProjects', args, true);
this.executeWithoutWaitingForResponse('compilerOptionsForInferredProjects', args);
}
private getCompilerOptionsForInferredProjects(configuration: TypeScriptServiceConfiguration): Proto.ExternalProjectCompilerOptions {
......@@ -679,19 +679,28 @@ export default class TypeScriptServiceClient extends Disposable implements IType
return undefined;
}
public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise<any> {
return this.executeImpl(command, args, { isAsync: true, token, expectsResult: true });
public execute(command: string, args: any, token: vscode.CancellationToken): Promise<any> {
return this.executeImpl(command, args, {
isAsync: false,
token,
expectsResult: true
});
}
public execute(command: string, args: any, expectsResultOrToken?: boolean | vscode.CancellationToken): Promise<any> {
let token: vscode.CancellationToken | undefined = undefined;
let expectsResult = true;
if (typeof expectsResultOrToken === 'boolean') {
expectsResult = expectsResultOrToken;
} else {
token = expectsResultOrToken;
}
return this.executeImpl(command, args, { isAsync: false, token, expectsResult });
public executeWithoutWaitingForResponse(command: string, args: any): void {
this.executeImpl(command, args, {
isAsync: false,
token: undefined,
expectsResult: false
});
}
public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise<any> {
return this.executeImpl(command, args, {
isAsync: true,
token,
expectsResult: true
});
}
private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean }): Promise<any> {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
const nulTokenSource = new vscode.CancellationTokenSource();
export const nulToken = nulTokenSource.token;
\ No newline at end of file
......@@ -19,7 +19,8 @@ export function getEditForCodeAction(
export async function applyCodeAction(
client: ITypeScriptServiceClient,
action: Proto.CodeAction
action: Proto.CodeAction,
token: vscode.CancellationToken
): Promise<boolean> {
const workspaceEdit = getEditForCodeAction(client, action);
if (workspaceEdit) {
......@@ -27,16 +28,17 @@ export async function applyCodeAction(
return false;
}
}
return applyCodeActionCommands(client, action.commands);
return applyCodeActionCommands(client, action.commands, token);
}
export async function applyCodeActionCommands(
client: ITypeScriptServiceClient,
commands: ReadonlyArray<{}> | undefined
commands: ReadonlyArray<{}> | undefined,
token: vscode.CancellationToken,
): Promise<boolean> {
if (commands && commands.length) {
for (const command of commands) {
await client.execute('applyCodeActionCommand', { command });
await client.execute('applyCodeActionCommand', { command }, token);
}
}
return true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册