Skip to content

Commit 0e8fceb

Browse files
authored
files - adopt fileService.stat method in more places (microsoft#143491)
* types * adopt fileservice.stat
1 parent 68fa627 commit 0e8fceb

33 files changed

Lines changed: 104 additions & 97 deletions

File tree

src/vs/platform/files/common/fileService.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { extUri, extUriIgnorePathCase, IExtUri, isAbsolutePath } from 'vs/base/c
1818
import { consumeStream, isReadableBufferedStream, isReadableStream, listenStream, newWriteableStream, peekReadable, peekStream, transform } from 'vs/base/common/stream';
1919
import { URI } from 'vs/base/common/uri';
2020
import { localize } from 'vs/nls';
21-
import { ensureFileSystemProviderError, etag, ETAG_DISABLED, FileChangesEvent, FileDeleteOptions, 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, IResolveFileResult, IResolveFileResultWithMetadata, IResolveMetadataFileOptions, IStat, IWatchOptions, IWriteFileOptions, NotModifiedSinceFileOperationError, toFileOperationResult, toFileSystemProviderErrorCode } from 'vs/platform/files/common/files';
21+
import { ensureFileSystemProviderError, etag, ETAG_DISABLED, FileChangesEvent, FileDeleteOptions, 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 } from 'vs/platform/files/common/files';
2222
import { readFileIntoStream } from 'vs/platform/files/common/io';
2323
import { ILogService } from 'vs/platform/log/common/log';
2424

@@ -249,7 +249,8 @@ export class FileService extends Disposable implements IFileService {
249249
ctime: stat.ctime,
250250
size: stat.size,
251251
readonly: Boolean((stat.permissions ?? 0) & FilePermission.Readonly) || Boolean(provider.capabilities & FileSystemProviderCapabilities.Readonly),
252-
etag: etag({ mtime: stat.mtime, size: stat.size })
252+
etag: etag({ mtime: stat.mtime, size: stat.size }),
253+
children: undefined
253254
};
254255

255256
// check to recurse for directories
@@ -283,9 +284,9 @@ export class FileService extends Disposable implements IFileService {
283284
return fileStat;
284285
}
285286

286-
async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]>;
287-
async resolveAll(toResolve: { resource: URI; options: IResolveMetadataFileOptions }[]): Promise<IResolveFileResultWithMetadata[]>;
288-
async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]> {
287+
async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise<IFileStatResult[]>;
288+
async resolveAll(toResolve: { resource: URI; options: IResolveMetadataFileOptions }[]): Promise<IFileStatResultWithMetadata[]>;
289+
async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise<IFileStatResult[]> {
289290
return Promises.settled(toResolve.map(async entry => {
290291
try {
291292
return { stat: await this.doResolveFile(entry.resource, entry.options), success: true };
@@ -297,7 +298,7 @@ export class FileService extends Disposable implements IFileService {
297298
}));
298299
}
299300

300-
async stat(resource: URI): Promise<IFileStatWithMetadata> {
301+
async stat(resource: URI): Promise<IFileStatWithPartialMetadata> {
301302
const provider = await this.withProvider(resource);
302303

303304
const stat = await provider.stat(resource);

src/vs/platform/files/common/files.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@ export interface IFileService {
118118
* If one of the resolve targets fails to resolve returns a fake `IFileStat` instead of
119119
* making the whole call fail.
120120
*/
121-
resolveAll(toResolve: { resource: URI; options: IResolveMetadataFileOptions }[]): Promise<IResolveFileResult[]>;
122-
resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise<IResolveFileResult[]>;
121+
resolveAll(toResolve: { resource: URI; options: IResolveMetadataFileOptions }[]): Promise<IFileStatResult[]>;
122+
resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions }[]): Promise<IFileStatResult[]>;
123123

124124
/**
125125
* Same as `resolve()` but without resolving the children of a folder if the
126126
* resource is pointing to a folder.
127127
*/
128-
stat(resource: URI): Promise<IFileStatWithMetadata>;
128+
stat(resource: URI): Promise<IFileStatWithPartialMetadata>;
129129

130130
/**
131131
* Finds out if a file/folder identified by the resource exists.
@@ -889,7 +889,7 @@ export function isParent(path: string, candidate: string, ignoreCase?: boolean):
889889
return path.indexOf(candidate) === 0;
890890
}
891891

892-
interface IBaseStat {
892+
interface IBaseFileStat {
893893

894894
/**
895895
* The unified resource identifier of this file or folder.
@@ -941,12 +941,12 @@ interface IBaseStat {
941941
readonly readonly?: boolean;
942942
}
943943

944-
export interface IBaseStatWithMetadata extends Required<IBaseStat> { }
944+
export interface IBaseFileStatWithMetadata extends Required<IBaseFileStat> { }
945945

946946
/**
947-
* A file resource with meta information.
947+
* A file resource with meta information and resolved children if any.
948948
*/
949-
export interface IFileStat extends IBaseStat {
949+
export interface IFileStat extends IBaseFileStat {
950950

951951
/**
952952
* The resource is a file.
@@ -969,36 +969,38 @@ export interface IFileStat extends IBaseStat {
969969
/**
970970
* The children of the file stat or undefined if none.
971971
*/
972-
children?: IFileStat[];
972+
children: IFileStat[] | undefined;
973973
}
974974

975-
export interface IFileStatWithMetadata extends IFileStat, IBaseStatWithMetadata {
975+
export interface IFileStatWithMetadata extends IFileStat, IBaseFileStatWithMetadata {
976976
readonly mtime: number;
977977
readonly ctime: number;
978978
readonly etag: string;
979979
readonly size: number;
980980
readonly readonly: boolean;
981-
readonly children?: IFileStatWithMetadata[];
981+
readonly children: IFileStatWithMetadata[] | undefined;
982982
}
983983

984-
export interface IResolveFileResult {
984+
export interface IFileStatResult {
985985
readonly stat?: IFileStat;
986986
readonly success: boolean;
987987
}
988988

989-
export interface IResolveFileResultWithMetadata extends IResolveFileResult {
989+
export interface IFileStatResultWithMetadata extends IFileStatResult {
990990
readonly stat?: IFileStatWithMetadata;
991991
}
992992

993-
export interface IFileContent extends IBaseStatWithMetadata {
993+
export interface IFileStatWithPartialMetadata extends Omit<IFileStatWithMetadata, 'children'> { }
994+
995+
export interface IFileContent extends IBaseFileStatWithMetadata {
994996

995997
/**
996998
* The content of a file as buffer.
997999
*/
9981000
readonly value: VSBuffer;
9991001
}
10001002

1001-
export interface IFileStreamContent extends IBaseStatWithMetadata {
1003+
export interface IFileStreamContent extends IBaseFileStatWithMetadata {
10021004

10031005
/**
10041006
* The content of a file as stream.

src/vs/platform/files/test/node/diskFileService.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ flakySuite('Disk File Service', function () {
468468
assert.strictEqual(resolved.readonly, false);
469469
assert.strictEqual(resolved.isSymbolicLink, false);
470470
assert.strictEqual(resolved.resource.toString(), resource.toString());
471-
assert.strictEqual(resolved.children, undefined);
472471
assert.ok(resolved.mtime! > 0);
473472
assert.ok(resolved.ctime! > 0);
474473
assert.ok(resolved.size! > 0);
@@ -481,7 +480,6 @@ flakySuite('Disk File Service', function () {
481480
assert.ok(result);
482481
assert.strictEqual(result.resource.toString(), resource.toString());
483482
assert.strictEqual(result.name, 'resolver');
484-
assert.strictEqual(result.children, undefined);
485483
assert.ok(result.isDirectory);
486484
assert.strictEqual(result.readonly, false);
487485
assert.ok(result.mtime! > 0);

src/vs/workbench/api/browser/mainThreadDocuments.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,11 @@ export class MainThreadDocuments extends Disposable implements MainThreadDocumen
264264

265265
private _handleUntitledScheme(uri: URI): Promise<URI> {
266266
const asLocalUri = toLocalResource(uri, this._environmentService.remoteAuthority, this._pathService.defaultUriScheme);
267-
return this._fileService.resolve(asLocalUri).then(stats => {
268-
// don't create a new file ontop of an existing file
269-
return Promise.reject(new Error('file already exists'));
270-
}, err => {
267+
return this._fileService.exists(asLocalUri).then(exists => {
268+
if (exists) {
269+
// don't create a new file ontop of an existing file
270+
return Promise.reject(new Error('file already exists'));
271+
}
271272
return this._doCreateUntitled(Boolean(uri.path) ? uri : undefined);
272273
});
273274
}

src/vs/workbench/api/browser/mainThreadFileSystem.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { Emitter, Event } from 'vs/base/common/event';
77
import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
88
import { URI, UriComponents } from 'vs/base/common/uri';
9-
import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions, FileOpenOptions, IFileStat, FileOperationError, FileOperationResult, FileSystemProviderErrorCode, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileFolderCopyCapability, FilePermission, toFileSystemProviderErrorCode, IFilesConfiguration } from 'vs/platform/files/common/files';
9+
import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions, FileOpenOptions, FileOperationError, FileOperationResult, FileSystemProviderErrorCode, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileFolderCopyCapability, FilePermission, toFileSystemProviderErrorCode, IFilesConfiguration, IFileStatWithPartialMetadata, IFileStat } from 'vs/platform/files/common/files';
1010
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
1111
import { ExtHostContext, ExtHostFileSystemShape, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../common/extHost.protocol';
1212
import { VSBuffer } from 'vs/base/common/buffer';
@@ -69,7 +69,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
6969
// --- consumer fs, vscode.workspace.fs
7070

7171
$stat(uri: UriComponents): Promise<IStat> {
72-
return this._fileService.resolve(URI.revive(uri), { resolveMetadata: true }).then(stat => {
72+
return this._fileService.stat(URI.revive(uri)).then(stat => {
7373
return {
7474
ctime: stat.ctime,
7575
mtime: stat.mtime,
@@ -91,7 +91,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
9191
}).catch(MainThreadFileSystem._handleError);
9292
}
9393

94-
private static _asFileType(stat: IFileStat): FileType {
94+
private static _asFileType(stat: IFileStat | IFileStatWithPartialMetadata): FileType {
9595
let res = 0;
9696
if (stat.isFile) {
9797
res += FileType.File;

src/vs/workbench/browser/dnd.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ export class ResourcesDropHandler {
298298

299299
// Check for Folder
300300
try {
301-
const stat = await this.fileService.resolve(resource);
301+
const stat = await this.fileService.stat(resource);
302302
if (stat.isDirectory) {
303303
toOpen.push({ folderUri: stat.resource });
304304
folderURIs.push({ uri: stat.resource });

src/vs/workbench/common/editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ export async function pathsToEditors(paths: IPathData[] | undefined, fileService
12771277
let type = path.type;
12781278
if (typeof exists !== 'boolean' || typeof type !== 'number') {
12791279
try {
1280-
type = (await fileService.resolve(resource)).isDirectory ? FileType.Directory : FileType.Unknown;
1280+
type = (await fileService.stat(resource)).isDirectory ? FileType.Directory : FileType.Unknown;
12811281
exists = true;
12821282
} catch {
12831283
exists = false;

src/vs/workbench/common/editor/binaryEditorModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class BinaryEditorModel extends EditorModel {
5858

5959
// Make sure to resolve up to date stat for file resources
6060
if (this.fileService.hasProvider(this.resource)) {
61-
const stat = await this.fileService.resolve(this.resource, { resolveMetadata: true });
61+
const stat = await this.fileService.stat(this.resource);
6262
this.etag = stat.etag;
6363
if (typeof stat.size === 'number') {
6464
this.size = stat.size;

src/vs/workbench/contrib/debug/browser/linkDetector.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ export class LinkDetector {
113113
const path = await this.pathService.path;
114114
const fileUrl = osPath.normalize(((path.sep === osPath.posix.sep) && platform.isWindows) ? fsPath.replace(/\\/g, osPath.posix.sep) : fsPath);
115115

116-
const resolvedLink = await this.fileService.resolve(URI.parse(fileUrl));
117-
if (!resolvedLink) {
116+
const fileUri = URI.parse(fileUrl);
117+
const exists = await this.fileService.exists(fileUri);
118+
if (!exists) {
118119
return;
119120
}
120121

121-
await this.editorService.openEditor({ resource: resolvedLink.resource, options: { pinned: true } });
122+
await this.editorService.openEditor({ resource: fileUri, options: { pinned: true } });
122123
return;
123124
}
124125

@@ -155,7 +156,7 @@ export class LinkDetector {
155156
const link = this.createLink(text);
156157
link.tabIndex = 0;
157158
const uri = URI.file(osPath.normalize(path));
158-
this.fileService.resolve(uri).then(stat => {
159+
this.fileService.stat(uri).then(stat => {
159160
if (stat.isDirectory) {
160161
return;
161162
}

src/vs/workbench/contrib/files/browser/fileActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => {
10101010
if (element.resource.toString() !== fileToPaste.toString() && resources.isEqualOrParent(element.resource, fileToPaste)) {
10111011
throw new Error(nls.localize('fileIsAncestor', "File to paste is an ancestor of the destination folder"));
10121012
}
1013-
const fileToPasteStat = await fileService.resolve(fileToPaste);
1013+
const fileToPasteStat = await fileService.stat(fileToPaste);
10141014

10151015
// Find target
10161016
let target: ExplorerItem;

0 commit comments

Comments
 (0)