Class: Shirobai::Cop::Layout::ExtraSpacing
- Inherits:
-
RuboCop::Cop::Base
- Object
- RuboCop::Cop::Base
- Shirobai::Cop::Layout::ExtraSpacing
- Extended by:
- RuboCop::Cop::AutoCorrector
- Includes:
- RuboCop::Cop::RangeHelp
- Defined in:
- lib/shirobai/cop/layout/extra_spacing.rb
Overview
Drop-in Rust reimplementation of Layout/ExtraSpacing.
A token-scan cop with an AST side input: Rust walks the parser-gem token
stream as adjacent pairs (tokens.each_cons(2), stock's check_tokens)
and, for the AllowForAlignment / ignored_ranges decisions, consults
the whole token list (the shared alignment helper) and the AST (the
key↔value spans of multi-line hash pairs, left to Layout/HashAlignment).
Both run in the bundle's walk-outer phase; Rust returns one record per
offense: [start, end, message, action, edits].
[start, end) is the offense highlight. action is 0
(corrector.remove(range) — the usual "delete extra spacing" fix) or 1
(ForceEqualSignAlignment: apply each [edit_start, edit_end, text] of
edits with corrector.replace — a zero-width range inserts, an empty
text deletes; Rust has already applied the @corrected dedup so each
token's edit appears under exactly one offense).
Config inputs: AllowForAlignment (default true) /
AllowBeforeTrailingComments (default false) / ForceEqualSignAlignment
(default false). All are purely config-driven, so the cop is always bundle
eligible — except when raw_source != buffer.source (CRLF/BOM
normalization), where the token byte positions would not line up and it
falls back to a standalone lex of buffer.source. (CRLF/buffer.source
trap, aee0e8e.)
Class Method Summary collapse
- .badge ⇒ Object
-
.bundle_args(config) ⇒ Object
Packed config nums:
[enabled, allow_for_alignment, allow_before_trailing_comments, force_equal_sign_alignment]. - .cop_name ⇒ Object
Instance Method Summary collapse
Class Method Details
.badge ⇒ Object
35 |
# File 'lib/shirobai/cop/layout/extra_spacing.rb', line 35 def self.badge = RuboCop::Cop::Badge.parse(cop_name) |
.bundle_args(config) ⇒ Object
Packed config nums: [enabled, allow_for_alignment, allow_before_trailing_comments, force_equal_sign_alignment].
enabled is a token-cop gate the bundle ORs into its decision to
collect the parser-gem token stream. It is a superset of "this cop
runs": a false positive only costs the token pass on a file the cop
never reads, never a wrong offense, so we only turn it off when
Enabled is literally false.
force_equal_sign_alignment is the same config key
(Layout/ExtraSpacing ForceEqualSignAlignment) that
Layout/SpaceAroundOperators reads; the bundle packs it once (num 126)
as the single wire source. It is carried here for the standalone
fallback call below.
51 52 53 54 55 56 57 58 |
# File 'lib/shirobai/cop/layout/extra_spacing.rb', line 51 def self.bundle_args(config) cop_config = config.for_badge(badge) enabled = cop_config["Enabled"] == false ? 0 : 1 allow = cop_config.fetch("AllowForAlignment", true) ? 1 : 0 trailing = cop_config["AllowBeforeTrailingComments"] ? 1 : 0 force = cop_config["ForceEqualSignAlignment"] ? 1 : 0 [[enabled, allow, trailing, force]] end |
.cop_name ⇒ Object
34 |
# File 'lib/shirobai/cop/layout/extra_spacing.rb', line 34 def self.cop_name = "Layout/ExtraSpacing" |
Instance Method Details
#on_new_investigation ⇒ Object
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/extra_spacing.rb', line 60 def on_new_investigation buffer = processed_source.buffer source_for_offsets = bundle_eligible? ? processed_source.raw_source : buffer.source off = SourceOffsets.for(source_for_offsets) ranges = ignored_ranges(source_for_offsets) resolved_result.each do |start_pos, end_pos, , action, edits| # `ignored_range?(ast, range.begin_pos)`: applied here (not in Rust) # with the memoized `@ignored_ranges`, reproducing stock's instance # memoization — across an autocorrect re-pass on a reused instance the # ranges go stale exactly as stock's do. Only the "remove extra space" # action (0) is subject to it; the ForceEqualSignAlignment action (1) # is not. next if action == 0 && ranges.any? { |s, e| (s...e).cover?(start_pos) } range = Parser::Source::Range.new(buffer, off[start_pos], off[end_pos]) add_offense(range, message: ) do |corrector| if action == 0 corrector.remove(range) else edits.each do |edit_start, edit_end, text| edit_range = Parser::Source::Range.new(buffer, off[edit_start], off[edit_end]) corrector.replace(edit_range, text) end end end end end |