提交 98ea8943 编写于 作者: J Johannes Rieken

more and better cancellation token sources

上级 c3d0e7a9
......@@ -7,7 +7,7 @@ import * as strings from 'vs/base/common/strings';
import { ICodeEditor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ITextModel } from 'vs/editor/common/model';
......@@ -74,13 +74,16 @@ export class EditorState {
}
}
/**
* A cancellation token source that cancels when the editor changes as expressed
* by the provided flags
*/
export class EditorStateCancellationTokenSource extends CancellationTokenSource {
private readonly _listener: IDisposable[] = [];
constructor(readonly editor: IActiveCodeEditor, flags: CodeEditorStateFlag) {
super();
constructor(readonly editor: IActiveCodeEditor, flags: CodeEditorStateFlag, parent?: CancellationToken) {
super(parent);
if (flags & CodeEditorStateFlag.Position) {
this._listener.push(editor.onDidChangeCursorPosition(_ => this.cancel()));
......@@ -103,12 +106,15 @@ export class EditorStateCancellationTokenSource extends CancellationTokenSource
}
}
/**
* A cancellation token source that cancels when the provided model changes
*/
export class TextModelCancellationTokenSource extends CancellationTokenSource {
private _listener: IDisposable;
constructor(model: ITextModel) {
super();
constructor(model: ITextModel, parent?: CancellationToken) {
super(parent);
this._listener = model.onDidChangeContent(() => this.cancel());
}
......
......@@ -56,9 +56,7 @@ export function getCodeActions(
trigger: trigger.type === 'manual' ? CodeActionTriggerKind.Manual : CodeActionTriggerKind.Automatic
};
const cts = new TextModelCancellationTokenSource(model);
token.onCancellationRequested(() => cts.cancel());
const cts = new TextModelCancellationTokenSource(model, token);
const providers = getCodeActionProviders(model, filter);
const promises = providers.map(provider => {
......
......@@ -274,9 +274,7 @@ export class OutlineModel extends TreeElement {
static _create(textModel: ITextModel, token: CancellationToken): Promise<OutlineModel> {
const chainedCancellation = new CancellationTokenSource();
token.onCancellationRequested(() => chainedCancellation.cancel());
const cts = new CancellationTokenSource(token);
const result = new OutlineModel(textModel);
const provider = DocumentSymbolProviderRegistry.ordered(textModel);
const promises = provider.map((provider, index) => {
......@@ -284,7 +282,7 @@ export class OutlineModel extends TreeElement {
let id = TreeElement.findId(`provider_${index}`, result);
let group = new OutlineGroup(id, result, provider, index);
return Promise.resolve(provider.provideDocumentSymbols(result.textModel, chainedCancellation.token)).then(result => {
return Promise.resolve(provider.provideDocumentSymbols(result.textModel, cts.token)).then(result => {
for (const info of result || []) {
OutlineModel._makeOutlineElement(info, group);
}
......@@ -304,12 +302,12 @@ export class OutlineModel extends TreeElement {
const listener = DocumentSymbolProviderRegistry.onDidChange(() => {
const newProvider = DocumentSymbolProviderRegistry.ordered(textModel);
if (!equals(newProvider, provider)) {
chainedCancellation.cancel();
cts.cancel();
}
});
return Promise.all(promises).then(() => {
if (chainedCancellation.token.isCancellationRequested && !token.isCancellationRequested) {
if (cts.token.isCancellationRequested && !token.isCancellationRequested) {
return OutlineModel._create(textModel, token);
} else {
return result._compact();
......
......@@ -5,10 +5,10 @@
import { alert } from 'vs/base/browser/ui/aria/aria';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { CancellationToken } from 'vs/base/common/cancellation';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { illegalArgument, onUnexpectedExternalError } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
import { CodeEditorStateFlag, EditorState } from 'vs/editor/browser/core/editorState';
import { CodeEditorStateFlag, EditorState, EditorStateCancellationTokenSource, TextModelCancellationTokenSource } from 'vs/editor/browser/core/editorState';
import { IActiveCodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
import { registerLanguageCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { Position } from 'vs/editor/common/core/position';
......@@ -227,26 +227,24 @@ export async function formatDocumentWithProvider(
const workerService = accessor.get(IEditorWorkerService);
let model: ITextModel;
let validate: () => boolean;
let cts: CancellationTokenSource;
if (isCodeEditor(editorOrModel)) {
model = editorOrModel.getModel();
const state = new EditorState(editorOrModel, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
validate = () => state.validate(editorOrModel);
cts = new EditorStateCancellationTokenSource(editorOrModel, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position, token);
} else {
model = editorOrModel;
const versionNow = editorOrModel.getVersionId();
validate = () => versionNow === editorOrModel.getVersionId();
cts = new TextModelCancellationTokenSource(editorOrModel, token);
}
const rawEdits = await provider.provideDocumentFormattingEdits(
model,
model.getFormattingOptions(),
token
cts.token
);
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
if (!validate()) {
if (cts.token.isCancellationRequested) {
return true;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册