Class: Shirobai::Cop::Metrics::BlockNesting

Inherits:
RuboCop::Cop::Base
  • Object
show all
Extended by:
RuboCop::ExcludeLimit
Defined in:
lib/shirobai/cop/metrics/block_nesting.rb

Overview

Drop-in Rust reimplementation of ‘Metrics/BlockNesting`.

Rust walks the AST tracking the running nesting level, applies the ‘CountBlocks` / `CountModifierForms` flags and returns the reportable offense ranges plus the deepest level that exceeded `Max`. Ruby keeps the `ExcludeLimit` bookkeeping (`self.max =`) and registers the offenses. Offenses come from the per-file bundled run (`Shirobai::Dispatch`); the config derivation is purely config-driven, so this cop is always bundle-eligible.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



21
# File 'lib/shirobai/cop/metrics/block_nesting.rb', line 21

def self.badge = RuboCop::Cop::Badge.parse("Metrics/BlockNesting")

.bundle_args(config) ⇒ Object

Packed args for the bundled run: ‘[max, count_blocks, count_modifier_forms]`. `Max` defaults to 3 (default.yml) so a config that does not mention this cop still packs cleanly; the computed slice is discarded in that case.



27
28
29
30
31
32
33
34
# File 'lib/shirobai/cop/metrics/block_nesting.rb', line 27

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  [
    cop_config["Max"] || 3,
    !!cop_config.fetch("CountBlocks", false),
    !!cop_config.fetch("CountModifierForms", false)
  ]
end

.cop_nameObject



20
# File 'lib/shirobai/cop/metrics/block_nesting.rb', line 20

def self.cop_name = "Metrics/BlockNesting"

Instance Method Details

#on_new_investigationObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/shirobai/cop/metrics/block_nesting.rb', line 36

def on_new_investigation
  return if processed_source.blank?

  max = bundle_args[0]
  offenses, deepest = Dispatch.offenses_for(processed_source, config, :block_nesting)
  return if offenses.empty?

  self.max = deepest
  message = "Avoid more than #{max} levels of block nesting."
  off = SourceOffsets.for(processed_source.raw_source)
  offenses.each do |start, fin|
    range = Parser::Source::Range.new(processed_source.buffer, off[start], off[fin])
    add_offense(range, message: message)
  end
end