Class: Shirobai::Cop::Style::BlockDelimiters
- Inherits:
-
RuboCop::Cop::Base
- Object
- RuboCop::Cop::Base
- Shirobai::Cop::Style::BlockDelimiters
- Extended by:
- RuboCop::Cop::AutoCorrector
- Includes:
- RuboCop::Cop::AllowedMethods, RuboCop::Cop::AllowedPattern
- Defined in:
- lib/shirobai/cop/style/block_delimiters.rb
Overview
Drop-in Rust reimplementation of ‘Style/BlockDelimiters`.
Rust walks the AST once, replicating stock’s callback order: ‘on_send` registers every block inside unparenthesized call arguments as ignored, and `on_block` (calls, `super`, lambda literals, numbered/`it` blocks) judges the configured style (all four `EnforcedStyle`s, the `require_do_end?` rescue quirk, `BracesRequiredMethods`, `AllowedMethods`, and the parser-parent emulation behind `semantic`). Corrections come back as the exact corrector call sequence (`replace`/`remove`/`insert_before`/`insert_after`/`wrap`), including the comment relocation and the `begin`..`end` wrapping of rescue bodies.
The cop instance accumulates the ignored block ranges across autocorrect iterations, mirroring ‘IgnoredNode`’s ‘@ignored_nodes` (which is never reset between investigations on one instance): blocks ignored by `on_send` unconditionally, offense blocks only when the offense is enabled — which is why the ignore lands inside the `add_offense` block, exactly like stock’s ‘ignore_node`.
The bundled / resolved path assumes every offense is enabled. When Rust reports that a candidate was suppressed solely by another offense’s range (‘has_conditional` — its real fate depends on `rubocop:disable` directives), or when `AllowedPatterns` need regex matching, the wrapper replays the raw event stream through `add_offense`, which natively reproduces the disable semantics.
Constant Summary collapse
- STYLES =
{ "line_count_based" => 0, "semantic" => 1, "braces_for_chaining" => 2, "always_braces" => 3 }.freeze
Class Method Summary collapse
-
.autocorrect_incompatible_with ⇒ Object
‘Style/RedundantBegin` rewrites the same `begin` bodies the do-end-to-braces correction wraps.
- .badge ⇒ Object
-
.bundle_args(config) ⇒ Object
Packed args for the bundled run: ‘[nums, lists]` with `nums = [style, AllowBracesOnProceduralOneLiners]` and `lists = [ProceduralMethods, FunctionalMethods, AllowedMethods, BracesRequiredMethods]`.
- .cop_name ⇒ Object
Instance Method Summary collapse
Class Method Details
.autocorrect_incompatible_with ⇒ Object
‘Style/RedundantBegin` rewrites the same `begin` bodies the do-end-to-braces correction wraps.
42 43 44 |
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 42 def self.autocorrect_incompatible_with [RuboCop::Cop::Style::RedundantBegin] end |
.badge ⇒ Object
38 |
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 38 def self.badge = RuboCop::Cop::Badge.parse("Style/BlockDelimiters") |
.bundle_args(config) ⇒ Object
Packed args for the bundled run: ‘[nums, lists]` with `nums = [style, AllowBracesOnProceduralOneLiners]` and `lists = [ProceduralMethods, FunctionalMethods, AllowedMethods, BracesRequiredMethods]`.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 57 def self.bundle_args(config) cop_config = config.for_badge(badge) [ [ STYLES.fetch(cop_config["EnforcedStyle"] || "line_count_based"), cop_config["AllowBracesOnProceduralOneLiners"] ? 1 : 0 ], [ Array(cop_config["ProceduralMethods"]).map(&:to_s), Array(cop_config["FunctionalMethods"]).map(&:to_s), Shirobai::Cop.allowed_methods_config(cop_config).map(&:to_s), Array(cop_config.fetch("BracesRequiredMethods", [])).map(&:to_s) ] ] end |
.cop_name ⇒ Object
37 |
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 37 def self.cop_name = "Style/BlockDelimiters" |
Instance Method Details
#on_new_investigation ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/shirobai/cop/style/block_delimiters.rb', line 73 def on_new_investigation @ignored_ranges ||= [] return replay_events if !allowed_patterns.empty? offenses, send_ignores, has_conditional = resolved_result # A candidate was suppressed solely by another offense's range: its # real fate depends on disable directives, so replay exactly. return replay_events if has_conditional buffer = processed_source.buffer off = SourceOffsets.for(processed_source.raw_source) send_ignores.each { |s, e| @ignored_ranges << [s, e] } offenses.each do |ts, te, bs, be, , ops| range = Parser::Source::Range.new(buffer, off[ts], off[te]) add_offense(range, message: ) do |corrector| apply_ops(corrector, buffer, off, ops) # `ignore_node` runs only when the offense is enabled; the # ranges stay BYTE offsets (they go back to Rust). @ignored_ranges << [bs, be] end end end |