Skip to content

Commit 92ec96d

Browse files
committed
start refactoring
1 parent cd50063 commit 92ec96d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1082
-4272
lines changed

backup.js

+318
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
'use strict';
2+
3+
/**
4+
* Module dependencies
5+
*/
6+
7+
const toRegex = require('to-regex');
8+
const unique = require('array-unique');
9+
const extend = require('extend-shallow');
10+
11+
/**
12+
* Local dependencies
13+
*/
14+
15+
const compilers = require('./lib/compilers');
16+
const parsers = require('./lib/parsers');
17+
const Braces = require('./lib/braces');
18+
const utils = require('./lib/utils');
19+
const MAX_LENGTH = 1024 * 64;
20+
let cache = {};
21+
22+
/**
23+
* Convert the given `braces` pattern into a regex-compatible string. By default, only one string is generated for every input string. Set `options.expand` to true to return an array of patterns (similar to Bash or minimatch. Before using `options.expand`, it's recommended that you read the [performance notes](#performance)).
24+
*
25+
* ```js
26+
* var braces = require('braces');
27+
* console.log(braces('{a,b,c}'));
28+
* //=> ['(a|b|c)']
29+
*
30+
* console.log(braces('{a,b,c}', {expand: true}));
31+
* //=> ['a', 'b', 'c']
32+
* ```
33+
* @param {String} `str`
34+
* @param {Object} `options`
35+
* @return {String}
36+
* @api public
37+
*/
38+
39+
function braces(pattern, options) {
40+
var key = utils.createKey(String(pattern), options);
41+
var arr = [];
42+
43+
var disabled = options && options.cache === false;
44+
if (!disabled && cache.hasOwnProperty(key)) {
45+
return cache[key];
46+
}
47+
48+
if (Array.isArray(pattern)) {
49+
for (var i = 0; i < pattern.length; i++) {
50+
arr.push.apply(arr, braces.create(pattern[i], options));
51+
}
52+
} else {
53+
arr = braces.create(pattern, options);
54+
}
55+
56+
if (options && options.nodupes === true) {
57+
arr = unique(arr);
58+
}
59+
60+
if (!disabled) {
61+
cache[key] = arr;
62+
}
63+
return arr;
64+
}
65+
66+
/**
67+
* Expands a brace pattern into an array. This method is called by the main [braces](#braces) function when `options.expand` is true. Before using this method it's recommended that you read the [performance notes](#performance)) and advantages of using [.optimize](#optimize) instead.
68+
*
69+
* ```js
70+
* var braces = require('braces');
71+
* console.log(braces.expand('a/{b,c}/d'));
72+
* //=> ['a/b/d', 'a/c/d'];
73+
* ```
74+
* @param {String} `pattern` Brace pattern
75+
* @param {Object} `options`
76+
* @return {Array} Returns an array of expanded values.
77+
* @api public
78+
*/
79+
80+
braces.expand = function(pattern, options) {
81+
return braces.create(pattern, extend({}, options, { expand: true }));
82+
};
83+
84+
/**
85+
* Expands a brace pattern into a regex-compatible, optimized string. This method is called by the main [braces](#braces) function by default.
86+
*
87+
* ```js
88+
* var braces = require('braces');
89+
* console.log(braces.expand('a/{b,c}/d'));
90+
* //=> ['a/(b|c)/d']
91+
* ```
92+
* @param {String} `pattern` Brace pattern
93+
* @param {Object} `options`
94+
* @return {Array} Returns an array of expanded values.
95+
* @api public
96+
*/
97+
98+
braces.optimize = function(pattern, options) {
99+
return braces.create(pattern, options);
100+
};
101+
102+
/**
103+
* Processes a brace pattern and returns either an expanded array (if `options.expand` is true), a highly optimized regex-compatible string. This method is called by the main [braces](#braces) function.
104+
*
105+
* ```js
106+
* var braces = require('braces');
107+
* console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
108+
* //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
109+
* ```
110+
* @param {String} `pattern` Brace pattern
111+
* @param {Object} `options`
112+
* @return {Array} Returns an array of expanded values.
113+
* @api public
114+
*/
115+
116+
braces.create = function(pattern, options) {
117+
if (typeof pattern !== 'string') {
118+
throw new TypeError('expected a string');
119+
}
120+
121+
var maxLength = (options && options.maxLength) || MAX_LENGTH;
122+
if (pattern.length >= maxLength) {
123+
throw new Error('expected pattern to be less than ' + maxLength + ' characters');
124+
}
125+
126+
function create() {
127+
if (pattern === '' || pattern.length < 3) {
128+
return [pattern];
129+
}
130+
131+
if (utils.isEmptySets(pattern)) {
132+
return [];
133+
}
134+
135+
if (utils.isQuotedString(pattern)) {
136+
return [pattern.slice(1, -1)];
137+
}
138+
139+
var proto = new Braces(options);
140+
var result = !options || options.expand !== true
141+
? proto.optimize(pattern, options)
142+
: proto.expand(pattern, options);
143+
144+
// get the generated pattern(s)
145+
var arr = result.output;
146+
147+
// filter out empty strings if specified
148+
if (options && options.noempty === true) {
149+
arr = arr.filter(Boolean);
150+
}
151+
152+
// filter out duplicates if specified
153+
if (options && options.nodupes === true) {
154+
arr = unique(arr);
155+
}
156+
157+
Object.defineProperty(arr, 'result', {
158+
enumerable: false,
159+
value: result
160+
});
161+
162+
return arr;
163+
}
164+
165+
return memoize('create', pattern, options, create);
166+
};
167+
168+
/**
169+
* Create a regular expression from the given string `pattern`.
170+
*
171+
* ```js
172+
* var braces = require('braces');
173+
*
174+
* console.log(braces.makeRe('id-{200..300}'));
175+
* //=> /^(?:id-(20[0-9]|2[1-9][0-9]|300))$/
176+
* ```
177+
* @param {String} `pattern` The pattern to convert to regex.
178+
* @param {Object} `options`
179+
* @return {RegExp}
180+
* @api public
181+
*/
182+
183+
braces.makeRe = function(pattern, options) {
184+
if (typeof pattern !== 'string') {
185+
throw new TypeError('expected a string');
186+
}
187+
188+
var maxLength = (options && options.maxLength) || MAX_LENGTH;
189+
if (pattern.length >= maxLength) {
190+
throw new Error('expected pattern to be less than ' + maxLength + ' characters');
191+
}
192+
193+
function makeRe() {
194+
var arr = braces(pattern, options);
195+
var opts = extend({strictErrors: false}, options);
196+
return toRegex(arr, opts);
197+
}
198+
199+
return memoize('makeRe', pattern, options, makeRe);
200+
};
201+
202+
/**
203+
* Parse the given `str` with the given `options`.
204+
*
205+
* ```js
206+
* var braces = require('braces');
207+
* var ast = braces.parse('a/{b,c}/d');
208+
* console.log(ast);
209+
* // { type: 'root',
210+
* // errors: [],
211+
* // input: 'a/{b,c}/d',
212+
* // nodes:
213+
* // [ { type: 'bos', val: '' },
214+
* // { type: 'text', val: 'a/' },
215+
* // { type: 'brace',
216+
* // nodes:
217+
* // [ { type: 'brace.open', val: '{' },
218+
* // { type: 'text', val: 'b,c' },
219+
* // { type: 'brace.close', val: '}' } ] },
220+
* // { type: 'text', val: '/d' },
221+
* // { type: 'eos', val: '' } ] }
222+
* ```
223+
* @param {String} `pattern` Brace pattern to parse
224+
* @param {Object} `options`
225+
* @return {Object} Returns an AST
226+
* @api public
227+
*/
228+
229+
braces.parse = function(pattern, options) {
230+
var proto = new Braces(options);
231+
return proto.parse(pattern, options);
232+
};
233+
234+
/**
235+
* Compile the given `ast` or string with the given `options`.
236+
*
237+
* ```js
238+
* var braces = require('braces');
239+
* var ast = braces.parse('a/{b,c}/d');
240+
* console.log(braces.compile(ast));
241+
* // { options: { source: 'string' },
242+
* // state: {},
243+
* // compilers:
244+
* // { eos: [Function],
245+
* // noop: [Function],
246+
* // bos: [Function],
247+
* // brace: [Function],
248+
* // 'brace.open': [Function],
249+
* // text: [Function],
250+
* // 'brace.close': [Function] },
251+
* // output: [ 'a/(b|c)/d' ],
252+
* // ast:
253+
* // { ... },
254+
* // parsingErrors: [] }
255+
* ```
256+
* @param {Object|String} `ast` AST from [.parse](#parse). If a string is passed it will be parsed first.
257+
* @param {Object} `options`
258+
* @return {Object} Returns an object that has an `output` property with the compiled string.
259+
* @api public
260+
*/
261+
262+
braces.compile = function(ast, options) {
263+
var proto = new Braces(options);
264+
return proto.compile(ast, options);
265+
};
266+
267+
/**
268+
* Clear the regex cache.
269+
*
270+
* ```js
271+
* braces.clearCache();
272+
* ```
273+
* @api public
274+
*/
275+
276+
braces.clearCache = function() {
277+
cache = braces.cache = {};
278+
};
279+
280+
/**
281+
* Memoize a generated regex or function. A unique key is generated
282+
* from the method name, pattern, and user-defined options. Set
283+
* options.memoize to false to disable.
284+
*/
285+
286+
function memoize(type, pattern, options, fn) {
287+
var key = utils.createKey(type + ':' + pattern, options);
288+
var disabled = options && options.cache === false;
289+
if (disabled) {
290+
braces.clearCache();
291+
return fn(pattern, options);
292+
}
293+
294+
if (cache.hasOwnProperty(key)) {
295+
return cache[key];
296+
}
297+
298+
var res = fn(pattern, options);
299+
cache[key] = res;
300+
return res;
301+
}
302+
303+
/**
304+
* Expose `Braces` constructor and methods
305+
* @type {Function}
306+
*/
307+
308+
braces.Braces = Braces;
309+
braces.compilers = compilers;
310+
braces.parsers = parsers;
311+
braces.cache = cache;
312+
313+
/**
314+
* Expose `braces`
315+
* @type {Function}
316+
*/
317+
318+
module.exports = braces;

