@@ -336,50 +336,6 @@ func registerAllCoreEslintRules() {
336336 }
337337}
338338
339- // isFileIgnored checks if a file is matched by ignore patterns, evaluated sequentially.
340- // Later patterns override earlier ones; a `!` prefix negates (re-includes) a previously
341- // ignored file. This aligns with ESLint v10's ignore semantics.
342- //
343- // For directory-level blocking (dir/** prevents traversal entirely), use isDirPathBlocked.
344- func isFileIgnored (filePath string , ignorePatterns []string , cwd string ) bool {
345- if cwd == "" {
346- return isFileIgnoredSimple (filePath , ignorePatterns )
347- }
348-
349- // Normalize the file path relative to cwd
350- normalizedPath := normalizePath (filePath , cwd )
351- unixPath := strings .ReplaceAll (normalizedPath , "\\ " , "/" )
352-
353- // Evaluate patterns sequentially. Later patterns override earlier ones.
354- // A `!` prefix negates (re-includes) a previously ignored file.
355- // This aligns with ESLint v10's ignore semantics.
356- ignored := false
357- for _ , pattern := range ignorePatterns {
358- negated := false
359- if strings .HasPrefix (pattern , "!" ) {
360- negated = true
361- pattern = pattern [1 :]
362- }
363-
364- normalizedPattern := normalizePattern (pattern )
365-
366- // Match against the relative path only. Do NOT fall back to the
367- // absolute filePath — patterns with **/ prefix (e.g., **/tmp/**/*)
368- // would incorrectly match system directory names in the absolute path
369- // (e.g., /tmp/ on Linux/macOS).
370- matched := matchGlob (normalizedPattern , normalizedPath )
371- // Windows path separator fallback.
372- if ! matched && unixPath != normalizedPath {
373- matched = matchGlob (normalizedPattern , unixPath )
374- }
375-
376- if matched {
377- ignored = ! negated
378- }
379- }
380- return ignored
381- }
382-
383339// normalizePattern cleans up a glob pattern to match paths produced by normalizePath.
384340// normalizePath uses tspath.NormalizePath on file paths (strips leading "./", collapses
385341// "/./", resolves ".."), so patterns must undergo the same transformation.
@@ -389,24 +345,16 @@ func matchGlob(pattern, path string) bool {
389345 return err == nil && m
390346}
391347
392- // isFileLevelPattern returns true if the pattern only matches files (not directories).
393- // File-level patterns end with /**/* or /* (but not /**).
394- // These do NOT block directory traversal in ESLint v10's isDirectoryIgnored.
395- func isFileLevelPattern (pattern string ) bool {
396- return strings .HasSuffix (pattern , "/**/*" ) ||
397- (strings .HasSuffix (pattern , "/*" ) && ! strings .HasSuffix (pattern , "/**" ))
398- }
399-
400348func normalizePattern (pattern string ) string {
401349 return tspath .NormalizePath (pattern )
402350}
403351
404352// isDirBlockedByIgnores checks if the file's directory is blocked by a
405- // directory-level ignore pattern (e.g., `dir/**`). File-level patterns
406- // (`dir/**/*`, `dir/*`) and negation patterns are skipped.
407- // This aligns with ESLint v10: `dir/**` blocks directory traversal entirely,
408- // and `!` negation cannot undo it.
409- func isDirBlockedByIgnores (filePath string , ignorePatterns []string , cwd string ) bool {
353+ // directory-level ignore pattern (e.g., `dir/**`). File-level patterns and
354+ // negation patterns are excluded (by Kind) in isDirAbsolutelyBlocked. This
355+ // aligns with ESLint v10: `dir/**` blocks directory traversal entirely, and
356+ // `!` negation cannot undo it.
357+ func isDirBlockedByIgnores (filePath string , patterns []IgnorePattern , cwd string ) bool {
410358 var dirPath string
411359 if cwd != "" {
412360 dirPath = normalizePath (tspath .GetDirectoryPath (filePath ), cwd )
@@ -418,39 +366,7 @@ func isDirBlockedByIgnores(filePath string, ignorePatterns []string, cwd string)
418366 if dirPath == "" || dirPath == "." {
419367 return false
420368 }
421- return isDirPathBlocked (dirPath , ignorePatterns )
422- }
423-
424- // isDirPathBlocked checks if a directory path is blocked by any directory-level ignore
425- // pattern. Shared between GetConfigForFile and DiscoverGapFiles.
426- //
427- // A directory is blocked if a pattern matches the path itself or any parent segment.
428- // For example, pattern "dir1/**" blocks "dir1", "dir1/sub", and "dir1/sub/deep".
429- // File-level patterns (ending with /**/* or /*) and negation (!) patterns are skipped —
430- // directory blocking is absolute and cannot be negated.
431- func isDirPathBlocked (dirPath string , ignorePatterns []string ) bool {
432- for _ , pattern := range ignorePatterns {
433- if pattern == "" || strings .HasPrefix (pattern , "!" ) {
434- continue
435- }
436- if isFileLevelPattern (pattern ) {
437- continue
438- }
439-
440- normalizedPattern := normalizePattern (pattern )
441-
442- if matchGlob (normalizedPattern , dirPath ) || matchGlob (normalizedPattern , dirPath + "/x" ) {
443- return true
444- }
445- segments := strings .Split (dirPath , "/" )
446- for i := 1 ; i < len (segments ); i ++ {
447- partial := strings .Join (segments [:i ], "/" )
448- if matchGlob (normalizedPattern , partial ) || matchGlob (normalizedPattern , partial + "/x" ) {
449- return true
450- }
451- }
452- }
453- return false
369+ return isDirAbsolutelyBlocked (dirPath , patterns )
454370}
455371
456372// normalizePath converts file path to be relative to cwd for consistent matching
@@ -461,23 +377,6 @@ func normalizePath(filePath, cwd string) string {
461377 }))
462378}
463379
464- // isFileIgnoredSimple provides fallback matching when cwd is unavailable
465- func isFileIgnoredSimple (filePath string , ignorePatterns []string ) bool {
466- ignored := false
467- for _ , pattern := range ignorePatterns {
468- negated := false
469- if strings .HasPrefix (pattern , "!" ) {
470- negated = true
471- pattern = pattern [1 :]
472- }
473- normalizedPattern := normalizePattern (pattern )
474- if matched , err := doublestar .Match (normalizedPattern , filePath ); err == nil && matched {
475- ignored = ! negated
476- }
477- }
478- return ignored
479- }
480-
481380// MergedConfig is the final computed configuration for a single file
482381type MergedConfig struct {
483382 Rules map [string ]* RuleConfig
@@ -546,8 +445,10 @@ func (config RslintConfig) GetConfigForFile(filePath string, cwd string) *Merged
546445 continue
547446 }
548447
549- // 3. Entry-level ignores
550- if isFileIgnored (filePath , entry .Ignores , cwd ) {
448+ // 3. Entry-level ignores. Parsed per entry; entry.Ignores is usually
449+ // empty (ESLint configs put ignores in a dedicated global-ignore entry),
450+ // so ParseIgnorePatterns returns nil and this is free in the common case.
451+ if isFileIgnored (filePath , ParseIgnorePatterns (entry .Ignores ), cwd ) {
551452 continue
552453 }
553454
0 commit comments