Class: Shirobai::Cop::Layout::FirstArgumentIndentation

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

Overview

Drop-in Rust reimplementation of Layout/FirstArgumentIndentation.

Rust parses the source, walks every method call with arguments, decides the alignment base for the configured EnforcedStyle, and returns the first argument as an offense range plus its column_delta, the message, the within? autocorrect flag and the range to realign (which for special_for_inner_method_call_in_parentheses may be the whole receiver chain). Ruby supplies the flattened config and applies the realignment via AlignmentCorrector (the same division of labour as the other alignment cops). Offenses come from the per-file bundled run (Shirobai::Dispatch); the config derivation is purely config-driven, so this cop is always bundle-eligible.

Constant Summary collapse

STYLES =
{
  "special_for_inner_method_call_in_parentheses" => 0,
  "consistent" => 1,
  "consistent_relative_to_receiver" => 2,
  "special_for_inner_method_call" => 3
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



31
# File 'lib/shirobai/cop/layout/first_argument_indentation.rb', line 31

def self.badge = RuboCop::Cop::Badge.parse("Layout/FirstArgumentIndentation")

.bundle_args(config) ⇒ Object

Packed args for the bundled run: [style, indentation_width, enforce_fixed_with_no_line_break]. The enforce flag replicates the instance derivation: Layout/ArgumentAlignment enforcing with_fixed_indentation while Layout/FirstMethodArgumentLineBreak is disabled.



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/shirobai/cop/layout/first_argument_indentation.rb', line 38

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  argument_alignment_config = config.for_enabled_cop("Layout/ArgumentAlignment")
  enforce = argument_alignment_config["EnforcedStyle"] == "with_fixed_indentation" &&
            !config.cop_enabled?("Layout/FirstMethodArgumentLineBreak")
  [
    STYLES.fetch(cop_config["EnforcedStyle"], 0),
    cop_config["IndentationWidth"] || config.for_cop("Layout/IndentationWidth")["Width"] || 2,
    enforce
  ]
end

.cop_nameObject



30
# File 'lib/shirobai/cop/layout/first_argument_indentation.rb', line 30

def self.cop_name = "Layout/FirstArgumentIndentation"

Instance Method Details

#on_new_investigationObject



50
51
52
53
54
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
# File 'lib/shirobai/cop/layout/first_argument_indentation.rb', line 50

def on_new_investigation
  buffer = processed_source.buffer

  offenses = Dispatch.offenses_for(processed_source, config, :first_argument_indentation)
  off = SourceOffsets.for(processed_source.raw_source)
  # Stock hands `AlignmentCorrector` the argument NODE; its
  # `inside_string_ranges` taboo then protects multi-line string
  # interiors from the shift. Locate the parser node for each
  # correctable range so the bare range (no taboo) is only the
  # fallback (same family as argument_alignment).
  located = NodeLocator.locate(
    processed_source,
    offenses.filter_map { |_s, _f, _d, _m, ac, cs, ce| [off[cs], off[ce]] if ac }
  )
  offenses.each do |start, fin, column_delta, message, autocorrect, cs, ce|
    range = Parser::Source::Range.new(buffer, off[start], off[fin])
    # Always pass a block so the offense is correctable, matching stock:
    # the Alignment mixin's `register_offense` always hands `add_offense`
    # a block, even for the `within?` case (`autocorrect: false`). A
    # blockless `add_offense` would mark the offense uncorrectable. When
    # `autocorrect` is false the block returns early, leaving an empty
    # (no-op) corrector, so the offense stays correctable but is not
    # rewritten this pass (see argument_alignment).
    add_offense(range, message: message) do |corrector|
      next unless autocorrect

      target = located[[off[cs], off[ce]]] ||
               Parser::Source::Range.new(buffer, off[cs], off[ce])
      RuboCop::Cop::AlignmentCorrector.correct(
        corrector, processed_source, target, column_delta
      )
    end
  end
end