未验证 提交 3fb482ef 编写于 作者: I Isidor Nikolic 提交者: GitHub

Merge pull request #46096 from Microsoft/tsalinger/multipath-detect-files

multi-path creation in explorer: validation detects if file is not leaf
......@@ -160,7 +160,8 @@ class TriggerRenameFileAction extends BaseFileAction {
this._updateEnablement();
}
public validateFileName(parent: ExplorerItem, name: string): string {
public validateFileName(name: string): string {
return this.renameAction.validateFileName(this.element.parent, name);
}
......@@ -182,7 +183,7 @@ class TriggerRenameFileAction extends BaseFileAction {
viewletState.setEditable(stat, {
action: this.renameAction,
validator: (value) => {
const message = this.validateFileName(this.element.parent, value);
const message = this.validateFileName(value);
if (!message) {
return null;
......@@ -1356,24 +1357,16 @@ export function validateFileName(parent: ExplorerItem, name: string, allowOverwr
}
const names: string[] = name.split(/[\\/]/).filter(part => !!part);
const analyzedPath = analyzePath(parent, names);
// Do not allow to overwrite existing file
if (!allowOverwriting) {
let p = parent;
const alreadyExisting = names.every((folderName) => {
let { exists, child } = alreadyExists(p, folderName);
if (!exists) {
return false;
} else {
p = child;
return true;
}
});
if (!allowOverwriting && analyzedPath.fullPathAlreadyExists) {
return nls.localize('fileNameExistsError', "A file or folder **{0}** already exists at this location. Please choose a different name.", name);
}
if (alreadyExisting) {
return nls.localize('fileNameExistsError', "A file or folder **{0}** already exists at this location. Please choose a different name.", name);
}
// A file must always be a leaf
if (analyzedPath.lastExistingPathSegment.isFile) {
return nls.localize('fileUsedAsFolderError', "**{0}** is a file and cannot have any descendants.", analyzedPath.lastExistingPathSegment.name);
}
// Invalid File name
......@@ -1392,6 +1385,24 @@ export function validateFileName(parent: ExplorerItem, name: string, allowOverwr
return null;
}
function analyzePath(parent: ExplorerItem, pathNames: string[]): { fullPathAlreadyExists: boolean; lastExistingPathSegment: { isFile: boolean; name: string; } } {
let lastExistingPathSegment = { isFile: false, name: '' };
for (const name of pathNames) {
const { exists, child } = alreadyExists(parent, name);
if (exists) {
lastExistingPathSegment = { isFile: !child.isDirectory, name };
parent = child;
} else {
return { fullPathAlreadyExists: false, lastExistingPathSegment };
}
}
return { fullPathAlreadyExists: true, lastExistingPathSegment };
}
function alreadyExists(parent: ExplorerItem, name: string): { exists: boolean, child: ExplorerItem | undefined } {
let duplicateChild: ExplorerItem;
......
......@@ -194,11 +194,6 @@ suite('Files - View Model', () => {
assert(validateFileName(s, '') !== null);
assert(validateFileName(s, ' ') !== null);
assert(validateFileName(s, 'Read Me') === null, 'name containing space');
assert(validateFileName(s, 'foo/bar') === null);
assert(validateFileName(s, 'foo\\bar') === null);
assert(validateFileName(s, 'all/slashes/are/same') === null);
assert(validateFileName(s, 'theres/one/different\\slash') === null);
assert(validateFileName(s, '/slashAtBeginning') === null);
if (isWindows) {
assert(validateFileName(s, 'foo:bar') !== null);
......@@ -236,6 +231,38 @@ suite('Files - View Model', () => {
assert(validateFileName(s, 'foo') === null);
});
test('Validate Multi-Path File Names', function () {
const d = new Date().getTime();
const wsFolder = createStat('/', 'workspaceFolder', true, false, 8096, d);
assert(validateFileName(wsFolder, 'foo/bar') === null);
assert(validateFileName(wsFolder, 'foo\\bar') === null);
assert(validateFileName(wsFolder, 'all/slashes/are/same') === null);
assert(validateFileName(wsFolder, 'theres/one/different\\slash') === null);
assert(validateFileName(wsFolder, '/slashAtBeginning') === null);
// validation should detect if user tries to add a child to a file
const fileInRoot = createStat('/fileInRoot', 'fileInRoot', false, false, 8096, d);
wsFolder.addChild(fileInRoot);
assert(validateFileName(wsFolder, 'fileInRoot/aChild') !== null);
wsFolder.removeChild(fileInRoot);
// attempting to add a child to a deeply nested file
const s1 = createStat('/path', 'path', true, false, 8096, d);
const s2 = createStat('/path/to', 'to', true, false, 8096, d);
const s3 = createStat('/path/to/stat', 'stat', true, false, 8096, d);
wsFolder.addChild(s1);
s1.addChild(s2);
s2.addChild(s3);
const fileDeeplyNested = createStat('/path/to/stat/fileNested', 'fileNested', false, false, 8096, d);
s3.addChild(fileDeeplyNested);
assert(validateFileName(wsFolder, '/path/to/stat/fileNested/aChild') !== null);
// detect if path already exists
assert(validateFileName(wsFolder, '/path/to/stat/fileNested') !== null);
assert(validateFileName(wsFolder, '/path/to/stat/') !== null);
});
test('Merge Local with Disk', function () {
const d = new Date().toUTCString();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册