diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index 1c5a97fcc38..c05a9374965 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -18,7 +18,7 @@ import { extUri, extUriIgnorePathCase, IExtUri, isAbsolutePath } from 'vs/base/c import { consumeStream, isReadableBufferedStream, isReadableStream, listenStream, newWriteableStream, peekReadable, peekStream, transform } from 'vs/base/common/stream'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; -import { ensureFileSystemProviderError, etag, ETAG_DISABLED, FileChangesEvent, IFileDeleteOptions, FileOperation, FileOperationError, FileOperationEvent, FileOperationResult, FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, hasFileAtomicReadCapability, hasFileFolderCopyCapability, hasFileReadStreamCapability, hasOpenReadWriteCloseCapability, hasReadWriteCapability, ICreateFileOptions, IFileContent, IFileService, IFileStat, IFileStatWithMetadata, IFileStreamContent, IFileSystemProvider, IFileSystemProviderActivationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderRegistrationEvent, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, IReadFileOptions, IReadFileStreamOptions, IResolveFileOptions, IFileStatResult, IFileStatResultWithMetadata, IResolveMetadataFileOptions, IStat, IFileStatWithPartialMetadata, IWatchOptions, IWriteFileOptions, NotModifiedSinceFileOperationError, toFileOperationResult, toFileSystemProviderErrorCode, hasFileCloneCapability, hasFileReadCapability, IFileSystemProviderWithFileReadCapability } from 'vs/platform/files/common/files'; +import { ensureFileSystemProviderError, etag, ETAG_DISABLED, FileChangesEvent, IFileDeleteOptions, FileOperation, FileOperationError, FileOperationEvent, FileOperationResult, FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, hasFileAtomicReadCapability, hasFileFolderCopyCapability, hasFileReadStreamCapability, hasOpenReadWriteCloseCapability, hasReadWriteCapability, ICreateFileOptions, IFileContent, IFileService, IFileStat, IFileStatWithMetadata, IFileStreamContent, IFileSystemProvider, IFileSystemProviderActivationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderRegistrationEvent, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, IReadFileOptions, IReadFileStreamOptions, IResolveFileOptions, IFileStatResult, IFileStatResultWithMetadata, IResolveMetadataFileOptions, IStat, IFileStatWithPartialMetadata, IWatchOptions, IWriteFileOptions, NotModifiedSinceFileOperationError, toFileOperationResult, toFileSystemProviderErrorCode, hasFileCloneCapability } from 'vs/platform/files/common/files'; import { readFileIntoStream } from 'vs/platform/files/common/io'; import { ILogService } from 'vs/platform/log/common/log'; @@ -146,14 +146,14 @@ export class FileService extends Disposable implements IFileService { return provider; } - private async withReadProvider(resource: URI): Promise { + private async withReadProvider(resource: URI): Promise { const provider = await this.withProvider(resource); - if (hasOpenReadWriteCloseCapability(provider) || hasReadWriteCapability(provider) || hasFileReadStreamCapability(provider) || hasFileReadCapability(provider)) { + if (hasOpenReadWriteCloseCapability(provider) || hasReadWriteCapability(provider) || hasFileReadStreamCapability(provider)) { return provider; } - throw new Error(`Filesystem provider for scheme '${resource.scheme}' neither has FileReadWrite, FileReadStream, FileOpenReadWriteClose nor Readonly capability which is needed for the read operation.`); + throw new Error(`Filesystem provider for scheme '${resource.scheme}' neither has FileReadWrite, FileReadStream nor FileOpenReadWriteClose capability which is needed for the read operation.`); } private async withWriteProvider(resource: URI): Promise { @@ -464,7 +464,7 @@ export class FileService extends Disposable implements IFileService { return this.doReadFile(provider, resource, options, token); } - private async doReadFileAtomic(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise { + private async doReadFileAtomic(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise { return new Promise((resolve, reject) => { this.writeQueue.queueFor(resource, this.getExtUri(provider).providerExtUri).queue(async () => { try { @@ -477,7 +477,7 @@ export class FileService extends Disposable implements IFileService { }); } - private async doReadFile(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise { + private async doReadFile(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise { const stream = await this.doReadFileStream(provider, resource, { ...options, // optimization: since we know that the caller does not @@ -500,7 +500,7 @@ export class FileService extends Disposable implements IFileService { return this.doReadFileStream(provider, resource, options, token); } - private async doReadFileStream(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions & { preferUnbuffered?: boolean }, token?: CancellationToken): Promise { + private async doReadFileStream(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions & { preferUnbuffered?: boolean }, token?: CancellationToken): Promise { // install a cancellation token that gets cancelled // when any error occurs. this allows us to resolve @@ -596,7 +596,7 @@ export class FileService extends Disposable implements IFileService { return stream; } - private readFileUnbuffered(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithFileAtomicReadCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions): VSBufferReadableStream { + private readFileUnbuffered(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithFileAtomicReadCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions): VSBufferReadableStream { const stream = newWriteableStream(data => VSBuffer.concat(data)); // Read the file into the stream async but do not wait for diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index b195dd396b6..9b6968f03aa 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -567,14 +567,6 @@ export function hasFileReadStreamCapability(provider: IFileSystemProvider): prov return !!(provider.capabilities & FileSystemProviderCapabilities.FileReadStream); } -export interface IFileSystemProviderWithFileReadCapability extends IFileSystemProvider { - readFile(resource: URI): Promise; -} - -export function hasFileReadCapability(provider: IFileSystemProvider): provider is IFileSystemProviderWithFileReadCapability { - return !!(provider.capabilities & FileSystemProviderCapabilities.Readonly); -} - export interface IFileSystemProviderWithFileAtomicReadCapability extends IFileSystemProvider { readFile(resource: URI, opts?: IFileAtomicReadOptions): Promise; } diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessionsFileSystemProvider.ts b/src/vs/workbench/contrib/editSessions/browser/editSessionsFileSystemProvider.ts index ced7fbb6fbd..47b1ca77bb6 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessionsFileSystemProvider.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessionsFileSystemProvider.ts @@ -6,10 +6,11 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; -import { FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileSystemProviderWithFileReadCapability, IStat, IWatchOptions } from 'vs/platform/files/common/files'; +import { FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileSystemProviderWithFileReadWriteCapability, IStat, IWatchOptions } from 'vs/platform/files/common/files'; import { ChangeType, decodeEditSessionFileContent, EDIT_SESSIONS_SCHEME, IEditSessionsStorageService } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { NotSupportedError } from 'vs/base/common/errors'; -export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFileReadCapability { +export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapability { static readonly SCHEMA = EDIT_SESSIONS_SCHEME; @@ -17,7 +18,7 @@ export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFi @IEditSessionsStorageService private editSessionsStorageService: IEditSessionsStorageService, ) { } - readonly capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.Readonly; + readonly capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite; async readFile(resource: URI): Promise { const match = /(?[^/]+)\/(?[^/]+)\/(?.*)/.exec(resource.path.substring(1)); @@ -59,5 +60,9 @@ export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFi async rename(from: URI, to: URI, opts: IFileOverwriteOptions): Promise { } async delete(resource: URI, opts: IFileDeleteOptions): Promise { } + + async writeFile() { + throw new NotSupportedError(); + } //#endregion }