33import { parseClass } from './brace-expressions.js'
44import { MinimatchOptions , MMRegExp } from './index.js'
55import { unescape } from './unescape.js'
6+ import { ArrayPrototypeFilter , ArrayPrototypeJoin , ArrayPrototypeMap , ArrayPrototypePop , ArrayPrototypePush , ArrayPrototypeSlice , ObjectAssign , SafeSet , StringPrototypeCharAt , StringPrototypeReplace , StringPrototypeSubstring , StringPrototypeToLowerCase , StringPrototypeToUpperCase } from "./primordials.js" ;
67
78// classes [] are handled by the parseClass method
89// for positive extglobs, we sub-parse the contents, and combine,
@@ -42,7 +43,7 @@ import { unescape } from './unescape.js'
4243// ['^a(?:i|w(?:(?!(?:x|y).*zb$).*)z|j)b$']
4344
4445export type ExtglobType = '!' | '?' | '+' | '*' | '@'
45- const types = new Set < ExtglobType > ( [ '!' , '?' , '+' , '*' , '@' ] )
46+ const types = new SafeSet < ExtglobType > ( [ '!' , '?' , '+' , '*' , '@' ] )
4647const isExtglobType = ( c : string ) : c is ExtglobType =>
4748 types . has ( c as ExtglobType )
4849
@@ -56,12 +57,12 @@ const startNoDot = '(?!\\.)'
5657// characters that indicate a start of pattern needs the "no dots" bit,
5758// because a dot *might* be matched. ( is not in the list, because in
5859// the case of a child extglob, it will handle the prevention itself.
59- const addPatternStart = new Set ( [ '[' , '.' ] )
60+ const addPatternStart = new SafeSet ( [ '[' , '.' ] )
6061// cases where traversal is A-OK, no dot prevention needed
61- const justDots = new Set ( [ '..' , '.' ] )
62- const reSpecials = new Set ( '().*{}+?[]^$\\!' )
62+ const justDots = new SafeSet ( [ '..' , '.' ] )
63+ const reSpecials = new SafeSet ( [ "'" , '(' , ')' , '.' , '*' , '{' , '}' , '+' , '?' , '[' , ']' , '^' , '$' , '\\' , '!' ] )
6364const regExpEscape = ( s : string ) =>
64- s . replace ( / [ - [ \] { } ( ) * + ? . , \\ ^ $ | # \s ] / g, '\\$&' )
65+ StringPrototypeReplace ( s , / [ - [ \] { } ( ) * + ? . , \\ ^ $ | # \s ] / g, '\\$&' )
6566
6667// any single thing other than /
6768const qmark = '[^/]'
@@ -95,7 +96,7 @@ export class AST {
9596 constructor (
9697 type : ExtglobType | null ,
9798 parent ?: AST ,
98- options : MinimatchOptions = { }
99+ options : MinimatchOptions = { __proto__ : null } as MinimatchOptions
99100 ) {
100101 this . type = type
101102 // extglobs are inherently magical
@@ -104,15 +105,16 @@ export class AST {
104105 this . #root = this . #parent ? this . #parent. #root : this
105106 this . #options = this . #root === this ? options : this . #root. #options
106107 this . #negs = this . #root === this ? [ ] : this . #root. #negs
107- if ( type === '!' && ! this . #root. #filledNegs) this . #negs. push ( this )
108+ if ( type === '!' && ! this . #root. #filledNegs) ArrayPrototypePush ( this . #negs, this )
108109 this . #parentIndex = this . #parent ? this . #parent. #parts. length : 0
109110 }
110111
111112 get hasMagic ( ) : boolean | undefined {
112113 /* c8 ignore start */
113114 if ( this . #hasMagic !== undefined ) return this . #hasMagic
114115 /* c8 ignore stop */
115- for ( const p of this . #parts) {
116+ for ( let i = 0 ; i < this . #parts. length ; i ++ ) {
117+ const p = this . #parts[ i ]
116118 if ( typeof p === 'string' ) continue
117119 if ( p . type || p . hasMagic ) return ( this . #hasMagic = true )
118120 }
@@ -123,11 +125,12 @@ export class AST {
123125 // reconstructs the pattern
124126 toString ( ) : string {
125127 if ( this . #toString !== undefined ) return this . #toString
128+ const parts = ArrayPrototypeMap ( this . #parts, p => String ( p ) ) ;
126129 if ( ! this . type ) {
127- return ( this . #toString = this . #parts . map ( p => String ( p ) ) . join ( '' ) )
130+ return ( this . #toString = ArrayPrototypeJoin ( parts , '' ) )
128131 } else {
129132 return ( this . #toString =
130- this . type + '(' + this . #parts . map ( p => String ( p ) ) . join ( '|' ) + ')' )
133+ this . type + '(' + ArrayPrototypeJoin ( parts , '|' ) + ')' )
131134 }
132135 }
133136
@@ -141,7 +144,7 @@ export class AST {
141144 this . toString ( )
142145 this . #filledNegs = true
143146 let n : AST | undefined
144- while ( ( n = this . #negs. pop ( ) ) ) {
147+ while ( ( n = ArrayPrototypePop ( this . #negs) ) ) {
145148 if ( n . type !== '!' ) continue
146149 // walk up the tree, appending everthing that comes AFTER parentIndex
147150 let p : AST | undefined = n
@@ -152,7 +155,8 @@ export class AST {
152155 ! pp . type && i < pp . #parts. length ;
153156 i ++
154157 ) {
155- for ( const part of n . #parts) {
158+ for ( let y = 0 ; y < n . #parts. length ; y ++ ) {
159+ const part = n . #parts[ y ] ;
156160 /* c8 ignore start */
157161 if ( typeof part === 'string' ) {
158162 throw new Error ( 'string part in extglob AST??' )
@@ -169,7 +173,8 @@ export class AST {
169173 }
170174
171175 push ( ...parts : ( string | AST ) [ ] ) {
172- for ( const p of parts ) {
176+ for ( let i = 0 ; i < parts . length ; i ++ ) {
177+ const p = parts [ i ] ;
173178 if ( p === '' ) continue
174179 /* c8 ignore start */
175180 if ( typeof p !== 'string' && ! ( p instanceof AST && p . #parent === this ) ) {
@@ -183,8 +188,8 @@ export class AST {
183188 toJSON ( ) {
184189 const ret : any [ ] =
185190 this . type === null
186- ? this . #parts. slice ( ) . map ( p => ( typeof p === 'string' ? p : p . toJSON ( ) ) )
187- : [ this . type , ...this . #parts. map ( p => ( p as AST ) . toJSON ( ) ) ]
191+ ? ArrayPrototypeMap ( ArrayPrototypeSlice ( this . #parts) , ( p : string | AST ) => ( typeof p === 'string' ? p : p . toJSON ( ) ) )
192+ : [ this . type , ...ArrayPrototypeMap ( this . #parts, ( p : AST ) => p . toJSON ( ) ) ]
188193 if ( this . isStart ( ) && ! this . type ) ret . unshift ( [ ] )
189194 if (
190195 this . isEnd ( ) &&
@@ -231,8 +236,8 @@ export class AST {
231236
232237 clone ( parent : AST ) {
233238 const c = new AST ( this . type , parent )
234- for ( const p of this . #parts) {
235- c . copyIn ( p )
239+ for ( let i = 0 ; i < this . #parts. length ; i ++ ) {
240+ c . copyIn ( this . #parts [ i ] )
236241 }
237242 return c
238243 }
@@ -252,7 +257,7 @@ export class AST {
252257 let i = pos
253258 let acc = ''
254259 while ( i < str . length ) {
255- const c = str . charAt ( i ++ )
260+ const c = StringPrototypeCharAt ( str , i ++ )
256261 // still accumulate escapes at this point, but we do ignore
257262 // starts that are escaped
258263 if ( escaping || c === '\\' ) {
@@ -279,7 +284,7 @@ export class AST {
279284 continue
280285 }
281286
282- if ( ! opt . noext && isExtglobType ( c ) && str . charAt ( i ) === '(' ) {
287+ if ( ! opt . noext && isExtglobType ( c ) && StringPrototypeCharAt ( str , i ) === '(' ) {
283288 ast . push ( acc )
284289 acc = ''
285290 const ext = new AST ( c , ast )
@@ -300,7 +305,7 @@ export class AST {
300305 const parts : AST [ ] = [ ]
301306 let acc = ''
302307 while ( i < str . length ) {
303- const c = str . charAt ( i ++ )
308+ const c = StringPrototypeCharAt ( str , i ++ ) ;
304309 // still accumulate escapes at this point, but we do ignore
305310 // starts that are escaped
306311 if ( escaping || c === '\\' ) {
@@ -327,7 +332,7 @@ export class AST {
327332 continue
328333 }
329334
330- if ( isExtglobType ( c ) && str . charAt ( i ) === '(' ) {
335+ if ( isExtglobType ( c ) && StringPrototypeCharAt ( str , i ) === '(' ) {
331336 part . push ( acc )
332337 acc = ''
333338 const ext = new AST ( c , part )
@@ -338,7 +343,7 @@ export class AST {
338343 if ( c === '|' ) {
339344 part . push ( acc )
340345 acc = ''
341- parts . push ( part )
346+ ArrayPrototypePush ( parts , part )
342347 part = new AST ( null , ast )
343348 continue
344349 }
@@ -359,11 +364,11 @@ export class AST {
359364 // maybe something else in there.
360365 ast . type = null
361366 ast . #hasMagic = undefined
362- ast . #parts = [ str . substring ( pos - 1 ) ]
367+ ast . #parts = [ StringPrototypeSubstring ( str , pos - 1 ) ]
363368 return i
364369 }
365370
366- static fromGlob ( pattern : string , options : MinimatchOptions = { } ) {
371+ static fromGlob ( pattern : string , options : MinimatchOptions = { __proto__ : null } as MinimatchOptions ) {
367372 const ast = new AST ( null , undefined , options )
368373 AST . #parseAST( pattern , ast , 0 , options )
369374 return ast
@@ -386,13 +391,13 @@ export class AST {
386391 this . #hasMagic ||
387392 ( this . #options. nocase &&
388393 ! this . #options. nocaseMagicOnly &&
389- glob . toUpperCase ( ) !== glob . toLowerCase ( ) )
394+ StringPrototypeToUpperCase ( glob ) !== StringPrototypeToLowerCase ( glob ) )
390395 if ( ! anyMagic ) {
391396 return body
392397 }
393398
394399 const flags = ( this . #options. nocase ? 'i' : '' ) + ( uflag ? 'u' : '' )
395- return Object . assign ( new RegExp ( `^${ re } $` , flags ) , {
400+ return ObjectAssign ( new RegExp ( `^${ re } $` , flags ) , {
396401 _src : re ,
397402 _glob : glob ,
398403 } )
@@ -474,8 +479,8 @@ export class AST {
474479 if ( this . #root === this ) this . #fillNegs( )
475480 if ( ! this . type ) {
476481 const noEmpty = this . isStart ( ) && this . isEnd ( )
477- const src = this . #parts
478- . map ( p => {
482+ const src = ArrayPrototypeJoin (
483+ ArrayPrototypeMap ( this . #parts , ( p : string | AST ) => {
479484 const [ re , _ , hasMagic , uflag ] =
480485 typeof p === 'string'
481486 ? AST . #parseGlob( p , this . #hasMagic, noEmpty )
@@ -484,7 +489,7 @@ export class AST {
484489 this . #uflag = this . #uflag || uflag
485490 return re
486491 } )
487- . join ( '' )
492+ , '' )
488493
489494 let start = ''
490495 if ( this . isStart ( ) ) {
@@ -502,14 +507,14 @@ export class AST {
502507 // and prevent that.
503508 const needNoTrav =
504509 // dots are allowed, and the pattern starts with [ or .
505- ( dot && aps . has ( src . charAt ( 0 ) ) ) ||
510+ ( dot && aps . has ( StringPrototypeCharAt ( src , 0 ) ) ) ||
506511 // the pattern starts with \., and then [ or .
507- ( src . startsWith ( '\\.' ) && aps . has ( src . charAt ( 2 ) ) ) ||
512+ ( src . startsWith ( '\\.' ) && aps . has ( StringPrototypeCharAt ( src , 2 ) ) ) ||
508513 // the pattern starts with \.\., and then [ or .
509- ( src . startsWith ( '\\.\\.' ) && aps . has ( src . charAt ( 4 ) ) )
514+ ( src . startsWith ( '\\.\\.' ) && aps . has ( StringPrototypeCharAt ( src , 4 ) ) )
510515 // no need to prevent dots if it can't match a dot, or if a
511516 // sub-pattern will be preventing it anyway.
512- const needNoDot = ! dot && ! allowDot && aps . has ( src . charAt ( 0 ) )
517+ const needNoDot = ! dot && ! allowDot && aps . has ( StringPrototypeCharAt ( src , 0 ) )
513518
514519 start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''
515520 }
@@ -597,8 +602,9 @@ export class AST {
597602 }
598603
599604 #partsToRegExp( dot : boolean ) {
600- return this . #parts
601- . map ( p => {
605+ return ArrayPrototypeJoin (
606+ ArrayPrototypeFilter (
607+ ArrayPrototypeMap ( this . #parts, ( p : string | AST ) => {
602608 // extglob ASTs should only contain parent ASTs
603609 /* c8 ignore start */
604610 if ( typeof p === 'string' ) {
@@ -610,8 +616,8 @@ export class AST {
610616 this . #uflag = this . #uflag || uflag
611617 return re
612618 } )
613- . filter ( p => ! ( this . isStart ( ) && this . isEnd ( ) ) || ! ! p )
614- . join ( '|' )
619+ , ( p : any ) => ! ( this . isStart ( ) && this . isEnd ( ) ) || ! ! p )
620+ , '|' )
615621 }
616622
617623 static #parseGlob(
@@ -623,7 +629,7 @@ export class AST {
623629 let re = ''
624630 let uflag = false
625631 for ( let i = 0 ; i < glob . length ; i ++ ) {
626- const c = glob . charAt ( i )
632+ const c = StringPrototypeCharAt ( glob , i )
627633 if ( escaping ) {
628634 escaping = false
629635 re += ( reSpecials . has ( c ) ? '\\' : '' ) + c
0 commit comments