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

.badge ⇒ Object



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, hash_separator]. hash_separator is stock's enforce_hash_argument_with_separator? (a separator-aligned Layout/HashAlignment). Rust derives the rest from it: with with_first_argument it disables the cop (autocorrect_incompatible_with_other_cops?); with with_fixed_indentation a trailing braceless hash's pairs are left to HashAlignment (1.91).



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

def self.bundle_args(config)
  cop_config = config.for_badge(badge)
  enforced_style = cop_config["EnforcedStyle"]
  hash_separator = 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,
    hash_separator
  ]
end

.cop_name ⇒ Object



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

def self.cop_name = "Layout/ArgumentAlignment"

Instance Method Details

#on_new_investigation ⇒ Object



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

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