rubocop 1.75.8 → 1.79.1
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/README.md +20 -16
- data/config/default.yml +107 -26
- data/config/obsoletion.yml +6 -3
- data/lib/rubocop/cli.rb +12 -1
- data/lib/rubocop/config_loader.rb +1 -38
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +0 -22
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +99 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +26 -5
- data/lib/rubocop/cop/layout/space_around_keyword.rb +6 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +8 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +2 -9
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -2
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +25 -4
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +4 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/literal_as_condition.rb +34 -28
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +4 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
- data/lib/rubocop/cop/lint/self_assignment.rb +25 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +29 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +24 -8
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/method_name.rb +127 -13
- data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +13 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +11 -17
- data/lib/rubocop/cop/style/array_intersect.rb +53 -23
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -2
- data/lib/rubocop/cop/style/dig_chain.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -2
- data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- data/lib/rubocop/cop/style/if_unless_modifier.rb +13 -6
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +36 -15
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -6
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +16 -0
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +32 -20
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +35 -5
- data/lib/rubocop/cop/style/redundant_self.rb +8 -5
- data/lib/rubocop/cop/style/safe_navigation.rb +24 -11
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -4
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +32 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +18 -7
- data/lib/rubocop/cops_documentation_generator.rb +1 -0
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -0
- data/lib/rubocop/lsp/diagnostic.rb +4 -4
- data/lib/rubocop/lsp/routes.rb +4 -4
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/rspec/expect_offense.rb +9 -3
- data/lib/rubocop/server/cache.rb +4 -2
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +11 -1
- data/lib/ruby_lsp/rubocop/addon.rb +2 -2
- metadata +21 -8
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Gemspec
|
6
|
+
# Use consistent style for Gemspec attributes assignment.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# # This example uses two styles for assignment of metadata attribute.
|
12
|
+
# Gem::Specification.new do |spec|
|
13
|
+
# spec.metadata = { 'key' => 'value' }
|
14
|
+
# spec.metadata['another-key'] = 'another-value'
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# Gem::Specification.new do |spec|
|
19
|
+
# spec.metadata['key'] = 'value'
|
20
|
+
# spec.metadata['another-key'] = 'another-value'
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# Gem::Specification.new do |spec|
|
25
|
+
# spec.metadata = { 'key' => 'value', 'another-key' => 'another-value' }
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# # bad
|
29
|
+
# # This example uses two styles for assignment of authors attribute.
|
30
|
+
# Gem::Specification.new do |spec|
|
31
|
+
# spec.authors = %w[author-0 author-1]
|
32
|
+
# spec.authors[2] = 'author-2'
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# Gem::Specification.new do |spec|
|
37
|
+
# spec.authors = %w[author-0 author-1 author-2]
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# Gem::Specification.new do |spec|
|
42
|
+
# spec.authors[0] = 'author-0'
|
43
|
+
# spec.authors[1] = 'author-1'
|
44
|
+
# spec.authors[2] = 'author-2'
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# # This example uses consistent assignment per attribute,
|
49
|
+
# # even though two different styles are used overall.
|
50
|
+
# Gem::Specification.new do |spec|
|
51
|
+
# spec.metadata = { 'key' => 'value' }
|
52
|
+
# spec.authors[0] = 'author-0'
|
53
|
+
# spec.authors[1] = 'author-1'
|
54
|
+
# spec.authors[2] = 'author-2'
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
class AttributeAssignment < Base
|
58
|
+
include GemspecHelp
|
59
|
+
|
60
|
+
MSG = 'Use consistent style for Gemspec attributes assignment.'
|
61
|
+
|
62
|
+
def on_new_investigation
|
63
|
+
return if processed_source.blank?
|
64
|
+
|
65
|
+
assignments = source_assignments(processed_source.ast)
|
66
|
+
indexed_assignments = source_indexed_assignments(processed_source.ast)
|
67
|
+
|
68
|
+
assignments.keys.intersection(indexed_assignments.keys).each do |attribute|
|
69
|
+
indexed_assignments[attribute].each do |node|
|
70
|
+
add_offense(node)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def source_assignments(ast)
|
78
|
+
assignment_method_declarations(ast)
|
79
|
+
.select(&:assignment_method?)
|
80
|
+
.group_by(&:method_name)
|
81
|
+
.transform_keys { |method_name| method_name.to_s.delete_suffix('=').to_sym }
|
82
|
+
end
|
83
|
+
|
84
|
+
def source_indexed_assignments(ast)
|
85
|
+
indexed_assignment_method_declarations(ast)
|
86
|
+
.group_by { |node| node.children.first.method_name }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -54,22 +54,6 @@ module RuboCop
|
|
54
54
|
MSG = '`%<assignment>s` method calls already given on line ' \
|
55
55
|
'%<line_of_first_occurrence>d of the gemspec.'
|
56
56
|
|
57
|
-
# @!method assignment_method_declarations(node)
|
58
|
-
def_node_search :assignment_method_declarations, <<~PATTERN
|
59
|
-
(send
|
60
|
-
(lvar #match_block_variable_name?) _ ...)
|
61
|
-
PATTERN
|
62
|
-
|
63
|
-
# @!method indexed_assignment_method_declarations(node)
|
64
|
-
def_node_search :indexed_assignment_method_declarations, <<~PATTERN
|
65
|
-
(send
|
66
|
-
(send (lvar #match_block_variable_name?) _)
|
67
|
-
:[]=
|
68
|
-
literal?
|
69
|
-
_
|
70
|
-
)
|
71
|
-
PATTERN
|
72
|
-
|
73
57
|
def on_new_investigation
|
74
58
|
return if processed_source.blank?
|
75
59
|
|
@@ -96,12 +80,6 @@ module RuboCop
|
|
96
80
|
end
|
97
81
|
end
|
98
82
|
|
99
|
-
def match_block_variable_name?(receiver_name)
|
100
|
-
gem_specification(processed_source.ast) do |block_variable_name|
|
101
|
-
return block_variable_name == receiver_name
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
83
|
def duplicated_assignment_method_nodes
|
106
84
|
assignment_method_declarations(processed_source.ast)
|
107
85
|
.select(&:assignment_method?)
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
71
71
|
|
72
72
|
dependency_declarations(processed_source.ast)
|
73
73
|
.each_cons(2) do |previous, current|
|
74
|
-
next unless consecutive_lines(previous, current)
|
74
|
+
next unless consecutive_lines?(previous, current)
|
75
75
|
next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
|
76
76
|
next unless get_dependency_name(previous) == get_dependency_name(current)
|
77
77
|
|
@@ -74,6 +74,14 @@ module RuboCop
|
|
74
74
|
}
|
75
75
|
PATTERN
|
76
76
|
|
77
|
+
# @!method metadata_assignment(node)
|
78
|
+
def_node_search :metadata_assignment, <<~PATTERN
|
79
|
+
`{
|
80
|
+
(send _ :metadata= _)
|
81
|
+
(send (send _ :metadata) :[]= (str _) _)
|
82
|
+
}
|
83
|
+
PATTERN
|
84
|
+
|
77
85
|
# @!method rubygems_mfa_required(node)
|
78
86
|
def_node_search :rubygems_mfa_required, <<~PATTERN
|
79
87
|
(pair (str "rubygems_mfa_required") $_)
|
@@ -131,9 +139,15 @@ module RuboCop
|
|
131
139
|
end
|
132
140
|
|
133
141
|
def insert_mfa_required(corrector, node, block_var)
|
134
|
-
|
142
|
+
require_mfa_directive = <<~RUBY.strip
|
135
143
|
#{block_var}.metadata['rubygems_mfa_required'] = 'true'
|
136
144
|
RUBY
|
145
|
+
|
146
|
+
if (last_assignment = metadata_assignment(processed_source.ast).to_a.last)
|
147
|
+
corrector.insert_after(last_assignment, "\n#{require_mfa_directive}")
|
148
|
+
else
|
149
|
+
corrector.insert_before(node.loc.end, "#{require_mfa_directive}\n")
|
150
|
+
end
|
137
151
|
end
|
138
152
|
|
139
153
|
def change_value(corrector, value)
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
/\A(does not|doesn't) (register|find|flag|report)/ => 'registers',
|
47
47
|
/\A(does not|doesn't) add (a|an|any )?offense/ => 'registers an offense',
|
48
48
|
/\Aregisters no offense/ => 'registers an offense',
|
49
|
-
/\A(accepts|register)\b/ => 'registers'
|
49
|
+
/\A(accepts|allows|register)\b/ => 'registers'
|
50
50
|
}.freeze
|
51
51
|
|
52
52
|
EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING = {
|
@@ -110,8 +110,8 @@ module RuboCop
|
|
110
110
|
def directive_offense_type(directive, actual_name)
|
111
111
|
return :missing_directive unless directive
|
112
112
|
|
113
|
-
return :wrong_scope if wrong_scope(directive, actual_name)
|
114
|
-
return :no_scope if no_scope(directive, actual_name)
|
113
|
+
return :wrong_scope if wrong_scope?(directive, actual_name)
|
114
|
+
return :no_scope if no_scope?(directive, actual_name)
|
115
115
|
|
116
116
|
# The method directive being prefixed by 'self.' is always an offense.
|
117
117
|
# The matched method_name does not contain the receiver but the
|
@@ -121,11 +121,11 @@ module RuboCop
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
def wrong_scope(directive, actual_name)
|
124
|
+
def wrong_scope?(directive, actual_name)
|
125
125
|
!actual_name.start_with?('self.') && directive[:has_scope_directive]
|
126
126
|
end
|
127
127
|
|
128
|
-
def no_scope(directive, actual_name)
|
128
|
+
def no_scope?(directive, actual_name)
|
129
129
|
actual_name.start_with?('self.') && !directive[:has_scope_directive]
|
130
130
|
end
|
131
131
|
|
@@ -29,6 +29,7 @@ module RuboCop
|
|
29
29
|
NODE_GROUPS = {
|
30
30
|
any_block: %i[block numblock itblock],
|
31
31
|
any_def: %i[def defs],
|
32
|
+
any_match_pattern: %i[match_pattern match_pattern_p],
|
32
33
|
argument: %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg forward_arg shadowarg],
|
33
34
|
boolean: %i[true false],
|
34
35
|
call: %i[send csend],
|
@@ -66,8 +66,9 @@ module RuboCop
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def autocorrect_to_explicit_predicate(corrector, node, group_name)
|
69
|
-
|
70
|
-
|
69
|
+
range = node.loc.selector.begin.join(node.source_range.end)
|
70
|
+
|
71
|
+
corrector.replace(range, "#{group_name}_type?")
|
71
72
|
end
|
72
73
|
|
73
74
|
def autocorrect_keep_method(corrector, symbol_args, group_name, group_types)
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Layout
|
6
|
+
# Checks for an empty line after a module inclusion method (`extend`,
|
7
|
+
# `include` and `prepend`), or a group of them.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# class Foo
|
12
|
+
# include Bar
|
13
|
+
# attr_reader :baz
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
# class Foo
|
18
|
+
# include Bar
|
19
|
+
#
|
20
|
+
# attr_reader :baz
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # also good - multiple module inclusions grouped together
|
24
|
+
# class Foo
|
25
|
+
# extend Bar
|
26
|
+
# include Baz
|
27
|
+
# prepend Qux
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
class EmptyLinesAfterModuleInclusion < Base
|
31
|
+
include RangeHelp
|
32
|
+
extend AutoCorrector
|
33
|
+
|
34
|
+
MSG = 'Add an empty line after module inclusion.'
|
35
|
+
|
36
|
+
MODULE_INCLUSION_METHODS = %i[include extend prepend].freeze
|
37
|
+
|
38
|
+
RESTRICT_ON_SEND = MODULE_INCLUSION_METHODS
|
39
|
+
|
40
|
+
def on_send(node)
|
41
|
+
return if node.receiver
|
42
|
+
return if node.parent&.type?(:send, :any_block)
|
43
|
+
|
44
|
+
return if next_line_empty_or_enable_directive_comment?(node.last_line)
|
45
|
+
|
46
|
+
next_line_node = next_line_node(node)
|
47
|
+
return unless require_empty_line?(next_line_node)
|
48
|
+
|
49
|
+
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def autocorrect(corrector, node)
|
55
|
+
node_range = range_by_whole_lines(node.source_range)
|
56
|
+
|
57
|
+
next_line = node_range.last_line + 1
|
58
|
+
if enable_directive_comment?(next_line)
|
59
|
+
node_range = processed_source.comment_at_line(next_line)
|
60
|
+
end
|
61
|
+
|
62
|
+
corrector.insert_after(node_range, "\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
def next_line_empty_or_enable_directive_comment?(line)
|
66
|
+
line_empty?(line) || (enable_directive_comment?(line + 1) && line_empty?(line + 1))
|
67
|
+
end
|
68
|
+
|
69
|
+
def enable_directive_comment?(line)
|
70
|
+
return false unless (comment = processed_source.comment_at_line(line))
|
71
|
+
|
72
|
+
DirectiveComment.new(comment).enabled?
|
73
|
+
end
|
74
|
+
|
75
|
+
def line_empty?(line)
|
76
|
+
processed_source[line].nil? || processed_source[line].blank?
|
77
|
+
end
|
78
|
+
|
79
|
+
def require_empty_line?(node)
|
80
|
+
return false unless node
|
81
|
+
|
82
|
+
!allowed_method?(node)
|
83
|
+
end
|
84
|
+
|
85
|
+
def allowed_method?(node)
|
86
|
+
return false unless node.send_type?
|
87
|
+
|
88
|
+
MODULE_INCLUSION_METHODS.include?(node.method_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
def next_line_node(node)
|
92
|
+
return if node.parent.if_type?
|
93
|
+
|
94
|
+
node.right_sibling
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -138,7 +138,7 @@ module RuboCop
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def previous_line_ignoring_comments(processed_source, send_line)
|
141
|
-
processed_source[0..send_line - 2].reverse.find { |line| !comment_line?(line) }
|
141
|
+
processed_source[0..(send_line - 2)].reverse.find { |line| !comment_line?(line) }
|
142
142
|
end
|
143
143
|
|
144
144
|
def previous_line_empty?(send_line)
|
@@ -258,7 +258,7 @@ module RuboCop
|
|
258
258
|
if ignore_cop_directives? && directive_on_source_line?(line_index)
|
259
259
|
return check_directive_line(line, line_index)
|
260
260
|
end
|
261
|
-
return
|
261
|
+
return check_line_for_exemptions(line, line_index) if allow_uri? || allow_qualified_name?
|
262
262
|
|
263
263
|
register_offense(excess_range(nil, line, line_index), line, line_index)
|
264
264
|
end
|
@@ -358,11 +358,32 @@ module RuboCop
|
|
358
358
|
)
|
359
359
|
end
|
360
360
|
|
361
|
-
def
|
362
|
-
uri_range
|
363
|
-
|
361
|
+
def check_line_for_exemptions(line, line_index)
|
362
|
+
uri_range = range_if_applicable(line, :uri)
|
363
|
+
qualified_name_range = range_if_applicable(line, :qualified_name)
|
364
364
|
|
365
|
-
|
365
|
+
return if allowed_combination?(line, uri_range, qualified_name_range)
|
366
|
+
|
367
|
+
range = uri_range || qualified_name_range
|
368
|
+
register_offense(excess_range(range, line, line_index), line, line_index)
|
369
|
+
end
|
370
|
+
|
371
|
+
def range_if_applicable(line, type)
|
372
|
+
return unless type == :uri ? allow_uri? : allow_qualified_name?
|
373
|
+
|
374
|
+
find_excessive_range(line, type)
|
375
|
+
end
|
376
|
+
|
377
|
+
def allowed_combination?(line, uri_range, qualified_name_range)
|
378
|
+
if uri_range && qualified_name_range
|
379
|
+
allowed_position?(line, uri_range) && allowed_position?(line, qualified_name_range)
|
380
|
+
elsif uri_range
|
381
|
+
allowed_position?(line, uri_range)
|
382
|
+
elsif qualified_name_range
|
383
|
+
allowed_position?(line, qualified_name_range)
|
384
|
+
else
|
385
|
+
false
|
386
|
+
end
|
366
387
|
end
|
367
388
|
|
368
389
|
def breakable_dstr?(node)
|
@@ -16,6 +16,8 @@ module RuboCop
|
|
16
16
|
#
|
17
17
|
# something = 123if test
|
18
18
|
#
|
19
|
+
# return(foo + bar)
|
20
|
+
#
|
19
21
|
# # good
|
20
22
|
# something 'test' do |x|
|
21
23
|
# end
|
@@ -24,6 +26,9 @@ module RuboCop
|
|
24
26
|
# end
|
25
27
|
#
|
26
28
|
# something = 123 if test
|
29
|
+
#
|
30
|
+
# return (foo + bar)
|
31
|
+
#
|
27
32
|
class SpaceAroundKeyword < Base
|
28
33
|
extend AutoCorrector
|
29
34
|
|
@@ -33,7 +38,7 @@ module RuboCop
|
|
33
38
|
DO = 'do'
|
34
39
|
SAFE_NAVIGATION = '&.'
|
35
40
|
NAMESPACE_OPERATOR = '::'
|
36
|
-
ACCEPT_LEFT_PAREN = %w[break defined? next not rescue
|
41
|
+
ACCEPT_LEFT_PAREN = %w[break defined? next not rescue super yield].freeze
|
37
42
|
ACCEPT_LEFT_SQUARE_BRACKET = %w[super yield].freeze
|
38
43
|
ACCEPT_NAMESPACE_OPERATOR = 'super'
|
39
44
|
RESTRICT_ON_SEND = %i[!].freeze
|
@@ -151,6 +151,14 @@ module RuboCop
|
|
151
151
|
check_operator(:match_pattern, node.loc.operator, node)
|
152
152
|
end
|
153
153
|
|
154
|
+
def on_match_alt(node)
|
155
|
+
check_operator(:match_alt, node.loc.operator, node)
|
156
|
+
end
|
157
|
+
|
158
|
+
def on_match_as(node)
|
159
|
+
check_operator(:match_as, node.loc.operator, node)
|
160
|
+
end
|
161
|
+
|
154
162
|
alias on_or on_binary
|
155
163
|
alias on_and on_binary
|
156
164
|
alias on_lvasgn on_assignment
|
@@ -22,10 +22,11 @@ module RuboCop
|
|
22
22
|
RESTRICT_ON_SEND = %i[[] []=].freeze
|
23
23
|
|
24
24
|
def on_send(node)
|
25
|
+
return if node.loc.dot
|
26
|
+
|
25
27
|
receiver_end_pos = node.receiver.source_range.end_pos
|
26
28
|
selector_begin_pos = node.loc.selector.begin_pos
|
27
29
|
return if receiver_end_pos >= selector_begin_pos
|
28
|
-
return if dot_before_brackets?(node, receiver_end_pos, selector_begin_pos)
|
29
30
|
|
30
31
|
range = range_between(receiver_end_pos, selector_begin_pos)
|
31
32
|
|
@@ -33,14 +34,6 @@ module RuboCop
|
|
33
34
|
corrector.remove(range)
|
34
35
|
end
|
35
36
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def dot_before_brackets?(node, receiver_end_pos, selector_begin_pos)
|
40
|
-
return false unless node.loc.respond_to?(:dot) && (dot = node.loc.dot)
|
41
|
-
|
42
|
-
dot.begin_pos == receiver_end_pos && dot.end_pos == selector_begin_pos
|
43
|
-
end
|
44
37
|
end
|
45
38
|
end
|
46
39
|
end
|
@@ -86,6 +86,7 @@ module RuboCop
|
|
86
86
|
def on_array(node)
|
87
87
|
return if node.array_type? && !node.square_brackets?
|
88
88
|
|
89
|
+
node = find_node_with_brackets(node)
|
89
90
|
tokens, left, right = array_brackets(node)
|
90
91
|
return unless left && right
|
91
92
|
|
@@ -102,6 +103,10 @@ module RuboCop
|
|
102
103
|
|
103
104
|
private
|
104
105
|
|
106
|
+
def find_node_with_brackets(node)
|
107
|
+
node.ancestors.find(&:const_pattern_type?) || node
|
108
|
+
end
|
109
|
+
|
105
110
|
def autocorrect(corrector, node)
|
106
111
|
tokens, left, right = array_brackets(node)
|
107
112
|
|
@@ -119,7 +124,7 @@ module RuboCop
|
|
119
124
|
def array_brackets(node)
|
120
125
|
tokens = processed_source.tokens_within(node)
|
121
126
|
|
122
|
-
left = tokens.find(&:
|
127
|
+
left = tokens.find(&:left_bracket?)
|
123
128
|
right = tokens.reverse_each.find(&:right_bracket?)
|
124
129
|
|
125
130
|
[tokens, left, right]
|
@@ -192,7 +197,7 @@ module RuboCop
|
|
192
197
|
if side == :right
|
193
198
|
processed_source.tokens_within(node)[i].right_bracket?
|
194
199
|
else
|
195
|
-
processed_source.tokens_within(node)[i].
|
200
|
+
processed_source.tokens_within(node)[i].left_bracket?
|
196
201
|
end
|
197
202
|
end
|
198
203
|
|
@@ -27,7 +27,9 @@ module RuboCop
|
|
27
27
|
# @example
|
28
28
|
# # bad
|
29
29
|
# x || 1..2
|
30
|
+
# x - 1..2
|
30
31
|
# (x || 1..2)
|
32
|
+
# x || 1..y || 2
|
31
33
|
# 1..2.to_a
|
32
34
|
#
|
33
35
|
# # good, unambiguous
|
@@ -41,6 +43,7 @@ module RuboCop
|
|
41
43
|
#
|
42
44
|
# # good, ambiguity removed
|
43
45
|
# x || (1..2)
|
46
|
+
# (x - 1)..2
|
44
47
|
# (x || 1)..2
|
45
48
|
# (x || 1)..(y || 2)
|
46
49
|
# (1..2).to_a
|
@@ -96,6 +99,8 @@ module RuboCop
|
|
96
99
|
# to avoid the ambiguity of `1..2.to_a`.
|
97
100
|
return false if node.receiver&.basic_literal?
|
98
101
|
|
102
|
+
return false if node.operator_method? && !node.method?(:[])
|
103
|
+
|
99
104
|
require_parentheses_for_method_chain? || node.receiver.nil?
|
100
105
|
end
|
101
106
|
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# Checks for duplicated instance (or singleton) method
|
7
7
|
# definitions.
|
8
8
|
#
|
9
|
+
# NOTE: Aliasing a method to itself is allowed, as it indicates that
|
10
|
+
# the developer intends to suppress Ruby's method redefinition warnings.
|
11
|
+
# See https://bugs.ruby-lang.org/issues/13574.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
#
|
11
15
|
# # bad
|
@@ -40,6 +44,18 @@ module RuboCop
|
|
40
44
|
#
|
41
45
|
# alias bar foo
|
42
46
|
#
|
47
|
+
# # good
|
48
|
+
# alias foo foo
|
49
|
+
# def foo
|
50
|
+
# 1
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# # good
|
54
|
+
# alias_method :foo, :foo
|
55
|
+
# def foo
|
56
|
+
# 1
|
57
|
+
# end
|
58
|
+
#
|
43
59
|
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
44
60
|
#
|
45
61
|
# # good
|
@@ -113,11 +129,13 @@ module RuboCop
|
|
113
129
|
|
114
130
|
# @!method method_alias?(node)
|
115
131
|
def_node_matcher :method_alias?, <<~PATTERN
|
116
|
-
(alias (sym $_name) sym)
|
132
|
+
(alias (sym $_name) (sym $_original_name))
|
117
133
|
PATTERN
|
118
134
|
|
119
135
|
def on_alias(node)
|
120
|
-
|
136
|
+
name, original_name = method_alias?(node)
|
137
|
+
return unless name && original_name
|
138
|
+
return if name == original_name
|
121
139
|
return if node.ancestors.any?(&:if_type?)
|
122
140
|
|
123
141
|
found_instance_method(node, name)
|
@@ -125,7 +143,7 @@ module RuboCop
|
|
125
143
|
|
126
144
|
# @!method alias_method?(node)
|
127
145
|
def_node_matcher :alias_method?, <<~PATTERN
|
128
|
-
(send nil? :alias_method (sym $_name)
|
146
|
+
(send nil? :alias_method (sym $_name) (sym $_original_name))
|
129
147
|
PATTERN
|
130
148
|
|
131
149
|
# @!method delegate_method?(node)
|
@@ -140,7 +158,10 @@ module RuboCop
|
|
140
158
|
def_node_matcher :sym_name, '(sym $_name)'
|
141
159
|
|
142
160
|
def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
143
|
-
|
161
|
+
name, original_name = alias_method?(node)
|
162
|
+
|
163
|
+
if name && original_name
|
164
|
+
return if name == original_name
|
144
165
|
return if node.ancestors.any?(&:if_type?)
|
145
166
|
|
146
167
|
found_instance_method(node, name)
|
@@ -19,7 +19,9 @@ module RuboCop
|
|
19
19
|
MSG = 'Empty interpolation detected.'
|
20
20
|
|
21
21
|
def on_interpolation(begin_node)
|
22
|
-
|
22
|
+
node_children = begin_node.children.dup
|
23
|
+
node_children.delete_if { |e| e.nil_type? || (e.basic_literal? && e.str_content&.empty?) }
|
24
|
+
return unless node_children.empty?
|
23
25
|
|
24
26
|
add_offense(begin_node) { |corrector| corrector.remove(begin_node) }
|
25
27
|
end
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
when :float
|
95
95
|
true
|
96
96
|
when :send
|
97
|
-
|
97
|
+
float_send?(node)
|
98
98
|
when :begin
|
99
99
|
float?(node.children.first)
|
100
100
|
else
|
@@ -108,18 +108,18 @@ module RuboCop
|
|
108
108
|
(node.numeric_type? && node.value.zero?) || node.nil_type?
|
109
109
|
end
|
110
110
|
|
111
|
-
def
|
111
|
+
def float_send?(node)
|
112
112
|
if node.arithmetic_operation?
|
113
113
|
float?(node.receiver) || float?(node.first_argument)
|
114
114
|
elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
|
115
115
|
true
|
116
116
|
elsif node.receiver&.float_type?
|
117
117
|
FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
|
118
|
-
|
118
|
+
numeric_returning_method?(node)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
def
|
122
|
+
def numeric_returning_method?(node)
|
123
123
|
return false unless node.receiver
|
124
124
|
|
125
125
|
case node.method_name
|