shirobai 2026.0713.1900-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/lib/shirobai/3.1/shirobai.so +0 -0
- data/lib/shirobai/3.2/shirobai.so +0 -0
- data/lib/shirobai/3.3/shirobai.so +0 -0
- data/lib/shirobai/3.4/shirobai.so +0 -0
- data/lib/shirobai/4.0/shirobai.so +0 -0
- data/lib/shirobai/cop/base.rb +45 -0
- data/lib/shirobai/cop/layout/access_modifier_indentation.rb +117 -0
- data/lib/shirobai/cop/layout/argument_alignment.rb +95 -0
- data/lib/shirobai/cop/layout/array_alignment.rb +109 -0
- data/lib/shirobai/cop/layout/assignment_indentation.rb +73 -0
- data/lib/shirobai/cop/layout/block_alignment.rb +79 -0
- data/lib/shirobai/cop/layout/closing_parenthesis_indentation.rb +51 -0
- data/lib/shirobai/cop/layout/def_end_alignment.rb +114 -0
- data/lib/shirobai/cop/layout/dot_position.rb +63 -0
- data/lib/shirobai/cop/layout/else_alignment.rb +86 -0
- data/lib/shirobai/cop/layout/empty_comment.rb +75 -0
- data/lib/shirobai/cop/layout/empty_line_after_guard_clause.rb +116 -0
- data/lib/shirobai/cop/layout/empty_line_after_magic_comment.rb +82 -0
- data/lib/shirobai/cop/layout/empty_line_between_defs.rb +78 -0
- data/lib/shirobai/cop/layout/empty_lines.rb +70 -0
- data/lib/shirobai/cop/layout/empty_lines_around_arguments.rb +55 -0
- data/lib/shirobai/cop/layout/empty_lines_around_begin_body.rb +22 -0
- data/lib/shirobai/cop/layout/empty_lines_around_block_body.rb +28 -0
- data/lib/shirobai/cop/layout/empty_lines_around_body_shared.rb +58 -0
- data/lib/shirobai/cop/layout/empty_lines_around_class_body.rb +27 -0
- data/lib/shirobai/cop/layout/empty_lines_around_exception_handling_keywords.rb +24 -0
- data/lib/shirobai/cop/layout/empty_lines_around_method_body.rb +22 -0
- data/lib/shirobai/cop/layout/empty_lines_around_module_body.rb +26 -0
- data/lib/shirobai/cop/layout/end_alignment.rb +101 -0
- data/lib/shirobai/cop/layout/end_of_line.rb +90 -0
- data/lib/shirobai/cop/layout/extra_spacing.rb +124 -0
- data/lib/shirobai/cop/layout/first_argument_indentation.rb +87 -0
- data/lib/shirobai/cop/layout/first_array_element_indentation.rb +89 -0
- data/lib/shirobai/cop/layout/first_hash_element_indentation.rb +104 -0
- data/lib/shirobai/cop/layout/hash_alignment.rb +135 -0
- data/lib/shirobai/cop/layout/indentation_consistency.rb +95 -0
- data/lib/shirobai/cop/layout/indentation_width.rb +146 -0
- data/lib/shirobai/cop/layout/initial_indentation.rb +80 -0
- data/lib/shirobai/cop/layout/leading_empty_lines.rb +72 -0
- data/lib/shirobai/cop/layout/line_continuation_spacing.rb +157 -0
- data/lib/shirobai/cop/layout/line_length.rb +235 -0
- data/lib/shirobai/cop/layout/multiline_method_call_brace_layout.rb +126 -0
- data/lib/shirobai/cop/layout/multiline_method_call_indentation.rb +87 -0
- data/lib/shirobai/cop/layout/multiline_operation_indentation.rb +61 -0
- data/lib/shirobai/cop/layout/rescue_ensure_alignment.rb +250 -0
- data/lib/shirobai/cop/layout/space_after_colon.rb +58 -0
- data/lib/shirobai/cop/layout/space_after_comma.rb +64 -0
- data/lib/shirobai/cop/layout/space_after_semicolon.rb +57 -0
- data/lib/shirobai/cop/layout/space_around_equals_in_parameter_default.rb +79 -0
- data/lib/shirobai/cop/layout/space_around_keyword.rb +69 -0
- data/lib/shirobai/cop/layout/space_around_method_call_operator.rb +55 -0
- data/lib/shirobai/cop/layout/space_around_operators.rb +121 -0
- data/lib/shirobai/cop/layout/space_before_block_braces.rb +150 -0
- data/lib/shirobai/cop/layout/space_before_comma.rb +63 -0
- data/lib/shirobai/cop/layout/space_before_comment.rb +56 -0
- data/lib/shirobai/cop/layout/space_before_first_arg.rb +65 -0
- data/lib/shirobai/cop/layout/space_before_semicolon.rb +57 -0
- data/lib/shirobai/cop/layout/space_inside_array_literal_brackets.rb +109 -0
- data/lib/shirobai/cop/layout/space_inside_block_braces.rb +116 -0
- data/lib/shirobai/cop/layout/space_inside_hash_literal_braces.rb +93 -0
- data/lib/shirobai/cop/layout/space_inside_parens.rb +67 -0
- data/lib/shirobai/cop/layout/space_inside_reference_brackets.rb +104 -0
- data/lib/shirobai/cop/layout/space_inside_string_interpolation.rb +81 -0
- data/lib/shirobai/cop/layout/trailing_empty_lines.rb +104 -0
- data/lib/shirobai/cop/lint/ambiguous_block_association.rb +117 -0
- data/lib/shirobai/cop/lint/debugger.rb +44 -0
- data/lib/shirobai/cop/lint/duplicate_magic_comment.rb +67 -0
- data/lib/shirobai/cop/lint/duplicate_methods.rb +109 -0
- data/lib/shirobai/cop/lint/ordered_magic_comments.rb +62 -0
- data/lib/shirobai/cop/lint/parentheses_as_grouped_expression.rb +54 -0
- data/lib/shirobai/cop/lint/require_parentheses.rb +35 -0
- data/lib/shirobai/cop/lint/safe_navigation_chain.rb +52 -0
- data/lib/shirobai/cop/lint/self_assignment.rb +105 -0
- data/lib/shirobai/cop/lint/unreachable_code.rb +48 -0
- data/lib/shirobai/cop/lint/useless_access_modifier.rb +61 -0
- data/lib/shirobai/cop/lint/void.rb +60 -0
- data/lib/shirobai/cop/metrics/abc_size.rb +66 -0
- data/lib/shirobai/cop/metrics/block_length.rb +139 -0
- data/lib/shirobai/cop/metrics/block_nesting.rb +62 -0
- data/lib/shirobai/cop/metrics/class_length.rb +88 -0
- data/lib/shirobai/cop/metrics/complexity_base.rb +35 -0
- data/lib/shirobai/cop/metrics/complexity_shared.rb +45 -0
- data/lib/shirobai/cop/metrics/cyclomatic_complexity.rb +30 -0
- data/lib/shirobai/cop/metrics/method_length.rb +70 -0
- data/lib/shirobai/cop/metrics/module_length.rb +83 -0
- data/lib/shirobai/cop/metrics/perceived_complexity.rb +30 -0
- data/lib/shirobai/cop/naming/ascii_identifiers.rb +63 -0
- data/lib/shirobai/cop/naming/method_name.rb +100 -0
- data/lib/shirobai/cop/naming/predicate_prefix.rb +107 -0
- data/lib/shirobai/cop/naming/variable_number.rb +72 -0
- data/lib/shirobai/cop/style/arguments_forwarding.rb +108 -0
- data/lib/shirobai/cop/style/block_delimiters.rb +164 -0
- data/lib/shirobai/cop/style/colon_method_call.rb +60 -0
- data/lib/shirobai/cop/style/empty_literal.rb +184 -0
- data/lib/shirobai/cop/style/file_null.rb +55 -0
- data/lib/shirobai/cop/style/frozen_string_literal_comment.rb +118 -0
- data/lib/shirobai/cop/style/hash_each_methods.rb +50 -0
- data/lib/shirobai/cop/style/hash_syntax.rb +147 -0
- data/lib/shirobai/cop/style/hash_transform_keys.rb +46 -0
- data/lib/shirobai/cop/style/if_unless_modifier.rb +207 -0
- data/lib/shirobai/cop/style/line_end_concatenation.rb +42 -0
- data/lib/shirobai/cop/style/magic_comment_format.rb +229 -0
- data/lib/shirobai/cop/style/mutable_constant.rb +286 -0
- data/lib/shirobai/cop/style/nested_parenthesized_calls.rb +88 -0
- data/lib/shirobai/cop/style/percent_literal_delimiters.rb +113 -0
- data/lib/shirobai/cop/style/redundant_freeze.rb +75 -0
- data/lib/shirobai/cop/style/redundant_self.rb +50 -0
- data/lib/shirobai/cop/style/redundant_self_assignment.rb +62 -0
- data/lib/shirobai/cop/style/semicolon.rb +192 -0
- data/lib/shirobai/cop/style/stabby_lambda_parentheses.rb +75 -0
- data/lib/shirobai/cop/style/string_literals.rb +135 -0
- data/lib/shirobai/cop/style/string_literals_in_interpolation.rb +130 -0
- data/lib/shirobai/cop/style/trailing_comma_in_arguments.rb +127 -0
- data/lib/shirobai/cop/style/trailing_comma_in_array_literal.rb +127 -0
- data/lib/shirobai/cop/style/trailing_comma_in_hash_literal.rb +127 -0
- data/lib/shirobai/dispatch.rb +530 -0
- data/lib/shirobai/inject.rb +218 -0
- data/lib/shirobai/node_locator.rb +124 -0
- data/lib/shirobai/source_offsets.rb +43 -0
- data/lib/shirobai/version.rb +5 -0
- data/lib/shirobai.rb +15 -0
- metadata +181 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a1a419f64630d93c94d120072f01047272ec8c3a810ff08ca0cd42005684a702
|
|
4
|
+
data.tar.gz: c96975359454665c58c5ae06825502d540895ddd4bf17971ce10f1870bdc097a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 88c81dbf1bfc415fdc4d09b8b477c9a6b0151d843644796bf299faffe84b2500cd5382402581dbc48602ab5bf461adf6448b2537018470aabed461b11ea74262
|
|
7
|
+
data.tar.gz: 1c395e268195a7fdcadf2f6ec8951d1d35244c6a6335fa53764536f0854dc550d0c0f83f190edd72e096f9b87d6a2fffc314d35ec5c5634cdfa15275ad1a2197
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 fusagiko / takayamaki
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rubocop"
|
|
4
|
+
|
|
5
|
+
module Shirobai
|
|
6
|
+
module Cop
|
|
7
|
+
# Class-level replica of `RuboCop::Cop::AllowedMethods#allowed_methods`,
|
|
8
|
+
# for `bundle_args` class methods that must derive a cop's config without
|
|
9
|
+
# a cop instance (`cop_config` is `config.for_badge(badge)`).
|
|
10
|
+
def self.allowed_methods_config(cop_config)
|
|
11
|
+
deprecated = Array(cop_config.fetch("IgnoredMethods", [])) +
|
|
12
|
+
Array(cop_config.fetch("ExcludedMethods", []))
|
|
13
|
+
allowed = Array(cop_config.fetch("AllowedMethods", []))
|
|
14
|
+
allowed += deprecated unless deprecated.any?(Regexp)
|
|
15
|
+
allowed
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Shared `bundle_eligible?` for wrapper cops.
|
|
19
|
+
#
|
|
20
|
+
# The bundled (shared-walk) path scans `raw_source`; the standalone path
|
|
21
|
+
# scans the parser-normalized `buffer.source`. The two agree only when they
|
|
22
|
+
# are byte-identical (CRLF / BOM / `__END__` truncation break that), so a cop
|
|
23
|
+
# may take the bundle path exactly then; otherwise it falls back so every
|
|
24
|
+
# offset lines up with parser-gem's index.
|
|
25
|
+
#
|
|
26
|
+
# The verdict is memoized, but the memo is guarded on the `processed_source`
|
|
27
|
+
# identity. RuboCop's real CLI builds a fresh cop per file, yet a reused
|
|
28
|
+
# instance (vendor specs, and any future RuboCop change to instance reuse)
|
|
29
|
+
# investigates several sources in turn. A plain `@bundle_eligible` /
|
|
30
|
+
# `.nil?` / `defined?` memo would freeze the first file's verdict and leak it
|
|
31
|
+
# onto later files with a different eligibility; keying on the source
|
|
32
|
+
# identity recomputes it on each new investigation.
|
|
33
|
+
module BundleEligible
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def bundle_eligible?
|
|
37
|
+
src = processed_source
|
|
38
|
+
return @bundle_eligible if defined?(@bundle_eligible_for) && @bundle_eligible_for.equal?(src)
|
|
39
|
+
|
|
40
|
+
@bundle_eligible_for = src
|
|
41
|
+
@bundle_eligible = src.buffer.source == src.raw_source
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shirobai
|
|
4
|
+
module Cop
|
|
5
|
+
module Layout
|
|
6
|
+
# Drop-in Rust reimplementation of `Layout/AccessModifierIndentation`.
|
|
7
|
+
#
|
|
8
|
+
# Rust walks the AST once, reproducing stock's `on_class` / `on_sclass` /
|
|
9
|
+
# `on_module` / `on_block` alias chain: for every class-like / block
|
|
10
|
+
# node, look at the body and — when it is a parser-`(begin ...)` (>= 2
|
|
11
|
+
# statements; prism's single-statement `StatementsNode` mirrors stock's
|
|
12
|
+
# bare body so we skip it) — inspect each direct child `send` that is a
|
|
13
|
+
# `bare_access_modifier?` (no receiver / no arguments / no block, name
|
|
14
|
+
# in `{public, protected, private, module_function}`). Same-line
|
|
15
|
+
# modifiers (`same_line?(node, modifier)`) are skipped, exactly like
|
|
16
|
+
# stock. For each kept modifier Rust returns `column_delta = expected -
|
|
17
|
+
# actual` (matching stock's `@column_delta` in
|
|
18
|
+
# `column_offset_between(modifier.source_range, node.loc.end)`); the
|
|
19
|
+
# wrapper either fires `correct_style_detected` (delta zero) or registers
|
|
20
|
+
# the offense and shifts the modifier's line by `column_delta` (mirroring
|
|
21
|
+
# stock's `AlignmentCorrector.correct(corrector, processed_source, node,
|
|
22
|
+
# column_delta)` for a one-line node, which simply inserts or removes
|
|
23
|
+
# leading whitespace).
|
|
24
|
+
#
|
|
25
|
+
# Stock's `AlignmentCorrector.correct` reads `processed_source.config`
|
|
26
|
+
# (for `using_tabs?`); a faithful drop-in does the same — autocorrect is
|
|
27
|
+
# skipped entirely under `Layout/IndentationStyle: tabs`, just like
|
|
28
|
+
# stock.
|
|
29
|
+
#
|
|
30
|
+
# Offenses come from the per-file bundled run (`Shirobai::Dispatch`); the
|
|
31
|
+
# behaviour is purely config-driven (`EnforcedStyle` + a per-cop or
|
|
32
|
+
# global `IndentationWidth`), so this cop is always bundle eligible.
|
|
33
|
+
class AccessModifierIndentation < RuboCop::Cop::Base
|
|
34
|
+
include RuboCop::Cop::ConfigurableEnforcedStyle
|
|
35
|
+
extend RuboCop::Cop::AutoCorrector
|
|
36
|
+
|
|
37
|
+
STYLE_TO_U8 = { indent: 0, outdent: 1 }.freeze
|
|
38
|
+
|
|
39
|
+
def self.cop_name = "Layout/AccessModifierIndentation"
|
|
40
|
+
def self.badge = RuboCop::Cop::Badge.parse(cop_name)
|
|
41
|
+
|
|
42
|
+
# Packed args for the bundled run: `[style, indentation_width]`.
|
|
43
|
+
# `indentation_width` mirrors `Alignment#configured_indentation_width`
|
|
44
|
+
# — the cop's own `IndentationWidth` if set, else
|
|
45
|
+
# `Layout/IndentationWidth`'s `Width`, else 2.
|
|
46
|
+
def self.bundle_args(config)
|
|
47
|
+
own = config.for_badge(badge)
|
|
48
|
+
style = STYLE_TO_U8.fetch((own["EnforcedStyle"] || "indent").to_sym, 0)
|
|
49
|
+
width = own["IndentationWidth"] ||
|
|
50
|
+
config.for_cop("Layout/IndentationWidth")["Width"] ||
|
|
51
|
+
2
|
|
52
|
+
[style, width]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def on_new_investigation
|
|
56
|
+
buffer = processed_source.buffer
|
|
57
|
+
off = SourceOffsets.for(processed_source.raw_source)
|
|
58
|
+
|
|
59
|
+
records_for_source.each do |start, fin, message, column_delta|
|
|
60
|
+
send_range = Parser::Source::Range.new(buffer, off[start], off[fin])
|
|
61
|
+
if column_delta.zero?
|
|
62
|
+
correct_style_detected
|
|
63
|
+
next
|
|
64
|
+
end
|
|
65
|
+
add_offense(send_range, message: message) do |corrector|
|
|
66
|
+
# Delegate to stock's `AlignmentCorrector.correct`. It reads
|
|
67
|
+
# `processed_source.config` for tab-style detection and string /
|
|
68
|
+
# block-comment range avoidance; for a single-line modifier
|
|
69
|
+
# those checks fall through to a single `each_line` iteration
|
|
70
|
+
# that just inserts or removes leading whitespace. Passing the
|
|
71
|
+
# `Parser::Source::Range` directly avoids needing the actual
|
|
72
|
+
# AST node — stock's implementation accepts either (`node
|
|
73
|
+
# .respond_to?(:loc) ? node.source_range : node`).
|
|
74
|
+
RuboCop::Cop::AlignmentCorrector.correct(
|
|
75
|
+
corrector, processed_source, send_range, column_delta
|
|
76
|
+
)
|
|
77
|
+
opposite_or_unrecognized_style(column_delta)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def records_for_source
|
|
85
|
+
Dispatch.offenses_for(processed_source, config, :access_modifier_indentation)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Mirror stock's `check_modifier` after `add_offense`: if the actual
|
|
89
|
+
# offset equals `unexpected_indent_offset` (`indentation_width -
|
|
90
|
+
# expected`), call `opposite_style_detected`; otherwise
|
|
91
|
+
# `unrecognized_style_detected`. Recover the actual offset from
|
|
92
|
+
# `column_delta` since `column_delta = expected - actual`.
|
|
93
|
+
def opposite_or_unrecognized_style(column_delta)
|
|
94
|
+
expected = expected_indent_offset
|
|
95
|
+
actual = expected - column_delta
|
|
96
|
+
unexpected = configured_indentation_width - expected
|
|
97
|
+
if actual == unexpected
|
|
98
|
+
opposite_style_detected
|
|
99
|
+
else
|
|
100
|
+
unrecognized_style_detected
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def expected_indent_offset
|
|
105
|
+
style == :outdent ? 0 : configured_indentation_width
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Mirror `Alignment#configured_indentation_width` exactly.
|
|
109
|
+
def configured_indentation_width
|
|
110
|
+
cop_config["IndentationWidth"] ||
|
|
111
|
+
config.for_cop("Layout/IndentationWidth")["Width"] ||
|
|
112
|
+
2
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shirobai
|
|
4
|
+
module Cop
|
|
5
|
+
module Layout
|
|
6
|
+
# Drop-in Rust reimplementation of `Layout/ArgumentAlignment`.
|
|
7
|
+
#
|
|
8
|
+
# Rust parses the source, walks every multi-argument method call, picks the
|
|
9
|
+
# alignment base for the configured `EnforcedStyle`
|
|
10
|
+
# (`with_first_argument` / `with_fixed_indentation`) and returns each
|
|
11
|
+
# misaligned argument as an offense range plus its `column_delta`. Ruby
|
|
12
|
+
# supplies the flattened config and applies the realignment via
|
|
13
|
+
# `AlignmentCorrector` (the same division of labour as the multiline
|
|
14
|
+
# indentation cops). Offenses come from the per-file bundled run
|
|
15
|
+
# (`Shirobai::Dispatch`); the config derivation is purely config-driven,
|
|
16
|
+
# so this cop is always bundle-eligible.
|
|
17
|
+
class ArgumentAlignment < RuboCop::Cop::Base
|
|
18
|
+
include RuboCop::Cop::Alignment
|
|
19
|
+
extend RuboCop::Cop::AutoCorrector
|
|
20
|
+
|
|
21
|
+
ALIGN_PARAMS_MSG = "Align the arguments of a method call if they span more than one line."
|
|
22
|
+
|
|
23
|
+
FIXED_INDENT_MSG = "Use one level of indentation for arguments " \
|
|
24
|
+
"following the first line of a multi-line method call."
|
|
25
|
+
|
|
26
|
+
def self.cop_name = "Layout/ArgumentAlignment"
|
|
27
|
+
def self.badge = RuboCop::Cop::Badge.parse("Layout/ArgumentAlignment")
|
|
28
|
+
|
|
29
|
+
# Packed args for the bundled run: `[style, indentation_width,
|
|
30
|
+
# incompatible]`. `incompatible` replicates the instance derivation
|
|
31
|
+
# exactly: it is only true for the explicit `with_first_argument` style
|
|
32
|
+
# combined with a separator-aligned `Layout/HashAlignment`.
|
|
33
|
+
def self.bundle_args(config)
|
|
34
|
+
cop_config = config.for_badge(badge)
|
|
35
|
+
enforced_style = cop_config["EnforcedStyle"]
|
|
36
|
+
incompatible = enforced_style == "with_first_argument" &&
|
|
37
|
+
RuboCop::Cop::Layout::HashAlignment::SEPARATOR_ALIGNMENT_STYLES.any? do |sep_style|
|
|
38
|
+
config.for_enabled_cop("Layout/HashAlignment")[sep_style]&.include?("separator")
|
|
39
|
+
end
|
|
40
|
+
[
|
|
41
|
+
enforced_style == "with_fixed_indentation" ? 1 : 0,
|
|
42
|
+
cop_config["IndentationWidth"] || config.for_cop("Layout/IndentationWidth")["Width"] || 2,
|
|
43
|
+
incompatible
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def on_new_investigation
|
|
48
|
+
buffer = processed_source.buffer
|
|
49
|
+
message = fixed_indentation? ? FIXED_INDENT_MSG : ALIGN_PARAMS_MSG
|
|
50
|
+
|
|
51
|
+
offenses = Dispatch.offenses_for(processed_source, config, :argument_alignment)
|
|
52
|
+
off = SourceOffsets.for(processed_source.raw_source)
|
|
53
|
+
# Stock hands `AlignmentCorrector` the argument NODE; its
|
|
54
|
+
# `inside_string_ranges` taboo then protects multi-line string
|
|
55
|
+
# interiors from the shift. Locate the parser node for each
|
|
56
|
+
# correctable range so the bare range (no taboo) is only the
|
|
57
|
+
# fallback (fluentd test_config_parser `%()` bodies).
|
|
58
|
+
located = NodeLocator.locate(
|
|
59
|
+
processed_source,
|
|
60
|
+
offenses.filter_map { |s, f, _d, ac| [off[s], off[f]] if ac }
|
|
61
|
+
)
|
|
62
|
+
offenses.each do |start, fin, column_delta, autocorrect|
|
|
63
|
+
range = Parser::Source::Range.new(buffer, off[start], off[fin])
|
|
64
|
+
# Always pass a block so the offense is correctable, matching stock:
|
|
65
|
+
# the Alignment mixin's `register_offense` always hands `add_offense`
|
|
66
|
+
# a block, even for the `within?` case where it passes a nil node and
|
|
67
|
+
# the corrector ends up empty. A blockless `add_offense` would instead
|
|
68
|
+
# mark the offense uncorrectable. `autocorrect` is false when the
|
|
69
|
+
# offense is nested in an already-corrected range; then the block
|
|
70
|
+
# returns early, leaving an empty (no-op) corrector, so the offense is
|
|
71
|
+
# reported and stays correctable but is not rewritten this pass.
|
|
72
|
+
add_offense(range, message: message) do |corrector|
|
|
73
|
+
next unless autocorrect
|
|
74
|
+
|
|
75
|
+
target = located[[off[start], off[fin]]] || range
|
|
76
|
+
RuboCop::Cop::AlignmentCorrector.correct(corrector, processed_source, target, column_delta)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Config-derived and stable for the life of the instance; shares the
|
|
84
|
+
# derivation with the bundled run (single source of truth).
|
|
85
|
+
def bundle_args
|
|
86
|
+
@bundle_args ||= self.class.bundle_args(config)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def fixed_indentation?
|
|
90
|
+
bundle_args[0] == 1
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shirobai
|
|
4
|
+
module Cop
|
|
5
|
+
module Layout
|
|
6
|
+
# Drop-in Rust reimplementation of `Layout/ArrayAlignment`.
|
|
7
|
+
#
|
|
8
|
+
# Rust parses the source, walks every 2+-element array literal (plus the
|
|
9
|
+
# bracket-less arrays parser-gem synthesizes: single-assignment RHS lists
|
|
10
|
+
# and `rescue` exception lists; masgn RHS lists are skipped like stock),
|
|
11
|
+
# picks the alignment base for the configured `EnforcedStyle`
|
|
12
|
+
# (`with_first_element` / `with_fixed_indentation`) and returns each
|
|
13
|
+
# misaligned element as an offense range plus its `column_delta`. Ruby
|
|
14
|
+
# supplies the flattened config and applies the realignment via
|
|
15
|
+
# `AlignmentCorrector` (the same division of labour as
|
|
16
|
+
# `Layout/ArgumentAlignment`). The corrector receives the parser NODE for
|
|
17
|
+
# the offense range (resolved like `Layout/IndentationConsistency`), so
|
|
18
|
+
# heredoc bodies and multi-line string interiors inside a shifted element
|
|
19
|
+
# stay untouched, matching stock's taboo-range protection. Offenses come
|
|
20
|
+
# from the per-file bundled run (`Shirobai::Dispatch`); the config
|
|
21
|
+
# derivation is purely config-driven, so this cop is always
|
|
22
|
+
# bundle-eligible.
|
|
23
|
+
class ArrayAlignment < RuboCop::Cop::Base
|
|
24
|
+
include RuboCop::Cop::Alignment
|
|
25
|
+
extend RuboCop::Cop::AutoCorrector
|
|
26
|
+
|
|
27
|
+
ALIGN_ELEMENTS_MSG = "Align the elements of an array literal " \
|
|
28
|
+
"if they span more than one line."
|
|
29
|
+
|
|
30
|
+
FIXED_INDENT_MSG = "Use one level of indentation for elements " \
|
|
31
|
+
"following the first line of a multi-line array."
|
|
32
|
+
|
|
33
|
+
def self.cop_name = "Layout/ArrayAlignment"
|
|
34
|
+
def self.badge = RuboCop::Cop::Badge.parse("Layout/ArrayAlignment")
|
|
35
|
+
|
|
36
|
+
# Packed args for the bundled run: `[style, indentation_width]`.
|
|
37
|
+
def self.bundle_args(config)
|
|
38
|
+
cop_config = config.for_badge(badge)
|
|
39
|
+
[
|
|
40
|
+
cop_config["EnforcedStyle"] == "with_fixed_indentation" ? 1 : 0,
|
|
41
|
+
cop_config["IndentationWidth"] || config.for_cop("Layout/IndentationWidth")["Width"] || 2
|
|
42
|
+
]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def on_new_investigation
|
|
46
|
+
buffer = processed_source.buffer
|
|
47
|
+
message = fixed_indentation? ? FIXED_INDENT_MSG : ALIGN_ELEMENTS_MSG
|
|
48
|
+
|
|
49
|
+
offenses = Dispatch.offenses_for(processed_source, config, :array_alignment)
|
|
50
|
+
off = SourceOffsets.for(processed_source.raw_source)
|
|
51
|
+
offenses.each do |start, fin, column_delta, autocorrect|
|
|
52
|
+
range = Parser::Source::Range.new(buffer, off[start], off[fin])
|
|
53
|
+
# Always pass a block so the offense is correctable, matching stock:
|
|
54
|
+
# the Alignment mixin's `register_offense` always hands `add_offense`
|
|
55
|
+
# a block, even for the `within?` case (`autocorrect: false`) where it
|
|
56
|
+
# passes a nil node and the corrector ends up empty. A blockless
|
|
57
|
+
# `add_offense` would instead mark the offense uncorrectable. When
|
|
58
|
+
# `autocorrect` is false the block returns early, leaving an empty
|
|
59
|
+
# (no-op) corrector, so the offense stays correctable but is not
|
|
60
|
+
# rewritten this pass.
|
|
61
|
+
add_offense(range, message: message) do |corrector|
|
|
62
|
+
next unless autocorrect
|
|
63
|
+
|
|
64
|
+
# Stock passes the element NODE, whose string/heredoc interiors
|
|
65
|
+
# `AlignmentCorrector` marks taboo. A bare range would realign
|
|
66
|
+
# heredoc bodies inside the element.
|
|
67
|
+
target = node_at(off[start], off[fin]) || range
|
|
68
|
+
RuboCop::Cop::AlignmentCorrector.correct(
|
|
69
|
+
corrector, processed_source, target, column_delta
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# Config-derived and stable for the life of the instance; shares the
|
|
78
|
+
# derivation with the bundled run (single source of truth).
|
|
79
|
+
def bundle_args
|
|
80
|
+
@bundle_args ||= self.class.bundle_args(config)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def fixed_indentation?
|
|
84
|
+
bundle_args[0] == 1
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# The parser node whose `source_range` matches `[cs, ce)` (CHARACTER
|
|
88
|
+
# offsets), so `AlignmentCorrector` can protect heredocs / string
|
|
89
|
+
# interiors that a bare range would not. Falls back to `nil` (bare
|
|
90
|
+
# range) when not found.
|
|
91
|
+
def node_at(cs, ce)
|
|
92
|
+
ast = processed_source.ast
|
|
93
|
+
return nil unless ast
|
|
94
|
+
|
|
95
|
+
found = nil
|
|
96
|
+
ast.each_node do |n|
|
|
97
|
+
r = n.source_range
|
|
98
|
+
next unless r
|
|
99
|
+
next unless r.begin_pos == cs && r.end_pos == ce
|
|
100
|
+
|
|
101
|
+
found = n
|
|
102
|
+
break
|
|
103
|
+
end
|
|
104
|
+
found
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shirobai
|
|
4
|
+
module Cop
|
|
5
|
+
module Layout
|
|
6
|
+
# Drop-in Rust reimplementation of `Layout/AssignmentIndentation`.
|
|
7
|
+
#
|
|
8
|
+
# Rust walks the AST once and, for each assignment / setter call whose
|
|
9
|
+
# operator is on a different line from the RHS, computes the RHS's
|
|
10
|
+
# expected display column (`leftmost_multiple_assignment.display_column +
|
|
11
|
+
# IndentationWidth`). Misaligned RHSes that begin their own line emit a
|
|
12
|
+
# `[rhs_start, rhs_end, column_delta]` record, which the wrapper turns
|
|
13
|
+
# into an offense at the RHS range. Autocorrect re-locates the matching
|
|
14
|
+
# `Parser::AST::Node` by `rhs_start` and hands it to stock's
|
|
15
|
+
# `AlignmentCorrector#correct` with the same `column_delta` (this keeps
|
|
16
|
+
# the heredoc / string-literal taboo handling identical to stock).
|
|
17
|
+
class AssignmentIndentation < RuboCop::Cop::Base
|
|
18
|
+
extend RuboCop::Cop::AutoCorrector
|
|
19
|
+
|
|
20
|
+
MSG = "Indent the first line of the right-hand-side of a multi-line assignment."
|
|
21
|
+
|
|
22
|
+
def self.cop_name = "Layout/AssignmentIndentation"
|
|
23
|
+
def self.badge = RuboCop::Cop::Badge.parse(cop_name)
|
|
24
|
+
|
|
25
|
+
# `IndentationWidth` falls back to `Layout/IndentationWidth.Width`,
|
|
26
|
+
# then to 2 — exactly stock's `configured_indentation_width`.
|
|
27
|
+
def self.bundle_args(config)
|
|
28
|
+
own = config.for_badge(badge)["IndentationWidth"]
|
|
29
|
+
width = own || config.for_cop("Layout/IndentationWidth")["Width"] || 2
|
|
30
|
+
[width]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def on_new_investigation
|
|
34
|
+
buffer = processed_source.buffer
|
|
35
|
+
off = SourceOffsets.for(processed_source.raw_source)
|
|
36
|
+
|
|
37
|
+
records_for_source.each do |rhs_start, rhs_end, column_delta|
|
|
38
|
+
range = Parser::Source::Range.new(buffer, off[rhs_start], off[rhs_end])
|
|
39
|
+
node = locate_rhs_node(off[rhs_start])
|
|
40
|
+
add_offense(range, message: MSG) do |corrector|
|
|
41
|
+
# The corrector target is the Parser::AST::Node so stock's
|
|
42
|
+
# `inside_string_ranges` / `block_comment_within?` checks work;
|
|
43
|
+
# if relocation fails (defensive), fall back to the range.
|
|
44
|
+
::RuboCop::Cop::AlignmentCorrector.correct(
|
|
45
|
+
corrector, processed_source, node || range, column_delta
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def records_for_source
|
|
54
|
+
Dispatch.offenses_for(processed_source, config, :assignment_indentation)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Locate the `Parser::AST::Node` whose source range begins at
|
|
58
|
+
# `rhs_begin_pos`. Stock hands the RHS node to `AlignmentCorrector` so
|
|
59
|
+
# that `inside_string_ranges` (heredoc / string literal taboos) and
|
|
60
|
+
# `block_comment_within?` can inspect descendants. Offenses are rare
|
|
61
|
+
# in practice, so the DFS cost is negligible per investigation.
|
|
62
|
+
def locate_rhs_node(rhs_begin_pos)
|
|
63
|
+
processed_source.ast&.each_node do |node|
|
|
64
|
+
return node if node.respond_to?(:loc) &&
|
|
65
|
+
node.source_range &&
|
|
66
|
+
node.source_range.begin_pos == rhs_begin_pos
|
|
67
|
+
end
|
|
68
|
+
nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shirobai
|
|
4
|
+
module Cop
|
|
5
|
+
module Layout
|
|
6
|
+
# Drop-in Rust reimplementation of `Layout/BlockAlignment`.
|
|
7
|
+
#
|
|
8
|
+
# Rust walks the AST once, reproducing stock's `on_block` (and
|
|
9
|
+
# `on_numblock` / `on_itblock`): it picks the block's alignment target by
|
|
10
|
+
# walking the lineage (`block_end_align_target`), unwraps op_asgn / masgn
|
|
11
|
+
# LHS (`find_lhs_node`), and decides whether the closing token (`end` /
|
|
12
|
+
# `}`) is misaligned under the configured `EnforcedStyleAlignWith`. Each
|
|
13
|
+
# misaligned block returns its closing-token range, the formatted message
|
|
14
|
+
# (including the `either`-only " or ..." alternative), and the autocorrect
|
|
15
|
+
# target column (`compute_start_col`).
|
|
16
|
+
#
|
|
17
|
+
# The autocorrect mirrors `BlockAlignment#autocorrect`: the delta between
|
|
18
|
+
# the target column and the closing token's column is applied as inserted
|
|
19
|
+
# spaces before the token (positive delta) or removed leading whitespace
|
|
20
|
+
# (negative delta).
|
|
21
|
+
#
|
|
22
|
+
# Offenses come from the per-file bundled run (`Shirobai::Dispatch`); the
|
|
23
|
+
# style is purely config-driven, so this cop is always bundle eligible.
|
|
24
|
+
class BlockAlignment < RuboCop::Cop::Base
|
|
25
|
+
include RuboCop::Cop::ConfigurableEnforcedStyle
|
|
26
|
+
include RuboCop::Cop::RangeHelp
|
|
27
|
+
extend RuboCop::Cop::AutoCorrector
|
|
28
|
+
|
|
29
|
+
STYLE_TO_U8 = { either: 0, start_of_block: 1, start_of_line: 2 }.freeze
|
|
30
|
+
|
|
31
|
+
def self.cop_name = "Layout/BlockAlignment"
|
|
32
|
+
def self.badge = RuboCop::Cop::Badge.parse(cop_name)
|
|
33
|
+
|
|
34
|
+
# Packed args for the bundled run: `[style]`. `EnforcedStyleAlignWith`
|
|
35
|
+
# defaults to `either` (0) when the config does not mention this cop.
|
|
36
|
+
def self.bundle_args(config)
|
|
37
|
+
align = config.for_badge(badge)["EnforcedStyleAlignWith"]
|
|
38
|
+
[STYLE_TO_U8.fetch((align || "either").to_sym, 0)]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def on_new_investigation
|
|
42
|
+
buffer = processed_source.buffer
|
|
43
|
+
off = SourceOffsets.for(processed_source.raw_source)
|
|
44
|
+
|
|
45
|
+
records_for_source.each do |end_start, end_end, message, align_column|
|
|
46
|
+
end_range = Parser::Source::Range.new(buffer, off[end_start], off[end_end])
|
|
47
|
+
add_offense(end_range, message: message) do |corrector|
|
|
48
|
+
autocorrect(corrector, buffer, end_range, align_column)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# `EnforcedStyleAlignWith` keys the style.
|
|
54
|
+
def style_parameter_name
|
|
55
|
+
"EnforcedStyleAlignWith"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def records_for_source
|
|
61
|
+
Dispatch.offenses_for(processed_source, config, :block_alignment)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# `BlockAlignment#autocorrect`: `delta = start_col - loc_end.column`.
|
|
65
|
+
# Positive inserts `delta` spaces before the closing token; negative
|
|
66
|
+
# removes `-delta` characters of leading whitespace.
|
|
67
|
+
def autocorrect(corrector, buffer, end_range, start_col)
|
|
68
|
+
delta = start_col - end_range.column
|
|
69
|
+
if delta.positive?
|
|
70
|
+
corrector.insert_before(end_range, " " * delta)
|
|
71
|
+
elsif delta.negative?
|
|
72
|
+
range = Parser::Source::Range.new(buffer, end_range.begin_pos + delta, end_range.begin_pos)
|
|
73
|
+
corrector.remove(range)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shirobai
|
|
4
|
+
module Cop
|
|
5
|
+
module Layout
|
|
6
|
+
# Drop-in Rust reimplementation of `Layout/ClosingParenthesisIndentation`.
|
|
7
|
+
#
|
|
8
|
+
# Rust parses the source, walks every parenthesized method call, method
|
|
9
|
+
# definition and grouped expression, and returns each hanging `)` that is
|
|
10
|
+
# misindented as an offense range plus its `column_delta` and message.
|
|
11
|
+
# Ruby supplies the flattened config and applies the realignment via
|
|
12
|
+
# `AlignmentCorrector` over the same `)` range, exactly like stock (whose
|
|
13
|
+
# `autocorrect` passes `right_paren` itself). Offenses come from the
|
|
14
|
+
# per-file bundled run (`Shirobai::Dispatch`); the config is a single
|
|
15
|
+
# number, so this cop is always bundle-eligible.
|
|
16
|
+
class ClosingParenthesisIndentation < RuboCop::Cop::Base
|
|
17
|
+
include RuboCop::Cop::Alignment
|
|
18
|
+
extend RuboCop::Cop::AutoCorrector
|
|
19
|
+
|
|
20
|
+
def self.cop_name = "Layout/ClosingParenthesisIndentation"
|
|
21
|
+
def self.badge = RuboCop::Cop::Badge.parse("Layout/ClosingParenthesisIndentation")
|
|
22
|
+
|
|
23
|
+
# Packed args for the bundled run: `[indentation_width]`
|
|
24
|
+
# (`configured_indentation_width` from the `Alignment` mixin).
|
|
25
|
+
def self.bundle_args(config)
|
|
26
|
+
cop_config = config.for_badge(badge)
|
|
27
|
+
[cop_config["IndentationWidth"] || config.for_cop("Layout/IndentationWidth")["Width"] || 2]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def on_new_investigation
|
|
31
|
+
buffer = processed_source.buffer
|
|
32
|
+
|
|
33
|
+
offenses = Dispatch.offenses_for(processed_source, config, :closing_parenthesis_indentation)
|
|
34
|
+
off = SourceOffsets.for(processed_source.raw_source)
|
|
35
|
+
offenses.each do |start, fin, column_delta, message|
|
|
36
|
+
range = Parser::Source::Range.new(buffer, off[start], off[fin])
|
|
37
|
+
# Stock yields the corrector block for every offense (no per-offense
|
|
38
|
+
# gating); `AlignmentCorrector` itself decides whether the corrector
|
|
39
|
+
# stays empty (tabs / block comments), which keeps the lint-mode
|
|
40
|
+
# `correctable?` status identical to stock.
|
|
41
|
+
add_offense(range, message: message) do |corrector|
|
|
42
|
+
RuboCop::Cop::AlignmentCorrector.correct(
|
|
43
|
+
corrector, processed_source, range, column_delta
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|