From c7ac541307a71917188fa67882b24a32a9b4c921 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 26 Apr 2023 17:49:21 +0200 Subject: [PATCH] make sure EditModeStrategy#apply/cancel isn't called twice, keep reference onto editor model to prevent dispose before reset fixes https://github.com/microsoft/vscode-internalbacklog/issues/3963 --- .../browser/interactiveEditorController.ts | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController.ts b/src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController.ts index d5b9aaa7867b9..600ea1dad88c5 100644 --- a/src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController.ts +++ b/src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController.ts @@ -31,6 +31,7 @@ import { ModelDecorationOptions, createTextBufferFactoryFromSnapshot } from 'vs/ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { IModelService } from 'vs/editor/common/services/model'; +import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { InlineCompletionsController } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -310,6 +311,7 @@ export class InteractiveEditorController implements IEditorContribution { @IStorageService private readonly _storageService: IStorageService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IModelService private readonly _modelService: IModelService, + @ITextModelService private readonly _textModelService: ITextModelService, @INotebookEditorService private readonly _notebookEditorService: INotebookEditorService, @IContextKeyService contextKeyService: IContextKeyService, @@ -375,15 +377,16 @@ export class InteractiveEditorController implements IEditorContribution { const store = new DisposableStore(); + // keep a snapshot of the "actual" model + const textModel0 = this._modelService.createModel(createTextBufferFactoryFromSnapshot(textModel.createSnapshot()), { languageId: textModel.getLanguageId(), onDidChange: Event.None }, undefined, true); + store.add(textModel0); + + // keep a reference to prevent disposal of the "actual" model + const refTextModelN = await this._textModelService.createModelReference(textModel.uri); + store.add(refTextModelN); let textModel0Changes: LineRangeMapping[] | undefined; - const textModel0 = this._modelService.createModel( - createTextBufferFactoryFromSnapshot(textModel.createSnapshot()), - { languageId: textModel.getLanguageId(), onDidChange: Event.None }, - undefined, true - ); - store.add(textModel0); this._currentSession = new Session(editMode, textModel0, textModel, provider, session); this._strategy = this._instaService.createInstance(EditModeStrategy.ctor(editMode), this._currentSession); @@ -459,9 +462,6 @@ export class InteractiveEditorController implements IEditorContribution { }, undefined, store); - const roundStore = new DisposableStore(); - store.add(roundStore); - const diffZone = this._instaService.createInstance(InteractiveEditorDiffWidget, this._editor, textModel0); do { @@ -507,7 +507,6 @@ export class InteractiveEditorController implements IEditorContribution { this.accept(); } const input = await inputPromise; - roundStore.clear(); if (!input) { continue; @@ -805,16 +804,20 @@ export class InteractiveEditorController implements IEditorContribution { } async applyChanges(): Promise { - if (this._currentSession?.lastResponse instanceof EditResponse) { + if (this._currentSession?.lastResponse instanceof EditResponse && this._strategy) { const { lastResponse } = this._currentSession; - await this._strategy?.apply(); + const strategy = this._strategy; + this._strategy = undefined; + await strategy?.apply(); this._ctsSession.cancel(); return lastResponse; } } async cancelSession() { - await this._strategy?.cancel(); + const strategy = this._strategy; + this._strategy = undefined; + await strategy?.cancel(); this._ctsSession.cancel(); } }