dispose working copy manager when disposing serializer, fyi @bpasero

This commit is contained in:
Johannes Rieken
2021-05-05 11:34:52 +02:00
parent 77b2a5fcfc
commit c98cc5cf81
5 changed files with 44 additions and 20 deletions
@@ -28,7 +28,7 @@ import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEd
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { NotebookService } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl';
import { CellKind, CellToolbarLocKey, CellUri, DisplayOrderKey, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NOTEBOOK_WORKING_COPY_TYPE_PREFIX, ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, CellToolbarLocKey, CellUri, DisplayOrderKey, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
@@ -436,11 +436,7 @@ class NotebookWorkingCopyEditorHandler extends Disposable implements IWorkbenchC
}
private getViewType(workingCopy: IWorkingCopyIdentifier): string | undefined {
if (workingCopy.typeId.startsWith(NOTEBOOK_WORKING_COPY_TYPE_PREFIX)) {
return workingCopy.typeId.substr(NOTEBOOK_WORKING_COPY_TYPE_PREFIX.length);
}
return undefined;
return NotebookWorkingCopyTypeIdentifier.parse(workingCopy.typeId);
}
}
@@ -302,6 +302,9 @@ export class NotebookService extends Disposable implements INotebookService, IEd
readonly onDidAddNotebookDocument = this._onDidAddNotebookDocument.event;
readonly onDidRemoveNotebookDocument = this._onDidRemoveNotebookDocument.event;
private readonly _onWillRemoveViewType = this._register(new Emitter<string>());
readonly onWillRemoveViewType = this._onWillRemoveViewType.event;
private readonly _onDidChangeEditorTypes = this._register(new Emitter<void>());
onDidChangeEditorTypes: Event<void> = this._onDidChangeEditorTypes.event;
@@ -471,15 +474,19 @@ export class NotebookService extends Disposable implements INotebookService, IEd
return this._notebookProviders.has(viewType);
}
private _registerProviderData(viewType: string, data: SimpleNotebookProviderInfo | ComplexNotebookProviderInfo): void {
private _registerProviderData(viewType: string, data: SimpleNotebookProviderInfo | ComplexNotebookProviderInfo): IDisposable {
if (this._notebookProviders.has(viewType)) {
throw new Error(`notebook controller for viewtype '${viewType}' already exists`);
}
this._notebookProviders.set(viewType, data);
return toDisposable(() => {
this._onWillRemoveViewType.fire(viewType);
this._notebookProviders.delete(viewType);
});
}
registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: INotebookContentProvider): IDisposable {
this._registerProviderData(viewType, new ComplexNotebookProviderInfo(viewType, controller, extensionData));
const reg = this._registerProviderData(viewType, new ComplexNotebookProviderInfo(viewType, controller, extensionData));
if (controller.viewOptions && !this._notebookProviderInfoStore.get(viewType)) {
// register this content provider to the static contribution, if it does not exist
const info = new NotebookProviderInfo({
@@ -504,16 +511,13 @@ export class NotebookService extends Disposable implements INotebookService, IEd
this._onDidChangeEditorTypes.fire();
return toDisposable(() => {
this._notebookProviders.delete(viewType);
reg.dispose();
this._onDidChangeEditorTypes.fire();
});
}
registerNotebookSerializer(viewType: string, extensionData: NotebookExtensionDescription, serializer: INotebookSerializer): IDisposable {
this._registerProviderData(viewType, new SimpleNotebookProviderInfo(viewType, serializer, extensionData));
return toDisposable(() => {
this._notebookProviders.delete(viewType);
});
return this._registerProviderData(viewType, new SimpleNotebookProviderInfo(viewType, serializer, extensionData));
}
async withNotebookDataProvider(resource: URI, viewType?: string): Promise<ComplexNotebookProviderInfo | SimpleNotebookProviderInfo> {
@@ -843,4 +843,18 @@ export interface INotebookDecorationRenderOptions {
top?: editorCommon.IContentDecorationRenderOptions;
}
export const NOTEBOOK_WORKING_COPY_TYPE_PREFIX = 'notebook/';
export class NotebookWorkingCopyTypeIdentifier {
private static _prefix = 'notebook/';
static create(viewType: string): string {
return `${NotebookWorkingCopyTypeIdentifier._prefix}/${viewType}`;
}
static parse(candidate: string): string | undefined {
if (candidate.startsWith(NotebookWorkingCopyTypeIdentifier._prefix)) {
return candidate.substr(NotebookWorkingCopyTypeIdentifier._prefix.length);
}
return undefined;
}
}
@@ -5,9 +5,9 @@
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import { CellUri, IResolvedNotebookEditorModel, NOTEBOOK_WORKING_COPY_TYPE_PREFIX } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellUri, IResolvedNotebookEditorModel, NotebookWorkingCopyTypeIdentifier } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ComplexNotebookEditorModel, NotebookFileWorkingCopyModel, NotebookFileWorkingCopyModelFactory, SimpleNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookEditorModel';
import { combinedDisposable, dispose, IDisposable, IReference, ReferenceCollection, toDisposable } from 'vs/base/common/lifecycle';
import { combinedDisposable, DisposableStore, dispose, IDisposable, IReference, ReferenceCollection, toDisposable } from 'vs/base/common/lifecycle';
import { ComplexNotebookProviderInfo, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService';
import { ILogService } from 'vs/platform/log/common/log';
import { Emitter, Event } from 'vs/base/common/event';
@@ -19,6 +19,7 @@ import { ResourceMap } from 'vs/base/common/map';
class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IResolvedNotebookEditorModel>> {
private readonly _disposables = new DisposableStore();
private readonly _workingCopyManagers = new Map<string, IFileWorkingCopyManager<NotebookFileWorkingCopyModel>>();
private readonly _modelListener = new Map<IResolvedNotebookEditorModel, IDisposable>();
@@ -36,9 +37,17 @@ class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IReso
@ILogService private readonly _logService: ILogService,
) {
super();
this._disposables.add(_notebookService.onWillRemoveViewType(viewType => {
const manager = this._workingCopyManagers.get(NotebookWorkingCopyTypeIdentifier.create(viewType));
if (manager) {
manager.dispose();
}
}));
}
dispose(): void {
this._disposables.dispose();
this._onDidSaveNotebook.dispose();
this._onDidChangeDirty.dispose();
dispose(this._modelListener.values());
@@ -60,7 +69,7 @@ class NotebookModelReferenceCollection extends ReferenceCollection<Promise<IReso
result = await model.load();
} else if (info instanceof SimpleNotebookProviderInfo) {
const workingCopyTypeId = `${NOTEBOOK_WORKING_COPY_TYPE_PREFIX}${viewType}`;
const workingCopyTypeId = NotebookWorkingCopyTypeIdentifier.create(viewType);
let workingCopyManager = this._workingCopyManagers.get(workingCopyTypeId);
if (!workingCopyManager) {
workingCopyManager = <IFileWorkingCopyManager<NotebookFileWorkingCopyModel>><any>this._instantiationService.createInstance(
@@ -60,9 +60,10 @@ export interface INotebookService {
readonly _serviceBrand: undefined;
canResolve(viewType: string): Promise<boolean>;
onDidCreateNotebookDocument: Event<NotebookTextModel>;
onDidAddNotebookDocument: Event<NotebookTextModel>;
onDidRemoveNotebookDocument: Event<NotebookTextModel>;
readonly onWillRemoveViewType: Event<string>;
readonly onDidCreateNotebookDocument: Event<NotebookTextModel>;
readonly onDidAddNotebookDocument: Event<NotebookTextModel>;
readonly onDidRemoveNotebookDocument: Event<NotebookTextModel>;
registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: INotebookContentProvider): IDisposable;
registerNotebookSerializer(viewType: string, extensionData: NotebookExtensionDescription, serializer: INotebookSerializer): IDisposable;