Skip to content

Commit

Permalink
filesystem: remove deprecated apis (#11176)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-marechal authored May 25, 2022
1 parent 9a10b6b commit 4099a4e
Show file tree
Hide file tree
Showing 12 changed files with 19 additions and 1,066 deletions.
15 changes: 12 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@
<a name="breaking_changes_1.26.0">[Breaking Changes:](#breaking_changes_1.26.0)</a>

- [core] Refactored the core messaging API. Replaced `vscode-ws-jsonrpc` with a custom RPC protocol that is better suited for handling binary data and enables message tunneling.
This impacts all main concepts of the messaging API. The API no longer exposes a `Connection` object and uses a generic `Channel` implementation instead.
- This impacts all main concepts of the messaging API. The API no longer exposes a `Connection` object and uses a generic `Channel` implementation instead.
- Replaces usage of `vscode-json-rpc`'s `Connection` with the new generic `Channel`. Affects `AbstractConnectionProvider`, `MessagingService`, `IPCConnectionProvider`, `ElectronMessagingService`
- `MessagingService`: No longer offers the `listen` and `forward` method. Use `wsChannel` instead.
- `RemoteFileSystemServer`: Use `UInt8Array` instead of plain number arrays for all arguments and return type that store binary data
- `DebugAdapter`: Replaced the debug-service internal `Channel` implementation with the newly introduced generic `Channel`.
[#11011](https://github.com/eclipse-theia/theia/pull/11011) - Contributed on behalf of STMicroelectronics.

- [#11011](https://github.com/eclipse-theia/theia/pull/11011) - Contributed on behalf of STMicroelectronics.
- [filesystem] Remove deprecated APIs:
- Deleted `@theia/filesystem/lib/browser/filesystem-watcher`:
- `FileChangeType`, `FileChange`, `FileChangeEvent`, `FileMoveEvent`, `FileEvent`, `FileOperationEmitter`, `FileSystemWatcher`
- Deleted `@theia/filesystem/lib/node/node-file-upload`:
- `NodeFileUpload`
- Deleted `@theia/filesystem/lib/node/nsfw-watcher/nsfw-filesystem-watcher`:
- `WatcherOptions`, `NsfwFileSystemWatcherServer`
- Removed from `@theia/filesystem/lib/common/filesystem`:
- `FileSystem`, `FileMoveOptions`, `FileDeleteOptions`, `FileStat`, `FileSystemError`
- [filesystem] Update `FileStatNodeData.fileStat` to use the non-deprecated `FileStat` from `@theia/core/lib/common/files`

## v1.25.0 - 4/28/2022

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export class FileTreeWidget extends CompressedTreeWidget {
if (node.fileStat) {
stat = {
type: node.fileStat.isDirectory ? FileType.Directory : FileType.File,
mtime: node.fileStat.lastModification,
mtime: node.fileStat.mtime,
size: node.fileStat.size
};
delete node['fileStat'];
Expand Down
3 changes: 1 addition & 2 deletions packages/filesystem/src/browser/file-tree/file-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import URI from '@theia/core/lib/common/uri';
import { TreeNode, CompositeTreeNode, SelectableTreeNode, ExpandableTreeNode, TreeImpl } from '@theia/core/lib/browser';
import { Mutable } from '@theia/core/lib/common/types';
import { FileStat, Stat, FileType, FileOperationError, FileOperationResult } from '../../common/files';
import { FileStat as DeprecatedFileStat } from '../../common/filesystem';
import { UriSelection } from '@theia/core/lib/common/selection';
import { MessageService } from '@theia/core/lib/common/message-service';
import { FileSelection } from '../file-selection';
Expand Down Expand Up @@ -117,7 +116,7 @@ export namespace FileStatNode {
export type FileStatNodeData = Omit<FileStatNode, 'uri' | 'fileStat'> & {
uri: string
stat?: Stat | { type: FileType } & Partial<Stat>
fileStat?: DeprecatedFileStat
fileStat?: FileStat
};
export namespace FileStatNodeData {
export function is(node: object | undefined): node is FileStatNodeData {
Expand Down
162 changes: 0 additions & 162 deletions packages/filesystem/src/browser/filesystem-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,14 @@ import { ResourceResolver, CommandContribution } from '@theia/core/lib/common';
import { WebSocketConnectionProvider, FrontendApplicationContribution, LabelProviderContribution, BreadcrumbsContribution } from '@theia/core/lib/browser';
import { FileResourceResolver } from './file-resource';
import { bindFileSystemPreferences } from './filesystem-preferences';
import { FileSystemWatcher } from './filesystem-watcher';
import { FileSystemFrontendContribution } from './filesystem-frontend-contribution';
import { FileUploadService } from './file-upload-service';
import { FileTreeDecoratorAdapter, FileTreeLabelProvider } from './file-tree';
import { FileService, FileServiceContribution } from './file-service';
import { RemoteFileSystemProvider, RemoteFileSystemServer, remoteFileSystemPath, RemoteFileSystemProxyFactory } from '../common/remote-file-system-provider';
import { FileSystem, FileStat, FileMoveOptions, FileDeleteOptions, FileSystemError } from '../common/filesystem';
import URI from '@theia/core/lib/common/uri';
import { FileOperationError, FileOperationResult, BaseStatWithMetadata, FileStatWithMetadata, etag } from '../common/files';
import { TextDocumentContentChangeEvent } from '@theia/core/shared/vscode-languageserver-protocol';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
import { RemoteFileServiceContribution } from './remote-file-service-contribution';
import { FileSystemWatcherErrorHandler } from './filesystem-watcher-error-handler';
import { UTF8 } from '@theia/core/lib/common/encodings';
import { FilepathBreadcrumbsContribution } from './breadcrumbs/filepath-breadcrumbs-contribution';
import { BreadcrumbsFileTreeWidget, createFileTreeBreadcrumbsWidget } from './breadcrumbs/filepath-breadcrumbs-container';
import { FilesystemSaveResourceService } from './filesystem-save-resource-service';
Expand All @@ -54,163 +47,8 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(RemoteFileServiceContribution).toSelf().inSingletonScope();
bind(FileServiceContribution).toService(RemoteFileServiceContribution);

bind(FileSystemWatcher).toSelf().inSingletonScope();
bind(FileSystemWatcherErrorHandler).toSelf().inSingletonScope();

// eslint-disable-next-line @typescript-eslint/no-explicit-any
bind(FileSystem).toDynamicValue(({ container }) => {
const fileService = container.get(FileService);
const environments = container.get<EnvVariablesServer>(EnvVariablesServer);
const convertStat: (stat: BaseStatWithMetadata | FileStatWithMetadata) => FileStat = stat => ({
uri: stat.resource.toString(),
lastModification: stat.mtime,
size: stat.size,
isDirectory: 'isDirectory' in stat && stat.isDirectory,
children: 'children' in stat ? stat.children?.map(convertStat) : undefined
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const rethrowError: (uri: string, error: any) => never = (uri, error) => {
if (error instanceof FileOperationError) {
if (error.fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {
throw FileSystemError.FileNotFound(uri);
}
if (error.fileOperationResult === FileOperationResult.FILE_IS_DIRECTORY) {
throw FileSystemError.FileIsDirectory(uri);
}
if (error.fileOperationResult === FileOperationResult.FILE_NOT_DIRECTORY) {
throw FileSystemError.FileNotDirectory(uri);
}
if (error.fileOperationResult === FileOperationResult.FILE_MODIFIED_SINCE) {
throw FileSystemError.FileIsOutOfSync(uri);
}
}
throw error;
};
return new class implements FileSystem {
async getFileStat(uri: string): Promise<FileStat | undefined> {
try {
const stat = await fileService.resolve(new URI(uri), { resolveMetadata: true });
return convertStat(stat);
} catch (e) {
if (e instanceof FileOperationError && e.fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {
return undefined;
}
rethrowError(uri, e);
}
}
exists(uri: string): Promise<boolean> {
return fileService.exists(new URI(uri));
}
async resolveContent(uri: string, options?: { encoding?: string | undefined; } | undefined): Promise<{ stat: FileStat; content: string; }> {
try {
const content = await fileService.read(new URI(uri), options);
return {
stat: convertStat(content),
content: content.value
};
} catch (e) {
rethrowError(uri, e);
}
}
async setContent(file: FileStat, content: string, options?: { encoding?: string | undefined; } | undefined): Promise<FileStat> {
try {
const result = await fileService.write(new URI(file.uri), content, {
...options,
mtime: file.lastModification
});
return convertStat(result);
} catch (e) {
rethrowError(file.uri, e);
}
}
async updateContent(file: FileStat, contentChanges: TextDocumentContentChangeEvent[], options?: {
encoding?: string | undefined;
overwriteEncoding?: string | undefined;
} | undefined): Promise<FileStat> {
try {
const result = await fileService.update(new URI(file.uri), contentChanges, {
mtime: file.lastModification,
etag: etag({ size: file.size, mtime: file.lastModification }),
readEncoding: options?.encoding || UTF8,
encoding: options?.overwriteEncoding,
overwriteEncoding: !!options?.overwriteEncoding
});
return convertStat(result);
} catch (e) {
rethrowError(file.uri, e);
}
}
async move(sourceUri: string, targetUri: string, options?: FileMoveOptions | undefined): Promise<FileStat> {
try {
const result = await fileService.move(new URI(sourceUri), new URI(targetUri), options);
return convertStat(result);
} catch (e) {
rethrowError(sourceUri, e);
}
}
async copy(sourceUri: string, targetUri: string, options?: { overwrite?: boolean | undefined; recursive?: boolean | undefined; } | undefined): Promise<FileStat> {
try {
const result = await fileService.copy(new URI(sourceUri), new URI(targetUri), options);
return convertStat(result);
} catch (e) {
rethrowError(sourceUri, e);
}
}
async createFile(uri: string, options?: { content?: string | undefined; encoding?: string | undefined; } | undefined): Promise<FileStat> {
try {
const result = await fileService.create(new URI(uri), options?.content, { encoding: options?.encoding });
return convertStat(result);
} catch (e) {
rethrowError(uri, e);
}
}
async createFolder(uri: string): Promise<FileStat> {
try {
const result = await fileService.createFolder(new URI(uri));
return convertStat(result);
} catch (e) {
rethrowError(uri, e);
}
}
touchFile(uri: string): Promise<FileStat> {
throw new Error('Method not implemented.');
}
async delete(uri: string, options?: FileDeleteOptions | undefined): Promise<void> {
try {
return await fileService.delete(new URI(uri), { useTrash: options?.moveToTrash, recursive: true });
} catch (e) {
rethrowError(uri, e);
}
}
async getEncoding(uri: string): Promise<string> {
const { encoding } = await fileService.read(new URI(uri));
return encoding;
}
async guessEncoding(uri: string): Promise<string | undefined> {
const { encoding } = await fileService.read(new URI(uri), { autoGuessEncoding: true });
return encoding;
}
async getRoots(): Promise<FileStat[]> {
const drives = await environments.getDrives();
const roots = await Promise.all(drives.map(uri => this.getFileStat(uri)));
return roots.filter(root => !!root) as FileStat[];
}
async getCurrentUserHome(): Promise<FileStat | undefined> {
return this.getFileStat(await environments.getHomeDirUri());
}
getDrives(): Promise<string[]> {
return environments.getDrives();
}
access(uri: string, mode?: number | undefined): Promise<boolean> {
return fileService.access(new URI(uri), mode);
}
getFsPath(uri: string): Promise<string | undefined> {
return fileService.fsPath(new URI(uri));
}

};
}).inSingletonScope();

bindFileResource(bind);

bind(FileUploadService).toSelf().inSingletonScope();
Expand Down
Loading

0 comments on commit 4099a4e

Please sign in to comment.