提交 40905b95 编写于 作者: J Johannes Rieken

eng - strict null checks for remoteFileService

上级 26f0a77c
......@@ -433,6 +433,7 @@
"./vs/workbench/services/extensions/node/rpcProtocol.ts",
"./vs/workbench/services/extensions/test/node/rpcProtocol.test.ts",
"./vs/workbench/services/files/node/encoding.ts",
"./vs/workbench/services/files/node/remoteFileService.ts",
"./vs/workbench/services/files/node/fileService.ts",
"./vs/workbench/services/files/node/streams.ts",
"./vs/workbench/services/files/test/electron-browser/utils.ts",
......@@ -521,4 +522,4 @@
"./typings/require-monaco.d.ts",
"./vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts"
]
}
\ No newline at end of file
}
......@@ -455,7 +455,7 @@ export interface IFileStat extends IBaseStat {
}
export interface IResolveFileResult {
stat: IFileStat;
stat?: IFileStat;
success: boolean;
}
......
......@@ -91,7 +91,7 @@ CommandsRegistry.registerCommand({
const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService);
return fileService.resolveFiles(resources.map(r => ({ resource: r }))).then(stats => {
const directoriesToOpen = distinct(stats.map(({ stat }) => stat.isDirectory ? stat.resource.fsPath : paths.dirname(stat.resource.fsPath)));
const directoriesToOpen = distinct(stats.filter(data => data.success).map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : paths.dirname(stat!.resource.fsPath)));
return directoriesToOpen.map(dir => {
if (configurationService.getValue<IExternalTerminalConfiguration>().terminal.explorerKind === 'integrated') {
const instance = integratedTerminalService.createTerminal({ cwd: dir }, true);
......
......@@ -368,7 +368,7 @@ export class WorkspaceStats implements IWorkbenchContribution {
}
return this.fileService.resolveFiles(folders.map(resource => ({ resource }))).then((files: IResolveFileResult[]) => {
const names = (<IFileStat[]>[]).concat(...files.map(result => result.success ? (result.stat.children || []) : [])).map(c => c.name);
const names = (<IFileStat[]>[]).concat(...files.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name);
const nameSet = names.reduce((s, n) => s.add(n.toLowerCase()), new Set());
if (participant) {
......@@ -664,7 +664,7 @@ export class WorkspaceStats implements IWorkbenchContribution {
});
return this.fileService.resolveFiles(uris.map(resource => ({ resource }))).then(
results => {
const names = (<IFileStat[]>[]).concat(...results.map(result => result.success ? (result.stat.children || []) : [])).map(c => c.name);
const names = (<IFileStat[]>[]).concat(...results.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name);
const referencesAzure = WorkspaceStats.searchArray(names, /azure/i);
if (referencesAzure) {
tags['node'] = true;
......
......@@ -70,7 +70,7 @@ function toIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], recurse
return Promise.resolve(fileStat);
}
export function toDeepIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], to: URI[]): Promise<IFileStat> {
export function toDeepIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], to?: URI[]): Promise<IFileStat> {
const trie = TernarySearchTree.forPaths<true>();
trie.set(tuple[0].toString(), true);
......@@ -281,7 +281,7 @@ export class RemoteFileService extends FileService {
FileOperationResult.FILE_NOT_FOUND
);
} else {
return data[0].stat;
return data[0].stat!;
}
});
}
......@@ -319,7 +319,7 @@ export class RemoteFileService extends FileService {
return toDeepIFileStat(provider, [item.resource, stat], item.options && item.options.resolveTo).then(fileStat => {
result[idx] = { stat: fileStat, success: true };
});
}, err => {
}, _err => {
result[idx] = { stat: undefined, success: false };
});
});
......@@ -440,7 +440,7 @@ export class RemoteFileService extends FileService {
return RemoteFileService._mkdirp(provider, resources.dirname(resource)).then(() => {
const encoding = this.encoding.getWriteEncoding(resource);
return this._writeFile(provider, resource, new StringSnapshot(content), encoding, { create: true, overwrite: Boolean(options && options.overwrite) });
return this._writeFile(provider, resource, new StringSnapshot(content || ''), encoding, { create: true, overwrite: Boolean(options && options.overwrite) });
});
}).then(fileStat => {
......@@ -449,7 +449,7 @@ export class RemoteFileService extends FileService {
}, err => {
const message = localize('err.create', "Failed to create file {0}", resource.toString(false));
const result = this._tryParseFileOperationResult(err);
throw new FileOperationError(message, result, options);
throw new FileOperationError(message, result || -1, options);
});
}
}
......@@ -467,7 +467,7 @@ export class RemoteFileService extends FileService {
}
}
private _writeFile(provider: IFileSystemProvider, resource: URI, snapshot: ITextSnapshot, preferredEncoding: string, options: FileWriteOptions): Promise<IFileStat> {
private _writeFile(provider: IFileSystemProvider, resource: URI, snapshot: ITextSnapshot, preferredEncoding: string | undefined = undefined, options: FileWriteOptions): Promise<IFileStat> {
const readable = createReadableOfSnapshot(snapshot);
const encoding = this.encoding.getWriteEncoding(resource, preferredEncoding);
const encoder = encodeStream(encoding);
......@@ -549,13 +549,13 @@ export class RemoteFileService extends FileService {
}
}
private _doMoveWithInScheme(source: URI, target: URI, overwrite?: boolean): Promise<IFileStat> {
private async _doMoveWithInScheme(source: URI, target: URI, overwrite: boolean = false): Promise<IFileStat> {
const prepare = overwrite
? Promise.resolve(this.del(target, { recursive: true }).then(undefined, err => { /*ignore*/ }))
: Promise.resolve(null);
if (overwrite) {
await this.del(target, { recursive: true }).catch(_err => { /*ignore*/ });
}
return prepare.then(() => this._withProvider(source)).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => {
return this._withProvider(source).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => {
return RemoteFileService._mkdirp(provider, resources.dirname(target)).then(() => {
return provider.rename(source, target, { overwrite }).then(() => {
return this.resolveFile(target);
......@@ -589,11 +589,11 @@ export class RemoteFileService extends FileService {
return super.copyFile(source, target, overwrite);
}
return this._withProvider(target).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => {
return this._withProvider(target).then(RemoteFileService._throwIfFileSystemIsReadonly).then(async provider => {
if (source.scheme === target.scheme && (provider.capabilities & FileSystemProviderCapabilities.FileFolderCopy)) {
// good: provider supports copy withing scheme
return provider.copy(source, target, { overwrite: !!overwrite }).then(() => {
return provider.copy!(source, target, { overwrite: !!overwrite }).then(() => {
return this.resolveFile(target);
}).then(fileStat => {
this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat));
......@@ -607,51 +607,46 @@ export class RemoteFileService extends FileService {
});
}
const prepare = overwrite
? Promise.resolve(this.del(target, { recursive: true }).then(undefined, err => { /*ignore*/ }))
: Promise.resolve(null);
return prepare.then(() => {
// todo@ben, can only copy text files
// https://github.com/Microsoft/vscode/issues/41543
return this.resolveContent(source, { acceptTextOnly: true }).then(content => {
return this._withProvider(target).then(provider => {
return this._writeFile(
provider, target,
new StringSnapshot(content.value),
content.encoding,
{ create: true, overwrite: !!overwrite }
).then(fileStat => {
this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat));
return fileStat;
});
}, err => {
const result = this._tryParseFileOperationResult(err);
if (result === FileOperationResult.FILE_MOVE_CONFLICT) {
throw new FileOperationError(localize('fileMoveConflict', "Unable to move/copy. File already exists at destination."), result);
} else if (err instanceof Error && err.name === 'ENOPRO') {
// file scheme
return super.updateContent(target, content.value, { encoding: content.encoding });
} else {
return Promise.reject(err);
}
if (overwrite) {
await this.del(target, { recursive: true }).catch(_err => { /*ignore*/ });
}
// todo@ben, can only copy text files
// https://github.com/Microsoft/vscode/issues/41543
return this.resolveContent(source, { acceptTextOnly: true }).then(content => {
return this._withProvider(target).then(provider => {
return this._writeFile(
provider, target,
new StringSnapshot(content.value),
content.encoding,
{ create: true, overwrite: !!overwrite }
).then(fileStat => {
this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat));
return fileStat;
});
}, err => {
const result = this._tryParseFileOperationResult(err);
if (result === FileOperationResult.FILE_MOVE_CONFLICT) {
throw new FileOperationError(localize('fileMoveConflict', "Unable to move/copy. File already exists at destination."), result);
} else if (err instanceof Error && err.name === 'ENOPRO') {
// file scheme
return super.updateContent(target, content.value, { encoding: content.encoding });
} else {
return Promise.reject(err);
}
});
});
});
}
private _activeWatches = new Map<string, { unwatch: Promise<IDisposable>, count: number }>();
watchFileChanges(resource: URI, opts?: IWatchOptions): void {
watchFileChanges(resource: URI, opts: IWatchOptions = { recursive: false, excludes: [] }): void {
if (resource.scheme === Schemas.file) {
return super.watchFileChanges(resource);
}
if (!opts) {
opts = { recursive: false, excludes: [] };
}
const key = resource.toString();
const entry = this._activeWatches.get(key);
if (entry) {
......@@ -663,7 +658,7 @@ export class RemoteFileService extends FileService {
count: 1,
unwatch: this._withProvider(resource).then(provider => {
return provider.watch(resource, opts);
}, err => {
}, _err => {
return { dispose() { } };
})
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册