123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::FilePatterns Private

Relationships & Source Files
Inherits: Object
Defined in: lib/rubocop/file_patterns.rb

Overview

A wrapper around patterns array to perform optimized search.

For projects with a large set of rubocop todo files, most items in Exclude/Include are exact file names. It is wasteful to linearly check the list of patterns over and over to check if the file is relevant to the cop.

This class partitions an array of patterns into a set of exact match strings and the rest of the patterns. This way we can firstly do a cheap check in the set and then proceed via the costly patterns check, if needed.

Class Method Summary

Instance Method Summary

Constructor Details

.new(patterns) ⇒ FilePatterns

[ GitHub ]

  
# File 'lib/rubocop/file_patterns.rb', line 21

def initialize(patterns)
  @strings = Set.new
  @patterns = []
  @match_cache = {}
  partition_patterns(patterns)
end

Class Method Details

.from(patterns)

[ GitHub ]

  
# File 'lib/rubocop/file_patterns.rb', line 17

def self.from(patterns)
  @cache[patterns] ||= new(patterns)
end

Instance Method Details

#match?(path) ⇒ Boolean

[ GitHub ]

  
# File 'lib/rubocop/file_patterns.rb', line 28

def match?(path)
  # `FilePatterns.from` memoizes one instance per pattern array (by identity),
  # so this cache is shared across every cop using the same Include/Exclude
  # list. Patterns are immutable within a run, so caching by path is safe.
  cached = @match_cache[path]
  return cached unless cached.nil?

  @match_cache[path] =
    @strings.include?(path) || @patterns.any? { |pattern| PathUtil.match_path?(pattern, path) }
end

#partition_patterns(patterns) (private)

[ GitHub ]

  
# File 'lib/rubocop/file_patterns.rb', line 41

def partition_patterns(patterns)
  patterns.each do |pattern|
    if pattern.is_a?(String) && !pattern.match?(/[*{\[?]/)
      @strings << pattern
    else
      @patterns << pattern
    end
  end
end