Class: Shirobai::Cop::Layout::ArgumentAlignment

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

Overview

Drop-in Rust reimplementation of Layout/ArgumentAlignment.

Rust parses the source, walks every multi-argument method call, picks the alignment base for the configured EnforcedStyle (with_first_argument / with_fixed_indentation) and returns each misaligned argument as an offense range plus its column_delta. Ruby supplies the flattened config and applies the realignment via AlignmentCorrector (the same division of labour as the multiline indentation 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

ALIGN_PARAMS_MSG =
"Align the arguments of a method call if they span more than one line."
FIXED_INDENT_MSG =
"Use one level of indentation for arguments " \
"following the first line of a multi-line method call."

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



27
# File 'lib/shirobai/cop/layout/argument_alignment.rb', line 27

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

.bundle_args(config) ⇒ Object

Packed args for the bundled run: [style, indentation_width, incompatible]. incompatible replicates the instance derivation exactly: it is only true for the explicit with_first_argument style combined with a separator-aligned Layout/HashAlignment.



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/shirobai/cop/layout/argument_alignment.rb', line 33

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  enforced_style = cop_config["EnforcedStyle"]
  incompatible = enforced_style == "with_first_argument" &&
                 RuboCop::Cop::Layout::HashAlignment::SEPARATOR_ALIGNMENT_STYLES.any? do |sep_style|
                   config.for_enabled_cop("Layout/HashAlignment")[sep_style]&.include?("separator")
                 end
  [
    enforced_style == "with_fixed_indentation" ? 1 : 0,
    cop_config["IndentationWidth"] || config.for_cop("Layout/IndentationWidth")["Width"] || 2,
    incompatible
  ]
end

.cop_nameObject



26
# File 'lib/shirobai/cop/layout/argument_alignment.rb', line 26

def self.cop_name = "Layout/ArgumentAlignment"

Instance Method Details

#on_new_investigationObject



47
48
49
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
# File 'lib/shirobai/cop/layout/argument_alignment.rb', line 47

def on_new_investigation
  buffer = processed_source.buffer
  message = fixed_indentation? ? FIXED_INDENT_MSG : ALIGN_PARAMS_MSG

  offenses = Dispatch.offenses_for(processed_source, config, :argument_alignment)
  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 (fluentd test_config_parser `%()` bodies).
  located = NodeLocator.locate(
    processed_source,
    offenses.filter_map { |s, f, _d, ac| [off[s], off[f]] if ac }
  )
  offenses.each do |start, fin, column_delta, autocorrect|
    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 where it passes a nil node and
    # the corrector ends up empty. A blockless `add_offense` would instead
    # mark the offense uncorrectable. `autocorrect` is false when the
    # offense is nested in an already-corrected range; then the block
    # returns early, leaving an empty (no-op) corrector, so the offense is
    # reported and stays correctable but is not rewritten this pass.
    add_offense(range, message: message) do |corrector|
      next unless autocorrect

      target = located[[off[start], off[fin]]] || range
      RuboCop::Cop::AlignmentCorrector.correct(corrector, processed_source, target, column_delta)
    end
  end
end