rubocop 1.75.1 → 1.75.6
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 +31 -18
- data/lib/rubocop/config_validator.rb +6 -6
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +6 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -4
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +10 -0
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +5 -1
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -5
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +46 -5
- data/lib/rubocop/cop/lint/literal_as_condition.rb +25 -11
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +7 -4
- data/lib/rubocop/cop/lint/return_in_void_context.rb +7 -2
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +2 -2
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +0 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/trailing_comma.rb +9 -5
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +19 -3
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
- data/lib/rubocop/cop/style/comparable_between.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +16 -4
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +4 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +0 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +3 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +3 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +20 -0
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/map_into_array.rb +3 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +13 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +0 -3
- data/lib/rubocop/cop/style/redundant_parentheses.rb +20 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +18 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -2
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +1 -2
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +7 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +6 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
- data/lib/rubocop/magic_comment.rb +8 -0
- data/lib/rubocop/rspec/cop_helper.rb +2 -2
- data/lib/rubocop/rspec/shared_contexts.rb +1 -2
- data/lib/rubocop/server/cache.rb +13 -10
- data/lib/rubocop/target_finder.rb +6 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +5 -5
@@ -4,6 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# Checks for inheritance from `Data.define` to avoid creating the anonymous parent class.
|
7
|
+
# Inheriting from `Data.define` adds a superfluous level in inheritance tree.
|
7
8
|
#
|
8
9
|
# @safety
|
9
10
|
# Autocorrection is unsafe because it will change the inheritance
|
@@ -17,12 +18,18 @@ module RuboCop
|
|
17
18
|
# end
|
18
19
|
# end
|
19
20
|
#
|
21
|
+
# Person.ancestors
|
22
|
+
# # => [Person, #<Class:0x000000010b4e14a0>, Data, (...)]
|
23
|
+
#
|
20
24
|
# # good
|
21
25
|
# Person = Data.define(:first_name, :last_name) do
|
22
26
|
# def age
|
23
27
|
# 42
|
24
28
|
# end
|
25
29
|
# end
|
30
|
+
#
|
31
|
+
# Person.ancestors
|
32
|
+
# # => [Person, Data, (...)]
|
26
33
|
class DataInheritance < Base
|
27
34
|
include RangeHelp
|
28
35
|
extend AutoCorrector
|
@@ -102,7 +102,7 @@ module RuboCop
|
|
102
102
|
|
103
103
|
def find_def_node_from_ascendant(node)
|
104
104
|
return unless (parent = node.parent)
|
105
|
-
return parent if parent.
|
105
|
+
return parent if parent.any_def_type?
|
106
106
|
return node.parent.child_nodes.first if define_method?(parent)
|
107
107
|
|
108
108
|
find_def_node_from_ascendant(node.parent)
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# Checks for the use of a method, the result of which
|
7
7
|
# would be a literal, like an empty array, hash, or string.
|
8
8
|
#
|
9
|
+
# NOTE: When frozen string literals are enabled, `String.new`
|
10
|
+
# isn't corrected to an empty string since the former is
|
11
|
+
# mutable and the latter would be frozen.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
# # bad
|
11
15
|
# a = Array.new
|
@@ -4,12 +4,12 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# Ensures that eval methods (`eval`, `instance_eval`, `class_eval`
|
7
|
-
# and `module_eval`) are given filename and line number values (
|
8
|
-
# and
|
7
|
+
# and `module_eval`) are given filename and line number values (`+__FILE__+`
|
8
|
+
# and `+__LINE__+`). This data is used to ensure that any errors raised
|
9
9
|
# within the evaluated code will be given the correct identification
|
10
10
|
# in a backtrace.
|
11
11
|
#
|
12
|
-
# The cop also checks that the line number given relative to
|
12
|
+
# The cop also checks that the line number given relative to `+__LINE__+` is
|
13
13
|
# correct.
|
14
14
|
#
|
15
15
|
# This cop will autocorrect incorrect or missing filename and line number
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
65
65
|
yielding_block?(block_node) do |send_node, block_args, yield_args|
|
66
66
|
return unless yielding_arguments?(block_args, yield_args)
|
67
67
|
|
68
|
-
def_node = block_node.each_ancestor(:
|
68
|
+
def_node = block_node.each_ancestor(:any_def).first
|
69
69
|
# if `yield` is being called outside of a method context, ignore
|
70
70
|
# this is not a valid ruby pattern, but can happen in haml or erb,
|
71
71
|
# so this can cause crashes in haml_lint
|
@@ -151,7 +151,7 @@ module RuboCop
|
|
151
151
|
end
|
152
152
|
|
153
153
|
def build_new_arguments_for_zsuper(node)
|
154
|
-
def_node = node.each_ancestor(:
|
154
|
+
def_node = node.each_ancestor(:any_def).first
|
155
155
|
def_node.arguments.map do |arg|
|
156
156
|
arg.optarg_type? ? arg.node_parts[0] : arg.source
|
157
157
|
end
|
@@ -151,7 +151,7 @@ module RuboCop
|
|
151
151
|
|
152
152
|
def frozen_string_literal_comment(processed_source)
|
153
153
|
processed_source.tokens.find do |token|
|
154
|
-
token.text.
|
154
|
+
MagicComment.parse(token.text).frozen_string_literal_specified?
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
@@ -189,8 +189,9 @@ module RuboCop
|
|
189
189
|
|
190
190
|
def enable_comment(corrector)
|
191
191
|
comment = frozen_string_literal_comment(processed_source)
|
192
|
+
replacement = MagicComment.parse(comment.text).new_frozen_string_literal(true)
|
192
193
|
|
193
|
-
corrector.replace(line_range(comment.line),
|
194
|
+
corrector.replace(line_range(comment.line), replacement)
|
194
195
|
end
|
195
196
|
|
196
197
|
def insert_comment(corrector)
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
8
8
|
# reassign (possibly to redirect some stream) constants in Ruby, you'll get
|
9
9
|
# an interpreter warning if you do so.
|
10
10
|
#
|
11
|
+
# Additionally, `$stdout/$stderr/$stdin` can safely be accessed in a Ractor because they
|
12
|
+
# are ractor-local, while `STDOUT/STDERR/STDIN` will raise `Ractor::IsolationError`.
|
13
|
+
#
|
11
14
|
# @safety
|
12
15
|
# Autocorrection is unsafe because `STDOUT` and `$stdout` may point to different
|
13
16
|
# objects, for example.
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Looks for uses of
|
7
|
-
#
|
6
|
+
# Looks for uses of `+_.each_with_object({}) {...}+`,
|
7
|
+
# `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
|
8
8
|
# transforming the keys of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_keys` instead.
|
10
10
|
# It should only be enabled on Ruby version 2.5 or newer.
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Looks for uses of
|
7
|
-
#
|
6
|
+
# Looks for uses of `+_.each_with_object({}) {...}+`,
|
7
|
+
# `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
|
8
8
|
# transforming the values of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_values` instead.
|
10
10
|
#
|
@@ -189,7 +189,7 @@ module RuboCop
|
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
192
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
193
193
|
def check_expressions(node, expressions, insert_position)
|
194
194
|
return if expressions.any?(&:nil?)
|
195
195
|
|
@@ -197,7 +197,7 @@ module RuboCop
|
|
197
197
|
|
198
198
|
expressions.each do |expression|
|
199
199
|
add_offense(expression) do |corrector|
|
200
|
-
next if node.if_type? && node.ternary?
|
200
|
+
next if node.if_type? && (node.ternary? || node.then?)
|
201
201
|
|
202
202
|
range = range_by_whole_lines(expression.source_range, include_final_newline: true)
|
203
203
|
corrector.remove(range)
|
@@ -213,7 +213,7 @@ module RuboCop
|
|
213
213
|
end
|
214
214
|
end
|
215
215
|
end
|
216
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
216
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
217
217
|
|
218
218
|
def correct_assignment(corrector, node, expression, insert_position)
|
219
219
|
if insert_position == :after_condition
|
@@ -23,6 +23,17 @@ module RuboCop
|
|
23
23
|
# end
|
24
24
|
# ----
|
25
25
|
#
|
26
|
+
# The code `def method_name = body if condition` is considered a bad case by
|
27
|
+
# `Style/AmbiguousEndlessMethodDefinition` cop. So, to respect the user's intention to use
|
28
|
+
# an endless method definition in the `if` body, the following code is allowed:
|
29
|
+
#
|
30
|
+
# [source,ruby]
|
31
|
+
# ----
|
32
|
+
# if condition
|
33
|
+
# def method_name = body
|
34
|
+
# end
|
35
|
+
# ----
|
36
|
+
#
|
26
37
|
# NOTE: It is allowed when `defined?` argument has an undefined value,
|
27
38
|
# because using the modifier form causes the following incompatibility:
|
28
39
|
#
|
@@ -77,10 +88,14 @@ module RuboCop
|
|
77
88
|
[Style::SoleNestedConditional]
|
78
89
|
end
|
79
90
|
|
91
|
+
# rubocop:disable Metrics/AbcSize
|
80
92
|
def on_if(node)
|
93
|
+
return if endless_method?(node.body)
|
94
|
+
|
81
95
|
condition = node.condition
|
82
96
|
return if defined_nodes(condition).any? { |n| defined_argument_is_undefined?(node, n) } ||
|
83
97
|
pattern_matching_nodes(condition).any?
|
98
|
+
|
84
99
|
return unless (msg = message(node))
|
85
100
|
|
86
101
|
add_offense(node.loc.keyword, message: format(msg, keyword: node.keyword)) do |corrector|
|
@@ -90,9 +105,14 @@ module RuboCop
|
|
90
105
|
ignore_node(node)
|
91
106
|
end
|
92
107
|
end
|
108
|
+
# rubocop:enable Metrics/AbcSize
|
93
109
|
|
94
110
|
private
|
95
111
|
|
112
|
+
def endless_method?(body)
|
113
|
+
body&.any_def_type? && body.endless?
|
114
|
+
end
|
115
|
+
|
96
116
|
def defined_nodes(condition)
|
97
117
|
if condition.defined_type?
|
98
118
|
[condition]
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# `nonzero?` method is allowed by default.
|
11
11
|
# These are customizable with `AllowedMethods` option.
|
12
12
|
#
|
13
|
-
# This cop targets only
|
13
|
+
# This cop targets only ``if``s with a single `elsif` or `else` branch. The following
|
14
14
|
# code will be allowed, because it has two `elsif` branches:
|
15
15
|
#
|
16
16
|
# [source,ruby]
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
42
42
|
return if kwarg_nodes.empty?
|
43
43
|
|
44
44
|
add_offense(node) do |corrector|
|
45
|
-
defining_node = node.each_ancestor(:
|
45
|
+
defining_node = node.each_ancestor(:any_def, :block).first
|
46
46
|
next if processed_source.contains_comment?(arguments_range(defining_node))
|
47
47
|
next unless node.parent.find(&:kwoptarg_type?) == node
|
48
48
|
|
@@ -54,9 +54,14 @@ module RuboCop
|
|
54
54
|
|
55
55
|
def prefer(node)
|
56
56
|
receiver = node.receiver.source
|
57
|
-
arguments = node.arguments.map(&:source).join(', ')
|
58
57
|
dot = node.loc.dot.source
|
59
|
-
|
58
|
+
call_arguments = if node.arguments.empty?
|
59
|
+
''
|
60
|
+
else
|
61
|
+
arguments = node.arguments.map(&:source).join(', ')
|
62
|
+
"(#{arguments})"
|
63
|
+
end
|
64
|
+
method = explicit_style? ? "call#{call_arguments}" : "(#{arguments})"
|
60
65
|
|
61
66
|
"#{receiver}#{dot}#{method}"
|
62
67
|
end
|
@@ -212,9 +212,11 @@ module RuboCop
|
|
212
212
|
end
|
213
213
|
|
214
214
|
def correct_push_node(corrector, push_node)
|
215
|
+
arg_node = push_node.first_argument
|
215
216
|
range = push_node.source_range
|
216
|
-
arg_range =
|
217
|
+
arg_range = arg_node.source_range
|
217
218
|
|
219
|
+
corrector.wrap(arg_node, '{ ', ' }') if arg_node.hash_type? && !arg_node.braces?
|
218
220
|
corrector.remove(range_between(range.begin_pos, arg_range.begin_pos))
|
219
221
|
corrector.remove(range_between(arg_range.end_pos, range.end_pos))
|
220
222
|
end
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
|
50
50
|
def inside_endless_method_def?(node)
|
51
51
|
# parens are required around arguments inside an endless method
|
52
|
-
node.each_ancestor(:
|
52
|
+
node.each_ancestor(:any_def).any?(&:endless?) && node.arguments.any?
|
53
53
|
end
|
54
54
|
|
55
55
|
def require_parentheses_for_hash_value_omission?(node) # rubocop:disable Metrics/PerceivedComplexity
|
@@ -222,6 +222,9 @@ module RuboCop
|
|
222
222
|
end
|
223
223
|
|
224
224
|
def unary_literal?(node)
|
225
|
+
# NOTE: should be removed after releasing https://github.com/rubocop/rubocop-ast/pull/379
|
226
|
+
return node.source.match?(/\A[+-]/) if node.complex_type?
|
227
|
+
|
225
228
|
(node.numeric_type? && node.sign?) ||
|
226
229
|
(node.parent&.send_type? && node.parent.unary_operation?)
|
227
230
|
end
|
@@ -23,11 +23,13 @@ module RuboCop
|
|
23
23
|
'clause in a multiline statement.'
|
24
24
|
|
25
25
|
def on_if(node)
|
26
|
+
return if part_of_ignored_node?(node)
|
26
27
|
return unless node.modifier_form? && node.body.multiline?
|
27
28
|
|
28
29
|
add_offense(node, message: format(MSG, keyword: node.keyword)) do |corrector|
|
29
30
|
corrector.replace(node, to_normal_if(node))
|
30
31
|
end
|
32
|
+
ignore_node(node)
|
31
33
|
end
|
32
34
|
|
33
35
|
private
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
# Report offense only if changing case doesn't change semantics,
|
46
46
|
# i.e., if the string would become dynamic or has special characters.
|
47
47
|
ast = parse(corrected(node.source)).ast
|
48
|
-
return if node.children != ast
|
48
|
+
return if node.children != ast&.children
|
49
49
|
|
50
50
|
add_offense(node.loc.begin) do |corrector|
|
51
51
|
corrector.replace(node, corrected(node.source))
|
@@ -230,6 +230,14 @@ module RuboCop
|
|
230
230
|
node.type?(:kwsplat, :forwarded_kwrestarg)
|
231
231
|
end
|
232
232
|
|
233
|
+
def wrap_arguments_with_parens(condition)
|
234
|
+
method = condition.source_range.begin.join(condition.loc.selector.end)
|
235
|
+
arguments = condition.first_argument.source_range.begin.join(condition.source_range.end)
|
236
|
+
|
237
|
+
"#{method.source}(#{arguments.source})"
|
238
|
+
end
|
239
|
+
|
240
|
+
# rubocop:disable Metrics/AbcSize
|
233
241
|
def if_source(if_branch, arithmetic_operation)
|
234
242
|
if branches_have_method?(if_branch.parent) && if_branch.parenthesized?
|
235
243
|
if_branch.source.delete_suffix(')')
|
@@ -238,11 +246,15 @@ module RuboCop
|
|
238
246
|
|
239
247
|
"#{if_branch.receiver.source} #{if_branch.method_name} (#{argument_source}"
|
240
248
|
elsif if_branch.true_type?
|
241
|
-
if_branch.parent.condition
|
249
|
+
condition = if_branch.parent.condition
|
250
|
+
return condition.source if condition.arguments.empty?
|
251
|
+
|
252
|
+
wrap_arguments_with_parens(condition)
|
242
253
|
else
|
243
254
|
if_branch.source
|
244
255
|
end
|
245
256
|
end
|
257
|
+
# rubocop:enable Metrics/AbcSize
|
246
258
|
|
247
259
|
def else_source(else_branch, arithmetic_operation) # rubocop:disable Metrics/AbcSize
|
248
260
|
if arithmetic_operation
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
|
21
21
|
MSG = 'Remove the redundant current directory path.'
|
22
22
|
RESTRICT_ON_SEND = %i[require_relative].freeze
|
23
|
-
CURRENT_DIRECTORY_PREFIX = %r{
|
23
|
+
CURRENT_DIRECTORY_PREFIX = %r{\./+}.freeze
|
24
24
|
REDUNDANT_CURRENT_DIRECTORY_PREFIX = /\A#{CURRENT_DIRECTORY_PREFIX}/.freeze
|
25
25
|
|
26
26
|
def on_send(node)
|
@@ -181,9 +181,7 @@ module RuboCop
|
|
181
181
|
ARGUMENT_TYPES.include?(next_token.type)
|
182
182
|
end
|
183
183
|
|
184
|
-
# rubocop:disable Metrics/AbcSize
|
185
184
|
def argument_newline?(node)
|
186
|
-
node = node.to_a.last if node.assignment?
|
187
185
|
return false if node.parenthesized_call?
|
188
186
|
|
189
187
|
node = node.children.first if node.root? && node.begin_type?
|
@@ -196,7 +194,6 @@ module RuboCop
|
|
196
194
|
node.loc.selector.line != node.first_argument.loc.line
|
197
195
|
end
|
198
196
|
end
|
199
|
-
# rubocop:enable Metrics/AbcSize
|
200
197
|
|
201
198
|
def find_node_for_line(last_line)
|
202
199
|
processed_source.ast.each_node do |node|
|
@@ -78,7 +78,7 @@ module RuboCop
|
|
78
78
|
ancestor = node.ancestors.first
|
79
79
|
return false unless ancestor
|
80
80
|
|
81
|
-
!ancestor.type?(:begin, :
|
81
|
+
!ancestor.type?(:begin, :any_def, :any_block)
|
82
82
|
end
|
83
83
|
|
84
84
|
def allowed_ternary?(node)
|
@@ -98,7 +98,7 @@ module RuboCop
|
|
98
98
|
return false unless node.type?(:send, :super, :yield)
|
99
99
|
|
100
100
|
node.arguments.one? && !node.parenthesized? &&
|
101
|
-
!node.
|
101
|
+
!node.operator_method? && node.first_argument.begin_type?
|
102
102
|
end
|
103
103
|
|
104
104
|
def multiline_control_flow_statements?(node)
|
@@ -134,7 +134,9 @@ module RuboCop
|
|
134
134
|
node = begin_node.children.first
|
135
135
|
|
136
136
|
if (message = find_offense_message(begin_node, node))
|
137
|
-
|
137
|
+
if node.range_type? && !argument_of_parenthesized_method_call?(begin_node)
|
138
|
+
begin_node = begin_node.parent
|
139
|
+
end
|
138
140
|
|
139
141
|
return offense(begin_node, message)
|
140
142
|
end
|
@@ -155,6 +157,7 @@ module RuboCop
|
|
155
157
|
return 'an expression'
|
156
158
|
end
|
157
159
|
return 'an interpolated expression' if interpolation?(begin_node)
|
160
|
+
return 'a method argument' if argument_of_parenthesized_method_call?(begin_node)
|
158
161
|
|
159
162
|
return if begin_node.chained?
|
160
163
|
|
@@ -177,6 +180,20 @@ module RuboCop
|
|
177
180
|
# @!method interpolation?(node)
|
178
181
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
179
182
|
|
183
|
+
def argument_of_parenthesized_method_call?(begin_node)
|
184
|
+
node = begin_node.children.first
|
185
|
+
return false if node.basic_conditional? || method_call_parentheses_required?(node)
|
186
|
+
return false unless (parent = begin_node.parent)
|
187
|
+
|
188
|
+
parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
|
189
|
+
end
|
190
|
+
|
191
|
+
def method_call_parentheses_required?(node)
|
192
|
+
return false unless node.call_type?
|
193
|
+
|
194
|
+
(node.receiver.nil? || node.loc.dot) && node.arguments.any?
|
195
|
+
end
|
196
|
+
|
180
197
|
def allow_in_multiline_conditions?
|
181
198
|
!!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
|
182
199
|
end
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
|
48
48
|
def on_return(node)
|
49
49
|
# Check Lint/NonLocalExitFromIterator first before this cop
|
50
|
-
node.each_ancestor(:block, :
|
50
|
+
node.each_ancestor(:block, :any_def) do |n|
|
51
51
|
break if scoped_node?(n)
|
52
52
|
|
53
53
|
send_node, args_node, _body_node = *n
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def scoped_node?(node)
|
86
|
-
node.
|
86
|
+
node.any_def_type? || node.lambda?
|
87
87
|
end
|
88
88
|
|
89
89
|
# @!method chained_send?(node)
|
@@ -174,12 +174,17 @@ module RuboCop
|
|
174
174
|
range_with_surrounding_space(range: lhs.source_range, side: :right),
|
175
175
|
range_with_surrounding_space(range: lhs_operator_range, side: :right),
|
176
176
|
offense_range: range_between(lhs.source_range.begin_pos, rhs.source_range.end_pos)
|
177
|
-
)
|
177
|
+
) do |corrector|
|
178
|
+
corrector.replace(rhs_receiver, lhs_receiver.source)
|
179
|
+
end
|
180
|
+
ignore_node(node)
|
178
181
|
end
|
179
182
|
end
|
180
183
|
|
181
184
|
def report_offense(node, rhs, rhs_receiver, *removal_ranges, offense_range: node)
|
182
185
|
add_offense(offense_range) do |corrector|
|
186
|
+
next if ignored_node?(node)
|
187
|
+
|
183
188
|
# If the RHS is an `or` we cannot safely autocorrect because in order to remove
|
184
189
|
# the non-nil check we need to add safe-navs to all clauses where the receiver is used
|
185
190
|
next if and_with_rhs_or?(node)
|
@@ -227,7 +232,7 @@ module RuboCop
|
|
227
232
|
end
|
228
233
|
|
229
234
|
def offending_node?(node, lhs_receiver, rhs, rhs_receiver) # rubocop:disable Metrics/CyclomaticComplexity
|
230
|
-
return false if lhs_receiver
|
235
|
+
return false if !matching_nodes?(lhs_receiver, rhs_receiver) || rhs_receiver.nil?
|
231
236
|
return false if use_var_only_in_unless_modifier?(node, lhs_receiver)
|
232
237
|
return false if chain_length(rhs, rhs_receiver) > max_chain_length
|
233
238
|
return false if unsafe_method_used?(rhs, rhs_receiver.parent)
|
@@ -306,11 +311,21 @@ module RuboCop
|
|
306
311
|
|
307
312
|
receiver = method_chain.receiver
|
308
313
|
|
309
|
-
return receiver if receiver
|
314
|
+
return receiver if matching_nodes?(receiver, checked_variable)
|
310
315
|
|
311
316
|
find_matching_receiver_invocation(receiver, checked_variable)
|
312
317
|
end
|
313
318
|
|
319
|
+
def matching_nodes?(left, right)
|
320
|
+
left == right || matching_call_nodes?(left, right)
|
321
|
+
end
|
322
|
+
|
323
|
+
def matching_call_nodes?(left, right)
|
324
|
+
return false unless left && right.respond_to?(:call_type?)
|
325
|
+
|
326
|
+
left.call_type? && right.call_type? && left.children == right.children
|
327
|
+
end
|
328
|
+
|
314
329
|
def chain_length(method_chain, method)
|
315
330
|
method.each_ancestor(:call).inject(0) do |total, ancestor|
|
316
331
|
break total + 1 if ancestor == method_chain
|
@@ -185,8 +185,10 @@ module RuboCop
|
|
185
185
|
end
|
186
186
|
|
187
187
|
def add_parentheses?(node)
|
188
|
-
node.assignment? || (node.operator_keyword? && !node.and_type?)
|
189
|
-
|
188
|
+
return true if node.assignment? || (node.operator_keyword? && !node.and_type?)
|
189
|
+
return false unless node.call_type?
|
190
|
+
|
191
|
+
(node.arguments.any? && !node.parenthesized?) || node.prefix_not?
|
190
192
|
end
|
191
193
|
|
192
194
|
def parenthesized_method_arguments(node)
|
@@ -51,7 +51,6 @@ module RuboCop
|
|
51
51
|
# Pathname.new('/') + 'test'
|
52
52
|
#
|
53
53
|
class StringConcatenation < Base
|
54
|
-
include RangeHelp
|
55
54
|
extend AutoCorrector
|
56
55
|
|
57
56
|
MSG = 'Prefer string interpolation to string concatenation.'
|
@@ -147,7 +146,7 @@ module RuboCop
|
|
147
146
|
when :str
|
148
147
|
adjust_str(part)
|
149
148
|
when :dstr
|
150
|
-
part.children.all?(&:str_type?) ? adjust_str(part) :
|
149
|
+
part.children.all?(&:str_type?) ? adjust_str(part) : part.value
|
151
150
|
else
|
152
151
|
"\#{#{part.source}}"
|
153
152
|
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for inheritance from Struct.new.
|
6
|
+
# Checks for inheritance from `Struct.new`. Inheriting from `Struct.new`
|
7
|
+
# adds a superfluous level in inheritance tree.
|
7
8
|
#
|
8
9
|
# @safety
|
9
10
|
# Autocorrection is unsafe because it will change the inheritance
|
@@ -17,12 +18,18 @@ module RuboCop
|
|
17
18
|
# end
|
18
19
|
# end
|
19
20
|
#
|
21
|
+
# Person.ancestors
|
22
|
+
# # => [Person, #<Class:0x000000010b4e14a0>, Struct, (...)]
|
23
|
+
#
|
20
24
|
# # good
|
21
25
|
# Person = Struct.new(:first_name, :last_name) do
|
22
26
|
# def age
|
23
27
|
# 42
|
24
28
|
# end
|
25
29
|
# end
|
30
|
+
#
|
31
|
+
# Person.ancestors
|
32
|
+
# # => [Person, Struct, (...)]
|
26
33
|
class StructInheritance < Base
|
27
34
|
include RangeHelp
|
28
35
|
extend AutoCorrector
|
@@ -68,7 +68,6 @@ module RuboCop
|
|
68
68
|
class SuperArguments < Base
|
69
69
|
extend AutoCorrector
|
70
70
|
|
71
|
-
DEF_TYPES = %i[def defs].freeze
|
72
71
|
ASSIGN_TYPES = %i[or_asgn lvasgn].freeze
|
73
72
|
|
74
73
|
MSG = 'Call `super` without arguments and parentheses when the signature is identical.'
|
@@ -100,7 +99,7 @@ module RuboCop
|
|
100
99
|
# `super` used within the block is always allowed.
|
101
100
|
break if node.any_block_type? && !block_sends_to_super?(super_node, node)
|
102
101
|
|
103
|
-
break node if
|
102
|
+
break node if node.any_def_type?
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
@@ -79,10 +79,16 @@ module RuboCop
|
|
79
79
|
# # bad
|
80
80
|
# method(1, 2,)
|
81
81
|
#
|
82
|
+
# # bad
|
83
|
+
# object[1, 2,]
|
84
|
+
#
|
82
85
|
# # good
|
83
86
|
# method(1, 2)
|
84
87
|
#
|
85
88
|
# # good
|
89
|
+
# object[1, 2]
|
90
|
+
#
|
91
|
+
# # good
|
86
92
|
# method(
|
87
93
|
# 1,
|
88
94
|
# 2
|
@@ -96,7 +102,7 @@ module RuboCop
|
|
96
102
|
end
|
97
103
|
|
98
104
|
def on_send(node)
|
99
|
-
return unless node.arguments? && node.parenthesized?
|
105
|
+
return unless node.arguments? && (node.parenthesized? || node.method?(:[]))
|
100
106
|
|
101
107
|
check(node, node.arguments, 'parameter of %<article>s method call',
|
102
108
|
node.last_argument.source_range.end_pos,
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
11
11
|
# * `comma`: Requires a comma after the last item in an array, but only when each item is on
|
12
12
|
# its own line.
|
13
13
|
# * `diff_comma`: Requires a comma after the last item in an array, but only when that item is
|
14
|
-
# followed by an immediate newline.
|
14
|
+
# followed by an immediate newline, even if there is an inline comment on the same line.
|
15
15
|
# * `no_comma`: Does not require a comma after the last item in an array
|
16
16
|
#
|
17
17
|
# @example EnforcedStyleForMultiline: consistent_comma
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
11
11
|
# * `comma`: Requires a comma after the last item in a hash, but only when each item is on its
|
12
12
|
# own line.
|
13
13
|
# * `diff_comma`: Requires a comma after the last item in a hash, but only when that item is
|
14
|
-
# followed by an immediate newline.
|
14
|
+
# followed by an immediate newline, even if there is an inline comment on the same line.
|
15
15
|
# * `no_comma`: Does not require a comma after the last item in a hash
|
16
16
|
#
|
17
17
|
# @example EnforcedStyleForMultiline: consistent_comma
|