Class: Shirobai::Cop::Lint::AmbiguousBlockAssociation
- Inherits:
-
RuboCop::Cop::Base
- Object
- RuboCop::Cop::Base
- Shirobai::Cop::Lint::AmbiguousBlockAssociation
- Extended by:
- RuboCop::Cop::AutoCorrector
- Defined in:
- lib/shirobai/cop/lint/ambiguous_block_association.rb
Overview
Drop-in Rust reimplementation of ‘Lint/AmbiguousBlockAssociation`.
Detection and autocorrect both happen in Rust; Ruby turns the byte offsets handed back into offenses and a ‘remove + insert_before + insert_after` corrector trio (matching stock’s ‘wrap_in_parentheses` byte-for-byte).
‘AllowedMethods` is taken from the cop’s own config (verbatim string entries; ‘Regexp` entries are filtered out and force the standalone fallback). `AllowedPatterns` (regexp) is matched in Ruby: the wrapper walks every block-bearing call candidate’s INNER sender source and collects the strings that match any pattern, then hands the list to the standalone Rust entry as ‘allowed_inner_sources` so the Rust path can drop them by exact-bytes lookup. Without `AllowedPatterns` the bundle path is taken (no regexp work).
Constant Summary collapse
- MSG =
"Parenthesize the param `%<param>s` to make sure that the " \ "block will be associated with the `%<method>s` method " \ "call."
Class Method Summary collapse
- .badge ⇒ Object
-
.bundle_args(config) ⇒ Object
Returns ‘[allowed_methods]`.
- .cop_name ⇒ Object
Instance Method Summary collapse
-
#bundle_eligible? ⇒ Boolean
Bundle path is OK only when ‘AllowedMethods` has no regexp AND `AllowedPatterns` is empty (regexp matching against inner-sender source is done in Ruby; the bundle path does not carry the pre-applied list).
- #on_new_investigation ⇒ Object
Class Method Details
.badge ⇒ Object
29 |
# File 'lib/shirobai/cop/lint/ambiguous_block_association.rb', line 29 def self.badge = RuboCop::Cop::Badge.parse(cop_name) |
.bundle_args(config) ⇒ Object
Returns ‘[allowed_methods]`. `allowed_methods` mirrors the stock `AllowedMethods` mixin: regexp entries filtered out (any regexp forces the wrapper into the standalone path via `bundle_eligible?`).
34 35 36 37 38 39 |
# File 'lib/shirobai/cop/lint/ambiguous_block_association.rb', line 34 def self.bundle_args(config) cfg = config.for_badge(badge) allowed = Array(cfg.fetch("AllowedMethods", [])) names = allowed.reject { |e| e.is_a?(Regexp) }.map(&:to_s) [names] end |
.cop_name ⇒ Object
28 |
# File 'lib/shirobai/cop/lint/ambiguous_block_association.rb', line 28 def self.cop_name = "Lint/AmbiguousBlockAssociation" |
Instance Method Details
#bundle_eligible? ⇒ Boolean
Bundle path is OK only when ‘AllowedMethods` has no regexp AND `AllowedPatterns` is empty (regexp matching against inner-sender source is done in Ruby; the bundle path does not carry the pre-applied list).
45 46 47 48 49 50 |
# File 'lib/shirobai/cop/lint/ambiguous_block_association.rb', line 45 def bundle_eligible? cfg = cop_config allowed = Array(cfg.fetch("AllowedMethods", [])) patterns = Array(cfg.fetch("AllowedPatterns", [])) allowed.none? { |e| e.is_a?(Regexp) } && patterns.empty? end |
#on_new_investigation ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/shirobai/cop/lint/ambiguous_block_association.rb', line 52 def on_new_investigation buffer = processed_source.buffer off = SourceOffsets.for(processed_source.raw_source) fetch_offenses.each do |start_offset, end_offset, param_start, param_end, inner_send_start, inner_send_end, ac_open_start, ac_open_end, ac_close_pos| range = Parser::Source::Range.new(buffer, off[start_offset], off[end_offset]) param_range = Parser::Source::Range.new(buffer, off[param_start], off[param_end]) inner_range = Parser::Source::Range.new(buffer, off[inner_send_start], off[inner_send_end]) = format(MSG, param: param_range.source, method: inner_range.source) add_offense(range, message: ) do |corrector| open_range = Parser::Source::Range.new(buffer, off[ac_open_start], off[ac_open_end]) close_range = Parser::Source::Range.new(buffer, off[ac_close_pos], off[ac_close_pos]) corrector.remove(open_range) corrector.insert_before(open_range, "(") corrector.insert_after(close_range, ")") end end end |