Class: Shirobai::Cop::Style::BlockDelimiters

Inherits:
RuboCop::Cop::Base
  • Object
show all
Extended by:
RuboCop::Cop::AutoCorrector
Includes:
RuboCop::Cop::AllowedMethods, RuboCop::Cop::AllowedPattern
Defined in:
lib/shirobai/cop/style/block_delimiters.rb

Overview

Drop-in Rust reimplementation of ‘Style/BlockDelimiters`.

Rust walks the AST once, replicating stock’s callback order: ‘on_send` registers every block inside unparenthesized call arguments as ignored, and `on_block` (calls, `super`, lambda literals, numbered/`it` blocks) judges the configured style (all four `EnforcedStyle`s, the `require_do_end?` rescue quirk, `BracesRequiredMethods`, `AllowedMethods`, and the parser-parent emulation behind `semantic`). Corrections come back as the exact corrector call sequence (`replace`/`remove`/`insert_before`/`insert_after`/`wrap`), including the comment relocation and the `begin`..`end` wrapping of rescue bodies.

The cop instance accumulates the ignored block ranges across autocorrect iterations, mirroring ‘IgnoredNode`’s ‘@ignored_nodes` (which is never reset between investigations on one instance): blocks ignored by `on_send` unconditionally, offense blocks only when the offense is enabled — which is why the ignore lands inside the `add_offense` block, exactly like stock’s ‘ignore_node`.

The bundled / resolved path assumes every offense is enabled. When Rust reports that a candidate was suppressed solely by another offense’s range (‘has_conditional` — its real fate depends on `rubocop:disable` directives), or when `AllowedPatterns` need regex matching, the wrapper replays the raw event stream through `add_offense`, which natively reproduces the disable semantics.

Constant Summary collapse

STYLES =
{
  "line_count_based" => 0,
  "semantic" => 1,
  "braces_for_chaining" => 2,
  "always_braces" => 3
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.autocorrect_incompatible_withObject

‘Style/RedundantBegin` rewrites the same `begin` bodies the do-end-to-braces correction wraps.



42
43
44
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 42

def self.autocorrect_incompatible_with
  [RuboCop::Cop::Style::RedundantBegin]
end

.badgeObject



38
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 38

def self.badge = RuboCop::Cop::Badge.parse("Style/BlockDelimiters")

.bundle_args(config) ⇒ Object

Packed args for the bundled run: ‘[nums, lists]` with `nums = [style, AllowBracesOnProceduralOneLiners]` and `lists = [ProceduralMethods, FunctionalMethods, AllowedMethods, BracesRequiredMethods]`.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 57

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  [
    [
      STYLES.fetch(cop_config["EnforcedStyle"] || "line_count_based"),
      cop_config["AllowBracesOnProceduralOneLiners"] ? 1 : 0
    ],
    [
      Array(cop_config["ProceduralMethods"]).map(&:to_s),
      Array(cop_config["FunctionalMethods"]).map(&:to_s),
      Shirobai::Cop.allowed_methods_config(cop_config).map(&:to_s),
      Array(cop_config.fetch("BracesRequiredMethods", [])).map(&:to_s)
    ]
  ]
end

.cop_nameObject



37
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 37

def self.cop_name = "Style/BlockDelimiters"

Instance Method Details

#on_new_investigationObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 73

def on_new_investigation
  @ignored_ranges ||= []
  return replay_events if !allowed_patterns.empty?

  offenses, send_ignores, has_conditional = resolved_result
  # A candidate was suppressed solely by another offense's range: its
  # real fate depends on disable directives, so replay exactly.
  return replay_events if has_conditional

  buffer = processed_source.buffer
  off = SourceOffsets.for(processed_source.raw_source)
  send_ignores.each { |s, e| @ignored_ranges << [s, e] }
  offenses.each do |ts, te, bs, be, message, ops|
    range = Parser::Source::Range.new(buffer, off[ts], off[te])
    add_offense(range, message: message) do |corrector|
      apply_ops(corrector, buffer, off, ops)
      # `ignore_node` runs only when the offense is enabled; the
      # ranges stay BYTE offsets (they go back to Rust).
      @ignored_ranges << [bs, be]
    end
  end
end