mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-25 11:08:51 +01:00
Merge pull request #136657 from microsoft/joh/shortcut_fs
Add shortcut between file system provider and consumer
This commit is contained in:
@@ -90,6 +90,7 @@ import { matchesScheme } from 'vs/platform/opener/common/opener';
|
||||
import { ExtHostNotebookEditors } from 'vs/workbench/api/common/extHostNotebookEditors';
|
||||
import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments';
|
||||
import { ExtHostInteractive } from 'vs/workbench/api/common/extHostInteractive';
|
||||
import { combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
@@ -916,7 +917,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
return extHostTask.registerTaskProvider(extension, type, provider);
|
||||
},
|
||||
registerFileSystemProvider(scheme, provider, options) {
|
||||
return extHostFileSystem.registerFileSystemProvider(extension, scheme, provider, options);
|
||||
return combinedDisposable(
|
||||
extHostFileSystem.registerFileSystemProvider(extension, scheme, provider, options),
|
||||
extHostConsumerFileSystem.addFileSystemProvider(scheme, provider)
|
||||
);
|
||||
},
|
||||
get fs() {
|
||||
return extHostConsumerFileSystem.value;
|
||||
|
||||
@@ -1016,6 +1016,8 @@ export interface MainThreadFileSystemShape extends IDisposable {
|
||||
$copy(resource: UriComponents, target: UriComponents, opts: files.FileOverwriteOptions): Promise<void>;
|
||||
$mkdir(resource: UriComponents): Promise<void>;
|
||||
$delete(resource: UriComponents, opts: files.FileDeleteOptions): Promise<void>;
|
||||
|
||||
$ensureActivation(scheme: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadLabelServiceShape extends IDisposable {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { MainContext } from './extHost.protocol';
|
||||
import { MainContext, MainThreadFileSystemShape } from './extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
import * as files from 'vs/platform/files/common/files';
|
||||
import { FileSystemError } from 'vs/workbench/api/common/extHostTypes';
|
||||
@@ -11,6 +11,7 @@ import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class ExtHostConsumerFileSystem {
|
||||
|
||||
@@ -18,36 +19,110 @@ export class ExtHostConsumerFileSystem {
|
||||
|
||||
readonly value: vscode.FileSystem;
|
||||
|
||||
private readonly _proxy: MainThreadFileSystemShape;
|
||||
private readonly _fileSystemProvider = new Map<string, vscode.FileSystemProvider>();
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService extHostRpc: IExtHostRpcService,
|
||||
@IExtHostFileSystemInfo fileSystemInfo: IExtHostFileSystemInfo,
|
||||
) {
|
||||
const proxy = extHostRpc.getProxy(MainContext.MainThreadFileSystem);
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadFileSystem);
|
||||
const that = this;
|
||||
|
||||
this.value = Object.freeze({
|
||||
stat(uri: vscode.Uri): Promise<vscode.FileStat> {
|
||||
return proxy.$stat(uri).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async stat(uri: vscode.Uri): Promise<vscode.FileStat> {
|
||||
try {
|
||||
const provider = that._fileSystemProvider.get(uri.scheme);
|
||||
if (!provider) {
|
||||
return await that._proxy.$stat(uri);
|
||||
}
|
||||
// use shortcut
|
||||
await that._proxy.$ensureActivation(uri.scheme);
|
||||
const stat = await provider.stat(uri);
|
||||
return <vscode.FileStat>{
|
||||
type: stat.type,
|
||||
ctime: stat.ctime,
|
||||
mtime: stat.mtime,
|
||||
size: stat.size,
|
||||
permissions: stat.permissions
|
||||
};
|
||||
} catch (err) {
|
||||
ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
readDirectory(uri: vscode.Uri): Promise<[string, vscode.FileType][]> {
|
||||
return proxy.$readdir(uri).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async readDirectory(uri: vscode.Uri): Promise<[string, vscode.FileType][]> {
|
||||
try {
|
||||
const provider = that._fileSystemProvider.get(uri.scheme);
|
||||
if (provider) {
|
||||
// use shortcut
|
||||
await that._proxy.$ensureActivation(uri.scheme);
|
||||
return (await provider.readDirectory(uri)).slice(); // safe-copy
|
||||
} else {
|
||||
return await that._proxy.$readdir(uri);
|
||||
}
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
createDirectory(uri: vscode.Uri): Promise<void> {
|
||||
return proxy.$mkdir(uri).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async createDirectory(uri: vscode.Uri): Promise<void> {
|
||||
try {
|
||||
// no shortcut: does mkdirp
|
||||
return await that._proxy.$mkdir(uri);
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
async readFile(uri: vscode.Uri): Promise<Uint8Array> {
|
||||
return proxy.$readFile(uri).then(buff => buff.buffer).catch(ExtHostConsumerFileSystem._handleError);
|
||||
try {
|
||||
const provider = that._fileSystemProvider.get(uri.scheme);
|
||||
if (provider) {
|
||||
// use shortcut
|
||||
await that._proxy.$ensureActivation(uri.scheme);
|
||||
return (await provider.readFile(uri)).slice(); // safe-copy
|
||||
} else {
|
||||
return that._proxy.$readFile(uri).then(buff => buff.buffer);
|
||||
}
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
writeFile(uri: vscode.Uri, content: Uint8Array): Promise<void> {
|
||||
return proxy.$writeFile(uri, VSBuffer.wrap(content)).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async writeFile(uri: vscode.Uri, content: Uint8Array): Promise<void> {
|
||||
try {
|
||||
// no shortcut: does mkdirp
|
||||
return await that._proxy.$writeFile(uri, VSBuffer.wrap(content));
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
delete(uri: vscode.Uri, options?: { recursive?: boolean; useTrash?: boolean; }): Promise<void> {
|
||||
return proxy.$delete(uri, { ...{ recursive: false, useTrash: false }, ...options }).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async delete(uri: vscode.Uri, options?: { recursive?: boolean; useTrash?: boolean; }): Promise<void> {
|
||||
try {
|
||||
const provider = that._fileSystemProvider.get(uri.scheme);
|
||||
if (provider) {
|
||||
// use shortcut
|
||||
await that._proxy.$ensureActivation(uri.scheme);
|
||||
return await provider.delete(uri, { recursive: false, ...options });
|
||||
} else {
|
||||
return await that._proxy.$delete(uri, { recursive: false, useTrash: false, ...options });
|
||||
}
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
rename(oldUri: vscode.Uri, newUri: vscode.Uri, options?: { overwrite?: boolean; }): Promise<void> {
|
||||
return proxy.$rename(oldUri, newUri, { ...{ overwrite: false }, ...options }).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async rename(oldUri: vscode.Uri, newUri: vscode.Uri, options?: { overwrite?: boolean; }): Promise<void> {
|
||||
try {
|
||||
// no shortcut: potentially involves different schemes, does mkdirp
|
||||
return await that._proxy.$rename(oldUri, newUri, { ...{ overwrite: false }, ...options });
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
copy(source: vscode.Uri, destination: vscode.Uri, options?: { overwrite?: boolean; }): Promise<void> {
|
||||
return proxy.$copy(source, destination, { ...{ overwrite: false }, ...options }).catch(ExtHostConsumerFileSystem._handleError);
|
||||
async copy(source: vscode.Uri, destination: vscode.Uri, options?: { overwrite?: boolean; }): Promise<void> {
|
||||
try {
|
||||
// no shortcut: potentially involves different schemes, does mkdirp
|
||||
return await that._proxy.$copy(source, destination, { ...{ overwrite: false }, ...options });
|
||||
} catch (err) {
|
||||
return ExtHostConsumerFileSystem._handleError(err);
|
||||
}
|
||||
},
|
||||
isWritableFileSystem(scheme: string): boolean | undefined {
|
||||
const capabilities = fileSystemInfo.getCapabilities(scheme);
|
||||
@@ -60,6 +135,11 @@ export class ExtHostConsumerFileSystem {
|
||||
}
|
||||
|
||||
private static _handleError(err: any): never {
|
||||
// desired error type
|
||||
if (err instanceof FileSystemError) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// generic error
|
||||
if (!(err instanceof Error)) {
|
||||
throw new FileSystemError(String(err));
|
||||
@@ -82,6 +162,13 @@ export class ExtHostConsumerFileSystem {
|
||||
default: throw new FileSystemError(err.message, err.name as files.FileSystemProviderErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
addFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider): IDisposable {
|
||||
this._fileSystemProvider.set(scheme, provider);
|
||||
return toDisposable(() => this._fileSystemProvider.delete(scheme));
|
||||
}
|
||||
}
|
||||
|
||||
export interface IExtHostConsumerFileSystem extends ExtHostConsumerFileSystem { }
|
||||
|
||||
Reference in New Issue
Block a user