@codingame/monaco-vscode-files-service-override 1.85.0 → 1.85.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,404 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
3
+ import { toErrorMessage } from 'monaco-editor/esm/vs/base/common/errorMessage.js';
4
+ import { Emitter, Event } from 'monaco-editor/esm/vs/base/common/event.js';
5
+ import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
6
+ import { TextFileEditorModel } from 'vscode/vscode/vs/workbench/services/textfile/common/textFileEditorModel';
7
+ import { Disposable, DisposableStore, dispose } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
8
+ import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
9
+ import { ResourceMap } from 'monaco-editor/esm/vs/base/common/map.js';
10
+ import { IFileService } from 'monaco-editor/esm/vs/platform/files/common/files.js';
11
+ import { ResourceQueue, Promises } from 'monaco-editor/esm/vs/base/common/async.js';
12
+ import { onUnexpectedError } from 'monaco-editor/esm/vs/base/common/errors.js';
13
+ import { TextFileSaveParticipant } from './textFileSaveParticipant.js';
14
+ import { INotificationService } from 'monaco-editor/esm/vs/platform/notification/common/notification.js';
15
+ import { IWorkingCopyFileService } from 'vscode/vscode/vs/workbench/services/workingCopy/common/workingCopyFileService';
16
+ import { joinPath, extname } from 'monaco-editor/esm/vs/base/common/resources.js';
17
+ import { createTextBufferFactoryFromSnapshot } from 'monaco-editor/esm/vs/editor/common/model/textModel.js';
18
+ import { PLAINTEXT_LANGUAGE_ID, PLAINTEXT_EXTENSION } from 'monaco-editor/esm/vs/editor/common/languages/modesRegistry.js';
19
+ import { IUriIdentityService } from 'monaco-editor/esm/vs/platform/uriIdentity/common/uriIdentity.js';
20
+
21
+ let TextFileEditorModelManager = class TextFileEditorModelManager extends Disposable {
22
+ get models() {
23
+ return [...( this.mapResourceToModel.values())];
24
+ }
25
+ constructor(instantiationService, fileService, notificationService, workingCopyFileService, uriIdentityService) {
26
+ super();
27
+ this.instantiationService = instantiationService;
28
+ this.fileService = fileService;
29
+ this.notificationService = notificationService;
30
+ this.workingCopyFileService = workingCopyFileService;
31
+ this.uriIdentityService = uriIdentityService;
32
+ this._onDidCreate = this._register(( new Emitter()));
33
+ this.onDidCreate = this._onDidCreate.event;
34
+ this._onDidResolve = this._register(( new Emitter()));
35
+ this.onDidResolve = this._onDidResolve.event;
36
+ this._onDidRemove = this._register(( new Emitter()));
37
+ this.onDidRemove = this._onDidRemove.event;
38
+ this._onDidChangeDirty = this._register(( new Emitter()));
39
+ this.onDidChangeDirty = this._onDidChangeDirty.event;
40
+ this._onDidChangeReadonly = this._register(( new Emitter()));
41
+ this.onDidChangeReadonly = this._onDidChangeReadonly.event;
42
+ this._onDidChangeOrphaned = this._register(( new Emitter()));
43
+ this.onDidChangeOrphaned = this._onDidChangeOrphaned.event;
44
+ this._onDidSaveError = this._register(( new Emitter()));
45
+ this.onDidSaveError = this._onDidSaveError.event;
46
+ this._onDidSave = this._register(( new Emitter()));
47
+ this.onDidSave = this._onDidSave.event;
48
+ this._onDidRevert = this._register(( new Emitter()));
49
+ this.onDidRevert = this._onDidRevert.event;
50
+ this._onDidChangeEncoding = this._register(( new Emitter()));
51
+ this.onDidChangeEncoding = this._onDidChangeEncoding.event;
52
+ this.mapResourceToModel = ( new ResourceMap());
53
+ this.mapResourceToModelListeners = ( new ResourceMap());
54
+ this.mapResourceToDisposeListener = ( new ResourceMap());
55
+ this.mapResourceToPendingModelResolvers = ( new ResourceMap());
56
+ this.modelResolveQueue = this._register(( new ResourceQueue()));
57
+ this.saveErrorHandler = (() => {
58
+ const notificationService = this.notificationService;
59
+ return {
60
+ onSaveError(error, model) {
61
+ notificationService.error(( localizeWithPath(
62
+ 'vs/workbench/services/textfile/common/textFileEditorModelManager',
63
+ { key: 'genericSaveError', comment: ['{0} is the resource that failed to save and {1} the error message'] },
64
+ "Failed to save '{0}': {1}",
65
+ model.name,
66
+ toErrorMessage(error, false)
67
+ )));
68
+ }
69
+ };
70
+ })();
71
+ this.mapCorrelationIdToModelsToRestore = ( new Map());
72
+ this.saveParticipants = this._register(this.instantiationService.createInstance(TextFileSaveParticipant));
73
+ this.registerListeners();
74
+ }
75
+ registerListeners() {
76
+ this._register(this.fileService.onDidFilesChange(e => this.onDidFilesChange(e)));
77
+ this._register(this.fileService.onDidChangeFileSystemProviderCapabilities(e => this.onDidChangeFileSystemProviderCapabilities(e)));
78
+ this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onDidChangeFileSystemProviderRegistrations(e)));
79
+ this._register(this.workingCopyFileService.onWillRunWorkingCopyFileOperation(e => this.onWillRunWorkingCopyFileOperation(e)));
80
+ this._register(this.workingCopyFileService.onDidFailWorkingCopyFileOperation(e => this.onDidFailWorkingCopyFileOperation(e)));
81
+ this._register(this.workingCopyFileService.onDidRunWorkingCopyFileOperation(e => this.onDidRunWorkingCopyFileOperation(e)));
82
+ }
83
+ onDidFilesChange(e) {
84
+ for (const model of this.models) {
85
+ if (model.isDirty()) {
86
+ continue;
87
+ }
88
+ if (e.contains(model.resource, 0 , 1 )) {
89
+ this.queueModelReload(model);
90
+ }
91
+ }
92
+ }
93
+ onDidChangeFileSystemProviderCapabilities(e) {
94
+ this.queueModelReloads(e.scheme);
95
+ }
96
+ onDidChangeFileSystemProviderRegistrations(e) {
97
+ if (!e.added) {
98
+ return;
99
+ }
100
+ this.queueModelReloads(e.scheme);
101
+ }
102
+ queueModelReloads(scheme) {
103
+ for (const model of this.models) {
104
+ if (model.isDirty()) {
105
+ continue;
106
+ }
107
+ if (scheme === model.resource.scheme) {
108
+ this.queueModelReload(model);
109
+ }
110
+ }
111
+ }
112
+ queueModelReload(model) {
113
+ const queue = this.modelResolveQueue.queueFor(model.resource);
114
+ if (queue.size <= 1) {
115
+ queue.queue(async () => {
116
+ try {
117
+ await this.reload(model);
118
+ }
119
+ catch (error) {
120
+ onUnexpectedError(error);
121
+ }
122
+ });
123
+ }
124
+ }
125
+ onWillRunWorkingCopyFileOperation(e) {
126
+ if (e.operation === 2 || e.operation === 3 ) {
127
+ const modelsToRestore = [];
128
+ for (const { source, target } of e.files) {
129
+ if (source) {
130
+ if (this.uriIdentityService.extUri.isEqual(source, target)) {
131
+ continue;
132
+ }
133
+ const sourceModels = [];
134
+ for (const model of this.models) {
135
+ if (this.uriIdentityService.extUri.isEqualOrParent(model.resource, source)) {
136
+ sourceModels.push(model);
137
+ }
138
+ }
139
+ for (const sourceModel of sourceModels) {
140
+ const sourceModelResource = sourceModel.resource;
141
+ let targetModelResource;
142
+ if (this.uriIdentityService.extUri.isEqual(sourceModelResource, source)) {
143
+ targetModelResource = target;
144
+ }
145
+ else {
146
+ targetModelResource = joinPath(target, sourceModelResource.path.substr(source.path.length + 1));
147
+ }
148
+ modelsToRestore.push({
149
+ source: sourceModelResource,
150
+ target: targetModelResource,
151
+ languageId: sourceModel.getLanguageId(),
152
+ encoding: sourceModel.getEncoding(),
153
+ snapshot: sourceModel.isDirty() ? sourceModel.createSnapshot() : undefined
154
+ });
155
+ }
156
+ }
157
+ }
158
+ this.mapCorrelationIdToModelsToRestore.set(e.correlationId, modelsToRestore);
159
+ }
160
+ }
161
+ onDidFailWorkingCopyFileOperation(e) {
162
+ if (((e.operation === 2 || e.operation === 3) )) {
163
+ const modelsToRestore = this.mapCorrelationIdToModelsToRestore.get(e.correlationId);
164
+ if (modelsToRestore) {
165
+ this.mapCorrelationIdToModelsToRestore.delete(e.correlationId);
166
+ modelsToRestore.forEach(model => {
167
+ if (model.snapshot) {
168
+ this.get(model.source)?.setDirty(true);
169
+ }
170
+ });
171
+ }
172
+ }
173
+ }
174
+ onDidRunWorkingCopyFileOperation(e) {
175
+ switch (e.operation) {
176
+ case 0 :
177
+ e.waitUntil((async () => {
178
+ for (const { target } of e.files) {
179
+ const model = this.get(target);
180
+ if (model && !model.isDisposed()) {
181
+ await model.revert();
182
+ }
183
+ }
184
+ })());
185
+ break;
186
+ case 2 :
187
+ case 3 :
188
+ e.waitUntil((async () => {
189
+ const modelsToRestore = this.mapCorrelationIdToModelsToRestore.get(e.correlationId);
190
+ if (modelsToRestore) {
191
+ this.mapCorrelationIdToModelsToRestore.delete(e.correlationId);
192
+ await Promises.settled(( modelsToRestore.map(async (modelToRestore) => {
193
+ const restoredModel = await this.resolve(modelToRestore.target, {
194
+ reload: { async: false },
195
+ contents: modelToRestore.snapshot ? createTextBufferFactoryFromSnapshot(modelToRestore.snapshot) : undefined,
196
+ encoding: modelToRestore.encoding
197
+ });
198
+ if (modelToRestore.languageId &&
199
+ modelToRestore.languageId !== PLAINTEXT_LANGUAGE_ID &&
200
+ restoredModel.getLanguageId() === PLAINTEXT_LANGUAGE_ID &&
201
+ extname(modelToRestore.target) !== PLAINTEXT_EXTENSION) {
202
+ restoredModel.updateTextEditorModel(undefined, modelToRestore.languageId);
203
+ }
204
+ })));
205
+ }
206
+ })());
207
+ break;
208
+ }
209
+ }
210
+ get(resource) {
211
+ return this.mapResourceToModel.get(resource);
212
+ }
213
+ has(resource) {
214
+ return ( this.mapResourceToModel.has(resource));
215
+ }
216
+ async reload(model) {
217
+ await this.joinPendingResolves(model.resource);
218
+ if (model.isDirty() || model.isDisposed() || !( this.has(model.resource))) {
219
+ return;
220
+ }
221
+ await this.doResolve(model, { reload: { async: false } });
222
+ }
223
+ async resolve(resource, options) {
224
+ const pendingResolve = this.joinPendingResolves(resource);
225
+ if (pendingResolve) {
226
+ await pendingResolve;
227
+ }
228
+ return this.doResolve(resource, options);
229
+ }
230
+ async doResolve(resourceOrModel, options) {
231
+ let model;
232
+ let resource;
233
+ if (URI.isUri(resourceOrModel)) {
234
+ resource = resourceOrModel;
235
+ model = this.get(resource);
236
+ }
237
+ else {
238
+ resource = resourceOrModel.resource;
239
+ model = resourceOrModel;
240
+ }
241
+ let modelResolve;
242
+ let didCreateModel = false;
243
+ if (model) {
244
+ if (options?.contents) {
245
+ modelResolve = model.resolve(options);
246
+ }
247
+ else if (options?.reload) {
248
+ if (options.reload.async) {
249
+ modelResolve = Promise.resolve();
250
+ (async () => {
251
+ try {
252
+ await model.resolve(options);
253
+ }
254
+ catch (error) {
255
+ onUnexpectedError(error);
256
+ }
257
+ })();
258
+ }
259
+ else {
260
+ modelResolve = model.resolve(options);
261
+ }
262
+ }
263
+ else {
264
+ modelResolve = Promise.resolve();
265
+ }
266
+ }
267
+ else {
268
+ didCreateModel = true;
269
+ const newModel = model = this.instantiationService.createInstance(TextFileEditorModel, resource, options ? options.encoding : undefined, options ? options.languageId : undefined);
270
+ modelResolve = model.resolve(options);
271
+ this.registerModel(newModel);
272
+ }
273
+ this.mapResourceToPendingModelResolvers.set(resource, modelResolve);
274
+ this.add(resource, model);
275
+ if (didCreateModel) {
276
+ this._onDidCreate.fire(model);
277
+ if (model.isDirty()) {
278
+ this._onDidChangeDirty.fire(model);
279
+ }
280
+ }
281
+ try {
282
+ await modelResolve;
283
+ }
284
+ catch (error) {
285
+ if (didCreateModel) {
286
+ model.dispose();
287
+ }
288
+ throw error;
289
+ }
290
+ finally {
291
+ this.mapResourceToPendingModelResolvers.delete(resource);
292
+ }
293
+ if (options?.languageId) {
294
+ model.setLanguageId(options.languageId);
295
+ }
296
+ if (didCreateModel && model.isDirty()) {
297
+ this._onDidChangeDirty.fire(model);
298
+ }
299
+ return model;
300
+ }
301
+ joinPendingResolves(resource) {
302
+ const pendingModelResolve = this.mapResourceToPendingModelResolvers.get(resource);
303
+ if (!pendingModelResolve) {
304
+ return;
305
+ }
306
+ return this.doJoinPendingResolves(resource);
307
+ }
308
+ async doJoinPendingResolves(resource) {
309
+ let currentModelCopyResolve;
310
+ while (( this.mapResourceToPendingModelResolvers.has(resource))) {
311
+ const nextPendingModelResolve = this.mapResourceToPendingModelResolvers.get(resource);
312
+ if (nextPendingModelResolve === currentModelCopyResolve) {
313
+ return;
314
+ }
315
+ currentModelCopyResolve = nextPendingModelResolve;
316
+ try {
317
+ await nextPendingModelResolve;
318
+ }
319
+ catch (error) {
320
+ }
321
+ }
322
+ }
323
+ registerModel(model) {
324
+ const modelListeners = ( new DisposableStore());
325
+ modelListeners.add(model.onDidResolve(reason => this._onDidResolve.fire({ model, reason })));
326
+ modelListeners.add(model.onDidChangeDirty(() => this._onDidChangeDirty.fire(model)));
327
+ modelListeners.add(model.onDidChangeReadonly(() => this._onDidChangeReadonly.fire(model)));
328
+ modelListeners.add(model.onDidChangeOrphaned(() => this._onDidChangeOrphaned.fire(model)));
329
+ modelListeners.add(model.onDidSaveError(() => this._onDidSaveError.fire(model)));
330
+ modelListeners.add(model.onDidSave(e => this._onDidSave.fire({ model, ...e })));
331
+ modelListeners.add(model.onDidRevert(() => this._onDidRevert.fire(model)));
332
+ modelListeners.add(model.onDidChangeEncoding(() => this._onDidChangeEncoding.fire(model)));
333
+ this.mapResourceToModelListeners.set(model.resource, modelListeners);
334
+ }
335
+ add(resource, model) {
336
+ const knownModel = this.mapResourceToModel.get(resource);
337
+ if (knownModel === model) {
338
+ return;
339
+ }
340
+ const disposeListener = this.mapResourceToDisposeListener.get(resource);
341
+ disposeListener?.dispose();
342
+ this.mapResourceToModel.set(resource, model);
343
+ this.mapResourceToDisposeListener.set(resource, model.onWillDispose(() => this.remove(resource)));
344
+ }
345
+ remove(resource) {
346
+ const removed = this.mapResourceToModel.delete(resource);
347
+ const disposeListener = this.mapResourceToDisposeListener.get(resource);
348
+ if (disposeListener) {
349
+ dispose(disposeListener);
350
+ this.mapResourceToDisposeListener.delete(resource);
351
+ }
352
+ const modelListener = this.mapResourceToModelListeners.get(resource);
353
+ if (modelListener) {
354
+ dispose(modelListener);
355
+ this.mapResourceToModelListeners.delete(resource);
356
+ }
357
+ if (removed) {
358
+ this._onDidRemove.fire(resource);
359
+ }
360
+ }
361
+ addSaveParticipant(participant) {
362
+ return this.saveParticipants.addSaveParticipant(participant);
363
+ }
364
+ runSaveParticipants(model, context, token) {
365
+ return this.saveParticipants.participate(model, context, token);
366
+ }
367
+ canDispose(model) {
368
+ if (model.isDisposed() ||
369
+ (!( this.mapResourceToPendingModelResolvers.has(model.resource)) && !model.isDirty())) {
370
+ return true;
371
+ }
372
+ return this.doCanDispose(model);
373
+ }
374
+ async doCanDispose(model) {
375
+ const pendingResolve = this.joinPendingResolves(model.resource);
376
+ if (pendingResolve) {
377
+ await pendingResolve;
378
+ return this.canDispose(model);
379
+ }
380
+ if (model.isDirty()) {
381
+ await Event.toPromise(model.onDidChangeDirty);
382
+ return this.canDispose(model);
383
+ }
384
+ return true;
385
+ }
386
+ dispose() {
387
+ super.dispose();
388
+ this.mapResourceToModel.clear();
389
+ this.mapResourceToPendingModelResolvers.clear();
390
+ dispose(( this.mapResourceToDisposeListener.values()));
391
+ this.mapResourceToDisposeListener.clear();
392
+ dispose(( this.mapResourceToModelListeners.values()));
393
+ this.mapResourceToModelListeners.clear();
394
+ }
395
+ };
396
+ TextFileEditorModelManager = ( __decorate([
397
+ ( __param(0, IInstantiationService)),
398
+ ( __param(1, IFileService)),
399
+ ( __param(2, INotificationService)),
400
+ ( __param(3, IWorkingCopyFileService)),
401
+ ( __param(4, IUriIdentityService))
402
+ ], TextFileEditorModelManager));
403
+
404
+ export { TextFileEditorModelManager };
@@ -0,0 +1,64 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
3
+ import { raceCancellation } from 'monaco-editor/esm/vs/base/common/async.js';
4
+ import { CancellationTokenSource } from 'monaco-editor/esm/vs/base/common/cancellation.js';
5
+ import { ILogService } from 'monaco-editor/esm/vs/platform/log/common/log.js';
6
+ import { IProgressService } from 'monaco-editor/esm/vs/platform/progress/common/progress.js';
7
+ import { Disposable, toDisposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
8
+ import { insert } from 'monaco-editor/esm/vs/base/common/arrays.js';
9
+
10
+ let TextFileSaveParticipant = class TextFileSaveParticipant extends Disposable {
11
+ constructor(progressService, logService) {
12
+ super();
13
+ this.progressService = progressService;
14
+ this.logService = logService;
15
+ this.saveParticipants = [];
16
+ }
17
+ addSaveParticipant(participant) {
18
+ const remove = insert(this.saveParticipants, participant);
19
+ return toDisposable(() => remove());
20
+ }
21
+ participate(model, context, token) {
22
+ const cts = ( new CancellationTokenSource(token));
23
+ return this.progressService.withProgress({
24
+ title: ( localizeWithPath(
25
+ 'vs/workbench/services/textfile/common/textFileSaveParticipant',
26
+ 'saveParticipants',
27
+ "Saving '{0}'",
28
+ model.name
29
+ )),
30
+ location: 15 ,
31
+ cancellable: true,
32
+ delay: model.isDirty() ? 3000 : 5000
33
+ }, async (progress) => {
34
+ model.textEditorModel?.pushStackElement();
35
+ for (const saveParticipant of this.saveParticipants) {
36
+ if (cts.token.isCancellationRequested || !model.textEditorModel ) {
37
+ break;
38
+ }
39
+ try {
40
+ const promise = saveParticipant.participate(model, context, progress, cts.token);
41
+ await raceCancellation(promise, cts.token);
42
+ }
43
+ catch (err) {
44
+ this.logService.error(err);
45
+ }
46
+ }
47
+ model.textEditorModel?.pushStackElement();
48
+ }, () => {
49
+ cts.cancel();
50
+ }).finally(() => {
51
+ cts.dispose();
52
+ });
53
+ }
54
+ dispose() {
55
+ this.saveParticipants.splice(0, this.saveParticipants.length);
56
+ super.dispose();
57
+ }
58
+ };
59
+ TextFileSaveParticipant = ( __decorate([
60
+ ( __param(0, IProgressService)),
61
+ ( __param(1, ILogService))
62
+ ], TextFileSaveParticipant));
63
+
64
+ export { TextFileSaveParticipant };
@@ -1,222 +0,0 @@
1
- import { VSBuffer } from 'monaco-editor/esm/vs/base/common/buffer.js';
2
- import { Emitter } from 'monaco-editor/esm/vs/base/common/event.js';
3
- import { Disposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
4
- import * as resources from 'monaco-editor/esm/vs/base/common/resources.js';
5
- import { newWriteableStream } from 'monaco-editor/esm/vs/base/common/stream.js';
6
- import { createFileSystemProviderError, FileSystemProviderErrorCode, FileType } from 'monaco-editor/esm/vs/platform/files/common/files.js';
7
-
8
- class File {
9
- constructor(name) {
10
- this.type = FileType.File;
11
- this.ctime = Date.now();
12
- this.mtime = Date.now();
13
- this.size = 0;
14
- this.name = name;
15
- }
16
- }
17
- class Directory {
18
- constructor(name) {
19
- this.type = FileType.Directory;
20
- this.ctime = Date.now();
21
- this.mtime = Date.now();
22
- this.size = 0;
23
- this.name = name;
24
- this.entries = ( new Map());
25
- }
26
- }
27
- class InMemoryFileSystemProvider extends Disposable {
28
- constructor() {
29
- super(...arguments);
30
- this.memoryFdCounter = 0;
31
- this.fdMemory = ( new Map());
32
- this._onDidChangeCapabilities = this._register(( new Emitter()));
33
- this.onDidChangeCapabilities = this._onDidChangeCapabilities.event;
34
- this._capabilities = 2 | 1024 ;
35
- this.root = ( new Directory(''));
36
- this._onDidChangeFile = this._register(( new Emitter()));
37
- this.onDidChangeFile = this._onDidChangeFile.event;
38
- this._bufferedChanges = [];
39
- }
40
- get capabilities() { return this._capabilities; }
41
- setReadOnly(readonly) {
42
- const isReadonly = !!((this._capabilities & 2048) );
43
- if (readonly !== isReadonly) {
44
- this._capabilities = readonly ? 2048 | 1024 | 2
45
- : 2 | 1024 ;
46
- this._onDidChangeCapabilities.fire();
47
- }
48
- }
49
- async stat(resource) {
50
- return this._lookup(resource, false);
51
- }
52
- async readdir(resource) {
53
- const entry = this._lookupAsDirectory(resource, false);
54
- const result = [];
55
- entry.entries.forEach((child, name) => result.push([name, child.type]));
56
- return result;
57
- }
58
- async readFile(resource) {
59
- const data = this._lookupAsFile(resource, false).data;
60
- if (data) {
61
- return data;
62
- }
63
- throw createFileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound);
64
- }
65
- readFileStream(resource) {
66
- const data = this._lookupAsFile(resource, false).data;
67
- const stream = newWriteableStream(data => VSBuffer.concat(( data.map(data => VSBuffer.wrap(data)))).buffer);
68
- stream.end(data);
69
- return stream;
70
- }
71
- async writeFile(resource, content, opts) {
72
- const basename = resources.basename(resource);
73
- const parent = this._lookupParentDirectory(resource);
74
- let entry = parent.entries.get(basename);
75
- if (entry instanceof Directory) {
76
- throw createFileSystemProviderError('file is directory', FileSystemProviderErrorCode.FileIsADirectory);
77
- }
78
- if (!entry && !opts.create) {
79
- throw createFileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound);
80
- }
81
- if (entry && opts.create && !opts.overwrite) {
82
- throw createFileSystemProviderError('file exists already', FileSystemProviderErrorCode.FileExists);
83
- }
84
- if (!entry) {
85
- entry = ( new File(basename));
86
- parent.entries.set(basename, entry);
87
- this._fireSoon({ type: 1 , resource });
88
- }
89
- entry.mtime = Date.now();
90
- entry.size = content.byteLength;
91
- entry.data = content;
92
- this._fireSoon({ type: 0 , resource });
93
- }
94
- open(resource, opts) {
95
- const data = this._lookupAsFile(resource, false).data;
96
- if (data) {
97
- const fd = this.memoryFdCounter++;
98
- this.fdMemory.set(fd, data);
99
- return Promise.resolve(fd);
100
- }
101
- throw createFileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound);
102
- }
103
- close(fd) {
104
- this.fdMemory.delete(fd);
105
- return Promise.resolve();
106
- }
107
- read(fd, pos, data, offset, length) {
108
- const memory = this.fdMemory.get(fd);
109
- if (!memory) {
110
- throw createFileSystemProviderError(`No file with that descriptor open`, FileSystemProviderErrorCode.Unavailable);
111
- }
112
- const toWrite = VSBuffer.wrap(memory).slice(pos, pos + length);
113
- data.set(toWrite.buffer, offset);
114
- return Promise.resolve(toWrite.byteLength);
115
- }
116
- write(fd, pos, data, offset, length) {
117
- const memory = this.fdMemory.get(fd);
118
- if (!memory) {
119
- throw createFileSystemProviderError(`No file with that descriptor open`, FileSystemProviderErrorCode.Unavailable);
120
- }
121
- const toWrite = VSBuffer.wrap(data).slice(offset, offset + length);
122
- memory.set(toWrite.buffer, pos);
123
- return Promise.resolve(toWrite.byteLength);
124
- }
125
- async rename(from, to, opts) {
126
- if (!opts.overwrite && this._lookup(to, true)) {
127
- throw createFileSystemProviderError('file exists already', FileSystemProviderErrorCode.FileExists);
128
- }
129
- const entry = this._lookup(from, false);
130
- const oldParent = this._lookupParentDirectory(from);
131
- const newParent = this._lookupParentDirectory(to);
132
- const newName = resources.basename(to);
133
- oldParent.entries.delete(entry.name);
134
- entry.name = newName;
135
- newParent.entries.set(newName, entry);
136
- this._fireSoon({ type: 2 , resource: from }, { type: 1 , resource: to });
137
- }
138
- async delete(resource, opts) {
139
- const dirname = resources.dirname(resource);
140
- const basename = resources.basename(resource);
141
- const parent = this._lookupAsDirectory(dirname, false);
142
- if (( parent.entries.has(basename))) {
143
- parent.entries.delete(basename);
144
- parent.mtime = Date.now();
145
- parent.size -= 1;
146
- this._fireSoon({ type: 0 , resource: dirname }, { resource, type: 2 });
147
- }
148
- }
149
- async mkdir(resource) {
150
- if (this._lookup(resource, true)) {
151
- throw createFileSystemProviderError('file exists already', FileSystemProviderErrorCode.FileExists);
152
- }
153
- const basename = resources.basename(resource);
154
- const dirname = resources.dirname(resource);
155
- const parent = this._lookupAsDirectory(dirname, false);
156
- const entry = ( new Directory(basename));
157
- parent.entries.set(entry.name, entry);
158
- parent.mtime = Date.now();
159
- parent.size += 1;
160
- this._fireSoon({ type: 0 , resource: dirname }, { type: 1 , resource });
161
- }
162
- _lookup(uri, silent) {
163
- const parts = uri.path.split('/');
164
- let entry = this.root;
165
- for (const part of parts) {
166
- if (!part) {
167
- continue;
168
- }
169
- let child;
170
- if (entry instanceof Directory) {
171
- child = entry.entries.get(part);
172
- }
173
- if (!child) {
174
- if (!silent) {
175
- throw createFileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound);
176
- }
177
- else {
178
- return undefined;
179
- }
180
- }
181
- entry = child;
182
- }
183
- return entry;
184
- }
185
- _lookupAsDirectory(uri, silent) {
186
- const entry = this._lookup(uri, silent);
187
- if (entry instanceof Directory) {
188
- return entry;
189
- }
190
- throw createFileSystemProviderError('file not a directory', FileSystemProviderErrorCode.FileNotADirectory);
191
- }
192
- _lookupAsFile(uri, silent) {
193
- const entry = this._lookup(uri, silent);
194
- if (entry instanceof File) {
195
- return entry;
196
- }
197
- throw createFileSystemProviderError('file is a directory', FileSystemProviderErrorCode.FileIsADirectory);
198
- }
199
- _lookupParentDirectory(uri) {
200
- const dirname = resources.dirname(uri);
201
- return this._lookupAsDirectory(dirname, false);
202
- }
203
- watch(resource, opts) {
204
- return Disposable.None;
205
- }
206
- _fireSoon(...changes) {
207
- this._bufferedChanges.push(...changes);
208
- if (this._fireSoonHandle) {
209
- clearTimeout(this._fireSoonHandle);
210
- }
211
- this._fireSoonHandle = setTimeout(() => {
212
- this._onDidChangeFile.fire(this._bufferedChanges);
213
- this._bufferedChanges.length = 0;
214
- }, 5);
215
- }
216
- dispose() {
217
- super.dispose();
218
- this.fdMemory.clear();
219
- }
220
- }
221
-
222
- export { InMemoryFileSystemProvider };