Module: Shirobai::Cop::Rails::IndexMethodSupport
Overview
Shared Architecture-B harness for Rails/IndexBy and Rails/IndexWith.
Both stock cops share the RuboCop::Cop::IndexMethod mixin, whose
autocorrect is heavy parser-AST geometry (strip prefix/suffix, rename
the method, rewrite block args, replace the body) plus cross-offense
ignore_node state. Rather than reproduce any of that, Rust nominates
candidate nodes (the four transform-to-hash shapes) once on the shared
walk; this module relocates each parser node (Shirobai::NodeLocator)
and runs stock's own handle_possible_offense / correction machinery
VERBATIM, so detection and -A bytes match stock by construction.
Stock's node callbacks (on_block / on_send / on_csend, plus the
on_numblock / on_itblock aliases) are undefined so the Commissioner
never dispatches them per node; the same bodies are re-exposed as
investigate_block / investigate_send / investigate_csend, driven
only from on_new_investigation. The candidate list is a superset —
the empty-hash arg, block arity, key/value identity and Ruby-version
gate are all re-checked by the stock matchers the cop still owns.
ignore_node is stock's real one (range/heredoc based, per cop
instance): candidates arrive in pre-order (an outer node before any it
contains), so a nested transform's inner offense is suppressed for
autocorrect exactly as stock does. IndexBy and IndexWith are separate
cop instances with separate @ignored_nodes, matching stock.
Class Method Summary collapse
Instance Method Summary collapse
-
#investigate_block(node) ⇒ Object
--- stock
IndexMethod#on_block/on_send/on_csend, copied verbatim (rubocop-rails 2.35.5) and renamed so they are not node callbacks. - #investigate_csend(node) ⇒ Object
- #investigate_send(node) ⇒ Object
- #on_new_investigation ⇒ Object
Class Method Details
.included(base) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/shirobai/cop/rails/index_method_support.rb', line 31 def self.included(base) # Pull in stock's `Captures` / `Autocorrection` structs and the # private glue (`handle_possible_offense`, `extract_captures`, # `prepare_correction`, `execute_correction`), then drop the public # node callbacks so only `on_new_investigation` drives the cop. base.include RuboCop::Cop::IndexMethod base.include Shirobai::Cop::BundleEligible %i[on_block on_numblock on_itblock on_send on_csend].each do |m| base.send(:undef_method, m) if base.method_defined?(m) end end |
Instance Method Details
#investigate_block(node) ⇒ Object
--- stock IndexMethod#on_block / on_send / on_csend, copied
verbatim (rubocop-rails 2.35.5) and renamed so they are not node
callbacks. Every on_bad_* matcher and the private glue are the
included stock code.
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/shirobai/cop/rails/index_method_support.rb', line 69 def investigate_block(node) on_bad_each_with_object(node) do |*match| handle_possible_offense(node, match, 'each_with_object') end return if target_ruby_version < 2.6 on_bad_to_h(node) do |*match| handle_possible_offense(node, match, 'to_h { ... }') end end |
#investigate_csend(node) ⇒ Object
91 92 93 94 95 |
# File 'lib/shirobai/cop/rails/index_method_support.rb', line 91 def investigate_csend(node) on_bad_map_to_h(node) do |*match| handle_possible_offense(node, match, 'map { ... }.to_h') end end |
#investigate_send(node) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/shirobai/cop/rails/index_method_support.rb', line 81 def investigate_send(node) on_bad_map_to_h(node) do |*match| handle_possible_offense(node, match, 'map { ... }.to_h') end on_bad_hash_brackets_map(node) do |*match| handle_possible_offense(node, match, 'Hash[map { ... }]') end end |
#on_new_investigation ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/shirobai/cop/rails/index_method_support.rb', line 43 def on_new_investigation ranges = resolved_candidates return if ranges.nil? || ranges.empty? source = bundle_eligible? ? processed_source.raw_source : processed_source.buffer.source off = SourceOffsets.for(source) keys = ranges.map { |(start, fin)| [off[start], off[fin]] } located = Shirobai::NodeLocator.locate(processed_source, keys) keys.each do |key| node = located[key] next unless node case node.type when :block, :numblock, :itblock then investigate_block(node) when :send then investigate_send(node) when :csend then investigate_csend(node) end end end |