rubocop 1.86.1 → 1.86.2
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/config/default.yml +8 -1
- data/lib/rubocop/cli/command/auto_generate_config.rb +27 -1
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/show_docs_url.rb +3 -7
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +4 -7
- data/lib/rubocop/comment_config.rb +12 -15
- data/lib/rubocop/cop/autocorrect_logic.rb +2 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/require_mfa.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +26 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +2 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -8
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +18 -7
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin.rb +85 -0
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +8 -0
- data/lib/rubocop/cop/registry.rb +19 -24
- data/lib/rubocop/cop/style/copyright.rb +21 -10
- data/lib/rubocop/cop/style/date_time.rb +2 -2
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/hash_lookup_method.rb +12 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +15 -2
- data/lib/rubocop/cop/style/module_member_existence_check.rb +6 -3
- data/lib/rubocop/cop/style/reduce_to_hash.rb +16 -0
- data/lib/rubocop/cop/style/redundant_self.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +29 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +3 -3
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
- data/lib/rubocop/cop/team.rb +86 -35
- data/lib/rubocop/formatter/disabled_config_formatter.rb +4 -1
- data/lib/rubocop/lsp/runtime.rb +1 -2
- data/lib/rubocop/options.rb +8 -4
- data/lib/rubocop/rspec/shared_contexts.rb +21 -0
- data/lib/rubocop/runner.rb +77 -55
- data/lib/rubocop/target_finder.rb +13 -6
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +7 -96
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dfb5d2d113d00eb380202a0e76f462318033838aa240febe88bd2861b1bf6609
|
|
4
|
+
data.tar.gz: 9463407310a9babcc5869f9b1db0ca273ed036a3b440b5c27438cba855bee4ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5084465b6aa455c8ecd75e8b8f1e52f92e966d64117d2d88ad343ca535eb6fdc02f05056e6f21ac86e2344ec52cc1db2d69f8bf14a76b76bdee86a2bd5971520
|
|
7
|
+
data.tar.gz: 2101bc8bb5b392fa971f9a881e96b03321442b5067b4952413d806363bb89389cb2631671bfa6af0e30203800cff947d587ac0c68ef1651fdec455cc453faa18
|
data/config/default.yml
CHANGED
|
@@ -529,6 +529,10 @@ Layout/ClosingParenthesisIndentation:
|
|
|
529
529
|
Description: 'Checks the indentation of hanging closing parentheses.'
|
|
530
530
|
Enabled: true
|
|
531
531
|
VersionAdded: '0.49'
|
|
532
|
+
VersionChanged: '1.86'
|
|
533
|
+
# By default the indentation width from `Layout/IndentationWidth` is used,
|
|
534
|
+
# but it can be overridden by setting this parameter.
|
|
535
|
+
IndentationWidth: ~
|
|
532
536
|
|
|
533
537
|
Layout/CommentIndentation:
|
|
534
538
|
Description: 'Indentation of comments.'
|
|
@@ -537,7 +541,10 @@ Layout/CommentIndentation:
|
|
|
537
541
|
# with a comment on the preceding line.
|
|
538
542
|
AllowForAlignment: false
|
|
539
543
|
VersionAdded: '0.49'
|
|
540
|
-
VersionChanged: '1.
|
|
544
|
+
VersionChanged: '1.86'
|
|
545
|
+
# By default the indentation width from `Layout/IndentationWidth` is used,
|
|
546
|
+
# but it can be overridden by setting this parameter.
|
|
547
|
+
IndentationWidth: ~
|
|
541
548
|
|
|
542
549
|
Layout/ConditionPosition:
|
|
543
550
|
Description: >-
|
|
@@ -24,13 +24,39 @@ module RuboCop
|
|
|
24
24
|
|
|
25
25
|
def run
|
|
26
26
|
add_formatter
|
|
27
|
+
use_temporary_cache
|
|
28
|
+
reset_auto_gen_tmp_dir
|
|
27
29
|
reset_config_and_auto_gen_file
|
|
28
30
|
line_length_contents = maybe_run_line_length_cop
|
|
29
|
-
run_all_cops(line_length_contents)
|
|
31
|
+
result = run_all_cops(line_length_contents)
|
|
32
|
+
reset_auto_gen_tmp_dir
|
|
33
|
+
result
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
private
|
|
33
37
|
|
|
38
|
+
def use_temporary_cache
|
|
39
|
+
# Use a separate cache directory to ensure MinDigits and Max values are calculated.
|
|
40
|
+
# This allows parallel execution (which requires cache) while ensuring MinDigits
|
|
41
|
+
# and Max values are computed, since the cache starts empty.
|
|
42
|
+
@options[:cache_root] = auto_gen_tmp_dir.join('cache').to_s
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def reset_auto_gen_tmp_dir
|
|
46
|
+
auto_gen_tmp_dir.rmtree if auto_gen_tmp_dir.exist?
|
|
47
|
+
auto_gen_tmp_dir.mkpath
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def auto_gen_tmp_dir
|
|
51
|
+
@auto_gen_tmp_dir ||= Pathname.new(
|
|
52
|
+
RuboCop::CacheConfig.root_dir_from_toplevel_config
|
|
53
|
+
).join('auto-gen-tmp').tap do |path|
|
|
54
|
+
path.mkpath
|
|
55
|
+
# Set the temp directory path for ExcludeLimit to use
|
|
56
|
+
RuboCop::ExcludeLimit.tmp_dir = path
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
34
60
|
def maybe_run_line_length_cop
|
|
35
61
|
if only_exclude?
|
|
36
62
|
skip_line_length_cop(PHASE_1_SKIPPED_ONLY_EXCLUDE)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
class CLI
|
|
5
|
+
module Command
|
|
6
|
+
# Lists the cops that will inspect the given file or directory.
|
|
7
|
+
# @api private
|
|
8
|
+
class ListEnabledCopsFor < Base
|
|
9
|
+
self.command_name = :list_enabled_cops_for
|
|
10
|
+
|
|
11
|
+
def initialize(env)
|
|
12
|
+
super
|
|
13
|
+
|
|
14
|
+
# Load the configs so the require()s are done for custom cops
|
|
15
|
+
@config = @config_store.for(@options[:list_enabled_cops_for])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run
|
|
19
|
+
print_available_cops
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def print_available_cops
|
|
25
|
+
registry = Cop::Registry.global
|
|
26
|
+
|
|
27
|
+
registry.departments.sort.each do |department|
|
|
28
|
+
puts cops_of_department(registry, department).sort
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cops_of_department(registry, department)
|
|
33
|
+
registry.with_department(department)
|
|
34
|
+
.map(&:cop_name)
|
|
35
|
+
.select { |cop_name| @config.cop_enabled?(cop_name) }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -25,10 +25,10 @@ module RuboCop
|
|
|
25
25
|
puts Cop::Documentation.default_base_url if cops_array.empty?
|
|
26
26
|
|
|
27
27
|
cops_array.each do |cop_name|
|
|
28
|
-
cop =
|
|
29
|
-
next
|
|
28
|
+
cop = Cop::Registry.global.find_by_cop_name(cop_name)
|
|
29
|
+
next unless cop
|
|
30
30
|
|
|
31
|
-
url = Cop::Documentation.url_for(cop
|
|
31
|
+
url = Cop::Documentation.url_for(cop, @config)
|
|
32
32
|
puts url if url
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -38,10 +38,6 @@ module RuboCop
|
|
|
38
38
|
def cops_array
|
|
39
39
|
@cops_array ||= @options[:show_docs_url]
|
|
40
40
|
end
|
|
41
|
-
|
|
42
|
-
def registry_hash
|
|
43
|
-
@registry_hash ||= Cop::Registry.global.to_h
|
|
44
|
-
end
|
|
45
41
|
end
|
|
46
42
|
end
|
|
47
43
|
end
|
|
@@ -60,7 +60,7 @@ module RuboCop
|
|
|
60
60
|
def print_opt_out_instruction
|
|
61
61
|
puts
|
|
62
62
|
puts 'You can opt out of this message by adding the following to your config ' \
|
|
63
|
-
'(see https://docs.rubocop.org/rubocop/
|
|
63
|
+
'(see https://docs.rubocop.org/rubocop/plugins.html#plugin-suggestions ' \
|
|
64
64
|
'for more options):'
|
|
65
65
|
puts ' AllCops:'
|
|
66
66
|
puts ' SuggestExtensions: false'
|
data/lib/rubocop/cli.rb
CHANGED
|
@@ -13,7 +13,7 @@ module RuboCop
|
|
|
13
13
|
DEFAULT_PARALLEL_OPTIONS = %i[
|
|
14
14
|
color config debug display_style_guide display_time display_only_fail_level_offenses
|
|
15
15
|
display_only_failed editor_mode except extra_details fail_level fix_layout format formatters
|
|
16
|
-
ignore_disable_comments lint only only_guide_cops require safe
|
|
16
|
+
ignore_disable_comments lint only only_guide_cops out require safe
|
|
17
17
|
autocorrect safe_autocorrect autocorrect_all
|
|
18
18
|
].freeze
|
|
19
19
|
|
|
@@ -200,18 +200,15 @@ module RuboCop
|
|
|
200
200
|
RuboCop::LSP.enable if @options[:editor_mode]
|
|
201
201
|
end
|
|
202
202
|
|
|
203
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
204
203
|
def handle_exiting_options
|
|
205
204
|
return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
|
|
206
205
|
|
|
207
206
|
run_command(:version) if @options[:version] || @options[:verbose_version]
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
run_command(:mcp) if @options[:mcp]
|
|
207
|
+
%i[show_cops list_enabled_cops_for show_docs_url lsp mcp].each do |name|
|
|
208
|
+
run_command(name) if @options[name]
|
|
209
|
+
end
|
|
212
210
|
raise Finished
|
|
213
211
|
end
|
|
214
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
215
212
|
|
|
216
213
|
def apply_default_formatter
|
|
217
214
|
# This must be done after the options have already been processed,
|
|
@@ -95,7 +95,8 @@ module RuboCop
|
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
99
|
+
def analyze
|
|
99
100
|
return {} if @no_directives
|
|
100
101
|
|
|
101
102
|
analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) }
|
|
@@ -103,9 +104,9 @@ module RuboCop
|
|
|
103
104
|
|
|
104
105
|
each_directive do |directive|
|
|
105
106
|
if directive.push?
|
|
106
|
-
|
|
107
|
-
@stack.push(
|
|
108
|
-
apply_push(analyses,
|
|
107
|
+
restore_point = analyses.transform_values(&:dup)
|
|
108
|
+
@stack.push(restore_point)
|
|
109
|
+
apply_push(analyses, resolve_push_cops(directive), directive.line_number)
|
|
109
110
|
elsif directive.pop?
|
|
110
111
|
pop_state(analyses, directive.line_number) if @stack.any?
|
|
111
112
|
else
|
|
@@ -121,10 +122,7 @@ module RuboCop
|
|
|
121
122
|
hash[cop_name] = cop_line_ranges(analysis)
|
|
122
123
|
end
|
|
123
124
|
end
|
|
124
|
-
|
|
125
|
-
def snapshot_cops(analyses, cop_names)
|
|
126
|
-
cop_names.to_h { |name| [name, analyses[name].dup] }
|
|
127
|
-
end
|
|
125
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
128
126
|
|
|
129
127
|
def resolve_push_cops(directive)
|
|
130
128
|
directive.push_args.transform_values do |names|
|
|
@@ -155,13 +153,12 @@ module RuboCop
|
|
|
155
153
|
end
|
|
156
154
|
|
|
157
155
|
def pop_state(analyses, line)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
new_range =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
analyses[cop] = CopAnalysis.new(ranges, new_start)
|
|
156
|
+
restore_point = @stack.pop
|
|
157
|
+
(restore_point.keys | analyses.keys).each do |cop|
|
|
158
|
+
current = analyses[cop]
|
|
159
|
+
new_range = current.start_line_number ? [current.start_line_number..(line - 1)] : []
|
|
160
|
+
new_start = restore_point[cop]&.start_line_number ? line : nil
|
|
161
|
+
analyses[cop] = CopAnalysis.new(current.line_ranges + new_range, new_start)
|
|
165
162
|
end
|
|
166
163
|
end
|
|
167
164
|
|
|
@@ -50,7 +50,8 @@ module RuboCop
|
|
|
50
50
|
|
|
51
51
|
def disable_offense(offense_range)
|
|
52
52
|
unbreakable_range = multiline_ranges(offense_range)&.find do |range|
|
|
53
|
-
|
|
53
|
+
offense_range.overlaps?(range) &&
|
|
54
|
+
eol_comment_would_be_inside_literal?(offense_range, range)
|
|
54
55
|
end
|
|
55
56
|
|
|
56
57
|
if unbreakable_range
|
|
@@ -59,11 +59,7 @@ module RuboCop
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def content_if_comment_present(corrector, node)
|
|
62
|
-
|
|
63
|
-
children(node).last.source_range,
|
|
64
|
-
side: :right
|
|
65
|
-
).end.resize(1)
|
|
66
|
-
if range.source == '#'
|
|
62
|
+
if processed_source.comment_at_line(children(node).last.last_line)
|
|
67
63
|
select_content_to_be_inserted_after_last_element(corrector, node)
|
|
68
64
|
else
|
|
69
65
|
node.loc.end.source
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop # rubocop:disable Style/Documentation
|
|
5
|
+
# Autoloads corrector classes used by cops. Classes are autoloaded to reduce the number of
|
|
6
|
+
# required classes because they're referenced only when autocorrection is performed.
|
|
7
|
+
|
|
8
|
+
# rubocop:disable Layout/LineLength
|
|
9
|
+
autoload :AlignmentCorrector, 'rubocop/cop/correctors/alignment_corrector'
|
|
10
|
+
autoload :ConditionCorrector, 'rubocop/cop/correctors/condition_corrector'
|
|
11
|
+
autoload :EachToForCorrector, 'rubocop/cop/correctors/each_to_for_corrector'
|
|
12
|
+
autoload :EmptyLineCorrector, 'rubocop/cop/correctors/empty_line_corrector'
|
|
13
|
+
autoload :ForToEachCorrector, 'rubocop/cop/correctors/for_to_each_corrector'
|
|
14
|
+
autoload :IfThenCorrector, 'rubocop/cop/correctors/if_then_corrector'
|
|
15
|
+
autoload :LambdaLiteralToMethodCorrector, 'rubocop/cop/correctors/lambda_literal_to_method_corrector'
|
|
16
|
+
autoload :LineBreakCorrector, 'rubocop/cop/correctors/line_break_corrector'
|
|
17
|
+
autoload :MultilineLiteralBraceCorrector, 'rubocop/cop/correctors/multiline_literal_brace_corrector'
|
|
18
|
+
autoload :OrderedGemCorrector, 'rubocop/cop/correctors/ordered_gem_corrector'
|
|
19
|
+
autoload :ParenthesesCorrector, 'rubocop/cop/correctors/parentheses_corrector'
|
|
20
|
+
autoload :PercentLiteralCorrector, 'rubocop/cop/correctors/percent_literal_corrector'
|
|
21
|
+
autoload :PunctuationCorrector, 'rubocop/cop/correctors/punctuation_corrector'
|
|
22
|
+
autoload :RequireLibraryCorrector, 'rubocop/cop/correctors/require_library_corrector'
|
|
23
|
+
autoload :SpaceCorrector, 'rubocop/cop/correctors/space_corrector'
|
|
24
|
+
autoload :StringLiteralCorrector, 'rubocop/cop/correctors/string_literal_corrector'
|
|
25
|
+
autoload :UnusedArgCorrector, 'rubocop/cop/correctors/unused_arg_corrector'
|
|
26
|
+
# rubocop:enable Layout/LineLength
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -4,16 +4,42 @@ module RuboCop
|
|
|
4
4
|
# Allows specified configuration options to have an exclude limit
|
|
5
5
|
# ie. a maximum value tracked that it can be used by `--auto-gen-config`.
|
|
6
6
|
module ExcludeLimit
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :tmp_dir
|
|
9
|
+
|
|
10
|
+
# Reads the aggregated exclude limit values for a cop from tmp files.
|
|
11
|
+
# Returns a hash like { 'Max' => 81 } or an empty hash if no values were written.
|
|
12
|
+
def read_limits(cop_name)
|
|
13
|
+
cop_dir = cop_dir_for(cop_name)
|
|
14
|
+
return {} unless cop_dir&.directory?
|
|
15
|
+
|
|
16
|
+
limits = {}
|
|
17
|
+
cop_dir.children.each do |filepath|
|
|
18
|
+
next unless filepath.file?
|
|
19
|
+
|
|
20
|
+
values = filepath.readlines.map(&:to_i)
|
|
21
|
+
limits[filepath.basename.to_s] = values.max unless values.empty?
|
|
22
|
+
end
|
|
23
|
+
limits
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns the tmp directory path for a given cop, or nil if tmp_dir is not set.
|
|
27
|
+
def cop_dir_for(cop_name)
|
|
28
|
+
tmp_dir&.join(cop_name.tr('/', '-'))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
7
32
|
# Sets up a configuration option to have an exclude limit tracked.
|
|
8
33
|
# The parameter name given is transformed into a method name (eg. `Max`
|
|
9
34
|
# becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
|
|
10
35
|
def exclude_limit(parameter_name, method_name: transform(parameter_name))
|
|
11
36
|
define_method(:"#{method_name}=") do |value|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
37
|
+
cop_dir = RuboCop::ExcludeLimit.cop_dir_for(self.class.badge.to_s)
|
|
38
|
+
return unless cop_dir
|
|
39
|
+
|
|
40
|
+
cop_dir.mkpath
|
|
41
|
+
filepath = cop_dir.join(parameter_name)
|
|
42
|
+
filepath.write("#{value}\n", mode: 'a')
|
|
17
43
|
end
|
|
18
44
|
end
|
|
19
45
|
|
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
|
70
70
|
def_node_matcher :metadata, <<~PATTERN
|
|
71
71
|
`{
|
|
72
72
|
(send _ :metadata= $_)
|
|
73
|
-
(send (send _ :metadata) :[]= (str "rubygems_mfa_required") $_)
|
|
73
|
+
(send (send _ :metadata) :[]= {(str "rubygems_mfa_required") (sym :rubygems_mfa_required)} $_)
|
|
74
74
|
}
|
|
75
75
|
PATTERN
|
|
76
76
|
|
|
@@ -78,13 +78,13 @@ module RuboCop
|
|
|
78
78
|
def_node_search :metadata_assignment, <<~PATTERN
|
|
79
79
|
`{
|
|
80
80
|
(send _ :metadata= _)
|
|
81
|
-
(send (send _ :metadata) :[]=
|
|
81
|
+
(send (send _ :metadata) :[]= {str sym} _)
|
|
82
82
|
}
|
|
83
83
|
PATTERN
|
|
84
84
|
|
|
85
85
|
# @!method rubygems_mfa_required(node)
|
|
86
86
|
def_node_search :rubygems_mfa_required, <<~PATTERN
|
|
87
|
-
(pair (str "rubygems_mfa_required") $_)
|
|
87
|
+
(pair {(str "rubygems_mfa_required") (sym :rubygems_mfa_required)} $_)
|
|
88
88
|
PATTERN
|
|
89
89
|
|
|
90
90
|
# @!method true_string?(node)
|
|
@@ -158,7 +158,7 @@ module RuboCop
|
|
|
158
158
|
@base = find_hash_pair_alignment_base(node)
|
|
159
159
|
return false if !@base && inside_multiline_chain_arg?(node)
|
|
160
160
|
|
|
161
|
-
@base ||= lhs.source_range
|
|
161
|
+
@base ||= first_dot_alignment_base(node, rhs) || lhs.source_range
|
|
162
162
|
return if aligned_with_first_line_dot?(node, rhs)
|
|
163
163
|
|
|
164
164
|
calculate_column_delta_offense(rhs, @base.column)
|
|
@@ -172,6 +172,31 @@ module RuboCop
|
|
|
172
172
|
first_call.loc.dot.join(first_call.loc.selector)
|
|
173
173
|
end
|
|
174
174
|
|
|
175
|
+
def first_dot_alignment_base(node, rhs)
|
|
176
|
+
return unless rhs.source.start_with?('.', '&.')
|
|
177
|
+
|
|
178
|
+
first_call = first_call_has_a_dot(node)
|
|
179
|
+
dot = first_call.loc.dot
|
|
180
|
+
return unless dot
|
|
181
|
+
return if first_call == node
|
|
182
|
+
|
|
183
|
+
after_block_base = after_multiline_block_base(first_call, node)
|
|
184
|
+
return after_block_base if after_block_base
|
|
185
|
+
|
|
186
|
+
return unless same_line?(dot, first_call.receiver.source_range)
|
|
187
|
+
|
|
188
|
+
dot.join(first_call.loc.selector)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def after_multiline_block_base(first_call, node)
|
|
192
|
+
return unless first_call.block_node&.multiline?
|
|
193
|
+
|
|
194
|
+
after_block = first_call.block_node.parent
|
|
195
|
+
return unless after_block&.call_type? && after_block.loc?(:dot) && after_block != node
|
|
196
|
+
|
|
197
|
+
after_block.loc.dot.join(after_block.loc.selector)
|
|
198
|
+
end
|
|
199
|
+
|
|
175
200
|
def inside_multiline_chain_arg?(node)
|
|
176
201
|
enclosing_call = find_enclosing_chain_call(node)
|
|
177
202
|
return false unless enclosing_call
|
|
@@ -63,19 +63,9 @@ module RuboCop
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def spaces_before_left_parenthesis(node)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
else
|
|
70
|
-
0
|
|
71
|
-
end
|
|
72
|
-
without_receiver = node.source[receiver_length..]
|
|
73
|
-
|
|
74
|
-
# Escape question mark if any.
|
|
75
|
-
method_regexp = Regexp.escape(node.method_name)
|
|
76
|
-
|
|
77
|
-
match = without_receiver.match(/^\s*&?\.?\s*#{method_regexp}(\s+)\(/)
|
|
78
|
-
match ? match.captures[0].length : 0
|
|
66
|
+
return 0 if node.parenthesized?
|
|
67
|
+
|
|
68
|
+
node.first_argument.source_range.begin_pos - node.loc.selector.end_pos
|
|
79
69
|
end
|
|
80
70
|
|
|
81
71
|
def space_range(expr, space_length)
|
|
@@ -40,8 +40,6 @@ module RuboCop
|
|
|
40
40
|
class UselessAssignment < Base
|
|
41
41
|
extend AutoCorrector
|
|
42
42
|
|
|
43
|
-
include RangeHelp
|
|
44
|
-
|
|
45
43
|
MSG = 'Useless assignment to variable - `%<variable>s`.'
|
|
46
44
|
|
|
47
45
|
def self.joining_forces
|
|
@@ -189,12 +187,9 @@ module RuboCop
|
|
|
189
187
|
# rubocop:enable Metrics/AbcSize
|
|
190
188
|
|
|
191
189
|
def remove_exception_assignment_part(corrector, node)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
node.source_range.end_pos
|
|
196
|
-
)
|
|
197
|
-
)
|
|
190
|
+
range = node.parent.children.first&.source_range || node.parent.location.keyword
|
|
191
|
+
|
|
192
|
+
corrector.remove(range.end.join(node.source_range.end))
|
|
198
193
|
end
|
|
199
194
|
|
|
200
195
|
def rename_variable_with_underscore(corrector, node)
|
|
@@ -60,9 +60,7 @@ module RuboCop
|
|
|
60
60
|
return true if _cant_be_nil?(node.expression, receiver)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
# using left_siblings will not work correctly for them.
|
|
65
|
-
if !else_branch?(node) || (node.if_type? && !node.elsif?)
|
|
63
|
+
if sequentially_reached?(node)
|
|
66
64
|
node.left_siblings.reverse_each do |sibling|
|
|
67
65
|
next unless sibling.is_a?(AST::Node)
|
|
68
66
|
|
|
@@ -82,15 +80,17 @@ module RuboCop
|
|
|
82
80
|
!NIL_METHODS.include?(method_name) && !@additional_nil_methods.include?(method_name)
|
|
83
81
|
end
|
|
84
82
|
|
|
85
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
83
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
86
84
|
def sole_condition_of_parent_if?(node)
|
|
87
85
|
child = node
|
|
88
86
|
parent = node.parent
|
|
89
87
|
|
|
90
88
|
while parent
|
|
91
89
|
if parent.if_type?
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
unless parent.unless?
|
|
91
|
+
condition = parent.condition
|
|
92
|
+
return true if !child.equal?(condition) && non_nil_condition?(condition, node)
|
|
93
|
+
end
|
|
94
94
|
|
|
95
95
|
parent = find_top_if(parent) if parent.elsif?
|
|
96
96
|
elsif else_branch?(parent)
|
|
@@ -104,7 +104,7 @@ module RuboCop
|
|
|
104
104
|
|
|
105
105
|
false
|
|
106
106
|
end
|
|
107
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
107
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
108
108
|
|
|
109
109
|
def non_nil_condition?(condition, node)
|
|
110
110
|
return true if condition == node
|
|
@@ -112,6 +112,17 @@ module RuboCop
|
|
|
112
112
|
condition.csend_type? && csend_root_receiver(condition) == node
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
# Whether control reaches `node` by falling through its left siblings rather than by
|
|
116
|
+
# a non-sequential entry. A `resbody` is entered via an exception, the `ensure` branch
|
|
117
|
+
# runs even after a partway raise, and the `else` arm of an `if/elsif` chain is reached by
|
|
118
|
+
# branching (its `if/case` siblings are walked via parent recursion instead).
|
|
119
|
+
def sequentially_reached?(node)
|
|
120
|
+
return false if node.resbody_type?
|
|
121
|
+
return false if node.parent&.ensure_type? && node.parent.branch.equal?(node)
|
|
122
|
+
|
|
123
|
+
!else_branch?(node) || (node.if_type? && !node.elsif?)
|
|
124
|
+
end
|
|
125
|
+
|
|
115
126
|
def else_branch?(node)
|
|
116
127
|
node.parent&.if_type? && node.parent.else_branch == node
|
|
117
128
|
end
|
|
@@ -13,11 +13,12 @@ module RuboCop
|
|
|
13
13
|
`max=` is deprecated. Use `exclude_limit <ParameterName>` instead.
|
|
14
14
|
WARNING
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
cop_dir = RuboCop::ExcludeLimit.cop_dir_for(self.class.badge.to_s)
|
|
17
|
+
return unless cop_dir
|
|
18
|
+
|
|
19
|
+
cop_dir.mkpath
|
|
20
|
+
filepath = cop_dir.join(max_parameter_name)
|
|
21
|
+
filepath.write("#{value}\n", mode: 'a')
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def max_parameter_name
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop # rubocop:disable Style/Documentation
|
|
5
|
+
# Autoloads mixin modules included by cops. Mixins are autoloaded to reduce the number of
|
|
6
|
+
# requires because they're used only when the relevant cop class is loaded.
|
|
7
|
+
|
|
8
|
+
autoload :ArrayMinSize, 'rubocop/cop/mixin/array_min_size'
|
|
9
|
+
autoload :ArraySyntax, 'rubocop/cop/mixin/array_syntax'
|
|
10
|
+
autoload :Alignment, 'rubocop/cop/mixin/alignment'
|
|
11
|
+
autoload :AllowedIdentifiers, 'rubocop/cop/mixin/allowed_identifiers'
|
|
12
|
+
autoload :AllowedMethods, 'rubocop/cop/mixin/allowed_methods'
|
|
13
|
+
autoload :AllowedPattern, 'rubocop/cop/mixin/allowed_pattern'
|
|
14
|
+
autoload :AllowedReceivers, 'rubocop/cop/mixin/allowed_receivers'
|
|
15
|
+
autoload :ForbiddenIdentifiers, 'rubocop/cop/mixin/forbidden_identifiers'
|
|
16
|
+
autoload :ForbiddenPattern, 'rubocop/cop/mixin/forbidden_pattern'
|
|
17
|
+
autoload :AutoCorrector, 'rubocop/cop/mixin/auto_corrector' # rubocop:todo Naming/InclusiveLanguage
|
|
18
|
+
autoload :CheckAssignment, 'rubocop/cop/mixin/check_assignment'
|
|
19
|
+
autoload :CheckLineBreakable, 'rubocop/cop/mixin/check_line_breakable'
|
|
20
|
+
autoload :CheckSingleLineSuitability, 'rubocop/cop/mixin/check_single_line_suitability'
|
|
21
|
+
autoload :ConfigurableMax, 'rubocop/cop/mixin/configurable_max'
|
|
22
|
+
autoload :CodeLength, 'rubocop/cop/mixin/code_length'
|
|
23
|
+
autoload :ConfigurableEnforcedStyle, 'rubocop/cop/mixin/configurable_enforced_style'
|
|
24
|
+
autoload :ConfigurableFormatting, 'rubocop/cop/mixin/configurable_formatting'
|
|
25
|
+
autoload :ConfigurableNaming, 'rubocop/cop/mixin/configurable_naming'
|
|
26
|
+
autoload :ConfigurableNumbering, 'rubocop/cop/mixin/configurable_numbering'
|
|
27
|
+
autoload :DigHelp, 'rubocop/cop/mixin/dig_help'
|
|
28
|
+
autoload :DocumentationComment, 'rubocop/cop/mixin/documentation_comment'
|
|
29
|
+
autoload :Duplication, 'rubocop/cop/mixin/duplication'
|
|
30
|
+
autoload :RangeHelp, 'rubocop/cop/mixin/range_help'
|
|
31
|
+
autoload :AnnotationComment, 'rubocop/cop/mixin/annotation_comment'
|
|
32
|
+
autoload :EmptyParameter, 'rubocop/cop/mixin/empty_parameter'
|
|
33
|
+
autoload :EndKeywordAlignment, 'rubocop/cop/mixin/end_keyword_alignment'
|
|
34
|
+
autoload :EndlessMethodRewriter, 'rubocop/cop/mixin/endless_method_rewriter'
|
|
35
|
+
autoload :EnforceSuperclass, 'rubocop/cop/mixin/enforce_superclass'
|
|
36
|
+
autoload :FirstElementLineBreak, 'rubocop/cop/mixin/first_element_line_break'
|
|
37
|
+
autoload :FrozenStringLiteral, 'rubocop/cop/mixin/frozen_string_literal'
|
|
38
|
+
autoload :GemDeclaration, 'rubocop/cop/mixin/gem_declaration'
|
|
39
|
+
autoload :GemspecHelp, 'rubocop/cop/mixin/gemspec_help'
|
|
40
|
+
autoload :HashAlignmentStyles, 'rubocop/cop/mixin/hash_alignment_styles'
|
|
41
|
+
autoload :HashSubset, 'rubocop/cop/mixin/hash_subset'
|
|
42
|
+
autoload :HashTransformMethod, 'rubocop/cop/mixin/hash_transform_method'
|
|
43
|
+
autoload :IntegerNode, 'rubocop/cop/mixin/integer_node'
|
|
44
|
+
autoload :Interpolation, 'rubocop/cop/mixin/interpolation'
|
|
45
|
+
autoload :LineLengthHelp, 'rubocop/cop/mixin/line_length_help'
|
|
46
|
+
autoload :MatchRange, 'rubocop/cop/mixin/match_range'
|
|
47
|
+
autoload :HashShorthandSyntax, 'rubocop/cop/mixin/hash_shorthand_syntax'
|
|
48
|
+
autoload :MethodComplexity, 'rubocop/cop/mixin/method_complexity'
|
|
49
|
+
autoload :MethodPreference, 'rubocop/cop/mixin/method_preference'
|
|
50
|
+
autoload :MinBodyLength, 'rubocop/cop/mixin/min_body_length'
|
|
51
|
+
autoload :MinBranchesCount, 'rubocop/cop/mixin/min_branches_count'
|
|
52
|
+
autoload :MultilineElementIndentation, 'rubocop/cop/mixin/multiline_element_indentation'
|
|
53
|
+
autoload :MultilineElementLineBreaks, 'rubocop/cop/mixin/multiline_element_line_breaks'
|
|
54
|
+
autoload :MultilineExpressionIndentation, 'rubocop/cop/mixin/multiline_expression_indentation'
|
|
55
|
+
autoload :MultilineLiteralBraceLayout, 'rubocop/cop/mixin/multiline_literal_brace_layout'
|
|
56
|
+
autoload :NegativeConditional, 'rubocop/cop/mixin/negative_conditional'
|
|
57
|
+
autoload :Heredoc, 'rubocop/cop/mixin/heredoc'
|
|
58
|
+
autoload :NilMethods, 'rubocop/cop/mixin/nil_methods'
|
|
59
|
+
autoload :OnNormalIfUnless, 'rubocop/cop/mixin/on_normal_if_unless'
|
|
60
|
+
autoload :OrderedGemNode, 'rubocop/cop/mixin/ordered_gem_node'
|
|
61
|
+
autoload :Parentheses, 'rubocop/cop/mixin/parentheses'
|
|
62
|
+
autoload :PercentArray, 'rubocop/cop/mixin/percent_array'
|
|
63
|
+
autoload :PercentLiteral, 'rubocop/cop/mixin/percent_literal'
|
|
64
|
+
autoload :PrecedingFollowingAlignment, 'rubocop/cop/mixin/preceding_following_alignment'
|
|
65
|
+
autoload :PreferredDelimiters, 'rubocop/cop/mixin/preferred_delimiters'
|
|
66
|
+
autoload :RationalLiteral, 'rubocop/cop/mixin/rational_literal'
|
|
67
|
+
autoload :RequireLibrary, 'rubocop/cop/mixin/require_library'
|
|
68
|
+
autoload :RescueNode, 'rubocop/cop/mixin/rescue_node'
|
|
69
|
+
autoload :SafeAssignment, 'rubocop/cop/mixin/safe_assignment'
|
|
70
|
+
autoload :SpaceAfterPunctuation, 'rubocop/cop/mixin/space_after_punctuation'
|
|
71
|
+
autoload :SpaceBeforePunctuation, 'rubocop/cop/mixin/space_before_punctuation'
|
|
72
|
+
autoload :SurroundingSpace, 'rubocop/cop/mixin/surrounding_space'
|
|
73
|
+
autoload :StatementModifier, 'rubocop/cop/mixin/statement_modifier'
|
|
74
|
+
autoload :StringHelp, 'rubocop/cop/mixin/string_help'
|
|
75
|
+
autoload :StringLiteralsHelp, 'rubocop/cop/mixin/string_literals_help'
|
|
76
|
+
autoload :SymbolHelp, 'rubocop/cop/mixin/symbol_help'
|
|
77
|
+
autoload :TargetRubyVersion, 'rubocop/cop/mixin/target_ruby_version'
|
|
78
|
+
autoload :TrailingBody, 'rubocop/cop/mixin/trailing_body'
|
|
79
|
+
autoload :TrailingComma, 'rubocop/cop/mixin/trailing_comma'
|
|
80
|
+
autoload :UncommunicativeName, 'rubocop/cop/mixin/uncommunicative_name'
|
|
81
|
+
autoload :VisibilityHelp, 'rubocop/cop/mixin/visibility_help'
|
|
82
|
+
autoload :CommentsHelp, 'rubocop/cop/mixin/comments_help'
|
|
83
|
+
autoload :DefNode, 'rubocop/cop/mixin/def_node'
|
|
84
|
+
end
|
|
85
|
+
end
|