Skip to content

Commit 105eef7

Browse files
authored
debt - ensure models are resolved (microsoft#151405)
1 parent d899cc9 commit 105eef7

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

src/vs/editor/common/services/resolverService.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,9 @@ export interface IResolvedTextEditorModel extends ITextEditorModel {
7070
*/
7171
readonly textEditorModel: ITextModel;
7272
}
73+
74+
export function isResolvedTextEditorModel(model: ITextEditorModel): model is IResolvedTextEditorModel {
75+
const candidate = model as IResolvedTextEditorModel;
76+
77+
return !!candidate.textEditorModel;
78+
}

src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import { IModelService } from 'vs/editor/common/services/model';
1111
import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel';
1212
import { ITextFileService, TextFileResolveReason } from 'vs/workbench/services/textfile/common/textfiles';
1313
import { Schemas } from 'vs/base/common/network';
14-
import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
14+
import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IResolvedTextEditorModel, isResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
1515
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
1616
import { IFileService } from 'vs/platform/files/common/files';
1717
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
1818
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
1919
import { ModelUndoRedoParticipant } from 'vs/editor/common/services/modelUndoRedoParticipant';
2020
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
2121

22-
class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorModel>> {
22+
class ResourceModelCollection extends ReferenceCollection<Promise<IResolvedTextEditorModel>> {
2323

2424
private readonly providers = new Map<string, ITextModelContentProvider[]>();
2525
private readonly modelsToDispose = new Set<string>();
@@ -33,11 +33,11 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
3333
super();
3434
}
3535

36-
createReferencedObject(key: string): Promise<ITextEditorModel> {
36+
createReferencedObject(key: string): Promise<IResolvedTextEditorModel> {
3737
return this.doCreateReferencedObject(key);
3838
}
3939

40-
private async doCreateReferencedObject(key: string, skipActivateProvider?: boolean): Promise<ITextEditorModel> {
40+
private async doCreateReferencedObject(key: string, skipActivateProvider?: boolean): Promise<IResolvedTextEditorModel> {
4141

4242
// Untrack as being disposed
4343
this.modelsToDispose.delete(key);
@@ -50,24 +50,36 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
5050
throw new Error(`Unable to resolve inMemory resource ${key}`);
5151
}
5252

53-
return this.instantiationService.createInstance(TextResourceEditorModel, resource);
53+
const model = this.instantiationService.createInstance(TextResourceEditorModel, resource);
54+
if (this.ensureResolvedModel(model, key)) {
55+
return model;
56+
}
5457
}
5558

5659
// Untitled Schema: go through untitled text service
5760
if (resource.scheme === Schemas.untitled) {
58-
return this.textFileService.untitled.resolve({ untitledResource: resource });
61+
const model = await this.textFileService.untitled.resolve({ untitledResource: resource });
62+
if (this.ensureResolvedModel(model, key)) {
63+
return model;
64+
}
5965
}
6066

6167
// File or remote file: go through text file service
6268
if (this.fileService.hasProvider(resource)) {
63-
return this.textFileService.files.resolve(resource, { reason: TextFileResolveReason.REFERENCE });
69+
const model = await this.textFileService.files.resolve(resource, { reason: TextFileResolveReason.REFERENCE });
70+
if (this.ensureResolvedModel(model, key)) {
71+
return model;
72+
}
6473
}
6574

6675
// Virtual documents
6776
if (this.providers.has(resource.scheme)) {
6877
await this.resolveTextModelContent(key);
6978

70-
return this.instantiationService.createInstance(TextResourceEditorModel, resource);
79+
const model = this.instantiationService.createInstance(TextResourceEditorModel, resource);
80+
if (this.ensureResolvedModel(model, key)) {
81+
return model;
82+
}
7183
}
7284

7385
// Either unknown schema, or not yet registered, try to activate
@@ -80,6 +92,14 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
8092
throw new Error(`Unable to resolve resource ${key}`);
8193
}
8294

95+
private ensureResolvedModel(model: ITextEditorModel, key: string): model is IResolvedTextEditorModel {
96+
if (isResolvedTextEditorModel(model)) {
97+
return true;
98+
}
99+
100+
throw new Error(`Unable to resolve resource ${key}`);
101+
}
102+
83103
destroyReferencedObject(key: string, modelPromise: Promise<ITextEditorModel>): void {
84104

85105
// untitled and inMemory are bound to a different lifecycle
@@ -173,7 +193,7 @@ export class TextModelResolverService extends Disposable implements ITextModelSe
173193

174194
declare readonly _serviceBrand: undefined;
175195

176-
private readonly resourceModelCollection = this.instantiationService.createInstance(ResourceModelCollection);
196+
private readonly resourceModelCollection: ResourceModelCollection & ReferenceCollection<Promise<IResolvedTextEditorModel>> /* TS Fail */ = this.instantiationService.createInstance(ResourceModelCollection);
177197
private readonly asyncModelCollection = new AsyncReferenceCollection(this.resourceModelCollection);
178198

179199
constructor(
@@ -195,8 +215,7 @@ export class TextModelResolverService extends Disposable implements ITextModelSe
195215
// with different resource forms (e.g. path casing on Windows)
196216
resource = this.uriIdentityService.asCanonicalUri(resource);
197217

198-
const result = await this.asyncModelCollection.acquire(resource.toString());
199-
return result as IReference<IResolvedTextEditorModel>; // TODO@Ben: why is this cast here?
218+
return await this.asyncModelCollection.acquire(resource.toString());
200219
}
201220

202221
registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable {

0 commit comments

Comments
 (0)