bench/index.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict';
2+
3+
const { Suite } = require('benchmark');
4+
const colors = require('ansi-colors');
5+
const argv = require('minimist')(process.argv.slice(2));
6+
const minimatch = require('minimatch');
7+
const compile = require('../lib/compile');
8+
const expand = require('../lib/expand');
9+
const parse = require('../lib/parse');
10+
11+
/**
12+
* Setup
13+
*/
14+
15+
const cycle = (e, newline) => {
16+
process.stdout.write(`\u001b[G ${e.target}${newline ? `\n` : ''}`);
17+
};
18+
19+
const bench = (name, options) => {
20+
const config = { name, ...options };
21+
const suite = new Suite(config);
22+
const add = suite.add.bind(suite);
23+
suite.on('error', console.error);
24+
25+
if (argv.run && !new RegExp(argv.run).test(name)) {
26+
suite.add = () => suite;
27+
return suite;
28+
}
29+
30+
console.log(colors.green(`● ${config.name}`));
31+
32+
suite.add = (key, fn, opts) => {
33+
if (typeof fn !== 'function') opts = fn;
34+
35+
add(key, {
36+
onCycle: e => cycle(e),
37+
onComplete: e => cycle(e, true),
38+
fn,
39+
...opts
40+
});
41+
return suite;
42+
};
43+
44+
return suite;
45+
};
46+
47+
const skip = () => {};
48+
skip.add = () => skip;
49+
skip.run = () => skip;
50+
bench.skip = name => {
51+
console.log(colors.cyan('● ' + colors.unstyle(name) + ' (skipped)'));
52+
return skip;
53+
};
54+
55+
bench('parse set')
56+
.add('picomatch', () => parse('foo/{a,b,c}/bar'))
57+
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,c}/bar'))
58+
.run();
59+
60+
bench('parse nested sets')
61+
.add('picomatch', () => parse('foo/{a,b,{x,y,z}}/bar'))
62+
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,{x,y,z}}/bar'))
63+
.run();
64+
65+
bench('parse range')
66+
.add('picomatch', () => parse('foo/{a..z}/bar'))
67+
.add('minimatch', () => minimatch.braceExpand('foo/{a..z}/bar'))
68+
.run();
69+
70+
bench.skip('expand')
71+
.add('picomatch', () => expand(parse('foo/{a,b,c}/bar')))
72+
.add('minimatch', () => minimatch.braceExpand('foo/{a,b,c}/bar'))
73+
.run();
74+
75+
bench.skip('compile')
76+
.add('picomatch', () => compile(parse('foo/{a,b,c}/bar')))
77+
.add('minimatch', () => minimatch.makeRe('foo/{a,b,c}/bar'))
78+
.run();

0 commit comments

Comments
 (0)