@@ -42,44 +42,25 @@ export function isUnboundedSearchGlob(pattern: string): boolean {
4242 return ! hasLiteralBefore ( pattern . slice ( 0 , firstRecursive ) ) ;
4343}
4444
45- // True when the pre-`**` prefix collapses to a real, name-bearing directory
46- // that anchors the walk away from the workspace root. The prefix is split on
47- // `/` and collapsed left-to-right on a stack: `.` and empty segments are
48- // skipped and `..` pops the preceding segment. A segment of only `*` wildcards
49- // is pushed as a non-name pin (it occupies a slot but cannot anchor the walk);
50- // the first surviving name-bearing segment is the pin. A prefix whose collapse
51- // runs the stack empty (the pattern reaches the root, e.g. `a/../**`) or where
52- // a `..` pops above the root (`src/../../**` escapes the workspace) leaves no
53- // literal pin, so the recursion is a whole-tree walk. A leading separator or
54- // dot-relative step (`/`, `./src/**`) likewise never pins to a real boundary.
45+ // True when the pre-`**` prefix names a real directory that anchors the walk
46+ // away from the root. Leading root-relative notation (`.`/`..`/empty) does not
47+ // pin; interior `.`/`..`/empty segments collapse first, so only a surviving
48+ // name segment counts.
5549function hasLiteralBefore ( prefix : string ) : boolean {
5650 const segments = prefix . split ( "/" ) ;
57- // A leading separator, dot, or dotdot step is root-relative notation that
58- // does not pin to a concrete boundary, even when a name follows (`./src/**`
59- // still walks from the root). `*/src/**` is unaffected: `*` is not a `..`.
6051 if ( segments [ 0 ] === "" || segments [ 0 ] === "." || segments [ 0 ] === ".." ) {
6152 return false ;
6253 }
63- // Stack of surviving segments (true = name-bearing pin). `.`/empty are
64- // skipped; `..` pops the top; all-wildcard runs push a non-name slot.
65- const stack : boolean [ ] = [ ] ;
54+ const names : string [ ] = [ ] ;
6655 for ( const segment of segments ) {
67- if ( segment . length === 0 || segment === "." ) continue ;
56+ if ( segment === "" || segment === "." ) continue ;
6857 if ( segment === ".." ) {
69- if ( stack . length === 0 ) return false ; // pop above the workspace root
70- stack . pop ( ) ;
58+ names . pop ( ) ;
7159 continue ;
7260 }
73- let isName = false ;
74- for ( const char of segment ) {
75- if ( char !== "*" ) {
76- isName = true ;
77- break ;
78- }
79- }
80- stack . push ( isName ) ;
61+ names . push ( segment ) ;
8162 }
82- return stack . some ( Boolean ) ; // at least one name-bearing pin survives
63+ return names . some ( ( segment ) => [ ... segment ] . some ( ( char ) => char !== "*" ) ) ;
8364}
8465
8566// The raw path argument resolved against the session root: omitted, empty,
0 commit comments