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

more and better cancellation token sources

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