Changeset 33517cc for node_modules/minimatch/dist/esm/ast.js
- Timestamp:
- 09/19/26 10:30:30 (10 days ago)
- Branches:
- finki-main, main
- Children:
- 06ebe74
- Parents:
- 62b2964
- File:
-
- 1 edited
-
node_modules/minimatch/dist/esm/ast.js (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
node_modules/minimatch/dist/esm/ast.js
r62b2964 r33517cc 1 1 // parse a single path portion 2 var _a; 2 3 import { parseClass } from './brace-expressions.js'; 3 4 import { unescape } from './unescape.js'; 4 5 const types = new Set(['!', '?', '+', '*', '@']); 5 6 const isExtglobType = (c) => types.has(c); 7 const isExtglobAST = (c) => isExtglobType(c.type); 8 // Map of which extglob types can adopt the children of a nested extglob 9 // 10 // anything but ! can adopt a matching type: 11 // +(a|+(b|c)|d) => +(a|b|c|d) 12 // *(a|*(b|c)|d) => *(a|b|c|d) 13 // @(a|@(b|c)|d) => @(a|b|c|d) 14 // ?(a|?(b|c)|d) => ?(a|b|c|d) 15 // 16 // * can adopt anything, because 0 or repetition is allowed 17 // *(a|?(b|c)|d) => *(a|b|c|d) 18 // *(a|+(b|c)|d) => *(a|b|c|d) 19 // *(a|@(b|c)|d) => *(a|b|c|d) 20 // 21 // + can adopt @, because 1 or repetition is allowed 22 // +(a|@(b|c)|d) => +(a|b|c|d) 23 // 24 // + and @ CANNOT adopt *, because 0 would be allowed 25 // +(a|*(b|c)|d) => would match "", on *(b|c) 26 // @(a|*(b|c)|d) => would match "", on *(b|c) 27 // 28 // + and @ CANNOT adopt ?, because 0 would be allowed 29 // +(a|?(b|c)|d) => would match "", on ?(b|c) 30 // @(a|?(b|c)|d) => would match "", on ?(b|c) 31 // 32 // ? can adopt @, because 0 or 1 is allowed 33 // ?(a|@(b|c)|d) => ?(a|b|c|d) 34 // 35 // ? and @ CANNOT adopt * or +, because >1 would be allowed 36 // ?(a|*(b|c)|d) => would match bbb on *(b|c) 37 // @(a|*(b|c)|d) => would match bbb on *(b|c) 38 // ?(a|+(b|c)|d) => would match bbb on +(b|c) 39 // @(a|+(b|c)|d) => would match bbb on +(b|c) 40 // 41 // ! CANNOT adopt ! (nothing else can either) 42 // !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c) 43 // 44 // ! can adopt @ 45 // !(a|@(b|c)|d) => !(a|b|c|d) 46 // 47 // ! CANNOT adopt * 48 // !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed 49 // 50 // ! CANNOT adopt + 51 // !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed 52 // 53 // ! CANNOT adopt ? 54 // x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x" 55 const adoptionMap = new Map([ 56 ['!', ['@']], 57 ['?', ['?', '@']], 58 ['@', ['@']], 59 ['*', ['*', '+', '?', '@']], 60 ['+', ['+', '@']], 61 ]); 62 // nested extglobs that can be adopted in, but with the addition of 63 // a blank '' element. 64 const adoptionWithSpaceMap = new Map([ 65 ['!', ['?']], 66 ['@', ['?']], 67 ['+', ['?', '*']], 68 ]); 69 // union of the previous two maps 70 const adoptionAnyMap = new Map([ 71 ['!', ['?', '@']], 72 ['?', ['?', '@']], 73 ['@', ['?', '@']], 74 ['*', ['*', '+', '?', '@']], 75 ['+', ['+', '@', '?', '*']], 76 ]); 77 // Extglobs that can take over their parent if they are the only child 78 // the key is parent, value maps child to resulting extglob parent type 79 // '@' is omitted because it's a special case. An `@` extglob with a single 80 // member can always be usurped by that subpattern. 81 const usurpMap = new Map([ 82 ['!', new Map([['!', '@']])], 83 [ 84 '?', 85 new Map([ 86 ['*', '*'], 87 ['+', '*'], 88 ]), 89 ], 90 [ 91 '@', 92 new Map([ 93 ['!', '!'], 94 ['?', '?'], 95 ['@', '@'], 96 ['*', '*'], 97 ['+', '+'], 98 ]), 99 ], 100 [ 101 '+', 102 new Map([ 103 ['?', '*'], 104 ['*', '*'], 105 ]), 106 ], 107 ]); 6 108 // Patterns that get prepended to bind to the start of either the 7 109 // entire string, or just a single path portion, to prevent dots … … 27 129 // remove the \ chars that we added if we end up doing a nonmagic compare 28 130 // const deslash = (s: string) => s.replace(/\\(.)/g, '$1') 131 let ID = 0; 29 132 export class AST { 30 133 type; … … 42 145 // (which really means one child of '') 43 146 #emptyExt = false; 147 id = ++ID; 148 get depth() { 149 return (this.#parent?.depth ?? -1) + 1; 150 } 151 [Symbol.for('nodejs.util.inspect.custom')]() { 152 return { 153 '@@type': 'AST', 154 id: this.id, 155 type: this.type, 156 root: this.#root.id, 157 parent: this.#parent?.id, 158 depth: this.depth, 159 partsLength: this.#parts.length, 160 parts: this.#parts, 161 }; 162 } 44 163 constructor(type, parent, options = {}) { 45 164 this.type = type; … … 71 190 // reconstructs the pattern 72 191 toString() { 73 if (this.#toString !== undefined) 74 return this.#toString; 75 if (!this.type) { 76 return (this.#toString = this.#parts.map(p => String(p)).join('')); 77 } 78 else { 79 return (this.#toString = 80 this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')'); 81 } 192 return (this.#toString !== undefined ? this.#toString 193 : !this.type ? 194 (this.#toString = this.#parts.map(p => String(p)).join('')) 195 : (this.#toString = 196 this.type + 197 '(' + 198 this.#parts.map(p => String(p)).join('|') + 199 ')')); 82 200 } 83 201 #fillNegs() { … … 121 239 /* c8 ignore start */ 122 240 if (typeof p !== 'string' && 123 !(p instanceof AST&& p.#parent === this)) {241 !(p instanceof _a && p.#parent === this)) { 124 242 throw new Error('invalid part: ' + p); 125 243 } … … 155 273 for (let i = 0; i < this.#parentIndex; i++) { 156 274 const pp = p.#parts[i]; 157 if (!(pp instanceof AST&& pp.type === '!')) {275 if (!(pp instanceof _a && pp.type === '!')) { 158 276 return false; 159 277 } … … 183 301 } 184 302 clone(parent) { 185 const c = new AST(this.type, parent);303 const c = new _a(this.type, parent); 186 304 for (const p of this.#parts) { 187 305 c.copyIn(p); … … 189 307 return c; 190 308 } 191 static #parseAST(str, ast, pos, opt) { 309 static #parseAST(str, ast, pos, opt, extDepth) { 310 const maxDepth = opt.maxExtglobRecursion ?? 2; 192 311 let escaping = false; 193 312 let inBrace = false; … … 226 345 continue; 227 346 } 228 if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { 347 // we don't have to check for adoption here, because that's 348 // done at the other recursion point. 349 const doRecurse = !opt.noext && 350 isExtglobType(c) && 351 str.charAt(i) === '(' && 352 extDepth <= maxDepth; 353 if (doRecurse) { 229 354 ast.push(acc); 230 355 acc = ''; 231 const ext = new AST(c, ast);232 i = AST.#parseAST(str, ext, i, opt);356 const ext = new _a(c, ast); 357 i = _a.#parseAST(str, ext, i, opt, extDepth + 1); 233 358 ast.push(ext); 234 359 continue; … … 242 367 // find the next | or ) 243 368 let i = pos + 1; 244 let part = new AST(null, ast);369 let part = new _a(null, ast); 245 370 const parts = []; 246 371 let acc = ''; … … 273 398 continue; 274 399 } 275 if (isExtglobType(c) && str.charAt(i) === '(') { 400 const doRecurse = !opt.noext && 401 isExtglobType(c) && 402 str.charAt(i) === '(' && 403 /* c8 ignore start - the maxDepth is sufficient here */ 404 (extDepth <= maxDepth || (ast && ast.#canAdoptType(c))); 405 /* c8 ignore stop */ 406 if (doRecurse) { 407 const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1; 276 408 part.push(acc); 277 409 acc = ''; 278 const ext = new AST(c, part);410 const ext = new _a(c, part); 279 411 part.push(ext); 280 i = AST.#parseAST(str, ext, i, opt);412 i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd); 281 413 continue; 282 414 } … … 285 417 acc = ''; 286 418 parts.push(part); 287 part = new AST(null, ast);419 part = new _a(null, ast); 288 420 continue; 289 421 } … … 307 439 return i; 308 440 } 441 #canAdoptWithSpace(child) { 442 return this.#canAdopt(child, adoptionWithSpaceMap); 443 } 444 #canAdopt(child, map = adoptionMap) { 445 if (!child || 446 typeof child !== 'object' || 447 child.type !== null || 448 child.#parts.length !== 1 || 449 this.type === null) { 450 return false; 451 } 452 const gc = child.#parts[0]; 453 if (!gc || typeof gc !== 'object' || gc.type === null) { 454 return false; 455 } 456 return this.#canAdoptType(gc.type, map); 457 } 458 #canAdoptType(c, map = adoptionAnyMap) { 459 return !!map.get(this.type)?.includes(c); 460 } 461 #adoptWithSpace(child, index) { 462 const gc = child.#parts[0]; 463 const blank = new _a(null, gc, this.options); 464 blank.#parts.push(''); 465 gc.push(blank); 466 this.#adopt(child, index); 467 } 468 #adopt(child, index) { 469 const gc = child.#parts[0]; 470 this.#parts.splice(index, 1, ...gc.#parts); 471 for (const p of gc.#parts) { 472 if (typeof p === 'object') 473 p.#parent = this; 474 } 475 this.#toString = undefined; 476 } 477 #canUsurpType(c) { 478 const m = usurpMap.get(this.type); 479 return !!m?.has(c); 480 } 481 #canUsurp(child) { 482 if (!child || 483 typeof child !== 'object' || 484 child.type !== null || 485 child.#parts.length !== 1 || 486 this.type === null || 487 this.#parts.length !== 1) { 488 return false; 489 } 490 const gc = child.#parts[0]; 491 if (!gc || typeof gc !== 'object' || gc.type === null) { 492 return false; 493 } 494 return this.#canUsurpType(gc.type); 495 } 496 #usurp(child) { 497 const m = usurpMap.get(this.type); 498 const gc = child.#parts[0]; 499 const nt = m?.get(gc.type); 500 /* c8 ignore start - impossible */ 501 if (!nt) 502 return false; 503 /* c8 ignore stop */ 504 this.#parts = gc.#parts; 505 for (const p of this.#parts) { 506 if (typeof p === 'object') { 507 p.#parent = this; 508 } 509 } 510 this.type = nt; 511 this.#toString = undefined; 512 this.#emptyExt = false; 513 } 309 514 static fromGlob(pattern, options = {}) { 310 const ast = new AST(null, undefined, options);311 AST.#parseAST(pattern, ast, 0, options);515 const ast = new _a(null, undefined, options); 516 _a.#parseAST(pattern, ast, 0, options, 0); 312 517 return ast; 313 518 } … … 413 618 toRegExpSource(allowDot) { 414 619 const dot = allowDot ?? !!this.#options.dot; 415 if (this.#root === this) 620 if (this.#root === this) { 621 this.#flatten(); 416 622 this.#fillNegs(); 417 if (!this.type) { 623 } 624 if (!isExtglobAST(this)) { 418 625 const noEmpty = this.isStart() && 419 626 this.isEnd() && … … 422 629 .map(p => { 423 630 const [re, _, hasMagic, uflag] = typeof p === 'string' ? 424 AST.#parseGlob(p, this.#hasMagic, noEmpty)631 _a.#parseGlob(p, this.#hasMagic, noEmpty) 425 632 : p.toRegExpSource(allowDot); 426 633 this.#hasMagic = this.#hasMagic || hasMagic; … … 484 691 // the entire path portion. 485 692 const s = this.toString(); 486 this.#parts = [s]; 487 this.type = null; 488 this.#hasMagic = undefined; 693 const me = this; 694 me.#parts = [s]; 695 me.type = null; 696 me.#hasMagic = undefined; 489 697 return [s, unescape(this.toString()), false, false]; 490 698 } 491 // XXX abstract out this map method492 699 let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? 493 700 '' … … 525 732 ]; 526 733 } 734 #flatten() { 735 if (!isExtglobAST(this)) { 736 for (const p of this.#parts) { 737 if (typeof p === 'object') { 738 p.#flatten(); 739 } 740 } 741 } 742 else { 743 // do up to 10 passes to flatten as much as possible 744 let iterations = 0; 745 let done = false; 746 do { 747 done = true; 748 for (let i = 0; i < this.#parts.length; i++) { 749 const c = this.#parts[i]; 750 if (typeof c === 'object') { 751 c.#flatten(); 752 if (this.#canAdopt(c)) { 753 done = false; 754 this.#adopt(c, i); 755 } 756 else if (this.#canAdoptWithSpace(c)) { 757 done = false; 758 this.#adoptWithSpace(c, i); 759 } 760 else if (this.#canUsurp(c)) { 761 done = false; 762 this.#usurp(c); 763 } 764 } 765 } 766 } while (!done && ++iterations < 10); 767 } 768 this.#toString = undefined; 769 } 527 770 #partsToRegExp(dot) { 528 771 return this.#parts … … 595 838 } 596 839 } 840 _a = AST; 597 841 //# sourceMappingURL=ast.js.map
Note:
See TracChangeset
for help on using the changeset viewer.
