Skip to content

Commit cb48ce5

Browse files
committed
Editor inputs marked as deleted for virtual resources (fix microsoft#133947)
1 parent 4fbe034 commit cb48ce5

File tree

9 files changed

+61
-9
lines changed

9 files changed

+61
-9
lines changed

src/vs/workbench/services/textfile/browser/textFileService.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,20 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
109109
}
110110
}));
111111

112+
// Removals: once a text file model is no longer
113+
// under our control, make sure to signal this as
114+
// decoration change because from this point on we
115+
// have no way of updating the decoration anymore.
116+
this._register(this.files.onDidRemove(modelUri => this._onDidChange.fire([modelUri])));
117+
112118
// Changes
113119
this._register(this.files.onDidChangeReadonly(model => this._onDidChange.fire([model.resource])));
114120
this._register(this.files.onDidChangeOrphaned(model => this._onDidChange.fire([model.resource])));
115121
}
116122

117123
provideDecorations(uri: URI): IDecorationData | undefined {
118124
const model = this.files.get(uri);
119-
if (!model) {
125+
if (!model || model.isDisposed()) {
120126
return undefined;
121127
}
122128

src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
3434
private readonly _onDidResolve = this._register(new Emitter<ITextFileResolveEvent>());
3535
readonly onDidResolve = this._onDidResolve.event;
3636

37+
private readonly _onDidRemove = this._register(new Emitter<URI>());
38+
readonly onDidRemove = this._onDidRemove.event;
39+
3740
private readonly _onDidChangeDirty = this._register(new Emitter<TextFileEditorModel>());
3841
readonly onDidChangeDirty = this._onDidChangeDirty.event;
3942

@@ -446,7 +449,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
446449
}
447450

448451
protected remove(resource: URI): void {
449-
this.mapResourceToModel.delete(resource);
452+
const removed = this.mapResourceToModel.delete(resource);
450453

451454
const disposeListener = this.mapResourceToDisposeListener.get(resource);
452455
if (disposeListener) {
@@ -459,6 +462,10 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
459462
dispose(modelListener);
460463
this.mapResourceToModelListeners.delete(resource);
461464
}
465+
466+
if (removed) {
467+
this._onDidRemove.fire(resource);
468+
}
462469
}
463470

464471
//#region Save participants

src/vs/workbench/services/textfile/common/textfiles.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ export interface ITextFileEditorModelManager {
336336
readonly onDidResolve: Event<ITextFileResolveEvent>;
337337
readonly onDidChangeDirty: Event<ITextFileEditorModel>;
338338
readonly onDidChangeReadonly: Event<ITextFileEditorModel>;
339+
readonly onDidRemove: Event<URI>;
339340
readonly onDidChangeOrphaned: Event<ITextFileEditorModel>;
340341
readonly onDidChangeEncoding: Event<ITextFileEditorModel>;
341342
readonly onDidSaveError: Event<ITextFileEditorModel>;

src/vs/workbench/services/textfile/test/browser/textFileEditorModelManager.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ suite('Files - TextFileEditorModelManager', () => {
187187
const resource2 = toResource.call(this, '/path/other.txt');
188188

189189
let resolvedCounter = 0;
190+
let removedCounter = 0;
190191
let gotDirtyCounter = 0;
191192
let gotNonDirtyCounter = 0;
192193
let revertedCounter = 0;
@@ -199,6 +200,12 @@ suite('Files - TextFileEditorModelManager', () => {
199200
}
200201
});
201202

203+
manager.onDidRemove(resource => {
204+
if (resource.toString() === resource1.toString() || resource.toString() === resource2.toString()) {
205+
removedCounter++;
206+
}
207+
});
208+
202209
manager.onDidChangeDirty(model => {
203210
if (model.resource.toString() === resource1.toString()) {
204211
if (model.isDirty()) {
@@ -247,6 +254,7 @@ suite('Files - TextFileEditorModelManager', () => {
247254
model2.dispose();
248255

249256
await model1.revert();
257+
assert.strictEqual(removedCounter, 2);
250258
assert.strictEqual(gotDirtyCounter, 2);
251259
assert.strictEqual(gotNonDirtyCounter, 2);
252260
assert.strictEqual(revertedCounter, 1);

src/vs/workbench/services/workingCopy/common/abstractFileWorkingCopyManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export abstract class BaseFileWorkingCopyManager<M extends IFileWorkingCopyModel
8181
this._onDidCreate.fire(workingCopy);
8282
}
8383

84-
protected remove(resource: URI): void {
84+
protected remove(resource: URI): boolean {
8585

8686
// Dispose any existing listener
8787
const disposeListener = this.mapResourceToDisposeListener.get(resource);
@@ -91,7 +91,7 @@ export abstract class BaseFileWorkingCopyManager<M extends IFileWorkingCopyModel
9191
}
9292

9393
// Remove from our working copy map
94-
this.mapResourceToWorkingCopy.delete(resource);
94+
return this.mapResourceToWorkingCopy.delete(resource);
9595
}
9696

9797
//#region Get / Get all

src/vs/workbench/services/workingCopy/common/fileWorkingCopyManager.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,20 @@ export class FileWorkingCopyManager<S extends IStoredFileWorkingCopyModel, U ext
219219
}
220220
}));
221221

222+
// Removals: once a stored working copy is no longer
223+
// under our control, make sure to signal this as
224+
// decoration change because from this point on we
225+
// have no way of updating the decoration anymore.
226+
this._register(this.stored.onDidRemove(workingCopyUri => this._onDidChange.fire([workingCopyUri])));
227+
222228
// Changes
223229
this._register(this.stored.onDidChangeReadonly(workingCopy => this._onDidChange.fire([workingCopy.resource])));
224230
this._register(this.stored.onDidChangeOrphaned(workingCopy => this._onDidChange.fire([workingCopy.resource])));
225231
}
226232

227233
provideDecorations(uri: URI): IDecorationData | undefined {
228234
const workingCopy = this.stored.get(uri);
229-
if (!workingCopy) {
235+
if (!workingCopy || workingCopy.isDisposed()) {
230236
return undefined;
231237
}
232238

src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ export interface IStoredFileWorkingCopyManager<M extends IStoredFileWorkingCopyM
7171
*/
7272
readonly onDidRevert: Event<IStoredFileWorkingCopy<M>>;
7373

74+
/**
75+
* An event for when a stored file working copy is removed from the manager.
76+
*/
77+
readonly onDidRemove: Event<URI>;
78+
7479
/**
7580
* Allows to resolve a stored file working copy. If the manager already knows
7681
* about a stored file working copy with the same `URI`, it will return that
@@ -152,6 +157,9 @@ export class StoredFileWorkingCopyManager<M extends IStoredFileWorkingCopyModel>
152157
private readonly _onDidRevert = this._register(new Emitter<IStoredFileWorkingCopy<M>>());
153158
readonly onDidRevert = this._onDidRevert.event;
154159

160+
private readonly _onDidRemove = this._register(new Emitter<URI>());
161+
readonly onDidRemove = this._onDidRemove.event;
162+
155163
//#endregion
156164

157165
private readonly mapResourceToWorkingCopyListeners = new ResourceMap<IDisposable>();
@@ -549,15 +557,21 @@ export class StoredFileWorkingCopyManager<M extends IStoredFileWorkingCopyModel>
549557
this.mapResourceToWorkingCopyListeners.set(workingCopy.resource, workingCopyListeners);
550558
}
551559

552-
protected override remove(resource: URI): void {
553-
super.remove(resource);
560+
protected override remove(resource: URI): boolean {
561+
const removed = super.remove(resource);
554562

555563
// Dispose any exsting working copy listeners
556564
const workingCopyListener = this.mapResourceToWorkingCopyListeners.get(resource);
557565
if (workingCopyListener) {
558566
dispose(workingCopyListener);
559567
this.mapResourceToWorkingCopyListeners.delete(resource);
560568
}
569+
570+
if (removed) {
571+
this._onDidRemove.fire(resource);
572+
}
573+
574+
return removed;
561575
}
562576

563577
//#endregion

src/vs/workbench/services/workingCopy/common/untitledFileWorkingCopyManager.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,17 @@ export class UntitledFileWorkingCopyManager<M extends IUntitledFileWorkingCopyMo
233233
}
234234
}
235235

236-
protected override remove(resource: URI): void {
237-
super.remove(resource);
236+
protected override remove(resource: URI): boolean {
237+
const removed = super.remove(resource);
238238

239239
// Dispose any exsting working copy listeners
240240
const workingCopyListener = this.mapResourceToWorkingCopyListeners.get(resource);
241241
if (workingCopyListener) {
242242
dispose(workingCopyListener);
243243
this.mapResourceToWorkingCopyListeners.delete(resource);
244244
}
245+
246+
return removed;
245247
}
246248

247249
//#endregion

src/vs/workbench/services/workingCopy/test/browser/storedFileWorkingCopyManager.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ suite('StoredFileWorkingCopyManager', () => {
182182

183183
let createdCounter = 0;
184184
let resolvedCounter = 0;
185+
let removedCounter = 0;
185186
let gotDirtyCounter = 0;
186187
let gotNonDirtyCounter = 0;
187188
let revertedCounter = 0;
@@ -192,6 +193,12 @@ suite('StoredFileWorkingCopyManager', () => {
192193
createdCounter++;
193194
});
194195

196+
manager.onDidRemove(resource => {
197+
if (resource.toString() === resource1.toString() || resource.toString() === resource2.toString()) {
198+
removedCounter++;
199+
}
200+
});
201+
195202
manager.onDidResolve(workingCopy => {
196203
if (workingCopy.resource.toString() === resource1.toString()) {
197204
resolvedCounter++;
@@ -256,6 +263,7 @@ suite('StoredFileWorkingCopyManager', () => {
256263
workingCopy2.dispose();
257264

258265
await workingCopy1.revert();
266+
assert.strictEqual(removedCounter, 2);
259267
assert.strictEqual(gotDirtyCounter, 3);
260268
assert.strictEqual(gotNonDirtyCounter, 2);
261269
assert.strictEqual(revertedCounter, 1);

0 commit comments

Comments
 (0)