rubocop 1.82.1 → 1.84.0
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 +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/config/default.yml +44 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli.rb +2 -1
- data/lib/rubocop/comment_config.rb +1 -0
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +20 -2
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +12 -5
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +32 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +34 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +102 -9
- data/lib/rubocop/cop/layout/line_length.rb +5 -2
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +8 -8
- data/lib/rubocop/cop/lint/duplicate_methods.rb +57 -5
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/to_json.rb +12 -16
- data/lib/rubocop/cop/lint/useless_or.rb +1 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +4 -4
- data/lib/rubocop/cop/naming/predicate_prefix.rb +11 -11
- data/lib/rubocop/cop/offense.rb +2 -1
- data/lib/rubocop/cop/security/json_load.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -2
- data/lib/rubocop/cop/style/documentation.rb +6 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -8
- data/lib/rubocop/cop/style/empty_class_definition.rb +144 -0
- data/lib/rubocop/cop/style/guard_clause.rb +7 -4
- data/lib/rubocop/cop/style/hash_lookup_method.rb +94 -0
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
- data/lib/rubocop/cop/style/lambda_call.rb +8 -8
- data/lib/rubocop/cop/style/module_member_existence_check.rb +56 -13
- data/lib/rubocop/cop/style/negative_array_index.rb +218 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/team.rb +3 -3
- data/lib/rubocop/cop/variable_force/branch.rb +28 -4
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +5 -2
- data/lib/rubocop/remote_config.rb +5 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/target_ruby.rb +3 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +4 -0
- metadata +9 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dbf40b2db6dffc0c0f6685b18afbef40441dfc3650f0176a701ca9442748d12b
|
|
4
|
+
data.tar.gz: 4a40e7f7dbc92057286865804e49fa60b33391cd1947d87447fdaa18a1ad6dd2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0da21b5bc8b4db1ce03eefd577ee4e680354fb4b9bc8c4a1626b74dfe4d8ca4c31f4fcd629a635596db74d8d270686d3b353c3378ccd4d6d7b154129ea4af038
|
|
7
|
+
data.tar.gz: 1b470746489d85337a2ce6f9304d69b875c079a72f383fd8bf2f5154535cac98618341022fc5a5bf1d1fdc5ebe02f6be69d82f64d97c04d250215d41bb7f598b
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -251,5 +251,5 @@ RuboCop's release notes are available [here](https://github.com/rubocop/rubocop/
|
|
|
251
251
|
|
|
252
252
|
## Copyright
|
|
253
253
|
|
|
254
|
-
Copyright (c) 2012-
|
|
254
|
+
Copyright (c) 2012-2026 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
|
255
255
|
further details.
|
data/config/default.yml
CHANGED
|
@@ -835,6 +835,7 @@ Layout/FirstArrayElementLineBreak:
|
|
|
835
835
|
multi-line array.
|
|
836
836
|
Enabled: false
|
|
837
837
|
VersionAdded: '0.49'
|
|
838
|
+
AllowImplicitArrayLiterals: false
|
|
838
839
|
AllowMultilineFinalElement: false
|
|
839
840
|
|
|
840
841
|
Layout/FirstHashElementIndentation:
|
|
@@ -1037,6 +1038,15 @@ Layout/IndentationWidth:
|
|
|
1037
1038
|
VersionAdded: '0.49'
|
|
1038
1039
|
# Number of spaces for each indentation level.
|
|
1039
1040
|
Width: 2
|
|
1041
|
+
# Block body indentation for method chain blocks.
|
|
1042
|
+
# The value `start_of_line` means that block bodies are indented
|
|
1043
|
+
# relative to the start of the line where the block starts.
|
|
1044
|
+
# The value `relative_to_receiver` means that block bodies are indented
|
|
1045
|
+
# relative to the method call position in the chain.
|
|
1046
|
+
EnforcedStyleAlignWith: start_of_line
|
|
1047
|
+
SupportedStylesAlignWith:
|
|
1048
|
+
- start_of_line
|
|
1049
|
+
- relative_to_receiver
|
|
1040
1050
|
AllowedPatterns: []
|
|
1041
1051
|
|
|
1042
1052
|
Layout/InitialIndentation:
|
|
@@ -3967,6 +3977,15 @@ Style/EmptyCaseCondition:
|
|
|
3967
3977
|
Enabled: true
|
|
3968
3978
|
VersionAdded: '0.40'
|
|
3969
3979
|
|
|
3980
|
+
Style/EmptyClassDefinition:
|
|
3981
|
+
Description: 'Enforces consistent style for empty class definitions.'
|
|
3982
|
+
Enabled: pending
|
|
3983
|
+
VersionAdded: '1.83'
|
|
3984
|
+
EnforcedStyle: class_definition
|
|
3985
|
+
SupportedStyles:
|
|
3986
|
+
- class_definition
|
|
3987
|
+
- class_new
|
|
3988
|
+
|
|
3970
3989
|
Style/EmptyElse:
|
|
3971
3990
|
Description: 'Avoid empty else-clauses.'
|
|
3972
3991
|
Enabled: true
|
|
@@ -4318,6 +4337,16 @@ Style/HashLikeCase:
|
|
|
4318
4337
|
# to trigger this cop
|
|
4319
4338
|
MinBranchesCount: 3
|
|
4320
4339
|
|
|
4340
|
+
Style/HashLookupMethod:
|
|
4341
|
+
Description: 'Enforces the use of either `Hash#[]` or `Hash#fetch` for hash lookup.'
|
|
4342
|
+
Enabled: false
|
|
4343
|
+
Safe: false
|
|
4344
|
+
VersionAdded: '1.83'
|
|
4345
|
+
EnforcedStyle: brackets
|
|
4346
|
+
SupportedStyles:
|
|
4347
|
+
- brackets
|
|
4348
|
+
- fetch
|
|
4349
|
+
|
|
4321
4350
|
Style/HashSlice:
|
|
4322
4351
|
Description: >-
|
|
4323
4352
|
Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods
|
|
@@ -4748,6 +4777,7 @@ Style/ModuleMemberExistenceCheck:
|
|
|
4748
4777
|
Description: 'Checks for usage of `Module` methods returning arrays that can be replaced with equivalent predicates.'
|
|
4749
4778
|
Enabled: pending
|
|
4750
4779
|
VersionAdded: '1.82'
|
|
4780
|
+
AllowedMethods: []
|
|
4751
4781
|
|
|
4752
4782
|
Style/MultilineBlockChain:
|
|
4753
4783
|
Description: 'Avoid multi-line chains of blocks.'
|
|
@@ -4876,6 +4906,14 @@ Style/NegatedWhile:
|
|
|
4876
4906
|
Enabled: true
|
|
4877
4907
|
VersionAdded: '0.20'
|
|
4878
4908
|
|
|
4909
|
+
Style/NegativeArrayIndex:
|
|
4910
|
+
Description: >-
|
|
4911
|
+
Use negative array indices instead of calculating array length minus a value.
|
|
4912
|
+
Also handles range patterns with length calculations. Recognizes preserving methods
|
|
4913
|
+
and their combinations, allowing safe replacement when the receiver matches.
|
|
4914
|
+
Enabled: pending
|
|
4915
|
+
VersionAdded: '1.83'
|
|
4916
|
+
|
|
4879
4917
|
Style/NestedFileDirname:
|
|
4880
4918
|
Description: 'Checks for nested `File.dirname`.'
|
|
4881
4919
|
Enabled: pending
|
|
@@ -5527,6 +5565,12 @@ Style/ReturnNilInPredicateMethodDefinition:
|
|
|
5527
5565
|
VersionAdded: '1.53'
|
|
5528
5566
|
VersionChanged: '1.67'
|
|
5529
5567
|
|
|
5568
|
+
Style/ReverseFind:
|
|
5569
|
+
Description: 'Use `array.rfind` instead of `array.reverse.find`.'
|
|
5570
|
+
Enabled: pending
|
|
5571
|
+
Safe: false
|
|
5572
|
+
VersionAdded: '1.83'
|
|
5573
|
+
|
|
5530
5574
|
Style/SafeNavigation:
|
|
5531
5575
|
Description: >-
|
|
5532
5576
|
Transforms usages of a method call safeguarded by
|
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
|
9
9
|
self.command_name = :lsp
|
|
10
10
|
|
|
11
11
|
def run
|
|
12
|
-
# Load on demand, `
|
|
12
|
+
# Load on demand, `language-server-protocol` is heavy to require.
|
|
13
13
|
require_relative '../../lsp/server'
|
|
14
14
|
RuboCop::LSP::Server.new(@config_store).start
|
|
15
15
|
end
|
data/lib/rubocop/cli.rb
CHANGED
|
@@ -165,6 +165,8 @@ module RuboCop
|
|
|
165
165
|
handle_editor_mode
|
|
166
166
|
|
|
167
167
|
@config_store.apply_options!(@options)
|
|
168
|
+
# Set cache root after apply_options! to ensure force_default_config is applied first.
|
|
169
|
+
ConfigLoader.cache_root = ResultCache.cache_root(@config_store, @options[:cache_root])
|
|
168
170
|
|
|
169
171
|
handle_exiting_options
|
|
170
172
|
|
|
@@ -183,7 +185,6 @@ module RuboCop
|
|
|
183
185
|
ConfigLoader.enable_pending_cops = @options[:enable_pending_cops]
|
|
184
186
|
ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion]
|
|
185
187
|
ConfigLoader.ignore_unrecognized_cops = @options[:ignore_unrecognized_cops]
|
|
186
|
-
ConfigLoader.cache_root = ResultCache.cache_root(@config_store, @options[:cache_root])
|
|
187
188
|
end
|
|
188
189
|
|
|
189
190
|
def set_options_to_pending_cops_reporter
|
|
@@ -70,6 +70,7 @@ module RuboCop
|
|
|
70
70
|
def extra_enabled_comments_with_names(extras:, names:)
|
|
71
71
|
each_directive do |directive|
|
|
72
72
|
next unless comment_only_line?(directive.line_number)
|
|
73
|
+
next if directive.push? || directive.pop?
|
|
73
74
|
|
|
74
75
|
if directive.enabled_all?
|
|
75
76
|
handle_enable_all(directive, names, extras)
|
|
@@ -7,48 +7,48 @@ module RuboCop
|
|
|
7
7
|
# ref, or tag) are either required or forbidden.
|
|
8
8
|
#
|
|
9
9
|
# @example EnforcedStyle: required (default)
|
|
10
|
-
#
|
|
11
|
-
#
|
|
10
|
+
# # bad
|
|
11
|
+
# gem 'rubocop'
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
13
|
+
# # good
|
|
14
|
+
# gem 'rubocop', '~> 1.12'
|
|
15
15
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
16
|
+
# # good
|
|
17
|
+
# gem 'rubocop', '>= 1.10.0'
|
|
18
18
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
19
|
+
# # good
|
|
20
|
+
# gem 'rubocop', '>= 1.5.0', '< 1.10.0'
|
|
21
21
|
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
22
|
+
# # good
|
|
23
|
+
# gem 'rubocop', branch: 'feature-branch'
|
|
24
24
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
25
|
+
# # good
|
|
26
|
+
# gem 'rubocop', ref: '74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b'
|
|
27
27
|
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
28
|
+
# # good
|
|
29
|
+
# gem 'rubocop', tag: 'v1.17.0'
|
|
30
30
|
#
|
|
31
31
|
# @example EnforcedStyle: forbidden
|
|
32
|
-
#
|
|
33
|
-
#
|
|
32
|
+
# # good
|
|
33
|
+
# gem 'rubocop'
|
|
34
34
|
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
35
|
+
# # bad
|
|
36
|
+
# gem 'rubocop', '~> 1.12'
|
|
37
37
|
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
38
|
+
# # bad
|
|
39
|
+
# gem 'rubocop', '>= 1.10.0'
|
|
40
40
|
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
41
|
+
# # bad
|
|
42
|
+
# gem 'rubocop', '>= 1.5.0', '< 1.10.0'
|
|
43
43
|
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
44
|
+
# # bad
|
|
45
|
+
# gem 'rubocop', branch: 'feature-branch'
|
|
46
46
|
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
47
|
+
# # bad
|
|
48
|
+
# gem 'rubocop', ref: '74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b'
|
|
49
49
|
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
50
|
+
# # bad
|
|
51
|
+
# gem 'rubocop', tag: 'v1.17.0'
|
|
52
52
|
#
|
|
53
53
|
class GemVersion < Base
|
|
54
54
|
include ConfigurableEnforcedStyle
|
|
@@ -16,6 +16,9 @@ module RuboCop
|
|
|
16
16
|
return unless node
|
|
17
17
|
|
|
18
18
|
@processed_source = processed_source
|
|
19
|
+
# Disable autocorrection for tabs as it requires special handling
|
|
20
|
+
return if using_tabs?
|
|
21
|
+
|
|
19
22
|
expr = node.respond_to?(:loc) ? node.source_range : node
|
|
20
23
|
return if block_comment_within?(expr)
|
|
21
24
|
|
|
@@ -30,11 +33,12 @@ module RuboCop
|
|
|
30
33
|
@processed_source = processed_source
|
|
31
34
|
whitespace = whitespace_range(node)
|
|
32
35
|
column = alignment_column(align_to)
|
|
36
|
+
indentation = indentation_string(column)
|
|
33
37
|
|
|
34
38
|
if whitespace.source.strip.empty?
|
|
35
|
-
corrector.replace(whitespace,
|
|
39
|
+
corrector.replace(whitespace, indentation)
|
|
36
40
|
else
|
|
37
|
-
corrector.insert_after(whitespace, "\n#{
|
|
41
|
+
corrector.insert_after(whitespace, "\n#{indentation}")
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
|
|
@@ -120,6 +124,20 @@ module RuboCop
|
|
|
120
124
|
align_to.column
|
|
121
125
|
end
|
|
122
126
|
end
|
|
127
|
+
|
|
128
|
+
def indentation_string(column)
|
|
129
|
+
if using_tabs?
|
|
130
|
+
"\t" * column
|
|
131
|
+
else
|
|
132
|
+
' ' * column
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def using_tabs?
|
|
137
|
+
config = processed_source.config
|
|
138
|
+
indentation_style = config.for_cop('Layout/IndentationStyle')['EnforcedStyle']
|
|
139
|
+
indentation_style == 'tabs'
|
|
140
|
+
end
|
|
123
141
|
end
|
|
124
142
|
end
|
|
125
143
|
end
|
|
@@ -9,15 +9,15 @@ module RuboCop
|
|
|
9
9
|
# the delimiter.
|
|
10
10
|
#
|
|
11
11
|
# @example
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
12
|
+
# # bad
|
|
13
|
+
# expect_offense(<<~CODE)
|
|
14
|
+
# example_ruby_code
|
|
15
|
+
# CODE
|
|
16
16
|
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
17
|
+
# # good
|
|
18
|
+
# expect_offense(<<~RUBY)
|
|
19
|
+
# example_ruby_code
|
|
20
|
+
# RUBY
|
|
21
21
|
class ExampleHeredocDelimiter < Base
|
|
22
22
|
extend AutoCorrector
|
|
23
23
|
|
|
@@ -8,16 +8,16 @@ module RuboCop
|
|
|
8
8
|
# method.
|
|
9
9
|
#
|
|
10
10
|
# @example
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
11
|
+
# # bad
|
|
12
|
+
# def_node_matcher :foo?, <<~PATTERN
|
|
13
|
+
# ...
|
|
14
|
+
# PATTERN
|
|
15
15
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
16
|
+
# # good
|
|
17
|
+
# # @!method foo?(node)
|
|
18
|
+
# def_node_matcher :foo?, <<~PATTERN
|
|
19
|
+
# ...
|
|
20
|
+
# PATTERN
|
|
21
21
|
#
|
|
22
22
|
class NodeMatcherDirective < Base
|
|
23
23
|
extend AutoCorrector
|
|
@@ -7,11 +7,11 @@ module RuboCop
|
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
10
|
+
# # bad
|
|
11
|
+
# expect(cop.messages).to eq([described_class::MSG])
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
13
|
+
# # good
|
|
14
|
+
# expect(cop.messages).to eq(['Do not write bad code like that.'])
|
|
15
15
|
#
|
|
16
16
|
class UselessMessageAssertion < Base
|
|
17
17
|
MSG = 'Do not specify cop behavior using `described_class::MSG`.'
|
|
@@ -128,7 +128,9 @@ module RuboCop
|
|
|
128
128
|
return if case_match_node.single_line?
|
|
129
129
|
return if enforced_style_end? && end_and_last_conditional_same_line?(case_match_node)
|
|
130
130
|
|
|
131
|
-
case_match_node.
|
|
131
|
+
case_match_node.in_pattern_branches.each do |in_pattern_node|
|
|
132
|
+
check_when(in_pattern_node, 'in')
|
|
133
|
+
end
|
|
132
134
|
end
|
|
133
135
|
|
|
134
136
|
private
|
|
@@ -223,7 +223,7 @@ module RuboCop
|
|
|
223
223
|
# @param node to be analysed
|
|
224
224
|
# @return String when the node type is a `:block` then
|
|
225
225
|
# {classify} recursively with the first children
|
|
226
|
-
# @return String when the node type is a `:send` then {
|
|
226
|
+
# @return String when the node type is a `:send` then {find_send_node_category}
|
|
227
227
|
# by method name
|
|
228
228
|
# @return String otherwise trying to {humanize_node} of the current node
|
|
229
229
|
def classify(node)
|
|
@@ -233,9 +233,10 @@ module RuboCop
|
|
|
233
233
|
when :block
|
|
234
234
|
classify(node.send_node)
|
|
235
235
|
when :send
|
|
236
|
-
|
|
236
|
+
find_send_node_category(node)
|
|
237
237
|
else
|
|
238
|
-
humanize_node(node)
|
|
238
|
+
name = humanize_node(node)
|
|
239
|
+
find_category(name) || name
|
|
239
240
|
end.to_s
|
|
240
241
|
end
|
|
241
242
|
|
|
@@ -244,9 +245,9 @@ module RuboCop
|
|
|
244
245
|
# also its visibility.
|
|
245
246
|
# @param node to be analysed.
|
|
246
247
|
# @return [String] with the key category or the `method_name` as string
|
|
247
|
-
def
|
|
248
|
+
def find_send_node_category(node)
|
|
248
249
|
name = node.method_name.to_s
|
|
249
|
-
category
|
|
250
|
+
category = find_category(name)
|
|
250
251
|
key = category || name
|
|
251
252
|
visibility_key =
|
|
252
253
|
if node.def_modifier?
|
|
@@ -257,6 +258,12 @@ module RuboCop
|
|
|
257
258
|
expected_order.include?(visibility_key) ? visibility_key : key
|
|
258
259
|
end
|
|
259
260
|
|
|
261
|
+
def find_category(name)
|
|
262
|
+
name = name.to_s
|
|
263
|
+
category, = categories.find { |_, names| names.include?(name) }
|
|
264
|
+
category
|
|
265
|
+
end
|
|
266
|
+
|
|
260
267
|
def walk_over_nested_class_definition(class_node)
|
|
261
268
|
class_elements(class_node).each do |node|
|
|
262
269
|
classification = classify(node)
|
|
@@ -172,7 +172,38 @@ module RuboCop
|
|
|
172
172
|
end
|
|
173
173
|
|
|
174
174
|
def autocorrect(corrector, node)
|
|
175
|
-
|
|
175
|
+
return unless node
|
|
176
|
+
|
|
177
|
+
send_node = node.parent
|
|
178
|
+
return unless send_node
|
|
179
|
+
|
|
180
|
+
top_level_send = find_top_level_send(send_node)
|
|
181
|
+
node_to_correct =
|
|
182
|
+
if top_level_send != send_node || should_correct_entire_method_call?(top_level_send)
|
|
183
|
+
top_level_send
|
|
184
|
+
else
|
|
185
|
+
node
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
AlignmentCorrector.correct(corrector, processed_source, node_to_correct, column_delta)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def find_top_level_send(send_node)
|
|
192
|
+
top_level_send = send_node
|
|
193
|
+
while top_level_send.parent&.send_type? &&
|
|
194
|
+
top_level_send.parent.receiver == top_level_send &&
|
|
195
|
+
top_level_send.parent.loc.dot
|
|
196
|
+
top_level_send = top_level_send.parent
|
|
197
|
+
end
|
|
198
|
+
top_level_send
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def should_correct_entire_method_call?(send_node)
|
|
202
|
+
return false unless style == :special_for_inner_method_call_in_parentheses
|
|
203
|
+
return false unless special_inner_call_indentation?(send_node)
|
|
204
|
+
|
|
205
|
+
closing_paren = send_node.loc.end
|
|
206
|
+
closing_paren && begins_its_line?(closing_paren)
|
|
176
207
|
end
|
|
177
208
|
|
|
178
209
|
def bare_operator?(node)
|
|
@@ -20,6 +20,27 @@ module RuboCop
|
|
|
20
20
|
# # good
|
|
21
21
|
# [:a, :b]
|
|
22
22
|
#
|
|
23
|
+
# @example AllowImplicitArrayLiterals: false (default)
|
|
24
|
+
#
|
|
25
|
+
# # bad
|
|
26
|
+
# a = b,
|
|
27
|
+
# c
|
|
28
|
+
#
|
|
29
|
+
# # good
|
|
30
|
+
# a =
|
|
31
|
+
# b,
|
|
32
|
+
# c
|
|
33
|
+
#
|
|
34
|
+
# @example AllowImplicitArrayLiterals: true
|
|
35
|
+
#
|
|
36
|
+
# # good
|
|
37
|
+
# a = b,
|
|
38
|
+
# c
|
|
39
|
+
#
|
|
40
|
+
# a =
|
|
41
|
+
# b,
|
|
42
|
+
# c
|
|
43
|
+
#
|
|
23
44
|
# @example AllowMultilineFinalElement: false (default)
|
|
24
45
|
#
|
|
25
46
|
# # bad
|
|
@@ -48,6 +69,7 @@ module RuboCop
|
|
|
48
69
|
|
|
49
70
|
def on_array(node)
|
|
50
71
|
return if !node.loc.begin && !assignment_on_same_line?(node)
|
|
72
|
+
return if allow_implicit_array_brackets? && !node.bracketed?
|
|
51
73
|
|
|
52
74
|
check_children_line_break(node, node.children, ignore_last: ignore_last_element?)
|
|
53
75
|
end
|
|
@@ -59,6 +81,10 @@ module RuboCop
|
|
|
59
81
|
/\s*=\s*$/.match?(source)
|
|
60
82
|
end
|
|
61
83
|
|
|
84
|
+
def allow_implicit_array_brackets?
|
|
85
|
+
!!cop_config['AllowImplicitArrayLiterals']
|
|
86
|
+
end
|
|
87
|
+
|
|
62
88
|
def ignore_last_element?
|
|
63
89
|
!!cop_config['AllowMultilineFinalElement']
|
|
64
90
|
end
|
|
@@ -8,40 +8,40 @@ module RuboCop
|
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
10
10
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
11
|
+
# # bad
|
|
12
|
+
# { a: 1,
|
|
13
|
+
# b: 2}
|
|
14
14
|
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
15
|
+
# # good
|
|
16
|
+
# {
|
|
17
|
+
# a: 1,
|
|
18
|
+
# b: 2 }
|
|
19
19
|
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
20
|
+
# # good
|
|
21
|
+
# {
|
|
22
|
+
# a: 1, b: {
|
|
23
|
+
# c: 3
|
|
24
|
+
# }}
|
|
25
25
|
#
|
|
26
26
|
# @example AllowMultilineFinalElement: false (default)
|
|
27
27
|
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
28
|
+
# # bad
|
|
29
|
+
# { a: 1, b: {
|
|
30
|
+
# c: 3
|
|
31
|
+
# }}
|
|
32
32
|
#
|
|
33
33
|
# @example AllowMultilineFinalElement: true
|
|
34
34
|
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
35
|
+
# # bad
|
|
36
|
+
# { a: 1,
|
|
37
|
+
# b: {
|
|
38
|
+
# c: 3
|
|
39
|
+
# }}
|
|
40
40
|
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
41
|
+
# # good
|
|
42
|
+
# { a: 1, b: {
|
|
43
|
+
# c: 3
|
|
44
|
+
# }}
|
|
45
45
|
#
|
|
46
46
|
class FirstHashElementLineBreak < Base
|
|
47
47
|
include FirstElementLineBreak
|
|
@@ -21,6 +21,23 @@ module RuboCop
|
|
|
21
21
|
# something
|
|
22
22
|
# RUBY
|
|
23
23
|
#
|
|
24
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
|
25
|
+
# # good
|
|
26
|
+
# <<-RUBY.squish
|
|
27
|
+
# something
|
|
28
|
+
# RUBY
|
|
29
|
+
#
|
|
30
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
|
31
|
+
# # bad
|
|
32
|
+
# <<-RUBY.squish
|
|
33
|
+
# something
|
|
34
|
+
# RUBY
|
|
35
|
+
#
|
|
36
|
+
# # good
|
|
37
|
+
# <<~RUBY.squish
|
|
38
|
+
# something
|
|
39
|
+
# RUBY
|
|
40
|
+
#
|
|
24
41
|
class HeredocIndentation < Base
|
|
25
42
|
include Alignment
|
|
26
43
|
include Heredoc
|
|
@@ -33,6 +50,11 @@ module RuboCop
|
|
|
33
50
|
'heredoc by using `<<~` instead of `%<current_indent_type>s`.'
|
|
34
51
|
WIDTH_MSG = 'Use %<indentation_width>d spaces for indentation in a heredoc.'
|
|
35
52
|
|
|
53
|
+
# @!method squish_method?(node)
|
|
54
|
+
def_node_matcher :squish_method?, <<~PATTERN
|
|
55
|
+
(send _ {:squish :squish!})
|
|
56
|
+
PATTERN
|
|
57
|
+
|
|
36
58
|
def on_heredoc(node)
|
|
37
59
|
body = heredoc_body(node)
|
|
38
60
|
return if body.strip.empty?
|
|
@@ -44,7 +66,7 @@ module RuboCop
|
|
|
44
66
|
expected_indent_level = base_indent_level(node) + configured_indentation_width
|
|
45
67
|
return if expected_indent_level == body_indent_level
|
|
46
68
|
else
|
|
47
|
-
return unless body_indent_level.zero?
|
|
69
|
+
return unless body_indent_level.zero? || heredoc_squish?(node)
|
|
48
70
|
end
|
|
49
71
|
|
|
50
72
|
return if line_too_long?(node)
|
|
@@ -60,6 +82,8 @@ module RuboCop
|
|
|
60
82
|
add_offense(node.loc.heredoc_body, message: message) do |corrector|
|
|
61
83
|
if heredoc_indent_type == '~'
|
|
62
84
|
adjust_squiggly(corrector, node)
|
|
85
|
+
elsif heredoc_squish?(node)
|
|
86
|
+
adjust_heredoc_squish(corrector, node)
|
|
63
87
|
else
|
|
64
88
|
adjust_minus(corrector, node)
|
|
65
89
|
end
|
|
@@ -109,6 +133,11 @@ module RuboCop
|
|
|
109
133
|
config.for_cop('Layout/LineLength')['AllowHeredoc']
|
|
110
134
|
end
|
|
111
135
|
|
|
136
|
+
def adjust_heredoc_squish(corrector, node)
|
|
137
|
+
adjust_squiggly(corrector, node)
|
|
138
|
+
adjust_minus(corrector, node)
|
|
139
|
+
end
|
|
140
|
+
|
|
112
141
|
def adjust_squiggly(corrector, node)
|
|
113
142
|
corrector.replace(node.loc.heredoc_body, indented_body(node))
|
|
114
143
|
corrector.replace(node.loc.heredoc_end, indented_end(node))
|
|
@@ -156,6 +185,10 @@ module RuboCop
|
|
|
156
185
|
def heredoc_end(node)
|
|
157
186
|
node.loc.heredoc_end.source
|
|
158
187
|
end
|
|
188
|
+
|
|
189
|
+
def heredoc_squish?(node)
|
|
190
|
+
active_support_extensions_enabled? && squish_method?(node.parent)
|
|
191
|
+
end
|
|
159
192
|
end
|
|
160
193
|
end
|
|
161
194
|
end
|