glob.ts ×19

Frontier kind: Code frontier

unlabeled · c_1daf24920ed7

89 tests · 7274 LOC · 32 files · introduces 0 tests · 83 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
19 ranges83 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1084 ranges7274 lines · 32 files · Browse complete extent
All tests (intent)
89 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 83 introduced LOC across 19 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/base/common/glob.ts 83 introduced LOC · 19 ranges

Open complete file

110 }
111
112 > function parseRegExp(pattern: string): string { glob.ts
113 > if (!pattern) {
114 return '';
115 }
116 > glob.ts
117 > let regEx = '';
118 >
119 > // Split up into segments for each slash found
120 > const segments = splitGlobAware(pattern, GLOB_SPLIT);
121 >
122 > // Special case where we only have globstars
123 > if (segments.every(segment => segment === GLOBSTAR)) {
124 regEx = '.*';
125 }
126 > glob.ts
127 > // Build regex over segments
128 > else {
129 > let previousSegmentWasGlobStar = false;
130 > segments.forEach((segment, index) => {
131 >
132 > // Treat globstar specially
133 > if (segment === GLOBSTAR) {
134
135 // if we have more than one globstar after another, just ignore it
140 regEx += starsToRegExp(2, index === segments.length - 1);
141 }
142 > glob.ts
143 > // Anything else, not globstar
144 > else {
145 >
146 > // States
147 > let inBraces = false;
148 > let braceVal = '';
149 >
150 > let inBrackets = false;
151 > let bracketVal = '';
152 >
153 > for (const char of segment) {
154 >
155 > // Support brace expansion
156 > if (char !== '}' && inBraces) {
157 braceVal += char;
158 continue;
159 }
160 > glob.ts
161 > // Support brackets
162 > if (inBrackets && (char !== ']' || !bracketVal) /* ] is literally only allowed as first character in brackets to match it */) {
163 let res: string;
164
187 continue;
188 }
189 > glob.ts
190 > switch (char) {
191 > case '{':
192 inBraces = true;
193 continue;
194 > glob.ts
195 > case '[':
196 inBrackets = true;
197 continue;
198 > glob.ts
199 > case '}': {
200 const choices = splitGlobAware(braceVal, ',');
201
210 break;
211 }
212 > glob.ts
213 > case ']': {
214 regEx += ('[' + bracketVal + ']');
215
219 break;
220 }
221 > glob.ts
222 > case '?':
223 regEx += NO_PATH_REGEX; // 1 ? matches any single character except path separator (/ and \)
224 continue;
225 > glob.ts
226 > case '*':
227 regEx += starsToRegExp(1);
228 continue;
229 > glob.ts
230 > default:
231 regEx += escapeRegExpCharacters(char);
232 > } glob.ts
233 > }
234 >
235 > // Tail: Add the slash we had split on if there is more to
236 > // come and the remaining pattern is not a globstar
237 > // For example if pattern: some/**/*.js we want the "/" after
238 > // some to be included in the RegEx to prevent a folder called
239 > // "something" to match as well.
240 > if (
241 > index < segments.length - 1 && // more segments to come after this
242 (
243 segments[index + 1] !== GLOBSTAR || // next segment is not **, or...
244 index + 2 < segments.length // ...next segment is ** but there is more segments after that
245 > ) glob.ts
246 > ) {
247 regEx += PATH_REGEX;
248 }
249 > } glob.ts
250 >
251 > // update globstar state
252 > previousSegmentWasGlobStar = (segment === GLOBSTAR);
253 > });
254 > }
255 >
256 > return regEx;
257 > }
258
259 // regexes to check for trivial glob patterns that just check for String#endsWith
379 parsedPattern = trivia4and5(match[1], pattern, false, internalOptions);
380 }
381 > glob.ts
382 > // Otherwise convert to pattern
383 > else {
384 > parsedPattern = toRegExp(pattern, internalOptions);
385 > }
386
387 // Cache
523 }
524
525 > function toRegExp(pattern: string, options: IGlobOptions): ParsedStringPattern { glob.ts
526 > try {
527 > const regExp = new RegExp(`^${parseRegExp(pattern)}$`, options.ignoreCase ? 'i' : undefined);
528 > return function (path: string) {
529 regExp.lastIndex = 0; // reset RegExp to its initial state to reuse it!
530
531 return typeof path === 'string' && regExp.test(path) ? pattern : null;
532 };
533 > } catch { glob.ts
534 return NULL;
535 }
536 > } glob.ts
537
538 /**