Class: RuboCop::Cop::Registry
- Inherits:
-
Object
- Object
- RuboCop::Cop::Registry
- Includes:
- Enumerable
- Defined in:
- lib/rubocop/cop/registry.rb
Overview
Registry that tracks all cops by their badge and department.
Class Attribute Summary collapse
-
.global ⇒ Object
readonly
Returns the value of attribute global.
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#warnings ⇒ Object
readonly
Returns the value of attribute warnings.
Class Method Summary collapse
- .all ⇒ Object
- .qualified_cop?(name) ⇒ Boolean
- .qualified_cop_name(name, origin, warn: true) ⇒ Object
- .reset! ⇒ Object
-
.with_temporary_global(temp_global = global.dup) ⇒ Object
Changes momentarily the global registry Intended for testing purposes.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #contains_cop_matching?(names) ⇒ Boolean
- #cops ⇒ Object
- #cops_for_department(department) ⇒ Object
-
#department?(name) ⇒ Boolean
Checks if given name is department.
- #department_missing?(badge, name) ⇒ Boolean
-
#departments ⇒ Array<Symbol>
List of departments for current cops.
- #disabled(config) ⇒ Object
-
#disabled_names(config) ⇒ Array<String>
private
Returns the names of the disabled cops without loading any of them.
- #dismiss(cop) ⇒ Object
- #each(&block) ⇒ Object
-
#enabled(config) ⇒ Array<Class>
Returns the enabled cop classes, loading lazy-loaded cops only when they are enabled.
- #enabled?(cop, config) ⇒ Boolean
- #enabled_pending_cop?(cop_cfg, config, cop = nil) ⇒ Boolean
- #enlist(cop) ⇒ Object
-
#filter_by_badge(options = {}) ⇒ Registry
private
Returns a new registry containing the cops whose badge satisfies the given block, keeping lazy-loaded cops unloaded.
- #find_by_cop_name(cop_name) ⇒ Class?
-
#find_cops_by_directive(directive) ⇒ Object
When a cop name is given returns a single-element array with the cop class.
- #freeze ⇒ Object
-
#initialize(cops = [], options = {}) ⇒ Registry
constructor
A new instance of Registry.
-
#lazy_load(badge, constant_name) ⇒ Object
Registers a cop by its badge and constant name without loading the class.
- #length ⇒ Object
- #names ⇒ Object
- #names_for_department(department) ⇒ Object
- #print_department_missing_warning(name, path) ⇒ Object
-
#qualified_cop_name(name, path, warn: true) ⇒ String
Convert a user provided cop name into a properly namespaced name.
- #qualify_badge(badge) ⇒ Object
- #select(&block) ⇒ Object
- #sort! ⇒ Object
- #to_h ⇒ Hash{String => Array<Class>}
- #unqualified_cop_names ⇒ Object
- #warnings?(path) ⇒ Boolean
-
#with_department(department) ⇒ Registry
Cops for that specific department.
-
#without_department(department) ⇒ Registry
Cops not for a specific department.
Constructor Details
#initialize(cops = [], options = {}) ⇒ Registry
Returns a new instance of Registry.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/rubocop/cop/registry.rb', line 51 def initialize(cops = [], = {}) @departments = Set.new # Maps each badge to its cop class, or to the fully qualified constant name (a `String`) # when the cop is registered for lazy loading and its file is not loaded yet. # A single insertion-ordered map keeps the registration order stable no matter when # a lazy-loaded cop's file gets loaded, because reassigning an existing key preserves # its position; the cop execution order depends on this order. @cops_by_badge = {} @enrollment_queue = cops @options = @enabled_cache = {}.compare_by_identity @disabled_cache = {}.compare_by_identity @disabled_names_cache = {}.compare_by_identity @warnings = {} end |
Class Attribute Details
.global ⇒ Object (readonly)
Returns the value of attribute global.
338 339 340 |
# File 'lib/rubocop/cop/registry.rb', line 338 def global @global end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
49 50 51 |
# File 'lib/rubocop/cop/registry.rb', line 49 def @options end |
#warnings ⇒ Object (readonly)
Returns the value of attribute warnings.
49 50 51 |
# File 'lib/rubocop/cop/registry.rb', line 49 def warnings @warnings end |
Class Method Details
.all ⇒ Object
22 23 24 |
# File 'lib/rubocop/cop/registry.rb', line 22 def self.all global.without_department(:Test).cops end |
.qualified_cop?(name) ⇒ Boolean
44 45 46 47 |
# File 'lib/rubocop/cop/registry.rb', line 44 def self.qualified_cop?(name) badge = Badge.parse(name) global.qualify_badge(badge).first == badge end |
.qualified_cop_name(name, origin, warn: true) ⇒ Object
26 27 28 |
# File 'lib/rubocop/cop/registry.rb', line 26 def self.qualified_cop_name(name, origin, warn: true) global.qualified_cop_name(name, origin, warn: warn) end |
.reset! ⇒ Object
40 41 42 |
# File 'lib/rubocop/cop/registry.rb', line 40 def self.reset! @global = new end |
.with_temporary_global(temp_global = global.dup) ⇒ Object
Changes momentarily the global registry Intended for testing purposes
32 33 34 35 36 37 38 |
# File 'lib/rubocop/cop/registry.rb', line 32 def self.with_temporary_global(temp_global = global.dup) previous = @global @global = temp_global yield ensure @global = previous end |
Instance Method Details
#==(other) ⇒ Object
290 291 292 |
# File 'lib/rubocop/cop/registry.rb', line 290 def ==(other) cops == other.cops end |
#contains_cop_matching?(names) ⇒ Boolean
138 139 140 |
# File 'lib/rubocop/cop/registry.rb', line 138 def contains_cop_matching?(names) registered_badges.any? { |badge| badge.match_name?(names) } end |
#cops ⇒ Object
222 223 224 225 226 |
# File 'lib/rubocop/cop/registry.rb', line 222 def cops clear_enrollment_queue load_all_lazy_cops @cops_by_badge.values end |
#cops_for_department(department) ⇒ Object
280 281 282 |
# File 'lib/rubocop/cop/registry.rb', line 280 def cops_for_department(department) with_department(department.to_sym).cops end |
#department?(name) ⇒ Boolean
Returns Checks if given name is department.
134 135 136 |
# File 'lib/rubocop/cop/registry.rb', line 134 def department?(name) departments.include?(name.to_sym) end |
#department_missing?(badge, name) ⇒ Boolean
188 189 190 |
# File 'lib/rubocop/cop/registry.rb', line 188 def department_missing?(badge, name) !badge.qualified? && unqualified_cop_names.include?(name) end |
#departments ⇒ Array<Symbol>
Returns list of departments for current cops.
104 105 106 107 |
# File 'lib/rubocop/cop/registry.rb', line 104 def departments clear_enrollment_queue @departments.to_a end |
#disabled(config) ⇒ Object
245 246 247 |
# File 'lib/rubocop/cop/registry.rb', line 245 def disabled(config) @disabled_cache[config] ||= reject { |cop| enabled?(cop, config) } end |
#disabled_names(config) ⇒ Array<String>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the names of the disabled cops without loading any of them.
253 254 255 256 257 258 |
# File 'lib/rubocop/cop/registry.rb', line 253 def disabled_names(config) @disabled_names_cache[config] ||= registered_badges.filter_map do |badge| name = badge.to_s name unless enabled_cop_name?(name, config) end end |
#dismiss(cop) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/rubocop/cop/registry.rb', line 90 def dismiss(cop) dismissed = !@enrollment_queue.delete(cop).nil? # A lazy-loaded cop that was not enlisted yet is dismissed by removing its registration. # Anonymous cop classes cannot have a badge. if !cop.name.nil? && @cops_by_badge[cop.badge].is_a?(String) @cops_by_badge.delete(cop.badge) dismissed = true end raise "Cop #{cop} could not be dismissed" unless dismissed end |
#each(&block) ⇒ Object
306 307 308 |
# File 'lib/rubocop/cop/registry.rb', line 306 def each(&block) cops.each(&block) end |
#enabled(config) ⇒ Array<Class>
Returns the enabled cop classes, loading lazy-loaded cops only when they are enabled.
236 237 238 239 240 241 242 243 |
# File 'lib/rubocop/cop/registry.rb', line 236 def enabled(config) @enabled_cache[config] ||= registered_badges.filter_map do |badge| next unless enabled_cop_name?(badge.to_s, config) cop_or_name = @cops_by_badge[badge] cop_or_name.is_a?(String) ? load_lazy_cop(badge) : cop_or_name end end |
#enabled?(cop, config) ⇒ Boolean
260 261 262 |
# File 'lib/rubocop/cop/registry.rb', line 260 def enabled?(cop, config) enabled_cop_name?(cop.cop_name, config) end |
#enabled_pending_cop?(cop_cfg, config, cop = nil) ⇒ Boolean
265 266 267 268 269 270 271 272 273 |
# File 'lib/rubocop/cop/registry.rb', line 265 def enabled_pending_cop?(cop_cfg, config, cop = nil) return false if @options[:disable_pending_cops] return false unless cop_cfg.fetch('Enabled') == 'pending' return true if @options[:enable_pending_cops] return config.enabled_new_cops? unless cop cop_name = cop.is_a?(String) ? cop : cop.cop_name config.enabled_new_cop?(cop_name) end |
#enlist(cop) ⇒ Object
86 87 88 |
# File 'lib/rubocop/cop/registry.rb', line 86 def enlist(cop) @enrollment_queue << cop end |
#filter_by_badge(options = {}) ⇒ Registry
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new registry containing the cops whose badge satisfies the given block, keeping lazy-loaded cops unloaded.
124 125 126 127 128 129 130 131 |
# File 'lib/rubocop/cop/registry.rb', line 124 def filter_by_badge( = {}) clear_enrollment_queue copy = self.class.new([], ) @cops_by_badge.each do |badge, cop_or_name| copy.add_entry(badge, cop_or_name) if yield(badge) end copy end |
#find_by_cop_name(cop_name) ⇒ Class?
312 313 314 315 316 317 318 |
# File 'lib/rubocop/cop/registry.rb', line 312 def find_by_cop_name(cop_name) clear_enrollment_queue badge = Badge.parse(cop_name) cop_or_name = @cops_by_badge[badge] cop_or_name.is_a?(String) ? load_lazy_cop(badge) : cop_or_name end |
#find_cops_by_directive(directive) ⇒ Object
When a cop name is given returns a single-element array with the cop class. When a department name is given returns an array with all the cop classes for that department.
323 324 325 326 |
# File 'lib/rubocop/cop/registry.rb', line 323 def find_cops_by_directive(directive) cop = find_by_cop_name(directive) cop ? [cop] : cops_for_department(directive) end |
#freeze ⇒ Object
328 329 330 331 332 333 |
# File 'lib/rubocop/cop/registry.rb', line 328 def freeze clear_enrollment_queue load_all_lazy_cops unqualified_cop_names # build cache super end |
#lazy_load(badge, constant_name) ⇒ Object
Registers a cop by its badge and constant name without loading the class.
The constant is resolved (loading the cop's file through autoload) only
when the cop class itself is needed.
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rubocop/cop/registry.rb', line 75 def lazy_load(badge, constant_name) badge = Badge.parse(badge) if badge.is_a?(String) # File any cops enlisted earlier first, so that the registration # order follows the call order. clear_enrollment_queue @departments << badge.department @cops_by_badge[badge] = constant_name unless @cops_by_badge[badge].is_a?(Class) end |
#length ⇒ Object
228 229 230 231 |
# File 'lib/rubocop/cop/registry.rb', line 228 def length clear_enrollment_queue @cops_by_badge.size end |
#names ⇒ Object
275 276 277 278 |
# File 'lib/rubocop/cop/registry.rb', line 275 def names clear_enrollment_queue @cops_by_badge.keys.map(&:to_s) end |
#names_for_department(department) ⇒ Object
284 285 286 287 288 |
# File 'lib/rubocop/cop/registry.rb', line 284 def names_for_department(department) department = department.to_sym registered_badges.filter_map { |badge| badge.to_s if badge.department == department } end |
#print_department_missing_warning(name, path) ⇒ Object
192 193 194 195 196 197 198 |
# File 'lib/rubocop/cop/registry.rb', line 192 def print_department_missing_warning(name, path) = "no department given for #{name}." if path.end_with?('.rb') += ' Run `rubocop -a --only Migration/DepartmentName` to fix.' end emit_warning(path, ) end |
#qualified_cop_name(name, path, warn: true) ⇒ String
Emits a warning if the provided name has an incorrect namespace
Convert a user provided cop name into a properly namespaced name
174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/rubocop/cop/registry.rb', line 174 def qualified_cop_name(name, path, warn: true) badge = Badge.parse(name) print_department_missing_warning(name, path) if warn && department_missing?(badge, name) return name if registered?(badge) potential_badges = qualify_badge(badge) case potential_badges.size when 0 then name # No namespace found. Deal with it later in caller. when 1 then resolve_badge(badge, potential_badges.first, path, warn: warn) else raise AmbiguousCopName.new(badge, path, potential_badges) end end |
#qualify_badge(badge) ⇒ Object
208 209 210 211 212 213 |
# File 'lib/rubocop/cop/registry.rb', line 208 def qualify_badge(badge) clear_enrollment_queue @departments .map { |department| badge.with_department(department) } .select { |potential_badge| registered?(potential_badge) } end |
#select(&block) ⇒ Object
302 303 304 |
# File 'lib/rubocop/cop/registry.rb', line 302 def select(&block) cops.select(&block) end |
#sort! ⇒ Object
294 295 296 297 298 299 300 |
# File 'lib/rubocop/cop/registry.rb', line 294 def sort! clear_enrollment_queue load_all_lazy_cops @cops_by_badge = @cops_by_badge.sort_by { |badge, _cop| badge.cop_name }.to_h self end |
#to_h ⇒ Hash{String => Array<Class>}
216 217 218 219 220 |
# File 'lib/rubocop/cop/registry.rb', line 216 def to_h clear_enrollment_queue load_all_lazy_cops @cops_by_badge.to_h { |_badge, cop| [cop.cop_name, [cop]] } end |
#unqualified_cop_names ⇒ Object
200 201 202 203 204 205 206 |
# File 'lib/rubocop/cop/registry.rb', line 200 def unqualified_cop_names clear_enrollment_queue @unqualified_cop_names ||= @cops_by_badge.keys.to_set do |badge| File.basename(badge.to_s) end << 'RedundantCopDisableDirective' end |
#warnings?(path) ⇒ Boolean
341 342 343 |
# File 'lib/rubocop/cop/registry.rb', line 341 def warnings?(path) @warnings[path] end |
#with_department(department) ⇒ Registry
Returns Cops for that specific department.
110 111 112 |
# File 'lib/rubocop/cop/registry.rb', line 110 def with_department(department) filter_by_badge { |badge| badge.department == department } end |
#without_department(department) ⇒ Registry
Returns Cops not for a specific department.
115 116 117 |
# File 'lib/rubocop/cop/registry.rb', line 115 def without_department(department) filter_by_badge { |badge| badge.department != department } end |