source: trip-planner-front/node_modules/picomatch/lib/scan.js@ fa375fe

Last change on this file since fa375fe was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 9.0 KB
Line 
1'use strict';
2
3const utils = require('./utils');
4const {
5 CHAR_ASTERISK, /* * */
6 CHAR_AT, /* @ */
7 CHAR_BACKWARD_SLASH, /* \ */
8 CHAR_COMMA, /* , */
9 CHAR_DOT, /* . */
10 CHAR_EXCLAMATION_MARK, /* ! */
11 CHAR_FORWARD_SLASH, /* / */
12 CHAR_LEFT_CURLY_BRACE, /* { */
13 CHAR_LEFT_PARENTHESES, /* ( */
14 CHAR_LEFT_SQUARE_BRACKET, /* [ */
15 CHAR_PLUS, /* + */
16 CHAR_QUESTION_MARK, /* ? */
17 CHAR_RIGHT_CURLY_BRACE, /* } */
18 CHAR_RIGHT_PARENTHESES, /* ) */
19 CHAR_RIGHT_SQUARE_BRACKET /* ] */
20} = require('./constants');
21
22const isPathSeparator = code => {
23 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
24};
25
26const depth = token => {
27 if (token.isPrefix !== true) {
28 token.depth = token.isGlobstar ? Infinity : 1;
29 }
30};
31
32/**
33 * Quickly scans a glob pattern and returns an object with a handful of
34 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
35 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
36 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
37 *
38 * ```js
39 * const pm = require('picomatch');
40 * console.log(pm.scan('foo/bar/*.js'));
41 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
42 * ```
43 * @param {String} `str`
44 * @param {Object} `options`
45 * @return {Object} Returns an object with tokens and regex source string.
46 * @api public
47 */
48
49const scan = (input, options) => {
50 const opts = options || {};
51
52 const length = input.length - 1;
53 const scanToEnd = opts.parts === true || opts.scanToEnd === true;
54 const slashes = [];
55 const tokens = [];
56 const parts = [];
57
58 let str = input;
59 let index = -1;
60 let start = 0;
61 let lastIndex = 0;
62 let isBrace = false;
63 let isBracket = false;
64 let isGlob = false;
65 let isExtglob = false;
66 let isGlobstar = false;
67 let braceEscaped = false;
68 let backslashes = false;
69 let negated = false;
70 let negatedExtglob = false;
71 let finished = false;
72 let braces = 0;
73 let prev;
74 let code;
75 let token = { value: '', depth: 0, isGlob: false };
76
77 const eos = () => index >= length;
78 const peek = () => str.charCodeAt(index + 1);
79 const advance = () => {
80 prev = code;
81 return str.charCodeAt(++index);
82 };
83
84 while (index < length) {
85 code = advance();
86 let next;
87
88 if (code === CHAR_BACKWARD_SLASH) {
89 backslashes = token.backslashes = true;
90 code = advance();
91
92 if (code === CHAR_LEFT_CURLY_BRACE) {
93 braceEscaped = true;
94 }
95 continue;
96 }
97
98 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
99 braces++;
100
101 while (eos() !== true && (code = advance())) {
102 if (code === CHAR_BACKWARD_SLASH) {
103 backslashes = token.backslashes = true;
104 advance();
105 continue;
106 }
107
108 if (code === CHAR_LEFT_CURLY_BRACE) {
109 braces++;
110 continue;
111 }
112
113 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
114 isBrace = token.isBrace = true;
115 isGlob = token.isGlob = true;
116 finished = true;
117
118 if (scanToEnd === true) {
119 continue;
120 }
121
122 break;
123 }
124
125 if (braceEscaped !== true && code === CHAR_COMMA) {
126 isBrace = token.isBrace = true;
127 isGlob = token.isGlob = true;
128 finished = true;
129
130 if (scanToEnd === true) {
131 continue;
132 }
133
134 break;
135 }
136
137 if (code === CHAR_RIGHT_CURLY_BRACE) {
138 braces--;
139
140 if (braces === 0) {
141 braceEscaped = false;
142 isBrace = token.isBrace = true;
143 finished = true;
144 break;
145 }
146 }
147 }
148
149 if (scanToEnd === true) {
150 continue;
151 }
152
153 break;
154 }
155
156 if (code === CHAR_FORWARD_SLASH) {
157 slashes.push(index);
158 tokens.push(token);
159 token = { value: '', depth: 0, isGlob: false };
160
161 if (finished === true) continue;
162 if (prev === CHAR_DOT && index === (start + 1)) {
163 start += 2;
164 continue;
165 }
166
167 lastIndex = index + 1;
168 continue;
169 }
170
171 if (opts.noext !== true) {
172 const isExtglobChar = code === CHAR_PLUS
173 || code === CHAR_AT
174 || code === CHAR_ASTERISK
175 || code === CHAR_QUESTION_MARK
176 || code === CHAR_EXCLAMATION_MARK;
177
178 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
179 isGlob = token.isGlob = true;
180 isExtglob = token.isExtglob = true;
181 finished = true;
182 if (code === CHAR_EXCLAMATION_MARK && index === start) {
183 negatedExtglob = true;
184 }
185
186 if (scanToEnd === true) {
187 while (eos() !== true && (code = advance())) {
188 if (code === CHAR_BACKWARD_SLASH) {
189 backslashes = token.backslashes = true;
190 code = advance();
191 continue;
192 }
193
194 if (code === CHAR_RIGHT_PARENTHESES) {
195 isGlob = token.isGlob = true;
196 finished = true;
197 break;
198 }
199 }
200 continue;
201 }
202 break;
203 }
204 }
205
206 if (code === CHAR_ASTERISK) {
207 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
208 isGlob = token.isGlob = true;
209 finished = true;
210
211 if (scanToEnd === true) {
212 continue;
213 }
214 break;
215 }
216
217 if (code === CHAR_QUESTION_MARK) {
218 isGlob = token.isGlob = true;
219 finished = true;
220
221 if (scanToEnd === true) {
222 continue;
223 }
224 break;
225 }
226
227 if (code === CHAR_LEFT_SQUARE_BRACKET) {
228 while (eos() !== true && (next = advance())) {
229 if (next === CHAR_BACKWARD_SLASH) {
230 backslashes = token.backslashes = true;
231 advance();
232 continue;
233 }
234
235 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
236 isBracket = token.isBracket = true;
237 isGlob = token.isGlob = true;
238 finished = true;
239 break;
240 }
241 }
242
243 if (scanToEnd === true) {
244 continue;
245 }
246
247 break;
248 }
249
250 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
251 negated = token.negated = true;
252 start++;
253 continue;
254 }
255
256 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
257 isGlob = token.isGlob = true;
258
259 if (scanToEnd === true) {
260 while (eos() !== true && (code = advance())) {
261 if (code === CHAR_LEFT_PARENTHESES) {
262 backslashes = token.backslashes = true;
263 code = advance();
264 continue;
265 }
266
267 if (code === CHAR_RIGHT_PARENTHESES) {
268 finished = true;
269 break;
270 }
271 }
272 continue;
273 }
274 break;
275 }
276
277 if (isGlob === true) {
278 finished = true;
279
280 if (scanToEnd === true) {
281 continue;
282 }
283
284 break;
285 }
286 }
287
288 if (opts.noext === true) {
289 isExtglob = false;
290 isGlob = false;
291 }
292
293 let base = str;
294 let prefix = '';
295 let glob = '';
296
297 if (start > 0) {
298 prefix = str.slice(0, start);
299 str = str.slice(start);
300 lastIndex -= start;
301 }
302
303 if (base && isGlob === true && lastIndex > 0) {
304 base = str.slice(0, lastIndex);
305 glob = str.slice(lastIndex);
306 } else if (isGlob === true) {
307 base = '';
308 glob = str;
309 } else {
310 base = str;
311 }
312
313 if (base && base !== '' && base !== '/' && base !== str) {
314 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
315 base = base.slice(0, -1);
316 }
317 }
318
319 if (opts.unescape === true) {
320 if (glob) glob = utils.removeBackslashes(glob);
321
322 if (base && backslashes === true) {
323 base = utils.removeBackslashes(base);
324 }
325 }
326
327 const state = {
328 prefix,
329 input,
330 start,
331 base,
332 glob,
333 isBrace,
334 isBracket,
335 isGlob,
336 isExtglob,
337 isGlobstar,
338 negated,
339 negatedExtglob
340 };
341
342 if (opts.tokens === true) {
343 state.maxDepth = 0;
344 if (!isPathSeparator(code)) {
345 tokens.push(token);
346 }
347 state.tokens = tokens;
348 }
349
350 if (opts.parts === true || opts.tokens === true) {
351 let prevIndex;
352
353 for (let idx = 0; idx < slashes.length; idx++) {
354 const n = prevIndex ? prevIndex + 1 : start;
355 const i = slashes[idx];
356 const value = input.slice(n, i);
357 if (opts.tokens) {
358 if (idx === 0 && start !== 0) {
359 tokens[idx].isPrefix = true;
360 tokens[idx].value = prefix;
361 } else {
362 tokens[idx].value = value;
363 }
364 depth(tokens[idx]);
365 state.maxDepth += tokens[idx].depth;
366 }
367 if (idx !== 0 || value !== '') {
368 parts.push(value);
369 }
370 prevIndex = i;
371 }
372
373 if (prevIndex && prevIndex + 1 < input.length) {
374 const value = input.slice(prevIndex + 1);
375 parts.push(value);
376
377 if (opts.tokens) {
378 tokens[tokens.length - 1].value = value;
379 depth(tokens[tokens.length - 1]);
380 state.maxDepth += tokens[tokens.length - 1].depth;
381 }
382 }
383
384 state.slashes = slashes;
385 state.parts = parts;
386 }
387
388 return state;
389};
390
391module.exports = scan;
Note: See TracBrowser for help on using the repository browser.