Class: Shirobai::Cop::RSpec::ScatteredSetup

Inherits:
RuboCop::Cop::Base
  • Object
show all
Extended by:
RuboCop::Cop::AutoCorrector
Includes:
RuboCop::Cop::RSpec::FinalEndLocation, RuboCop::Cop::RSpec::RepeatedItems, RuboCop::Cop::RangeHelp, RuboCop::RSpec::Language, BundleEligible
Defined in:
lib/shirobai/cop/rspec/scattered_setup.rb

Overview

Drop-in Rust reimplementation of RSpec/ScatteredSetup (rubocop-rspec 3.10.2).

Architecture B: Rust identifies example-group blocks on the shared walk; the Ruby wrapper locates the parser node via NodeLocator and runs stock's detection logic VERBATIM.

Detection depends on RuboCop::RSpec::ExampleGroup.new(node).hooks which walks the parser AST to enumerate hooks, filters by inside_class_method?, knowable_scope?, and hook name. AC is body-merge manipulation with heredoc-aware final_end_location. The RepeatedItems grouping and the Hook wrapper's [name, scope, metadata] key are parser-AST-shaped.

Constant Summary collapse

MSG =
'Do not define multiple `%<hook_name>s` hooks in the same ' \
'example group (also defined on %<lines>s).'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



31
# File 'lib/shirobai/cop/rspec/scattered_setup.rb', line 31

def self.badge = RuboCop::Cop::Badge.parse(cop_name)

.bundle_args(_config) ⇒ Object

Config-less (the segment's role lists cover everything).



34
35
36
# File 'lib/shirobai/cop/rspec/scattered_setup.rb', line 34

def self.bundle_args(_config)
  []
end

.cop_nameObject



30
# File 'lib/shirobai/cop/rspec/scattered_setup.rb', line 30

def self.cop_name = "RSpec/ScatteredSetup"

Instance Method Details

#on_new_investigationObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/shirobai/cop/rspec/scattered_setup.rb', line 38

def on_new_investigation
  super
  RuboCop::RSpec::Language.config = config["RSpec"]["Language"]

  ranges = resolved_ranges
  return if ranges.empty?

  source = bundle_eligible? ? processed_source.raw_source : processed_source.buffer.source
  off = SourceOffsets.for(source)
  located = locate_blocks(ranges, off)

  ranges.each do |(start, fin)|
    node = located[[off[start], off[fin]]]
    next unless node

    process_candidate(node)
  end
end