66import { URI } from 'vs/base/common/uri' ;
77import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
88import { ITextModel } from 'vs/editor/common/model' ;
9- import { IDisposable , toDisposable , IReference , ReferenceCollection , ImmortalReference } from 'vs/base/common/lifecycle' ;
9+ import { IDisposable , toDisposable , IReference , ReferenceCollection } from 'vs/base/common/lifecycle' ;
1010import { IModelService } from 'vs/editor/common/services/modelService' ;
1111import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel' ;
1212import { ITextFileService , TextFileLoadReason } from 'vs/workbench/services/textfile/common/textfiles' ;
1313import * as network from 'vs/base/common/network' ;
1414import { ITextModelService , ITextModelContentProvider , ITextEditorModel , IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService' ;
15- import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService' ;
1615import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel' ;
1716import { IFileService } from 'vs/platform/files/common/files' ;
1817import { registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
1918import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
2019
2120class ResourceModelCollection extends ReferenceCollection < Promise < ITextEditorModel > > {
2221
23- private providers : { [ scheme : string ] : ITextModelContentProvider [ ] } = Object . create ( null ) ;
24- private modelsToDispose = new Set < string > ( ) ;
22+ private readonly providers : { [ scheme : string ] : ITextModelContentProvider [ ] } = Object . create ( null ) ;
23+ private readonly modelsToDispose = new Set < string > ( ) ;
2524
2625 constructor (
2726 @IInstantiationService private readonly instantiationService : IInstantiationService ,
2827 @ITextFileService private readonly textFileService : ITextFileService ,
2928 @IFileService private readonly fileService : IFileService ,
3029 @ITelemetryService private readonly telemetryService : ITelemetryService ,
30+ @IModelService private readonly modelService : IModelService
3131 ) {
3232 super ( ) ;
3333 }
3434
3535 async createReferencedObject ( key : string , skipActivateProvider ?: boolean ) : Promise < ITextEditorModel > {
36+
37+ // Untrack as being disposed
3638 this . modelsToDispose . delete ( key ) ;
3739
40+ // inMemory Schema: go through model service cache
3841 const resource = URI . parse ( key ) ;
42+ if ( resource . scheme === network . Schemas . inMemory ) {
43+ const cachedModel = this . modelService . getModel ( resource ) ;
44+ if ( ! cachedModel ) {
45+ throw new Error ( `Unable to resolve inMemory resource ${ key } ` ) ;
46+ }
47+
48+ return this . instantiationService . createInstance ( ResourceEditorModel , resource ) ;
49+ }
3950
40- // File or remote file provider already known
51+ // Untitled Schema: go through untitled text service
52+ if ( resource . scheme === network . Schemas . untitled ) {
53+ return this . textFileService . untitled . resolve ( { untitledResource : resource } ) ;
54+ }
55+
56+ // File or remote file: go through text file service
4157 if ( this . fileService . canHandleResource ( resource ) ) {
4258 return this . textFileService . files . resolve ( resource , { reason : TextFileLoadReason . REFERENCE } ) ;
4359 }
@@ -56,19 +72,26 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
5672 return this . createReferencedObject ( key , true ) ;
5773 }
5874
59- throw new Error ( 'resource is not available' ) ;
75+ throw new Error ( `Unable to resolve resource ${ key } ` ) ;
6076 }
6177
6278 destroyReferencedObject ( key : string , modelPromise : Promise < ITextEditorModel > ) : void {
79+
80+ // Track as being disposed
6381 this . modelsToDispose . add ( key ) ;
6482
6583 modelPromise . then ( model => {
66- if ( this . modelsToDispose . has ( key ) ) {
67- if ( model instanceof TextFileEditorModel ) {
68- this . textFileService . files . disposeModel ( model ) ;
69- } else {
70- model . dispose ( ) ;
71- }
84+ if ( ! this . modelsToDispose . has ( key ) ) {
85+ return ; // return if model has been aquired again meanwhile
86+ }
87+
88+ const resource = URI . parse ( key ) ;
89+ if ( resource . scheme === network . Schemas . untitled || resource . scheme === network . Schemas . inMemory ) {
90+ // untitled and inMemory are bound to a different lifecycle
91+ } else if ( model instanceof TextFileEditorModel ) {
92+ this . textFileService . files . disposeModel ( model ) ;
93+ } else {
94+ model . dispose ( ) ;
7295 }
7396 } , err => {
7497 // ignore
@@ -131,53 +154,33 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
131154 return value ;
132155 }
133156 }
134- throw new Error ( 'resource is not available' ) ;
157+
158+ throw new Error ( `Unable to resolve text model content for resource ${ key } ` ) ;
135159 }
136160}
137161
138162export class TextModelResolverService implements ITextModelService {
139163
140164 _serviceBrand : undefined ;
141165
142- private resourceModelCollection : ResourceModelCollection ;
166+ private readonly resourceModelCollection = this . instantiationService . createInstance ( ResourceModelCollection ) ;
143167
144168 constructor (
145- @IUntitledTextEditorService private readonly untitledTextEditorService : IUntitledTextEditorService ,
146169 @IInstantiationService private readonly instantiationService : IInstantiationService ,
147- @IModelService private readonly modelService : IModelService
170+ @IFileService private readonly fileService : IFileService
148171 ) {
149- this . resourceModelCollection = instantiationService . createInstance ( ResourceModelCollection ) ;
150172 }
151173
152- createModelReference ( resource : URI ) : Promise < IReference < IResolvedTextEditorModel > > {
153- return this . doCreateModelReference ( resource ) ;
154- }
155-
156- private async doCreateModelReference ( resource : URI ) : Promise < IReference < IResolvedTextEditorModel > > {
157-
158- // Untitled Schema: go through untitled text service
159- if ( resource . scheme === network . Schemas . untitled ) {
160- const model = await this . untitledTextEditorService . resolve ( { untitledResource : resource } ) ;
161-
162- return new ImmortalReference ( model ) ;
163- }
164-
165- // InMemory Schema: go through model service cache
166- if ( resource . scheme === network . Schemas . inMemory ) {
167- const cachedModel = this . modelService . getModel ( resource ) ;
168- if ( ! cachedModel ) {
169- throw new Error ( 'Cant resolve inmemory resource' ) ;
170- }
171-
172- return new ImmortalReference ( this . instantiationService . createInstance ( ResourceEditorModel , resource ) as IResolvedTextEditorModel ) ;
173- }
174-
174+ async createModelReference ( resource : URI ) : Promise < IReference < IResolvedTextEditorModel > > {
175175 const ref = this . resourceModelCollection . acquire ( resource . toString ( ) ) ;
176176
177177 try {
178178 const model = await ref . object ;
179179
180- return { object : model as IResolvedTextEditorModel , dispose : ( ) => ref . dispose ( ) } ;
180+ return {
181+ object : model as IResolvedTextEditorModel ,
182+ dispose : ( ) => ref . dispose ( )
183+ } ;
181184 } catch ( error ) {
182185 ref . dispose ( ) ;
183186
@@ -189,12 +192,12 @@ export class TextModelResolverService implements ITextModelService {
189192 return this . resourceModelCollection . registerTextModelContentProvider ( scheme , provider ) ;
190193 }
191194
192- hasTextModelContentProvider ( scheme : string ) : boolean {
193- if ( scheme === network . Schemas . untitled || scheme === network . Schemas . inMemory ) {
194- return true ; // we handle untitled:// and inMemory:// within
195+ canHandleResource ( resource : URI ) : boolean {
196+ if ( this . fileService . canHandleResource ( resource ) || resource . scheme === network . Schemas . untitled || resource . scheme === network . Schemas . inMemory ) {
197+ return true ; // we handle file://, untitled:// and inMemory:// automatically
195198 }
196199
197- return this . resourceModelCollection . hasTextModelContentProvider ( scheme ) ;
200+ return this . resourceModelCollection . hasTextModelContentProvider ( resource . scheme ) ;
198201 }
199202}
200203
0 commit comments