Class: Shirobai::Cop::Layout::MultilineMethodCallBraceLayout

Inherits:
RuboCop::Cop::Base
  • Object
show all
Extended by:
RuboCop::Cop::AutoCorrector
Includes:
RuboCop::Cop::ConfigurableEnforcedStyle
Defined in:
lib/shirobai/cop/layout/multiline_method_call_brace_layout.rb

Overview

Drop-in Rust reimplementation of ‘Layout/MultilineMethodCallBraceLayout`.

Rust walks the AST once, classifies every parenthesized ‘send` / `csend` by the open/close line layout per `EnforcedStyle` (`symmetrical`, `new_line`, `same_line`), and returns the close `)` offense range, the message-code (`SAME_LINE` / `NEW_LINE` / `ALWAYS_NEW_LINE` / `ALWAYS_SAME_LINE`), the send node’s ‘source_range.begin_pos` and a `correctable` flag (false when stock’s ‘new_line_needed_before_closing_brace?` fires — comment after the last element AND the call is chained / an argument). Ruby builds the offense, re-resolves the parser-gem node from `processed_source.ast.each_node` (single linear walk per offense — autocorrect-eligible offenses per file are tiny in real corpora) and delegates the autocorrect to stock’s ‘MultilineLiteralBraceCorrector` so the byte-exact behaviour is preserved (heredoc-chain relocation, comment-block reflow, trailing commas).

Constant Summary collapse

STYLES =
{ "symmetrical" => 0, "new_line" => 1, "same_line" => 2 }.freeze
SAME_LINE_MESSAGE =

Re-export the stock message constants so vendor specs that read ‘described_class::SAME_LINE_MESSAGE` etc. resolve them on the wrapper (the shared examples are run with `described_class` == this class).

RuboCop::Cop::Layout::MultilineMethodCallBraceLayout::SAME_LINE_MESSAGE
NEW_LINE_MESSAGE =
RuboCop::Cop::Layout::MultilineMethodCallBraceLayout::NEW_LINE_MESSAGE
ALWAYS_NEW_LINE_MESSAGE =
RuboCop::Cop::Layout::MultilineMethodCallBraceLayout::ALWAYS_NEW_LINE_MESSAGE
ALWAYS_SAME_LINE_MESSAGE =
RuboCop::Cop::Layout::MultilineMethodCallBraceLayout::ALWAYS_SAME_LINE_MESSAGE
MESSAGES =
[
  SAME_LINE_MESSAGE,
  NEW_LINE_MESSAGE,
  ALWAYS_NEW_LINE_MESSAGE,
  ALWAYS_SAME_LINE_MESSAGE
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



44
# File 'lib/shirobai/cop/layout/multiline_method_call_brace_layout.rb', line 44

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

.bundle_args(config) ⇒ Object

Packed args for the bundled run: ‘[[style], []]`. Unknown styles default to symmetrical (0); stock raises `Unknown EnforcedStyle` lazily from `ConfigurableEnforcedStyle#style`, so we surface the same error before the bundle run if the configured value is invalid.



50
51
52
53
# File 'lib/shirobai/cop/layout/multiline_method_call_brace_layout.rb', line 50

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  [[STYLES.fetch(cop_config["EnforcedStyle"] || "symmetrical", 0)], []]
end

.cop_nameObject



43
# File 'lib/shirobai/cop/layout/multiline_method_call_brace_layout.rb', line 43

def self.cop_name = "Layout/MultilineMethodCallBraceLayout"

Instance Method Details

#on_new_investigationObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/shirobai/cop/layout/multiline_method_call_brace_layout.rb', line 55

def on_new_investigation
  # Trigger `ConfigurableEnforcedStyle`'s `style` lookup once so an
  # unknown EnforcedStyle raises identically to stock before any
  # offense is emitted.
  _ = style

  buffer = processed_source.buffer
  off = SourceOffsets.for(processed_source.raw_source)
  offenses = offenses_for_source

  offenses.each do |start, fin, msg_code, send_start, send_end, correctable|
    range = Parser::Source::Range.new(buffer, off[start], off[fin])
    message = MESSAGES.fetch(msg_code)
    if correctable
      add_offense(range, message: message) do |corrector|
        # `(send_start, send_end)` are Rust BYTE offsets — convert to
        # parser-gem CHAR offsets via SourceOffsets to match what
        # `node.source_range.begin_pos/end_pos` actually report.
        node = node_for_send_range(off[send_start], off[send_end])
        next unless node

        RuboCop::Cop::MultilineLiteralBraceCorrector.correct(
          corrector, node, processed_source
        )
      end
    else
      # Stock emits the offense but returns BEFORE touching `corrector`
      # so `correctable?` stays false. Calling `add_offense` without a
      # block matches.
      add_offense(range, message: message)
    end
  end
end