do not resolve siblings unless needed (for #9962)

This commit is contained in:
Benjamin Pasero 2016-08-15 16:04:21 +02:00
parent d0836bbbf8
commit 8784665590
4 changed files with 31 additions and 18 deletions

View file

@ -281,8 +281,8 @@ function toRegExp(regEx: string): RegExp {
* - character ranges (using [...])
*/
export function match(pattern: string, path: string): boolean;
export function match(expression: IExpression, path: string, siblings?: string[]): string /* the matching pattern */;
export function match(arg1: string | IExpression, path: string, siblings?: string[]): any {
export function match(expression: IExpression, path: string, siblingsFn?: () => string[]): string /* the matching pattern */;
export function match(arg1: string | IExpression, path: string, siblingsFn?: () => string[]): any {
if (!arg1 || !path) {
return false;
}
@ -315,10 +315,13 @@ export function match(arg1: string | IExpression, path: string, siblings?: strin
}
// Glob with Expression
return matchExpression(<IExpression>arg1, path, siblings);
return matchExpression(<IExpression>arg1, path, siblingsFn);
}
function matchExpression(expression: IExpression, path: string, siblings?: string[]): string /* the matching pattern */ {
function matchExpression(expression: IExpression, path: string, siblingsFn?: () => string[]): string /* the matching pattern */ {
let siblings: string[];
let siblingsResolved = false;
let patterns = Object.getOwnPropertyNames(expression);
let basename: string;
for (let i = 0; i < patterns.length; i++) {
@ -339,6 +342,17 @@ function matchExpression(expression: IExpression, path: string, siblings?: strin
// Expression Pattern is <SiblingClause>
if (value && typeof (<SiblingClause>value).when === 'string') {
// Resolve siblings only once
if (!siblingsResolved) {
siblingsResolved = true;
if (siblingsFn) {
siblings = siblingsFn();
} else {
siblings = [];
}
}
if (!siblings || !siblings.length) {
continue; // pattern is malformed or we don't have siblings
}

View file

@ -401,9 +401,9 @@ suite('Glob', () => {
}
};
assert.equal('**/*.js', glob.match(expression, 'test.js', siblings));
assert(!glob.match(expression, 'test.js', []));
assert(!glob.match(expression, 'test.js', ['te.ts']));
assert.equal('**/*.js', glob.match(expression, 'test.js', () => siblings));
assert(!glob.match(expression, 'test.js', () => []));
assert(!glob.match(expression, 'test.js', () => ['te.ts']));
assert(!glob.match(expression, 'test.js'));
expression = {
@ -412,18 +412,18 @@ suite('Glob', () => {
}
};
assert(!glob.match(expression, 'test.js', siblings));
assert(!glob.match(expression, 'test.js', () => siblings));
expression = <any>{
'**/*.js': {
}
};
assert.equal('**/*.js', glob.match(expression, 'test.js', siblings));
assert.equal('**/*.js', glob.match(expression, 'test.js', () => siblings));
expression = {};
assert(!glob.match(expression, 'test.js', siblings));
assert(!glob.match(expression, 'test.js', () => siblings));
});
test('expression support (multiple)', function () {
@ -437,11 +437,11 @@ suite('Glob', () => {
'**/*.bananas': { bananas: true }
};
assert.equal('**/*.js', glob.match(expression, 'test.js', siblings));
assert.equal('**/*.as', glob.match(expression, 'test.as', siblings));
assert.equal('**/*.bananas', glob.match(expression, 'test.bananas', siblings));
assert.equal('**/*.js', glob.match(expression, 'test.js', () => siblings));
assert.equal('**/*.as', glob.match(expression, 'test.as', () => siblings));
assert.equal('**/*.bananas', glob.match(expression, 'test.bananas', () => siblings));
assert.equal('**/*.bananas', glob.match(expression, 'test.bananas'));
assert(!glob.match(expression, 'test.foo', siblings));
assert(!glob.match(expression, 'test.foo', () => siblings));
});
test('brackets', function () {

View file

@ -682,10 +682,9 @@ export class FileFilter implements IFilter {
return true; // always visible
}
let siblings = stat.parent && stat.parent.children && stat.parent.children.map(c => c.name);
// Hide those that match Hidden Patterns
if (glob.match(this.hiddenExpression, this.contextService.toWorkspaceRelativePath(stat.resource), siblings)) {
const siblingsFn = () => stat.parent && stat.parent.children && stat.parent.children.map(c => c.name);
if (glob.match(this.hiddenExpression, this.contextService.toWorkspaceRelativePath(stat.resource), siblingsFn)) {
return false; // hidden through pattern
}

View file

@ -181,7 +181,7 @@ export class FileWalker {
// Check exclude pattern
let currentRelativePathWithSlashes = relativeParentPathWithSlashes ? [relativeParentPathWithSlashes, file].join('/') : file;
if (glob.match(this.excludePattern, currentRelativePathWithSlashes, siblings)) {
if (glob.match(this.excludePattern, currentRelativePathWithSlashes, () => siblings)) {
return clb(null);
}